From f920584d7997f89aa366690a656a303a98710b63 Mon Sep 17 00:00:00 2001 From: ONDC-Tech <110763128+ONDC-Tech@users.noreply.github.com> Date: Sun, 7 Aug 2022 18:36:20 +0530 Subject: [PATCH 001/228] Initial commit --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..150fdd6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# reference-implementations +ONDC reference apps From a3fdac0c7eb1d9919d60e2f5f03792adac789288 Mon Sep 17 00:00:00 2001 From: navdeep710 Date: Sat, 20 Aug 2022 09:56:22 +0530 Subject: [PATCH 002/228] Added reference apps for each layer --- .gitmodules | 15 +++++++++++++++ README.md | 9 +++++++++ frontend-ui/frontend-react-js-based-buyer-app | 1 + .../kotlin-based-buyer-app-side-protocol-layer | 1 + .../python-based-buyer-app-side-protocol-layer | 1 + server-side-clients/kotlin-based-buyer-app-client | 1 + .../node-js-based-buyer-app-client | 1 + 7 files changed, 29 insertions(+) create mode 100644 .gitmodules create mode 160000 frontend-ui/frontend-react-js-based-buyer-app create mode 160000 protocol-layer/kotlin-based-buyer-app-side-protocol-layer create mode 160000 protocol-layer/python-based-buyer-app-side-protocol-layer create mode 160000 server-side-clients/kotlin-based-buyer-app-client create mode 160000 server-side-clients/node-js-based-buyer-app-client diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..108ae69 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,15 @@ +[submodule "protocol-layer/python-based-protocol-layer"] + path = protocol-layer/python-based-buyer-app-side-protocol-layer + url = https://github.com/Open-network-for-digital-commerce/py-protocol-layer.git +[submodule "protocol-layer/kotlin-based-buyer-app-side-protocol-layer"] + path = protocol-layer/kotlin-based-buyer-app-side-protocol-layer + url = https://github.com/beckn/biab-bap-protocol.git +[submodule "server-side-clients/node-js-based-buyer-app-client"] + path = server-side-clients/node-js-based-buyer-app-client + url = https://github.com/Open-network-for-digital-commerce/biap-client-node-js.git +[submodule "server-side-clients/kotlin-based-buyer-app-client"] + path = server-side-clients/kotlin-based-buyer-app-client + url = https://github.com/beckn/biab-bap-client.git +[submodule "frontend-ui/frontend-react-js-based-buyer-app"] + path = frontend-ui/frontend-react-js-based-buyer-app + url = https://github.com/Open-network-for-digital-commerce/biap-app-ui-front.git diff --git a/README.md b/README.md index 150fdd6..81658e6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # reference-implementations ONDC reference apps + +- [ ] protocol layer + - [ ] https://github.com/Open-network-for-digital-commerce/py-protocol-layer.git + - [ ] https://github.com/beckn/biab-bap-protocol.git +- [ ] server-side clients + - [ ] https://github.com/Open-network-for-digital-commerce/biap-client-node-js.git + - [ ] https://github.com/beckn/biab-bap-client.git +- [ ] frontend-ui + - [ ] https://github.com/Open-network-for-digital-commerce/biap-app-ui-front.git diff --git a/frontend-ui/frontend-react-js-based-buyer-app b/frontend-ui/frontend-react-js-based-buyer-app new file mode 160000 index 0000000..f49d20a --- /dev/null +++ b/frontend-ui/frontend-react-js-based-buyer-app @@ -0,0 +1 @@ +Subproject commit f49d20ad02c2aa12d2b135a01d1f6f3673a4f6db diff --git a/protocol-layer/kotlin-based-buyer-app-side-protocol-layer b/protocol-layer/kotlin-based-buyer-app-side-protocol-layer new file mode 160000 index 0000000..8036db2 --- /dev/null +++ b/protocol-layer/kotlin-based-buyer-app-side-protocol-layer @@ -0,0 +1 @@ +Subproject commit 8036db2551b94dcc9c5eb6e158d80f617597b7d4 diff --git a/protocol-layer/python-based-buyer-app-side-protocol-layer b/protocol-layer/python-based-buyer-app-side-protocol-layer new file mode 160000 index 0000000..2a9b71c --- /dev/null +++ b/protocol-layer/python-based-buyer-app-side-protocol-layer @@ -0,0 +1 @@ +Subproject commit 2a9b71c42175fcf649a5071f076760820a9016c7 diff --git a/server-side-clients/kotlin-based-buyer-app-client b/server-side-clients/kotlin-based-buyer-app-client new file mode 160000 index 0000000..145b487 --- /dev/null +++ b/server-side-clients/kotlin-based-buyer-app-client @@ -0,0 +1 @@ +Subproject commit 145b487332baeef727bdba8918a383d51e58da7d diff --git a/server-side-clients/node-js-based-buyer-app-client b/server-side-clients/node-js-based-buyer-app-client new file mode 160000 index 0000000..5813e79 --- /dev/null +++ b/server-side-clients/node-js-based-buyer-app-client @@ -0,0 +1 @@ +Subproject commit 5813e79471e68d41bc71c319af69dd9cf54cd740 From 73ff5cdb54578c9900e31fc0181dd4247b08cbbb Mon Sep 17 00:00:00 2001 From: navdeep710 Date: Thu, 10 Nov 2022 10:42:45 +0530 Subject: [PATCH 003/228] Added utilities --- utilities/docs/allclasses-index.html | 76 ++ utilities/docs/allpackages-index.html | 64 ++ utilities/docs/element-list | 1 + utilities/docs/help-doc.html | 176 ++++ utilities/docs/index-files/index-1.html | 81 ++ utilities/docs/index-files/index-2.html | 65 ++ utilities/docs/index-files/index-3.html | 81 ++ utilities/docs/index-files/index-4.html | 63 ++ utilities/docs/index-files/index-5.html | 73 ++ utilities/docs/index-files/index-6.html | 75 ++ utilities/docs/index-files/index-7.html | 65 ++ utilities/docs/index.html | 26 + utilities/docs/jquery-ui.overrides.css | 34 + utilities/docs/legal/ADDITIONAL_LICENSE_INFO | 1 + utilities/docs/legal/ASSEMBLY_EXCEPTION | 1 + utilities/docs/legal/LICENSE | 1 + utilities/docs/legal/jquery.md | 72 ++ utilities/docs/legal/jqueryUI.md | 49 + utilities/docs/member-search-index.js | 1 + utilities/docs/module-search-index.js | 1 + .../org/ondc/crypto/util/CryptoFunctions.html | 419 +++++++++ .../org/ondc/crypto/util/CryptoKeyPair.html | 224 +++++ .../docs/org/ondc/crypto/util/CryptoTest.html | 225 +++++ .../util/class-use/CryptoFunctions.html | 57 ++ .../crypto/util/class-use/CryptoKeyPair.html | 82 ++ .../crypto/util/class-use/CryptoTest.html | 57 ++ .../org/ondc/crypto/util/package-summary.html | 92 ++ .../org/ondc/crypto/util/package-tree.html | 69 ++ .../org/ondc/crypto/util/package-use.html | 74 ++ utilities/docs/overview-tree.html | 73 ++ utilities/docs/package-search-index.js | 1 + utilities/docs/resources/glass.png | Bin 0 -> 499 bytes utilities/docs/resources/x.png | Bin 0 -> 394 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 335 bytes .../images/ui-bg_glass_65_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 280 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 6999 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes utilities/docs/script-dir/jquery-3.5.1.min.js | 2 + utilities/docs/script-dir/jquery-ui.min.css | 7 + utilities/docs/script-dir/jquery-ui.min.js | 6 + .../script-dir/jquery-ui.structure.min.css | 5 + utilities/docs/script.js | 132 +++ utilities/docs/search.js | 354 +++++++ utilities/docs/stylesheet.css | 865 ++++++++++++++++++ utilities/docs/tag-search-index.js | 1 + utilities/docs/type-search-index.js | 1 + .../ondc-crypto-utility-master/LICENSE.txt | 48 + .../ondc-crypto-utility-master/README.md | 27 + .../docs/allclasses-index.html | 76 ++ .../docs/allpackages-index.html | 64 ++ .../docs/element-list | 1 + .../docs/help-doc.html | 176 ++++ .../docs/index-files/index-1.html | 81 ++ .../docs/index-files/index-2.html | 65 ++ .../docs/index-files/index-3.html | 81 ++ .../docs/index-files/index-4.html | 63 ++ .../docs/index-files/index-5.html | 73 ++ .../docs/index-files/index-6.html | 75 ++ .../docs/index-files/index-7.html | 65 ++ .../docs/index.html | 26 + .../docs/jquery-ui.overrides.css | 34 + .../docs/legal/ADDITIONAL_LICENSE_INFO | 1 + .../docs/legal/ASSEMBLY_EXCEPTION | 1 + .../docs/legal/LICENSE | 1 + .../docs/legal/jquery.md | 72 ++ .../docs/legal/jqueryUI.md | 49 + .../docs/member-search-index.js | 1 + .../docs/module-search-index.js | 1 + .../org/ondc/crypto/util/CryptoFunctions.html | 419 +++++++++ .../org/ondc/crypto/util/CryptoKeyPair.html | 224 +++++ .../docs/org/ondc/crypto/util/CryptoTest.html | 225 +++++ .../util/class-use/CryptoFunctions.html | 57 ++ .../crypto/util/class-use/CryptoKeyPair.html | 82 ++ .../crypto/util/class-use/CryptoTest.html | 57 ++ .../org/ondc/crypto/util/package-summary.html | 92 ++ .../org/ondc/crypto/util/package-tree.html | 69 ++ .../org/ondc/crypto/util/package-use.html | 74 ++ .../docs/overview-tree.html | 73 ++ .../docs/package-search-index.js | 1 + .../docs/resources/glass.png | Bin 0 -> 499 bytes .../docs/resources/x.png | Bin 0 -> 394 bytes .../images/ui-bg_glass_55_fbf9ee_1x400.png | Bin 0 -> 335 bytes .../images/ui-bg_glass_65_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_dadada_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_75_e6e6e6_1x400.png | Bin 0 -> 262 bytes .../images/ui-bg_glass_95_fef1ec_1x400.png | Bin 0 -> 332 bytes .../ui-bg_highlight-soft_75_cccccc_1x100.png | Bin 0 -> 280 bytes .../images/ui-icons_222222_256x240.png | Bin 0 -> 6922 bytes .../images/ui-icons_2e83ff_256x240.png | Bin 0 -> 4549 bytes .../images/ui-icons_454545_256x240.png | Bin 0 -> 6992 bytes .../images/ui-icons_888888_256x240.png | Bin 0 -> 6999 bytes .../images/ui-icons_cd0a0a_256x240.png | Bin 0 -> 4549 bytes .../docs/script-dir/jquery-3.5.1.min.js | 2 + .../docs/script-dir/jquery-ui.min.css | 7 + .../docs/script-dir/jquery-ui.min.js | 6 + .../script-dir/jquery-ui.structure.min.css | 5 + .../ondc-crypto-utility-master/docs/script.js | 132 +++ .../ondc-crypto-utility-master/docs/search.js | 354 +++++++ .../docs/stylesheet.css | 865 ++++++++++++++++++ .../docs/tag-search-index.js | 1 + .../docs/type-search-index.js | 1 + utilities/ondc-crypto-utility-master/pom.xml | 171 ++++ .../org/ondc/crypto/util/CryptoFunctions.java | 283 ++++++ .../org/ondc/crypto/util/CryptoKeyPair.java | 66 ++ .../java/org/ondc/crypto/util/CryptoTest.java | 228 +++++ .../target/ondc-crypto-util-0.1-GA.jar | Bin 0 -> 6189 bytes .../TEST-org.ondc.crypto.util.CryptoTest.xml | 64 ++ .../org.ondc.crypto.util.CryptoTest.txt | 4 + utilities/signing_and_verification/README.md | 51 ++ .../signing_and_verification/cryptic_utils.py | 104 +++ .../request_body.json | 31 + .../signing_and_verification/requirements.txt | 2 + 119 files changed, 8583 insertions(+) create mode 100644 utilities/docs/allclasses-index.html create mode 100644 utilities/docs/allpackages-index.html create mode 100644 utilities/docs/element-list create mode 100644 utilities/docs/help-doc.html create mode 100644 utilities/docs/index-files/index-1.html create mode 100644 utilities/docs/index-files/index-2.html create mode 100644 utilities/docs/index-files/index-3.html create mode 100644 utilities/docs/index-files/index-4.html create mode 100644 utilities/docs/index-files/index-5.html create mode 100644 utilities/docs/index-files/index-6.html create mode 100644 utilities/docs/index-files/index-7.html create mode 100644 utilities/docs/index.html create mode 100644 utilities/docs/jquery-ui.overrides.css create mode 100644 utilities/docs/legal/ADDITIONAL_LICENSE_INFO create mode 100644 utilities/docs/legal/ASSEMBLY_EXCEPTION create mode 100644 utilities/docs/legal/LICENSE create mode 100644 utilities/docs/legal/jquery.md create mode 100644 utilities/docs/legal/jqueryUI.md create mode 100644 utilities/docs/member-search-index.js create mode 100644 utilities/docs/module-search-index.js create mode 100644 utilities/docs/org/ondc/crypto/util/CryptoFunctions.html create mode 100644 utilities/docs/org/ondc/crypto/util/CryptoKeyPair.html create mode 100644 utilities/docs/org/ondc/crypto/util/CryptoTest.html create mode 100644 utilities/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html create mode 100644 utilities/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html create mode 100644 utilities/docs/org/ondc/crypto/util/class-use/CryptoTest.html create mode 100644 utilities/docs/org/ondc/crypto/util/package-summary.html create mode 100644 utilities/docs/org/ondc/crypto/util/package-tree.html create mode 100644 utilities/docs/org/ondc/crypto/util/package-use.html create mode 100644 utilities/docs/overview-tree.html create mode 100644 utilities/docs/package-search-index.js create mode 100644 utilities/docs/resources/glass.png create mode 100644 utilities/docs/resources/x.png create mode 100644 utilities/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 utilities/docs/script-dir/images/ui-bg_glass_65_dadada_1x400.png create mode 100644 utilities/docs/script-dir/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 utilities/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 utilities/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 utilities/docs/script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 utilities/docs/script-dir/images/ui-icons_222222_256x240.png create mode 100644 utilities/docs/script-dir/images/ui-icons_2e83ff_256x240.png create mode 100644 utilities/docs/script-dir/images/ui-icons_454545_256x240.png create mode 100644 utilities/docs/script-dir/images/ui-icons_888888_256x240.png create mode 100644 utilities/docs/script-dir/images/ui-icons_cd0a0a_256x240.png create mode 100644 utilities/docs/script-dir/jquery-3.5.1.min.js create mode 100644 utilities/docs/script-dir/jquery-ui.min.css create mode 100644 utilities/docs/script-dir/jquery-ui.min.js create mode 100644 utilities/docs/script-dir/jquery-ui.structure.min.css create mode 100644 utilities/docs/script.js create mode 100644 utilities/docs/search.js create mode 100644 utilities/docs/stylesheet.css create mode 100644 utilities/docs/tag-search-index.js create mode 100644 utilities/docs/type-search-index.js create mode 100644 utilities/ondc-crypto-utility-master/LICENSE.txt create mode 100644 utilities/ondc-crypto-utility-master/README.md create mode 100644 utilities/ondc-crypto-utility-master/docs/allclasses-index.html create mode 100644 utilities/ondc-crypto-utility-master/docs/allpackages-index.html create mode 100644 utilities/ondc-crypto-utility-master/docs/element-list create mode 100644 utilities/ondc-crypto-utility-master/docs/help-doc.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-1.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-2.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-3.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-4.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-5.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-6.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index-files/index-7.html create mode 100644 utilities/ondc-crypto-utility-master/docs/index.html create mode 100644 utilities/ondc-crypto-utility-master/docs/jquery-ui.overrides.css create mode 100644 utilities/ondc-crypto-utility-master/docs/legal/ADDITIONAL_LICENSE_INFO create mode 100644 utilities/ondc-crypto-utility-master/docs/legal/ASSEMBLY_EXCEPTION create mode 100644 utilities/ondc-crypto-utility-master/docs/legal/LICENSE create mode 100644 utilities/ondc-crypto-utility-master/docs/legal/jquery.md create mode 100644 utilities/ondc-crypto-utility-master/docs/legal/jqueryUI.md create mode 100644 utilities/ondc-crypto-utility-master/docs/member-search-index.js create mode 100644 utilities/ondc-crypto-utility-master/docs/module-search-index.js create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoFunctions.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoKeyPair.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoTest.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoTest.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-summary.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-tree.html create mode 100644 utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-use.html create mode 100644 utilities/ondc-crypto-utility-master/docs/overview-tree.html create mode 100644 utilities/ondc-crypto-utility-master/docs/package-search-index.js create mode 100644 utilities/ondc-crypto-utility-master/docs/resources/glass.png create mode 100644 utilities/ondc-crypto-utility-master/docs/resources/x.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_65_dadada_1x400.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_75_dadada_1x400.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_highlight-soft_75_cccccc_1x100.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_222222_256x240.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_2e83ff_256x240.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_454545_256x240.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_888888_256x240.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_cd0a0a_256x240.png create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/jquery-3.5.1.min.js create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/jquery-ui.min.css create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/jquery-ui.min.js create mode 100644 utilities/ondc-crypto-utility-master/docs/script-dir/jquery-ui.structure.min.css create mode 100644 utilities/ondc-crypto-utility-master/docs/script.js create mode 100644 utilities/ondc-crypto-utility-master/docs/search.js create mode 100644 utilities/ondc-crypto-utility-master/docs/stylesheet.css create mode 100644 utilities/ondc-crypto-utility-master/docs/tag-search-index.js create mode 100644 utilities/ondc-crypto-utility-master/docs/type-search-index.js create mode 100644 utilities/ondc-crypto-utility-master/pom.xml create mode 100644 utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java create mode 100644 utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java create mode 100644 utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java create mode 100644 utilities/ondc-crypto-utility-master/target/ondc-crypto-util-0.1-GA.jar create mode 100644 utilities/ondc-crypto-utility-master/target/surefire-reports/TEST-org.ondc.crypto.util.CryptoTest.xml create mode 100644 utilities/ondc-crypto-utility-master/target/surefire-reports/org.ondc.crypto.util.CryptoTest.txt create mode 100644 utilities/signing_and_verification/README.md create mode 100644 utilities/signing_and_verification/cryptic_utils.py create mode 100644 utilities/signing_and_verification/request_body.json create mode 100644 utilities/signing_and_verification/requirements.txt diff --git a/utilities/docs/allclasses-index.html b/utilities/docs/allclasses-index.html new file mode 100644 index 0000000..b353296 --- /dev/null +++ b/utilities/docs/allclasses-index.html @@ -0,0 +1,76 @@ + + + + +All Classes and Interfaces + + + + + + + + + + + + + + + +
+ +
+
+
+

All Classes and Interfaces

+
+
+
Classes
+
+
Class
+
Description
+ +
+
The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
+
+ +
+
The Class CryptoKeyPair is used to store keypair
+
+ +
+
The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
+
+
+
+
+
+
+ + diff --git a/utilities/docs/allpackages-index.html b/utilities/docs/allpackages-index.html new file mode 100644 index 0000000..2a26cad --- /dev/null +++ b/utilities/docs/allpackages-index.html @@ -0,0 +1,64 @@ + + + + +All Packages + + + + + + + + + + + + + + + +
+ +
+
+
+

All Packages

+
+
Package Summary
+
+
Package
+
Description
+ +
 
+
+
+
+
+ + diff --git a/utilities/docs/element-list b/utilities/docs/element-list new file mode 100644 index 0000000..4f36876 --- /dev/null +++ b/utilities/docs/element-list @@ -0,0 +1 @@ +org.ondc.crypto.util diff --git a/utilities/docs/help-doc.html b/utilities/docs/help-doc.html new file mode 100644 index 0000000..f8b92e4 --- /dev/null +++ b/utilities/docs/help-doc.html @@ -0,0 +1,176 @@ + + + + +API Help + + + + + + + + + + + + + + + +
+ +
+
+

JavaDoc Help

+ +
+
+

Navigation

+Starting from the Overview page, you can browse the documentation using the links in each page, and in the navigation bar at the top of each page. The Index and Search box allow you to navigate to specific declarations and summary pages, including: All Packages, All Classes and Interfaces + +
+
+
+

Kinds of Pages

+The following sections describe the different kinds of pages in this collection. +
+

Package

+

Each package has a page that contains a list of its classes and interfaces, with a summary for each. These pages may contain the following categories:

+
    +
  • Interfaces
  • +
  • Classes
  • +
  • Enums
  • +
  • Exceptions
  • +
  • Errors
  • +
  • Annotation Types
  • +
+
+
+

Class or Interface

+

Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a declaration and description, member summary tables, and detailed member descriptions. Entries in each of these sections are omitted if they are empty or not applicable.

+
    +
  • Class Inheritance Diagram
  • +
  • Direct Subclasses
  • +
  • All Known Subinterfaces
  • +
  • All Known Implementing Classes
  • +
  • Class or Interface Declaration
  • +
  • Class or Interface Description
  • +
+
+
    +
  • Nested Class Summary
  • +
  • Enum Constant Summary
  • +
  • Field Summary
  • +
  • Property Summary
  • +
  • Constructor Summary
  • +
  • Method Summary
  • +
  • Required Element Summary
  • +
  • Optional Element Summary
  • +
+
+
    +
  • Enum Constant Details
  • +
  • Field Details
  • +
  • Property Details
  • +
  • Constructor Details
  • +
  • Method Details
  • +
  • Element Details
  • +
+

Note: Annotation interfaces have required and optional elements, but not methods. Only enum classes have enum constants. The components of a record class are displayed as part of the declaration of the record class. Properties are a feature of JavaFX.

+

The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

+
+
+

Other Files

+

Packages and modules may contain pages with additional information related to the declarations nearby.

+
+
+

Use

+

Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the USE link in the navigation bar.

+
+
+

Tree (Class Hierarchy)

+

There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. Classes are organized by inheritance structure starting with java.lang.Object. Interfaces do not inherit from java.lang.Object.

+
    +
  • When viewing the Overview page, clicking on TREE displays the hierarchy for all packages.
  • +
  • When viewing a particular package, class or interface page, clicking on TREE displays the hierarchy for only that package.
  • +
+
+
+

All Packages

+

The All Packages page contains an alphabetic index of all packages contained in the documentation.

+
+
+

All Classes and Interfaces

+

The All Classes and Interfaces page contains an alphabetic index of all classes and interfaces contained in the documentation, including annotation interfaces, enum classes, and record classes.

+
+
+

Index

+

The Index contains an alphabetic index of all classes, interfaces, constructors, methods, and fields in the documentation, as well as summary pages such as All Packages, All Classes and Interfaces.

+
+
+
+This help file applies to API documentation generated by the standard doclet.
+
+
+ + diff --git a/utilities/docs/index-files/index-1.html b/utilities/docs/index-files/index-1.html new file mode 100644 index 0000000..2afef9d --- /dev/null +++ b/utilities/docs/index-files/index-1.html @@ -0,0 +1,81 @@ + + + + +C-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

C

+
+
CryptoFunctions - Class in org.ondc.crypto.util
+
+
The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
+
+
CryptoFunctions() - Constructor for class org.ondc.crypto.util.CryptoFunctions
+
 
+
CryptoKeyPair - Class in org.ondc.crypto.util
+
+
The Class CryptoKeyPair is used to store keypair
+
+
CryptoKeyPair(byte[], byte[]) - Constructor for class org.ondc.crypto.util.CryptoKeyPair
+
+
Instantiates a new crypto key pair.
+
+
CryptoTest - Class in org.ondc.crypto.util
+
+
The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
+
+
CryptoTest() - Constructor for class org.ondc.crypto.util.CryptoTest
+
 
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index-files/index-2.html b/utilities/docs/index-files/index-2.html new file mode 100644 index 0000000..335f9e0 --- /dev/null +++ b/utilities/docs/index-files/index-2.html @@ -0,0 +1,65 @@ + + + + +E-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

E

+
+
encryptDecrypt(int, byte[], byte[], byte[]) - Static method in class org.ondc.crypto.util.CryptoFunctions
+
+
This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm
+
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index-files/index-3.html b/utilities/docs/index-files/index-3.html new file mode 100644 index 0000000..338417b --- /dev/null +++ b/utilities/docs/index-files/index-3.html @@ -0,0 +1,81 @@ + + + + +G-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

G

+
+
generateBlakeHash(String) - Static method in class org.ondc.crypto.util.CryptoFunctions
+
+
Generate blake hash.
+
+
generateEncDecKey() - Static method in class org.ondc.crypto.util.CryptoFunctions
+
+
Generate encryption decryption key pair using x25519 key exchange algorithm.
+
+
generateSigningKeyPair() - Static method in class org.ondc.crypto.util.CryptoFunctions
+
+
This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing
+
+
getPrivateKey() - Method in class org.ondc.crypto.util.CryptoKeyPair
+
+
Gets the private key.
+
+
getPublickKey() - Method in class org.ondc.crypto.util.CryptoKeyPair
+
+
Gets the public key.
+
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index-files/index-4.html b/utilities/docs/index-files/index-4.html new file mode 100644 index 0000000..be0459f --- /dev/null +++ b/utilities/docs/index-files/index-4.html @@ -0,0 +1,63 @@ + + + + +O-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

O

+
+
org.ondc.crypto.util - package org.ondc.crypto.util
+
 
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index-files/index-5.html b/utilities/docs/index-files/index-5.html new file mode 100644 index 0000000..a2744ff --- /dev/null +++ b/utilities/docs/index-files/index-5.html @@ -0,0 +1,73 @@ + + + + +S-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

S

+
+
setPrivateKey(byte[]) - Method in class org.ondc.crypto.util.CryptoKeyPair
+
+
Sets the private key.
+
+
setPublicKey(byte[]) - Method in class org.ondc.crypto.util.CryptoKeyPair
+
+
Sets the public key.
+
+
sign(byte[], byte[]) - Static method in class org.ondc.crypto.util.CryptoFunctions
+
+
This method generates signature using given ED25519 32 byte/ 256 bits Private key
+
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index-files/index-6.html b/utilities/docs/index-files/index-6.html new file mode 100644 index 0000000..b0f148c --- /dev/null +++ b/utilities/docs/index-files/index-6.html @@ -0,0 +1,75 @@ + + + + +T-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

T

+
+
testGenerateBlakeHash() - Method in class org.ondc.crypto.util.CryptoTest
+
 
+
testGenerateEncryptionDecryptionKeyPair_Normal() - Method in class org.ondc.crypto.util.CryptoTest
+
+
Test generate encryption decryption key pair, encrypt and then decrypt.
+
+
testGenerateSigningKeyPair_Normal() - Method in class org.ondc.crypto.util.CryptoTest
+
+
Test generation of signing key pair
+
+
testGenerateSigningKeyPair_Tampered() - Method in class org.ondc.crypto.util.CryptoTest
+
+
Test to verify tampered message and signature
+
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index-files/index-7.html b/utilities/docs/index-files/index-7.html new file mode 100644 index 0000000..e500463 --- /dev/null +++ b/utilities/docs/index-files/index-7.html @@ -0,0 +1,65 @@ + + + + +V-Index + + + + + + + + + + + + + + + +
+ +
+
+
+

Index

+
+C E G O S T V 
All Classes and Interfaces|All Packages +

V

+
+
verify(byte[], byte[], byte[]) - Static method in class org.ondc.crypto.util.CryptoFunctions
+
+
Verify given signature using ED25519 Public Key
+
+
+C E G O S T V 
All Classes and Interfaces|All Packages
+
+
+ + diff --git a/utilities/docs/index.html b/utilities/docs/index.html new file mode 100644 index 0000000..dfdba15 --- /dev/null +++ b/utilities/docs/index.html @@ -0,0 +1,26 @@ + + + + +Generated Documentation (Untitled) + + + + + + + + + + + +
+ +

org/ondc/crypto/util/package-summary.html

+
+ + diff --git a/utilities/docs/jquery-ui.overrides.css b/utilities/docs/jquery-ui.overrides.css new file mode 100644 index 0000000..f89acb6 --- /dev/null +++ b/utilities/docs/jquery-ui.overrides.css @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + /* Overrides the color of selection used in jQuery UI */ + background: #F8981D; +} diff --git a/utilities/docs/legal/ADDITIONAL_LICENSE_INFO b/utilities/docs/legal/ADDITIONAL_LICENSE_INFO new file mode 100644 index 0000000..b62cc3e --- /dev/null +++ b/utilities/docs/legal/ADDITIONAL_LICENSE_INFO @@ -0,0 +1 @@ +Please see ..\java.base\ADDITIONAL_LICENSE_INFO diff --git a/utilities/docs/legal/ASSEMBLY_EXCEPTION b/utilities/docs/legal/ASSEMBLY_EXCEPTION new file mode 100644 index 0000000..0d4cfb4 --- /dev/null +++ b/utilities/docs/legal/ASSEMBLY_EXCEPTION @@ -0,0 +1 @@ +Please see ..\java.base\ASSEMBLY_EXCEPTION diff --git a/utilities/docs/legal/LICENSE b/utilities/docs/legal/LICENSE new file mode 100644 index 0000000..4ad9fe4 --- /dev/null +++ b/utilities/docs/legal/LICENSE @@ -0,0 +1 @@ +Please see ..\java.base\LICENSE diff --git a/utilities/docs/legal/jquery.md b/utilities/docs/legal/jquery.md new file mode 100644 index 0000000..8054a34 --- /dev/null +++ b/utilities/docs/legal/jquery.md @@ -0,0 +1,72 @@ +## jQuery v3.5.1 + +### jQuery License +``` +jQuery v 3.5.1 +Copyright JS Foundation and other contributors, https://js.foundation/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +****************************************** + +The jQuery JavaScript Library v3.5.1 also includes Sizzle.js + +Sizzle.js includes the following license: + +Copyright JS Foundation and other contributors, https://js.foundation/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/sizzle + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +********************* + +``` diff --git a/utilities/docs/legal/jqueryUI.md b/utilities/docs/legal/jqueryUI.md new file mode 100644 index 0000000..8031bdb --- /dev/null +++ b/utilities/docs/legal/jqueryUI.md @@ -0,0 +1,49 @@ +## jQuery UI v1.12.1 + +### jQuery UI License +``` +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-ui + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +``` diff --git a/utilities/docs/member-search-index.js b/utilities/docs/member-search-index.js new file mode 100644 index 0000000..95d50ba --- /dev/null +++ b/utilities/docs/member-search-index.js @@ -0,0 +1 @@ +memberSearchIndex = [{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"CryptoFunctions()","u":"%3Cinit%3E()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"CryptoKeyPair(byte[], byte[])","u":"%3Cinit%3E(byte[],byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"CryptoTest()","u":"%3Cinit%3E()"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"encryptDecrypt(int, byte[], byte[], byte[])","u":"encryptDecrypt(int,byte[],byte[],byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"generateBlakeHash(String)","u":"generateBlakeHash(java.lang.String)"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"generateEncDecKey()"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"generateSigningKeyPair()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"getPrivateKey()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"getPublickKey()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"setPrivateKey(byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"setPublicKey(byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"sign(byte[], byte[])","u":"sign(byte[],byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateBlakeHash()"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateEncryptionDecryptionKeyPair_Normal()"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateSigningKeyPair_Normal()"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateSigningKeyPair_Tampered()"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"verify(byte[], byte[], byte[])","u":"verify(byte[],byte[],byte[])"}];updateSearchResults(); \ No newline at end of file diff --git a/utilities/docs/module-search-index.js b/utilities/docs/module-search-index.js new file mode 100644 index 0000000..0d59754 --- /dev/null +++ b/utilities/docs/module-search-index.js @@ -0,0 +1 @@ +moduleSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/utilities/docs/org/ondc/crypto/util/CryptoFunctions.html b/utilities/docs/org/ondc/crypto/util/CryptoFunctions.html new file mode 100644 index 0000000..5775709 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/CryptoFunctions.html @@ -0,0 +1,419 @@ + + + + +CryptoFunctions + + + + + + + + + + + + + + + +
+ +
+
+ +
+ +

Class CryptoFunctions

+
+
java.lang.Object +
org.ondc.crypto.util.CryptoFunctions
+
+
+
+
public class CryptoFunctions +extends Object
+
The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
+
+
+
    + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    + +
     
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    static byte[]
    +
    encryptDecrypt(int mode, + byte[] challenge_string, + byte[] privateKey, + byte[] publicKey)
    +
    +
    This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm
    +
    +
    static byte[]
    + +
    +
    Generate blake hash.
    +
    + + +
    +
    Generate encryption decryption key pair using x25519 key exchange algorithm.
    +
    + + +
    +
    This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing
    +
    +
    static byte[]
    +
    sign(byte[] privateKey, + byte[] message)
    +
    +
    This method generates signature using given ED25519 32 byte/ 256 bits Private key
    +
    +
    static boolean
    +
    verify(byte[] signature, + byte[] message, + byte[] publicKey)
    +
    +
    Verify given signature using ED25519 Public Key
    +
    +
    +
    +
    +
    +

    Methods inherited from class java.lang.Object

    +equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CryptoFunctions

      +
      public CryptoFunctions()
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      generateSigningKeyPair

      +
      public static CryptoKeyPair generateSigningKeyPair()
      +

      This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing +

      . +
      + 
      + System.out.println("Testing whether Signing Keys are generated::");
      + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
      + 
      + String message="message to be signed";
      + 
      + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
      + 
      + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
      + 
      +
      +
      Returns:
      +
      the crypto key pair
      +
      Since:
      +
      0.1
      +
      See Also:
      +
      + +
      +
      +
      +
    • +
    • +
      +

      sign

      +
      public static byte[] sign(byte[] privateKey, + byte[] message)
      +

      This method generates signature using given ED25519 32 byte/ 256 bits Private key +

      . +
      + 
      + System.out.println("Testing whether Signing Keys are generated::");
      + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
      +        
      + 
      + String message="message to be signed";
      + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
      + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
      + 
      +
      +
      Parameters:
      +
      privateKey - the private key that should be used to sign the message
      +
      message - the message that should be signed using given private key
      +
      Returns:
      +
      the byte[] signature of given message generated using given private key
      +
      Since:
      +
      0.1
      +
      See Also:
      +
      + +
      +
      +
      +
    • +
    • +
      +

      verify

      +
      public static boolean verify(byte[] signature, + byte[] message, + byte[] publicKey)
      +
      Verify given signature using ED25519 Public Key +
      + 
      + System.out.println("Testing whether Signing Keys are generated::");
      + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
      +        
      + 
      + String message="message to be signed";
      + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
      + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
      + 
      +
      +
      Parameters:
      +
      signature - the signature that needs to be verified
      +
      message - the message that needs to verified along with signature
      +
      publicKey - the public key to be used for verifying the signature
      +
      Returns:
      +
      true, if successful
      +
      See Also:
      +
      + +
      +
      +
      +
    • +
    • +
      +

      generateEncDecKey

      + +
      Generate encryption decryption key pair using x25519 key exchange algorithm.
      +
      +
      Returns:
      +
      the crypto key pair
      +
      Throws:
      +
      InvalidKeyException - the invalid key exception
      +
      NoSuchPaddingException - the no such padding exception
      +
      IllegalBlockSizeException - the illegal block size exception
      +
      BadPaddingException - the bad padding exception
      +
      NoSuchAlgorithmException - the no such algorithm exception
      +
      NoSuchProviderException - the no such provider exception
      +
      See Also:
      +
      + +
      +
      +
      +
    • +
    • +
      +

      encryptDecrypt

      +
      public static byte[] encryptDecrypt(int mode, + byte[] challenge_string, + byte[] privateKey, + byte[] publicKey) + throws NoSuchAlgorithmException, +NoSuchProviderException, +InvalidKeySpecException, +InvalidKeyException, +NoSuchPaddingException, +IllegalBlockSizeException, +BadPaddingException
      +
      This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm + + +
      +                CryptoKeyPair senderEncDecKeyPair=null;
      +                CryptoKeyPair receiverEncDecKeyPair=null;
      +                
      +                try {
      +                        senderEncDecKeyPair= CryptoFunctions.generateEncDecKey();
      +                        receiverEncDecKeyPair= CryptoFunctions.generateEncDecKey();
      +                } catch (Exception e) {
      +                        // TODO Auto-generated catch block
      +                        e.printStackTrace();
      +                } 
      +                String message="message to be encrypted";
      +                
      +                byte[] encrypted= CryptoFunctions.encryptDecrypt(Cipher.ENCRYPT_MODE,message.getBytes(),senderEncDecKeyPair.getPrivateKey(),receiverEncDecKeyPair.getPublickKey());
      +                
      +                System.out.println("\n\n/* Sender Side /");
      +                System.out.println("{");
      +                System.out.println("\t\"plainChallengeString \":\""+message +"\",");
      +                System.out.println("\t\"EncryptedChallengeString \":\""+Base64.getEncoder().encodeToString(encrypted)+"\",");
      +                System.out.println("\t\"senderPrivateKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPrivateKey()) +"\",");
      +                System.out.println("\t\"receiverPublicKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPublickKey()) +"\"");
      +                System.out.println("}\n\n");
      +                byte[] decrypted= CryptoFunctions.encryptDecrypt(Cipher.DECRYPT_MODE,encrypted,receiverEncDecKeyPair.getPrivateKey(),senderEncDecKeyPair.getPublickKey());
      +                String decryptedMessage=new String(decrypted);
      +                System.out.println("\n\n/** Receiver Side ");
      +                System.out.println("{");
      +                System.out.println("\t\"DecryptedChallengeString \":\""+decryptedMessage+"\",");
      +                System.out.println("\t\"receiverPrivateKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPrivateKey()) +"\",");
      +                System.out.println("\t\"senderPublicKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPublickKey()) +"\"");
      +                System.out.println("}");
      + 
      +
      +
      Parameters:
      +
      mode - the mode to set either encrypt (Cipher.ENCRYPT_MODE) or decrypt (Cipher.DECRYPT_MODE )
      +
      challenge_string - the challenge string that needs to be encrypted or decrypted depending on mode that is set. In case if mode is set to Cipher.ENCRYPT_MODE then this text shall be encrypted; whereas if mode is set to Cipher.DECRYPT_MODE, this text shall be decrypted
      +
      privateKey - the private key. +

      In case of mode=Cipher.ENCRYPT_MODE, it should be private key of the sender +
      In case of mode=Cipher.DECRYPT_MODE, it should be private key of the receiver

      +
      publicKey - the public key +

      In case of mode=Cipher.ENCRYPT_MODE, it should be public key of the receiver +
      In case of mode=Cipher.DECRYPT_MODE, it should be public key of the sender

      +
      Returns:
      +
      the byte[]
      +
      Throws:
      +
      NoSuchAlgorithmException - the no such algorithm exception
      +
      NoSuchProviderException - the no such provider exception
      +
      InvalidKeySpecException - the invalid key spec exception
      +
      InvalidKeyException - the invalid key exception
      +
      NoSuchPaddingException - the no such padding exception
      +
      IllegalBlockSizeException - the illegal block size exception
      +
      BadPaddingException - the bad padding exception
      +
      See Also:
      +
      + +
      +
      +
      +
    • +
    • +
      +

      generateBlakeHash

      +
      public static byte[] generateBlakeHash(String req) + throws Exception
      +
      Generate blake hash. + +
      + String message = "message to hash";
      + byte[] hash_1=CryptoFunctions.generateBlakeHash(message);
      + String bs64_1 = Base64.getEncoder().encodeToString(hash_1);
      + System.out.println(bs64_1);
      + 
      +
      +
      Parameters:
      +
      req - the message for which digest(blake2b hash) needs to be generated
      +
      Returns:
      +
      the byte[] hash value
      +
      Throws:
      +
      Exception - the exception
      +
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/CryptoKeyPair.html b/utilities/docs/org/ondc/crypto/util/CryptoKeyPair.html new file mode 100644 index 0000000..fd384a9 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/CryptoKeyPair.html @@ -0,0 +1,224 @@ + + + + +CryptoKeyPair + + + + + + + + + + + + + + + +
+ +
+
+ +
+ +

Class CryptoKeyPair

+
+
java.lang.Object +
org.ondc.crypto.util.CryptoKeyPair
+
+
+
+
public class CryptoKeyPair +extends Object
+
The Class CryptoKeyPair is used to store keypair
+
+
+
    + +
  • +
    +

    Constructor Summary

    +
    Constructors
    +
    +
    Constructor
    +
    Description
    +
    CryptoKeyPair(byte[] publicKey, + byte[] privateKey)
    +
    +
    Instantiates a new crypto key pair.
    +
    +
    +
    +
  • + +
  • +
    +

    Method Summary

    +
    +
    +
    +
    +
    Modifier and Type
    +
    Method
    +
    Description
    +
    byte[]
    + +
    +
    Gets the private key.
    +
    +
    byte[]
    + +
    +
    Gets the public key.
    +
    +
    void
    +
    setPrivateKey(byte[] privateKey)
    +
    +
    Sets the private key.
    +
    +
    void
    +
    setPublicKey(byte[] publicKey)
    +
    +
    Sets the public key.
    +
    +
    +
    +
    +
    +

    Methods inherited from class java.lang.Object

    +equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    +
    +
  • +
+
+
+
    + +
  • +
    +

    Constructor Details

    +
      +
    • +
      +

      CryptoKeyPair

      +
      public CryptoKeyPair(byte[] publicKey, + byte[] privateKey)
      +
      Instantiates a new crypto key pair.
      +
      +
      Parameters:
      +
      publicKey - the public key
      +
      privateKey - the private key
      +
      +
      +
    • +
    +
    +
  • + +
  • +
    +

    Method Details

    +
      +
    • +
      +

      getPrivateKey

      +
      public byte[] getPrivateKey()
      +
      Gets the private key.
      +
      +
      Returns:
      +
      the private key
      +
      +
      +
    • +
    • +
      +

      setPrivateKey

      +
      public void setPrivateKey(byte[] privateKey)
      +
      Sets the private key.
      +
      +
      Parameters:
      +
      privateKey - the new private key
      +
      +
      +
    • +
    • +
      +

      getPublickKey

      +
      public byte[] getPublickKey()
      +
      Gets the public key.
      +
      +
      Returns:
      +
      the public key
      +
      +
      +
    • +
    • +
      +

      setPublicKey

      +
      public void setPublicKey(byte[] publicKey)
      +
      Sets the public key.
      +
      +
      Parameters:
      +
      publicKey - the new public key
      +
      +
      +
    • +
    +
    +
  • +
+
+ +
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/CryptoTest.html b/utilities/docs/org/ondc/crypto/util/CryptoTest.html new file mode 100644 index 0000000..4c71ea0 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/CryptoTest.html @@ -0,0 +1,225 @@ + + + + +CryptoTest + + + + + + + + + + + + + + + +
+ +
+
+ +
+ +

Class CryptoTest

+
+
java.lang.Object +
org.ondc.crypto.util.CryptoTest
+
+
+
+
public class CryptoTest +extends Object
+
The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
+
+
+ +
+
+ +
+ +
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html b/utilities/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html new file mode 100644 index 0000000..12378a3 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html @@ -0,0 +1,57 @@ + + + + +Uses of Class org.ondc.crypto.util.CryptoFunctions + + + + + + + + + + + + + + + +
+ +
+
+
+

Uses of Class
org.ondc.crypto.util.CryptoFunctions

+
+No usage of org.ondc.crypto.util.CryptoFunctions
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html b/utilities/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html new file mode 100644 index 0000000..74cc509 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html @@ -0,0 +1,82 @@ + + + + +Uses of Class org.ondc.crypto.util.CryptoKeyPair + + + + + + + + + + + + + + + +
+ +
+
+
+

Uses of Class
org.ondc.crypto.util.CryptoKeyPair

+
+
+ +
+
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/class-use/CryptoTest.html b/utilities/docs/org/ondc/crypto/util/class-use/CryptoTest.html new file mode 100644 index 0000000..e7cf79d --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/class-use/CryptoTest.html @@ -0,0 +1,57 @@ + + + + +Uses of Class org.ondc.crypto.util.CryptoTest + + + + + + + + + + + + + + + +
+ +
+
+
+

Uses of Class
org.ondc.crypto.util.CryptoTest

+
+No usage of org.ondc.crypto.util.CryptoTest
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/package-summary.html b/utilities/docs/org/ondc/crypto/util/package-summary.html new file mode 100644 index 0000000..7930046 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/package-summary.html @@ -0,0 +1,92 @@ + + + + +org.ondc.crypto.util + + + + + + + + + + + + + + + +
+ +
+
+
+

Package org.ondc.crypto.util

+
+
+
package org.ondc.crypto.util
+
+
    +
  • +
    +
    Classes
    +
    +
    Class
    +
    Description
    + +
    +
    The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
    +
    + +
    +
    The Class CryptoKeyPair is used to store keypair
    +
    + +
    +
    The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
    +
    +
    +
    +
  • +
+
+
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/package-tree.html b/utilities/docs/org/ondc/crypto/util/package-tree.html new file mode 100644 index 0000000..951ad2f --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/package-tree.html @@ -0,0 +1,69 @@ + + + + +org.ondc.crypto.util Class Hierarchy + + + + + + + + + + + + + + + +
+ +
+
+
+

Hierarchy For Package org.ondc.crypto.util

+
+
+

Class Hierarchy

+ +
+
+
+
+ + diff --git a/utilities/docs/org/ondc/crypto/util/package-use.html b/utilities/docs/org/ondc/crypto/util/package-use.html new file mode 100644 index 0000000..6c11a23 --- /dev/null +++ b/utilities/docs/org/ondc/crypto/util/package-use.html @@ -0,0 +1,74 @@ + + + + +Uses of Package org.ondc.crypto.util + + + + + + + + + + + + + + + +
+ +
+
+
+

Uses of Package
org.ondc.crypto.util

+
+
+ +
+
+
+
+ + diff --git a/utilities/docs/overview-tree.html b/utilities/docs/overview-tree.html new file mode 100644 index 0000000..d775267 --- /dev/null +++ b/utilities/docs/overview-tree.html @@ -0,0 +1,73 @@ + + + + +Class Hierarchy + + + + + + + + + + + + + + + +
+ +
+
+
+

Hierarchy For All Packages

+Package Hierarchies: + +
+
+

Class Hierarchy

+ +
+
+
+
+ + diff --git a/utilities/docs/package-search-index.js b/utilities/docs/package-search-index.js new file mode 100644 index 0000000..7fe94ce --- /dev/null +++ b/utilities/docs/package-search-index.js @@ -0,0 +1 @@ +packageSearchIndex = [{"l":"All Packages","u":"allpackages-index.html"},{"l":"org.ondc.crypto.util"}];updateSearchResults(); \ No newline at end of file diff --git a/utilities/docs/resources/glass.png b/utilities/docs/resources/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f591f467a1c0c949bbc510156a0c1afb860a6e GIT binary patch literal 499 zcmVJoRsvExf%rEN>jUL}qZ_~k#FbE+Q;{`;0FZwVNX2n-^JoI; zP;4#$8DIy*Yk-P>VN(DUKmPse7mx+ExD4O|;?E5D0Z5($mjO3`*anwQU^s{ZDK#Lz zj>~{qyaIx5K!t%=G&2IJNzg!ChRpyLkO7}Ry!QaotAHAMpbB3AF(}|_f!G-oI|uK6 z`id_dumai5K%C3Y$;tKS_iqMPHg<*|-@e`liWLAggVM!zAP#@l;=c>S03;{#04Z~5 zN_+ss=Yg6*hTr59mzMwZ@+l~q!+?ft!fF66AXT#wWavHt30bZWFCK%!BNk}LN?0Hg z1VF_nfs`Lm^DjYZ1(1uD0u4CSIr)XAaqW6IT{!St5~1{i=i}zAy76p%_|w8rh@@c0Axr!ns=D-X+|*sY6!@wacG9%)Qn*O zl0sa739kT-&_?#oVxXF6tOnqTD)cZ}2vi$`ZU8RLAlo8=_z#*P3xI~i!lEh+Pdu-L zx{d*wgjtXbnGX_Yf@Tc7Q3YhLhPvc8noGJs2DA~1DySiA&6V{5JzFt ojAY1KXm~va;tU{v7C?Xj0BHw!K;2aXV*mgE07*qoM6N<$f;4TDA^-pY literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png b/utilities/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..34abd18f32d3a55a297fdcf93409bd033ae573e7 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&fCnc6a#?2AmP!?*K(O3p^r= zfwTu0yPeFo12TF&T^vI^j=w#x$i?I+((tf;UXnmgbH|3oY>pC!)f}(GR!16S-u+#{ ze6YEqRkW=8vGl=5qArKM<9}TC-}iEvB{zdaTcX5$wyRTK&ALRXUCGx5b?-VBQkUm|IuXOmYJrBRJgj{Vx zMbNnqUkncy+qa2-mWYc>swkcIuvGK#>(0d)B7)5f`@$Ei28nH~0h*~=;u=wsl30>z zm0Xkxq!^403@vmGjdTsnLJUl-Obo4zO|=aStPBhe<(7X!(U6;;l9^VCTf=69^L{`L N44$rjF6*2UngDu&PXPb` literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png b/utilities/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..a90afb8bf8028404d206114965669b023dcb85ea GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&0LWmFTHNUZq?nSt-Ch3w7g=q17Rci)@Q5r1 z(jH*!b~4)z#PD=+46!(!TrvH)L6@80)r*_cdCvDr%)6ghVL16=s@mbz7H!uRdGeDa z?kzLg)16i!f8fKx84s0>4hES%`s&m5HI1v5B^Uft7(lid2moiiX_$l+3hB+!{pPkNg5^ OVDNPHb6Mw<&;$T*0!_~V literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png b/utilities/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe091f6dc036fc1dc11b005738e951e27a43f7a GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&fCnc6a#?2AmP!?*K(O3p^r= zfwTu0yPeFo12VciT^vI^j=w#>k(V)1qW$CZ|6)SVV-&*#dav<$DMuV&n0Dbpw@aE%W-S*bfB&J`pw9sa4-R?IGW?p~6`>jMSP&M+u3 zY@9al)zrvpHlQu4C9V-ADTyViR>?)FK#IZ0z|cb1&`8(7EX2UX%EZvh*hJgFz{Ot{4q9c^pg%OaK6Yqo^RG1puHty#h|2KYM!0=6Ogw z8K9N2ybORL_{i$}QxC&U!O-)`D*V04jXJ#n04P`#Wh8ZcmyUA%?QMqxhsEu>DC;^~ z{8O8G!7ta)D{l)9O_iD5-A{FwUpb*$IVfjou`0AAQAiyPXs{~wzE|2cZ&-acSF5PE zECGBcRRVEnRHOae;6NyU=IDOFj1wfusG0S<3Q6l>z)~KZvoIliF0!*y?O)1|ko7+n z>+zd%4dS;8>iMJUMwP(40V}{-=QZ#}vlkKtjgT?gI8R3`s`{eg^A0iB|9C;N3jtvV z-Ng~;#kXO^6$qh)N`faRB-+@-bRYixX&v+7cZ47thp08jNs?kcf|lu#~em zp9vU17gB)u1qJ$;?70533PMsKum#Eq1WJ#2?+bZ7pACeTd>j>;rVp1okB*+jU>j7I z%j60+UbCER>?m`t-k_0UMwtLk6PNMY=f5dhQ8l$!D_vWBr7CGPcDXr`NYC0uXipIi(5RZ4R25t$~o-$U3fdSZ+t8-MmF==ihWU zps_B2WTuZJSqfEd1jJTJmIrBIIwGFP-`8)$-Iqppx}nZ^1vgyQ|l#q!hDI^2df&H%uZ~e0(cO7rqdczX@s)(9Eo-vb-MZ9T{=?X2emAalsxjR} zDp-RS7ef2fYsNm|W!_~xs+U7sTjX>);xAM$zqqaVh4|Euxo{YB$Ue0yH`R1%LS$R3 z_E+lO@6`C-O(hNK66x`)5glEd?{N3v6k%2iXu|DB7JlD_tIlHzQyL8|YqSl}2YGDC zVO=PpVE0uei+57#cSm-&mw%S6mdRjiXxq5W{LsvhSJ)azPC6$j8(XY|f^_Z&*1)W@ zy3m>x-39!zm0@c~zOZVs=NV_}R#gjtmK1&jPTBe7AFZ@zbRGz_6UwWLFcH!wR&|Kh zZORU;Y=?b=mQgrwQ7Jg5s`cWOAy<{^y4=~BY|8kNP41J6stuM$_oKMaSoT+r{gE=%vLbm}y-G-s!n*{3q^tC?7saRyDEHx#C%bDVlF- zT{dLhAcKm7_JHGWuM**1_IMVdiq^ z7D85%apck0)*q}ipK9LUem#)m&v^B|Widn`=US)y=oK{$PHqJfvPxXB01zn#HFdLP zQ&f?0$}kSU6DYm1#Q#-wfTbj=yH!1g2x|0WP2z>tuyO>41bFp+m<`<8K(}e{bVRRc z;_)`s&>3Igl%b}j4U`xH6cyED;w`@e*RvZRe2WjElbi=jJ?KR2PO|E4(J3bsCK3K3 zO01O90g8f8lG@TKjOF|Rq%J+HV&UYOoY19`zLkp~FG{YsK8Ir~X$|7*;yB&_zla!o zjYA=|t$atYh-F)y4Yz_vl#Mfhr7?c5+w!f^NDNI!Z?A?TFj8jfkyqH$zWRai4c9qe^hVZXz8Ua{_Qt*H|88x@P1f|(u2`*pny^DSvt z0cPlYpbVeN$&S_0igz=*jS?B}QmUqqvPHqKaAx2G>fO4YRa{E>XB6Xs(Qzm?KF6{) zH*UG(7f?FngNv=%+Zmde2NyXUJG!M`!A5Mki?MT(W9PZmXv@ zmep!=;N_2(YH&j9mbmVOT4-HZILhZTNTy1NuR|!sWu45-D4y_D0QqJt{zs;jlrvoW zMFI`6#{NR91Oga_$sPvQT2>*W zRIBmn5wo&P6T=9La7LKS#PfEKzLL;iMp+{1Q`z*5zFAs*0Ls&H`$&3{Kj4$V_i@Y3 zQ5#cDOZZXP4LiO`exN`(4@q9eQ8uV|2&zu8c<`IAi}X>xjQ2rZjo9+7c~B?p(#|;v zer1U!kvAG8TJgQf$Vb%&$$*?mTT^8q!mb=&j!S9)P#ih$wSndg2IQ$5(%D4r5YvN6 zSlmi#A+9~6hT+SJhfNn)&@?dH$60LL#zBHZW2#jikLi?i+d6FT_TdaEj!3q>= zs3B{;qsuhOi~=T+n7bcnD>mKC9SPia&sf-S6=bWBZ&k_0DVVff(=-5WLMn9=GM7-h zI0uf;xB8kYZb^lJ0n~JvuvK$V>}r19I>e+O66f|wPr+;wZh})Gw^&qqYZA}x4c57y`^h7)C>5Z1%3*cW z)cL6g#o{A8TI2pxi@_j)Q_eBD)Y1zWnK6FCJ*Vusx`G!m)?EOSA0act>OlBcw2kno znt+5a_hNxdJ!=)?x{qU|#3A*G_rm|KnYzPYV{szQS;o+Vc_nTJny7jnL?4}g| zq}9Rn^^$O}pD>4Wzz073HN<|S{OaO`3SdI%H!gr$kE|3cZg#S#ZmtN6jU!-W@kLCX2^KjZN_cvo3qAj2yCB?L16iZiG(a`(MHoh@NuA?dUdwAZsu^p~Uhti2ZH!rb9pRfx3K8kW z_?}^DSUvk!SkI1_Ny((_yDi!;g+*N#ElFI*hGVTo^~6evaow^^-a3wu+^vYErC)MU zEPyLe@#)2))oWu=PU`!)g^X7j-n;da0;cWGPIx}|{5}0&Gqw&mh_FTI_8yp+ZyIs# zi~~~V0>b733>{kC2`xluGp9ko+Syq=cLVEdK6dYbAnqPQpJ0yP1^$LT-{4Y$I*shl-3{@hbXlEaQ{OVJr6@vM$U7%VXui z69mW&G~@=wLkd6GC5LthA@FO8P^{E$HP}ph8}5s#;Fxy2?&9$ADS==?cc9DBgZ^BP z_DJ*8;w>hq(8u#n@8pPzhy{cF{4*+k-5}N1fZ&QXpqw@-WKbl7G-h<-fqQ5cUWgtZ ziPTTk*ivA(LV;7lZd*s>eSsM}+`^Lx#d$*#KPXr1pVrK0_^RM)uk}!!5L8>TO42Ru)kIb>l@A`(fi(etM0m#G<>kwwV~O zw(xaW6da4~#^(Y}PMxbp(iU(Th3CZf}3l^;h0r| z=MBo3m?-`p-VaQZT{78zLHSWNm32oJxoy&ks72t34^d!Gj8=dH+swRGn`d&6|j&n&PXLhwd zY?@dYT9b2uRt2;Fk>XXgPObcg`WLnv)u0L7*LN9TQ!dI4(B!mp9~}26atgA|Vl-1g zG1Mt)k?;6P4~*b9-+9z*fz4Xirg8k=gdS5xM_x#bV2|fmb8UMyiN$jH6WDG-k&!?G z7St9U#R|{RkKRcgSQnjdIK`zJd)?yFvD(DPh5-hpASH|!dA=)}N`Sxzdd7x9cr;&x z0?>+V`+=QN8F#cdo=5>iLeFsFc?ywL+hR9-dzt%0?%k)DK`Q zQ)!Pt6Auj>-6d23k2rTJpgSt=6SoV46u@%xuQKC8?cPl+>*s=DEZVpN7$>q1boY5* zW0O0~;UO$-=GT`m&GNYD-B<_TuV1~NR7&M0g7vw8=6o*KiL1c-3(y&pYSCOg_bjc`cG%->f>UT`;z zd<`+z@DhiS8g3Ej`NeU079;}kV+@JEqw=S1M4S)vpZ>f#e9Sb7)?;J*jPQ$o%jcL( z9$^>WxCE2zM$4Kh%Eo-KYvU}3BuuOxw#eC!({l2D6&`xunIoF$i2=Gg0oOH^x|Al; ziE$^IzopsMH;7d|WB#*{?LS*KYZR`8vFpVXe0x7M7(cI?fu)Yy9Qf zJg5w2#h`;t_ksT~YSk0fp6bXA&oHh|`M_xKx|irpxo|F)x82hH58PF|R4t27)9cKqaDz~7a@Ub32?mq5-4r4x9%Iem7Lr&xv>xdzdT4a%LsTjG12W?qN^+ z@!iZ3G`0DLzjcvM4RBD?gd5nN<_J(I18CxC>BNi_)y31reLH!#llOMD_Bg16eH%Z+ zI@5tf6YFG76bE+OR-tMscC-@k{FJTg^1cx>`h^6`{VI4q?#JA4s=KcG>oiD^L_xi+ zB9fNx(}VD&&!0Vp)p;!Sq@biL&x|Y2nRO@szL>_T7f_d^t2f=H1rP6$*dNk9oAK?! zN8kT+^=Y)gvMi3OX~M4qet%`%xvxqm{V^J4{^~Hs3Q6-Ozj$q&l*nDAhHS?*SuBJT z>1JWh2gQ14CnBI6K5U@JQIZuh#0MSj4qreM_!q_$+5dMzf-WI`F#D0l6JQxO0w~nN zN+2rI*O$V^wBuB(e=TPm5fA@tIVG9)#Aa$#3gm`FIbATR^{iB-qf&ubqlbcZ1yjl| zD-G(`AB!|X{kCx~J&%J(tINbfI_uV-SBuuHe1`iI;+Fc-{}H>dI0Y8;hq-TLYGv#= zhtQaY6vT2bzz+NAc&43SvdjlIGFF&@ybK!Fw*HDu_i7fBlm1z0*!SY)u7<9ZY$O+TBqN|FN9Is93lc2hfxq9nTU-D+<)*)73G?0Tbyq-0-Cy$ptt z(t0Hr5qmTCUdNWnmw-k*AjEr&Our;Q8=j1&G=lNvQt&r`N(Za9h0Hi?xKemGQofjwQ6 zEfOUxr~hNrrOY=DeNV)MHAz2xVyBip17X`9g*GZTExdiraYcBBk4MP1N-uBUATzwL z(z076^l1D(WzqG?hXB;P+t~YZT{6!yRk<1RRh#?lrI~d^{5EioHD^r!QsGeT9$#Nb z=cJt4L(J8!Yu(LMHCXyUUA*XMAeb%To(5CqTah||6kx@DMr!X_#1p!dW0fQv&nulS zOv9Nvw>;;%zuZ&z>2W@Ns^9w*v8;KpQHLsLeN%B9pufo^@$Abp1*uxTLE-IYWFj2A zo?eRJCYJFH-lL(A0b6A2icAbemDxEoRkbBCSVS_#pQZc^@503DOu6mquJ*#i`7CSU zMLUE>+8QgcPYL34g1*$KkR6=qQRmqHEk5A1LG#i4S-PJ+D|g(Jh=NHlAfcI&rk`Bg_ySed@e8Hq&)UIEwY_S;&-MbLul^u<^-*}B?;p5!e6 z5#0kXU8Yj~oxOH^gOg$mH;Nk3ap)|~){hGPm0MolJMP^O6W{JFcGSzvT?l;Xk)@<@x=`k3Q*F8qv z;&cbNL}{uYIMz@oRd|#JJSZ&(jm~LzN~q&j#$eMOEX1PL&m{W^W+%XLYMki&Z$kJW z3%K>=u5Y0?M}#F))ibW!sD-!weE{?W7W#FTzQ-*BBc@RDU+x!dFQ4_as9bt?>+JL;8sTYo&@eAiY~+@<*P0<1~jO0P2;5hMtQ<13y0#*{n`AT zj!xOv50?u8TDy6x1^-ynNWte0LY)Htw>Vyb?a?C|D6~gIOy>lWpLKmbHtoGfBOUdN zNTcrHea*|K-6wfOB>G~L9QHlr^�_j6WK+Gj+xJRxVvl#lh7y-4uY);t)n47k4ot z9YsU`HVk7fg4;r{;)FHk7ZHyZJ+W|$aKwj=g&_$VCVFn5%XzSA`|z}+4ItZ|`hB}R z>h-6Be`d>nmv8;kQHJg!HMr^cCGG=T5;3HhZ_JRq0_4a3TsY7Pz{V+}z>;!R^U4*c zJ>wRI59B-)92Vi?b&EWvH(`<(G5A?W)z>EuDMG@VENAb7aHa`I#tKw{0uUc3(#J8& z*_S%A_ZxCIY385{%qN-b1K)TWmCjUA4nWKx_ZnKLSvEf0($&_0@DS~ zN8JOXJXXcaFm^OCYrz(R7N5DQkXKGnnt}yzfw^8s%=A?7hxza;ylJ;XQ&XtC`pM%b z6$5Ff0{(ALcSlTKvIbr@mR`0Z)*iM`2EfO|E5OMk$jQsE!^mat*drqV literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/images/ui-icons_2e83ff_256x240.png b/utilities/docs/script-dir/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5f49756ca64bd20a1048bd7a3a584457d4bf00 GIT binary patch literal 4549 zcmeHK2U8PFw@yL`geFZ|P@*V;w1D&)N-z*QNarO;QRz)l2oR(yU5bE$@JbZ~M4A){ zMUW<7Xc|gHkY1#>kc)mZ-`x8j?lU`k&hG3pXZP8eGv_=pHoVEqz{dap0GM^r+NJ;i z@XQ5l($k#H6S{hbXB#ZW`sOH!2L%N^&k_wk58Uw#*BX~{9Oe{(!2H)ZKd9X_X#oyfU5m#1Q82_f^tw6O11(<7c zWrG0%qDlJqcA8#ZrRU7cn@;N9VJUYHk^lTY3j(~2xv33^rM-YYTR?r#*8XSqkBCLbg&Z9G zp-dC_BuoqAkc7;MJ$9jCDbZN_FFIp=mvYI8l)OlkJ2GcKGFRh03>eyeeRF`W3VO-< zC@;;5k3f&*z5C#XoxT-q8o(%^R8K&f=k{8C{Y0uqmWi%PaU6jYo(5);yFd`Pn(!El z9h1vEhwlH1Q*|5X!lGvH`BD!7(^?OdAd$XP8=x~O{-Q}sy<2@T8`8IN;o*)L;K1*C zz~`x^5S%i=-8fHXQ{cyPiZj`|pV*e}T1g-QFmGBzZJ}z9t&~LL?-9yqp3x_EMw?h% zR0P^RfsG7yxX`l^uHgxl8V3PJTxM-b@>%bt-xEPCC)WNC4L*~?BL_6;e`XLVLVOkZ zaY1crUf;C9r#r|ebAHIp$KdM#$G60s#+4?*)mH)^4Rrn^&ZPOyOvZQO09veRcnbCX zWQc5fEAPmQd7=aqrZPBYAy;!Ph{cmfC@z-hpTuotqr$Mt? zY7woww1bOdZZNt7uHxGKm9$w8ozW}U!S8~V?{0A^bi{^$t00v7M zy;S7sm>vMCBz+=8TH~>zJ3!E9INJ1E6=!x^{;q9Biu$){2DGEIbB=oh!`QMCEx$ds$)Rc&7P*}`pd3{PqA}tIjp&y&{w{YrsPqhxaO4qerTDpM`WTlW5 zu*{F5ID98N%XU%ltVphxZ4Tra!)bpNih&)&Xx+d#q1{G`5icBuvTfv^7X{W}JXD*B z5!u=L*x{^0TXODlF@ziPt+=ars9OiJOv1hU4sSKFa z=)|j@+%OFH1Oa3f>ffz{O6~wHhDJrN4=)Y|I6DD)9CPw@Ytx6M2-O;{GQTQG&gg?A zr_VPJ&6+f^hXn|7pvwa+o;bXAc{n)lTn{~TF;3#>=AS1_iaGZheU=*xbHD8CUNUCj z^3&DKA#op+3tPQa@eK1RUg%D!n%5J4ICni7xELQIvd$Qz&+%!EZ!S{js)F!S5x>3O zLCB>-TbYHXS1?}__Xfm{r>(wAU3INPvHaWIIYbsxO^Oe0h0xglZWFakn6z+$6`V(< zSimFunLw;GdHMnWx=-GqPeuvo)l|sHaFJ~`DxMN)4Y7U!J8D=^MqeQn$`lS|1%mdN zK^morEND%3ee@_Yb<>IVIW2*6NZ^*QDg@w`H$3}uYsbleFidycDox+uzraGexRKEV z)Wd(JYU$(enZkGJ3{9REQOJppi6EBrWrXU;Ho*EGRUG&RC-ceTd@*C1J$c=Jk~Ty0 zAJE}+ZgP611Nw}-*K%$Od}R)=^6W|sl);faH`l2OA>=zFmy@8vVK$&%4OTWEhnx^< zs6V-c51bUMvJ@`4zcieGu?{L+ z6(ZMYhQND%M5s7uB)($Pv`1e&xPRDwWGD>e&;;;sA;yn_>F>rJH-M!+=wbl1_|+h6ttu(NB3r*FCdU;|1QOB?AGaVz-O zFMj-^FpfDR$apG zp!5Ji|53`FLrz-d>YnYEv6T0wDN8?-+$@_Nk-6nai){TtA=w&Qa=^woXbB~azV{PSFnB7zJF-k|zJbp8E$W1!v#tcX8%TiKFo-n7uCut-v(fLn$6ypSnrZ z$*S34s_(`S1jtESyVuI|{3uW2BhK-{jQp05>-^UGi}#K$%3bE8bM>i8<~MKu=Z4e! zh0A#tX_IOB39o+SdnJzu7<`KoCri$9{I*mr4A2uJr&$q1-r=Lzfussme7r{sQYl;m0a`a^hI)69ux681k(h4* zN9|Ywb^i7xF=uPVr*az7RYlVWPxhKmOE)Fgo>mlB<7pYaz6VsBW7J04%DxENck4rx zgM6#>hT78o;>S1Jt8MqV+4Jng1ERmSoX9dGIW`CC2VaF9CwL8-Bi|83mD2!Dee`Lm zCU-luuD>aLYJU7ZD?3R8tYYSVzoEVM_7n=hEcv1FN{h`Dk*ik1Q)z?ie^&}a1;86B!(s%}s%T_y4o&Ilh~d4DHn(86bo>p-*Ct4!-v)W$h1{J?4IrLKT@^?`26FF*@(2A4^@6og<7ngtWmIBVp>g{gwCG=1WX4srm*>E(6gC>!E~o-<{=AHg;~h zr)4{j`glAMBt_n{+%n8))~tNAyYCizc)D8wlZ8(Mn(svkWSi{A*vq>kCT}fIzl|Cn zy>PR|9cIRx;PBE5*-4+O?~_|$F<}5ur(2S|FAw=N&4pNnTk#=xhxAK3L=6a{X{DRocw%r8utUc^U?}*_ zr(y*T#U}{tCh=GT-ig;Dn~K`ilK*9stV#@EBAC9TOf4ugkA;~Nt2ej0?du%%-=F_m zz_LA$2jOO2Xk0r}zAZwZs7;VwA4S}3#)0t0SXSerLIo`;%;<|0ji~+vl}hOk9i+zx zUuZGWeo-DskUoPx=uJ)C!2Ep5@-PzwsF1^fj6kXJV!gU9L;{+5Gue#|!$uOssQo@K zR+uvJS*YTwuIPpVsz4PRkj93f17`97b|eBhl?7-Z9~n0f6EDor>foo2fPb$h4?A7> zT%r7x%5bpcUlV8+ByvZ7G1za^zhKiWJonD$xaS#k!hAE4p;QgaM*&tH)GI*HnxRE` zKM&1Lk7kAdR0w0M^qbP-LBil+NXKi;ihqCio{6=#|O(C$v0m`Z##4NXD+__-g z(_-U=I?+`IvcD6z77?Nw;fys4D9CFwg)Aldh6fQ?7N5`ui7^y6CC!+Es(Gr9qTHPK z-0ma)tFN+?V$ZP1e1t=yi(Zs8_S&zkh{hmaoulswfZ1Dqa1RNYC-25^Rm!I<>GW3k zjUOHLY78yVOfQ4@4mA&>xohn_3&n{JwbI7c3dEV^o%%0Fv=51+iH6T4?jF;IPPfqw zokxnwN5uxo9?XI&Sz@-f12P;WQ%GNbFK1CCdDhs}sVDCdBr~;?W)WZ)U0iw42JJnB z7i*tnrsnBMBpw^Ay}gobnSM$V#D;&2_@aql^X86vylX4gc?Y;m(y8v2NuB;;wJQoV^z3UpIO6adgOK|rh`I83cQ92vN z*nDrN5bxLa^N8pN&PPh7e;t?O#;^ACf0T)hr9bD^{p0K0aKs6fP=#ZL0@Q)?jH1G4 zmGhC&x$cBzQD~bW$K$+5{ylRuGYJ=lL0%_3KE(evW+WZI`zqmN3H0Yi?*N0(R64#J z>}+>eAmE{uko29IXjycIN3NS#IqY;9$u>caW?(bvKw+_ zgG{F`FVBpFDwJwR~R;O-V!9D+Lphp>2% zCAeJPdrp0I&;9O?nVzZYuAY9Td#2`@Ff|ofJRC|K004j|F9+2C0DzA}z%e%ZV=t5G zEb%Bnri!vqfK1uzM9#CcN_%;z#n=8gA#PS3;tcI;~uofXisxsK~{&;VR#1 z!o>>A2X%jk6mmfdq0-jyMN=cu0=VG)#_Jf_>&KuMX8ti@lH{h`>lhL}=z0k4IB519 z2z+_ZC;46kNd^v6LH`zyWz zc=pCDRd~N_<2su2s8&{(HU!aVC@&H;3-}=D4 zmn4&Xqtz|N;fr4ZX*`x)O>~I#fDAFWbF}%9b@c^V1-YMxSf6U)DQRkB+43Xqb9MFy zjo;f7Zl(+0@U{ZOZ-5LtI^A(gphls-(I>bAO%b)X0%Rr}JgWGZvD+JlsTxN^% zxJBLbH-$q!0L=#%jxX5Vq_FKJ<2w!*===-Y@qzQ*_ z&ov@B+(5Xb?{lf2ViA!OfgI3o#$9BtFq%%7KSq&MDxi7pySJYoi*Mo(W6r!DLSMQT z5R^D?yx*g7)k}}4ziwHEoWI5K%3hPst6voipJkIw?!%9N$K$TWC4VuQM9)7yVq;a$ z=Z;n#4~)-1561t|Pxey=Qu^0P2#JYboJR5co5Ktl*iAC2?$BN>JINDo_+7dptH4MZ z=#a=xrMtj%`CVN()`GKp3RFADpy$xF7~O&&p0-yeG=xW8uhj9Af`YV6uf@~_v;;D#h=*T)D!O`_6(IwY zIw^B!$W|O05eRI*b>Pe%GGlOW`<(mkpbS$G@7HEko`s{=g~2c4kqO2D{R_c$HXzr|(vU9~bVZ9Zw90;2AsK2ig}XTGY6fY#HgGpEaxY zO`D_Z@O8%f#^@5G;myQ5fA(JXK{rgcieDr!{s`~{nU%CRe=1;4og^%^Ts{A8>Sq8@ z7MLFuiJ9lh@TXEbSXQb0;l#nbg^u{Ky;vCuCLR537HT%5FxM^fs5pS1gq3J(Tf!*6 zAc~!aiCB8(;cEmBeX<`V&xqvsk92&%dsXd*G@M$W7!TVsoD%c%!p~lGHEz(ckd{tR z##JAyc1)YR0b@JW|HWX=EIHNMaui<>jUPal5F|-#l#?ar-oHSbCyZG*EuqOC?V5Iz zROd8mBy{ukJ_DuzLTBsPdF^WZ7NW}CWcww?Uwp))_brh+D#JdL%%G}bh zEbmg}yJc_xX1_|6iSomOV4IgTV&UNVe-P4B!*v}&@hLXe=h7%`bcW^Eta_BE?bf*&82)UKj^6nE@ zA$RoKncM;1&!nmY^=yjr6=wgBr%e9BXAxKh^0A1=&iQhn5mfUB$_1N5DJ-DZ4!pLCChW*MHin>-!AX+Twe_SsV%)n#? z9m<01Z}*b;{SU$Rd-`axfZ;y8#-Dau@wD~tukEo#I1b5JhkDp%r;hf2&TH29Y`$=G zCT=}&CU#_(G5)E0y~*>piG@IHnT&WP>Bef5eoMnuRP?tb7aFH_AYy@I!S34oD{g9j zt&5vt`pheqh=GvgZDzlqDuidT)11qC;R35@PC4Z4(p=SICoeHq+3uEqgbmq)}q|_NRzcOHv0J`WLpt+1=j?0A{<5%OLxd!f~^V zfofe-Y;s4+yganmBlRs9L-MCkb@HkcIGzakx6p52sHx;MA}LA_@xo(MP} zDc);OVH(SgwrVlgqy!Vb7cIqe8X$!ECB5e#-)15warssOnkR%x%-o>1T_T=}^z83m z>?c?Vcl|}zH)Gve#!UTymO66c$B^I*%B*@2y23hf5=?aCeBzz7EJe|b9Sex0(wO>7 zRb>P4peOZ<5iwK?l!Imu++&w7Syj6VQ7HaGhAd%tr!?^1W9BpDb9K6w6&K*5X?Mg{ zJ-9!QlR>z>DK+)226mPe<+h_rzFAHI!mzVV#GU?Fzw~_RoaIT4yg6y4BAsT`&lzDE zN8&hg3mPdVnZE*z(B&{cUCbdEZcwCc!M07oJQWk{gQd-> zr9dqLy@o0}77srWq=#f}hD*4;Wr{`XhNy3(QRG7u=})1~*VvvJg7)}?r}&$RlQwv$ zXdGV%bswf)=onk3jFfL;P++Q%v8Zx@HLpgdXD??Rgfd0J7%TheMo&G8Ri zY%xQ58GYjiumJ@R#%;;*4f6=Jqyt;B^WLz4)&y*MwAuEm);Ad)VfKQ8Sr0CY@t@~> zUQjgZ#QB*y&{~9gc(!{BsVt<##<@4;&)IsJD6YtQmo_p%?&3O=8)wZazJdioWa<4X zlrD5`HRzYUVx9XSHNrRMeJbsZXE$L%`CjK>#AvI+17q)*ws2o~m+2h|RXRpuvZ;D* zQY%WR`fzBy@JjoZU*XW8`Fqv?ZRVOCeS4``J028Q{72zS6OggtuOq;?NrF=gLU{T1 z2Ey5bAX2R!_@I`V<&n7vuSD$!&t^oE$C16?6i^2+oXgJEQ^GRtyq7y|3J zjS5W(iH2Od&+O~1mD#qt_V(U2`D~yWIe}Wmh)Pz z`3B*tPj%Q1@@njj!dC^nL67Y3HjBux!~dkMt88TTtEyZ&gy!?kq=hW3X+P_Vrv0a= zk$G`d4jR#UC3q&uVr_NfxeAI|1?9Qb7nKH>x*7HzWEl1J7=Vy~_xZtg^d+=;~q6HX~P<3!HF61g_w>7y^ge1>z>0>CJBlwhy*m zu^e%|FDE`Pg>^K2tw_~`;#;lt;kHE=dWx%}d@{Ep`+}fUYEkRY@7R4z^Gi3a z%p3!^U0{T-%L?kl_g;>HbVbT_)6tT-&YtzE=5CeyU1!c&e8r`X(rWY(&&Hn$;!z<3 z@ZD^M|7w69ux8!!$a=u3Jm9vMnxk@c@;-#Vi;?20XYrZU4{Zg*wkL!!)33(XXlz1R zYdSCxbAF4VGcc|P>jR^>ye$Fvd;}`W;VnrnsgUp09az2h?}6$Hh^S}<)Tc=<&3>*uCLEyR_hY_tr{or zrLSkS#T^|h1|_TSdo$fLueegLlN{0i)^=e2EtbySBh*?saAY}fWW_pZPj89qIdGQG zuxq;}FZf}T8*ZUnyil7Q8o@Dmf8dp6l_IDkJXm0=&ivCe1tvmX*|Y9)KZx>*u)cj!gV3~eOWE0KE$Vd(C$NowTz3Z#GR58MoW7U>(7WibQR7zU zr(M+U)R3#cCD?IbC3MmtR7?nlyi9(d)Z8dBwm5Yv#gE zH~5Y@zD>tVcGN_vSwLt5=jvf;p2JDnXQDL55iWH_(o7-&$C@w1ezEAGF`loMo{^9s z+qL-4cT!g|bS7(^aDM{#4CP=QsdpQhA-B3WQ@8x}1Z~5_L6>yv41-IOKT3S%nn6e5 zjJw+eepy<9mtX+LaCH|?5I*+c*Y9Mnr%8@i5vn4Hu@i=9XtWGol{AM#ixz~m!Q15N zdc*o)e1I~VccQpl$M!|<;DHX$F%un;kJwM!;3X{(+24sQz;UoP+D;pG5OrK;NSpRJ zAoo7h4z`5^2%$YZK@il;j!YY-k-Zk}e^u&AqL*9qyz-Oxo3!(5hwER%GJ1>eeJHnI(0ne%RzAyI5mDgG%|(-4~b=*CY8r|1uLy`6pa z`a`AqLvAMzmPMnOi;v!%;Z#k2RPeMo!UaOYtBz2^Z@;8%ZuCM|L0q-P*6`3fqiw^L zL3`*T0~C5-#Fy`zV$lw~_4mI6WLZS@zu$b)@(M16E0J%hHBZ=3P0gJyo*6+fXZ0|) zB~_}943 z?Lc#&-_51qs+HcN0==Y{;S2E*(c#J}TF1dOq>+oBq7^BO)gtN36`@RskHQ1S3iYcE zdr^>R{%$WSvX(kRE8=0x3WtG3iW!hA)a`Qss{lN*6S62fAT80qpF>~U0K*^ef>uYa zroXwa>=4bE(Me{aSAcQ#S=$1-=uQTg;;=5KvvH5q>2fiJX)f+RsBB9uXVi%6<=o_J z;Fb|nE-|%J+QxjX*FPtOMZ0yTw$HWu++eB$65&pLY_$8rd6A`F5DZM&a@ox>EyZF; zI35+4PUyZ(Fq1PdiWWylndF0L`Bi&mEFQ4%ig#h6sXl- zY}`wuiiW&n92*N#!?nXU?R|&(llg1N@n!AqFF{IZ&>!ujl|0-wU5gGY2E08{lSjF4 zt|sNhwGNVmJc`EVWEc7S%r0=*uWj19qAzg@1=s-H)o&Wz<Lli7-+}2Ha{kq=!XZ~pZc&+Q=0Cr|?#_d2wy>XJyrz^0!NJym zO7^0TjMo8~-}C35db!jXTrFn2nwOg2p{IJ)TMKtnrmOTK9*AKe0{j(&<)*eqt8N!v zpq|U58&sl=USB36p%G@>`5=>n9`TBDZ+p}y$w2uADdGxvcz^~D|-g+X6KZ?b`a6w%sL2=P|o1#BP})wq9P6^I;EBnI=7-f6T*2aKAh(r zXjh?;*}}bE?&sMes#m4`20olUS!0kmkhy2DS0V9I zOVfN+i{L@-)F3v$JA2t)D}TAUs6WZNKJ{$kx`%Omgx%I7Je24zhTUZh(V%L!aHijs zeCcMA`}iNqfj%Fu?+*QOj<}bl1LV*Ss@{fNU5=lL+RyR}X`nw|5$c(I=~X%=VUF8A zjt6XyO6Eiq%OTZ+GJkTSuKVD2LWrlV!?~tMbg?upc?2iFnnE_oJ8?xt5w%`pFE$TSofbGY9Nn%^00N{i~> z!<-d}5xbK}N##I0*iFO8_PIgdMSVO=^HewXRYhMjzGFhagblsyGGu2-wW7GZZ{ zQoU1S*zc%l7-^UdxP0GxT<1fpCrTSsH9D$z?_|R6 z_Vg7Qh~N<#KqCEj{{Z9*u}7$G?~LK>=6PI~v3uf)l@UJV^0t@wG+ak)aZ`yOwUxZ0 ziHYw>>qDBv?tyTN>lry=XZ*IuTz=$P-6wpGW>1{a66PVs?H#@p6~=_6dhZ zQ_C6oC7I*oSKm7UI^y|S@_%pNF_jc0z9XL9|03`HyXxpE1D3c|=~P-|F$QK4)n|(p zysic<{o^^p=+kD)6#_wCVnRh3{vm;FfO(3hp^DhdCadwzK8XzOBXkoPy^at}Pap*v zBU(QN-y|aejaOi@kWw<2H}EDHC;A&JKG2L*Bi1ZUvuMuO9`swC=#*((@P6()>?sWt zSXDf0QV4qoH^Tn-f32+A7sI%V8~ZP)1~6@8g`2`)UUIaRX&f=wzC8&T0D+%B;88ZL z&{X@v#(SwT20&G$4|rq^D~AiK(oG-XF=1UsB7s4^AE5^`5hh(e;#fOR%+1EhfO@H| z^%1^X;6oC2lZX7+_QP$!5C2yH7CdlD4a*frVc;CDYPb|XeSReoPs*JS;SMlZ9?j#N z08l}h{pNsNINt0bkR@G~?a{{%xO{8T{LwZ*OrlaiqT}-+i-P#Wt~zlIz^>o7J46EY zIKG)9Tbm%h6~Cx4ESc-WZhQQJVs@2z?`m%1Y5_5Gws;f(UNDa!Cs>G+hwmK^7{bc~ z5fI@3gCSrr6)-H~KMd?0&220_|EB?11i~u_5#axq0cs?h@X_G;KOQt4EnVGBoGk#7 j=8mQoFXZh_tSmGvOw2u<1}#J%l>qWGD$oikWB>mG5~xOM literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/images/ui-icons_888888_256x240.png b/utilities/docs/script-dir/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5e33f27235d1b5cf0259f63f3894a6be33c679 GIT binary patch literal 6999 zcmZvBWmsH6vi9I^!4hPU5L^Zs2n2T@2=4Cg4nwd3lHdeFfC<5aTkx4cu%N-+2@Dnp z?w8&DzUSG!cYmByefref{ZyTr&!bfS=cPE{A_)M{_^Qau=myRos0#;zfZ>Q;mcGYRie@({fXRC!lf?(~P}uA5O=^WkN6w$E?Bk(QZ@d56yF zvzCin``<%De?$=3f{5%D%>3Rj1G6Iggn@+A<^UREK7ar#ZuV1uR{tmF0D1KqJXc{A z%xfM%w}%vYbcT&PdfJXWqe{@F-Trf1G!PdObSLjZ_+aq%)c>XFRvZg-spg=oj_&;fOm^QKjzig4q;#%o~svm01A0n%NG{&+6qNHCHpjv5-Fjdm&ppQW@gOQc^ZHpV-IqO+^k-I=s7UxRF z-R`7Yak0kmg&9$h1hga2of%GS5j?9PZP3G8 zY0qVzY1dmU>_646Aaqp@=~(-1S>H3%0EF{C8r?%6R{leTHmW}L4@byn3zD(w<~E9O z=Fn0y) zY}2L1AsRK!Z$gx%=12t}dqV5_&hRH<7OR=c;+t`wxrz(}MSDEjxp{*oahH%kyf6V` zAo0S<{8~I3yH)g{!uPj5<8J|IT@-Tc^VzIyi?Tzb@L}&FlF5%e%5=Qa7^9eVC$*`A z82?nDIx;)K2d}6&TMusbX4q*~w<0H@sgZGE!VEh_&x+dXmDx|3XGE*TVtenrF_d@& zOU1DjvGy|ES4oRGhn5;zFm!vDs_}%x318u~U0qSGUuPr#>uUIi_kw&J*SY-yYi=+Y zSWKOfJiwcNofx>;_vN4L2ROpKgvHuiY9Bx)xB^t%?MF zP?PQuootUA?J1D>+&m*iHdeItn?^Q2;v3DFgbnkz4*vq({R&KBB3%!cV5_LAc2V8- z%u0X{E5>%S@Xqv9^EGx&wLfk}FC%4`U@@CmaTcu!eHJ*GV~aaFP>(5pa6C#n46Fa{ zL)oQX4`ZT>4YUe>7xww~^l$y45w{tA^R6X5E9FWBI~%}{6KQ_uk5|hIXc^T%=0M0<<#BJ0RRd_O;3 zsb-D8O$U4S5BOLl_;#4cj;)2Hw;;O_e`}b{FVzp-3IL54{lXt|va~$t(hFS=qc!L) z-3e~P6-a%iT5Ri_Lr?B+gKG~s+?*f;UVI_B^JO>bs$O@!q-4u7(Ml7m|0^KP0oU)W zKGt(FB7jKjw2q%eJLKSlr6|R_MXbz$Lo%+mpGFNp){u);^4_8Q@dp# z(C`~#{#iw$hiaH|e>D#7J1QrG#1@WlsC!qB+e+0yo@4d=SpTXkr--hWpbISfyP>Mc zYi2kQBa1khy84P)({Me9RIes%E`2#p2KKd*kKN1Q%(M|Y>o1(dB7l}m6tl%M{_Fc- zlLA37rfpNZGi_--$j?kmH>Ao0CMGF~4OIuoyBJeGYckr{@11Tf=O-0{8O!w>=)vwA ztf$Cr5BLRwW%tqR@{BrIoS1n(hReKhl7J@GP8|Zf-XdoS7Rn{}qED97tGi<4k7H9*9qX~33TOxusi*f(HP z&viDOR1te?v8OHDy4Pj1M2(q+$ELZQcTaHtGdXfknhJ2j-5AvL%4v$HRh0~PBL4N+ za)Hyn-KMJqXLDdZLy3~% zQze#I%SMB6QK>s`t`$If5J3%(O9R7zZ9!7WBrhq&sWhXw*%Vp!4Eey}bMe=Y??HU! zb)us6SBE=Ax*ulxk;mrf0T*OMQ8$rfO}qtCpd_?icx1?f8OWKKSv<}E=@$orqgn0$ zf1W(L`+WxsKnJDXJt;lDGWz|}V={IGOp1qeHTB{e($_>WB^Is3CQpnzN7ku-vgWz# zEPgAYrzU=WLN!xAEIf0P`5LphqD6{EC&@YQbIF2r7miQFZ?-~Hd`Wt}`#V!iV{U@T zdV{*T(|fvYAr*(4T`JMaY;~#>68=#ibONi$`qx`kTV0TP^EbTPS{ZF$+S%_Ud)3DO zM466a+aQJA%vb%~h)VOdU8#yO3NRcJo-%(8GI=&pb|Rn3hh9^j9b=-8+s`SuQ&T#C zG`x0elQvoRIyHRm%}r*NmJCMWxu~l#gL1zt92X?FvBzCq(!TY=%}T(M`2fk%*IK;L zBXT~eU|)AqjR&~?Fz|X7o3)jQBygoIaU$uRnV2WVA*`hie6NFj{fSYR$tSf6-H=*d zdg}V*#wU?b6zPJx_?i*)^2ZdWsa5|LJ@!W|k<1z1=y^2{->z_u{ii?p@!+*1 z{h8i=ictpi5|yFmiDrcW;%N!e{dA-3vMkJ6wh__#hsHxo;NDM7S9sqrR*Ea%B8bay z%X~oeF6AiMIIttj{)0rXEtx0%X!)!~g*1q(y!4>GqHs<~ni<`37IN#`5Y=we;sV48 z0^j>rz6pk@HOv9#P1osT_@$Rqji)f6X1^9>Z_zAx7ZYa@{Y<|wF-ZqzZ;N3*tvyWUlgZae9C@OZ_LDT2H`F?q&u z!k&TYj{q-6?lkD3=IGZNqwuV3sEQZglk180ch%^iZfE(@dqorO^(^oR2@#VUjpZ92 z*us5g!F35st14zVf55PT_N3~({Bvd_NP8L)=`w+^BdtEgl=jgASgv%&x1HhxA5DJI zz6c)lWhxJ6F7wU9r|m)ug)F^-AVN@O;4qgQPN2i#$La#d(AxaQE-p)9WvV}$aZXJ# zz)-VGidtmqQHL?Egt@AMsbz!!2?#$6J>2Z_?vp(u*f1Jy86l;U1fr|I&^Aw>lTt-r z<)_$xVFFdc`nS+{OiM!u^4E2?nETPkyl1m2;|2$E+_PRAPnKYr_#g8`WNKaK4F7^` z?Ubvq{W1>s1^7Y{HItAy&8^_JgrpO%s=DZp4tZCbahEi+1%pC0#fCYEu7hL3$tZ50 zXuFu6Yp-chB5r{mj(GFKp_Ly^d~x}|agLYR8*{vMq*5frzoTSB4MIX`VXWcT5J(p$ zvb|v$4c?8v;T!4IdUfGv>>H^7+@>gzX^B|paL3B~Eke}ziUGpPQ}dIn03g4gRNJh8wrgjZppN344yAl%PT>?dXQfM#P!sRwL z;KMIu(ce?sUkiv?!Vy1m=vGTp^K>83Yjo?d$#<=t-KkL}_==YbTSL3tgWR6)-Ro8r zg>cv=%3Rb9yeFBfD78$8J*?6gjy>9c`q1R8Qn(CxX}XM8Mj^JBOyR>=?rRKQXO9*gvJyjfbJrs0U~2168KVOU;jdTE zc^Mh^)?{DY*$cO1{5f&&9Bm`e-;2K6o#q?)^0k*DB`UkBhVcdDfrep|D->3J#MJp+ zXY1nE?S}HFz60zQiVNOD@25Sa*0SK_@r3 zC(tKK+*fXb0BXgdWEt29pxJlcGHzY zJkOun3<4jbr>1T_TTE+(G2fT~#EBMFE0%pmldkXeM2*ccV3jW|Q1%;GkEKr2f0jK$5CC(%my!&suy}Ege*D+mwSTsfwKm{=38iPdckt95#-u`Gvf%NB z;Jh9Y$q!*z#v9yQDy~nPEHhs8Qkw?&{9op;3~$xMQ7^lQ+Vhi5nq!hLeB_uq=fV`i z!E)geaw+Zv{3e01>Ja?YPHdnFy?gNc=tt*_9!=`7Pxa?6vDx7m z-0>Iz7kq>(phWuFYjg~71xPKq{iPwgaFzo`h735{1u|PL&;op4?W}XU z*Zy62q5Zpw>NWW%j9#6bduP-Wx-U7vc>pnX^^HJeuMF)nYzFL z%R|OuztH2Mvi-7KmK*i^jJvfjk^KvfFB=8yB`>Tf2m;=skPWJI`bo3orf~30518bt<-Gc+ep2#?If-gL z;_V5G4bEA`J=zvwI~Q@$Og=!W8uwTmkeO|h{T!d3G}TRwN4S(@6%mj>r>tEd-;I6xK}CyHNR z`W}vjd36p~^P67IHm7n0WplM~-h0G4d(^lQdh*;f$GS9QH}m7A_@SjdB<{Q@lSpks z#9Z>MGSepD!)70Z0=($IJ>f|tC992?O1@XfyaXPp;h$rKrsx6fGn7zu0DK-m%11pb zGs9l*hMI>!-euGLyZpfz$09N2tK7I|b;S-_#kFUjE5M#v)sglMJH-hP9PYzL!(X=C z&l?pTPZ)^!L+CzJldxTEnRX$U#7DonI=OJLC|?k4#%1GNfv4AB1Wnw!xI3XLtci;D z>-ZQ7cE%tm1TrT|p*;#G65?!pEWW|rV?DJVanShnI9f(F!n8!3pJz=ASgeotHM#nQlcCth-Uv8eYLIFq|3 z$8;wJtnCMzOA2y}?03AoxqP{&<<^LHq+AC=(zuu(*k+;i3vxtnzWwUcSRvqT@9p9U z6B$%<@gcw_XUet5{BmU@iP+3ij=x_$z4QHD)k`HvNGXwccALGY(cnw0iuw^T!X3kM zCPp%7p}~l8b7j81O$PF3Yj&4)EbM@*agLVppE|pzn$sS(tEqN45aMSbu8N?*|P}v74M2!K~C@*$2i}SB=KKK-lw5%5K-;( zx7f;>L=##Ydm&d@RA~naR#0%3 z%Jt(5o)V(kBwAXNS$kQ*X>zg{Hz$*p)jQ~CPvPAOXWSlU?UV&`;kEB#yUYYnQYm~( zM{Wz^qIPF1>EY9Qm zs(bJSW9*o|Vh+{F4kmXlq<#GjIhTPKk38K-n5^lF$9s-<)ehAI3h7s(%ZAM}PxI~BVn6$b^R>=qIM4`F$ zHJIDKBpfOts&!OC?+vc@YFza+(}>X6gGd#)^)Y1hg_B@0JN)W{o&aj8uTC07^&Ms0 z+%4m=-h-4rU;#PK3cr=COqN7gJd2o&8|~IR-aaTjI5t4v;163AT%imiB9*B`OHKYd z7NM%=d}-LtFW0pp5c*3wNhme>^b+O=nYY9$&%s0Sj+J~*BL>Kh_`#Nl)sIOAZg z@t&kUUg#t5=ox78pG2wvT1_sF)`xJ~q{34riYgi$4F=znBeG~miClofeMJwEaUBJtDa?9tQBUX0F$_zoU8SmzfCfb$uMED{p)utjDJe)DYI z|CEyh*7Tn9ST3$vSa2?msDZYHy%xc@6F?0j`BW54t!2@(cVeLa`6Iqa(Vt=&R~pre z+kdK%&@j?q&W~Vtepw;nuBC_|N39bWl{VjCMLK`6Dg076ctt`Gz>vl+96WWc@{?M> zSc-4f6T=QQ^XGcPBDe*8N z6p)h91fy@X^D`W}r!QrGa69d*j; z0IVCMHC8T5WH;YpbB8+~JA^kzJs&&r?!uzKV&i7BhyG;ZzAYoGHQ!UkNW2O?$))({W;@58;aMHIOGn@%AJsy8Vz3^2q^tH9}wG*@PwtEx+0T9114@iWE zUr?7HBqqQw1{UQ4fy6){TD17Y{{Xmo*gDw<{W}08DkdN-1{V4k;A9w1`UrUTj~R44 r?0o~QyzKxowjS1Yj4Ezc4tB5YtZak42JFNil>jOVn(|e$mT&$CkHH7} literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/images/ui-icons_cd0a0a_256x240.png b/utilities/docs/script-dir/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..7e8ebc180a2d2a74739059799407b8b7b57a9092 GIT binary patch literal 4549 zcmeHK2U8PFw@yL`geFb85=9ZD1*F$df}vOGyaXvKy$K2df>fnT5l|3bse%xZCPhLK zq(s2bG?a)Sy-1T5a?x+*n|uGmeP(CR*`0mn>^?hl=A6f-#y6Q6_!s~H0J9!S#~c6v zp1FW6dYZF&QcwTzY=gzr&=N^tVEF&>Uj<|d!K-Hi*#?;#TL5@jZ-D7d+aKjhUB2ay za7XiT$P6-HQsvS@8Ne>u30;%65Ra9O$98#q8tPF*3bZzTz*N?kB)u+wBUmd+0T!5D z*<^r#Xj1>ZovB|~<30Q0ri+GeWcuAh#6Q2zf&gzD+|&Ui&|W~DEuelV+rTsX$43El z`#jYFfOD>TI+~UbzO6elx{w;!AbqIU%Q;US-y3k0y&ZS`{PXJ9%GKuT? zA=YB~_}-7h}grk~UMM~1{IJu5z36&nH&VPs=tlLlQ$TWf}@j0@_1Mr{7PN}kZ@ zU@9N%V%HL9eSE z*BdLzdW%d9Pf1SA5`lAsx?6C@pGL*pIra&^83Gx%WYG^8aT%R?OG4Ou=0P3R5)KZ5 z2&PGFszDp$u%zsXBYLrEImJ}xFS--_mkY=#l)@OKCnEoMOo8S*eqcoB^(_J&4tmM< zs4&xp4^NNgy&HVP!O(^_6JQclp)V-Ib9=q9aWcaz*Gx~fED_HM%LFsYU%*S)OnQwc zjLYYoLk)hxsCi6qp^!9HRp8G%b|f68yfB?n<^DBz9!E*WgJ2gV*g5_E7alHp*g2_wbc8Pw7*-B9ToxV53c2rO-Vs4Px{7M!NqIXUcMSHv1cqfD&&RnMQs) z8771gCX+j09M{&*+~vB&SSU^b{}8I6?+$$T9I*OL*{LYxAHX;*iW?dX43jc> zp~TZQLjbC#e#FPvV$ou|K+q=`%KR&iGq0m)&%Qcc{(18s?cH)B<=dn&oKq#&CVm$KVlo#Io;OGBX$ckfqw0sl%9n2giktQ~NFXr`I; z@h650el?%I!6y~!d;+G2vdswoOkzni?&A=OT9T`SipWyQFEyIunl_G*e?HE^ zx7hkb*WF(Q-{^pB`|k8FH76TXH6UL4I}2h>bLnbqDDskSJx^zYBqL{y$Sn($8Qire zMAVY2aEEb~T~WwSd>Zm#SF3TtfRem42m@SaPkNC3#AX)UgT%TW=5u7S=dxp|3h~tk+8yZee}?!M9HI@f1WTU?%HqiNq#8O^RmBZ`M8nW z4|fZvl;5BN{Lb=BYDGdiZ)y8 zAJE}UL0VRg6Y7k--*#>qd}SW1`t(XXl);%iKi{ne!56tAR#KrNk#?YdO;$EPr~Ghg zL?F4G51g8yyaYA|gz0Frg48>AICegIAO6!sUwFPVn!UV}NVFIh?iYutyf9vPz5yy( z6DHSbg~R&3N2@w%ro3d+aztG`xPRDrWGn*Y&;syq!6%Nw=lpy*v1>S; zz{fdE9!dF+My~C&wlU5dQQi|liohaCEU{7=clSmk*wsDU+doSXunDD0ppEf~z7_WK zr+{Ip?==2A3sWeggPH~cD#9z$y`Scm$bJE%)>E|H9P>`Q=3WWq&5Gckv?(2+idix- z=}@U*Mw5z1u`6g?w5skq?WtvLzqBse`dg0I`$C5Hc0=;s zkPHED_%Qv>At$X$ZQoAYc=|i@^yMF^9@eeSh=MAFRi5FHuyr-LC*Z!C9W%qiV99!$ z+O4V2zvRN1wsMwg1WGvGv~LqgOA2pQZi~E#pY5Lj`j`sW1jcRidq&GPu(oq7&iz*W zKqyJ$uZ1uC=#zeW>zJF-nx-gt-}Ak+qN{)H+eFKjl(8fvzoS10rN}hbM=2ZHn7&EW z&8^#HYV0+@3zAc}_pVhH22dU+MW5s4HwjodZU|T(EZaZ2D1Vuc&fO1}CSck5&kdJ% zi5gTPGKuKSk8XiGTl>tjIdMWO%>rJ^?&*|Ie1H+ zQLN{pqOrow2FVb%V>X_jBIhzH6s6~oS_oYp;iE>C%Z8w|lf!Ev?jfhYkP?FOAJ=__ zr3Ndn*>IP;iK|Ccxw##$W6H7snuYuHC7o)bP}ir&X4B|!Zd3cDm`a244dW*}1CN%5 zXbw16r3xZMsYF85zpYIaVr} z?@&!YCHZY9Dhmzcwq`}f17^3P{$})GtY|@wRkgs2TGgSwUV|As8%gAY&4}SLTG6V7 zW4_tEA;9}Q!A@(ZaEcrzDlf2bSL%{R)ka6gH9z06;tUEGAxQhi>~Q}sg1^506i46bzM;PHOzX~mY*`jhIiS}ZN2&$pmjO9S=Mj>^wMj=hEu zl~8}2{%}WDK+?okXRZA{H+!LjL{Qw9wi7vK1jiPkap+~_ak9^lCE_h!OeGWGGC-f1 zVRpAm`}*sOCzi+Ga`RF(!KxOX_nSKFZ%-ou%u?^0ue8}s6S?Xo-QGlc{EYuH{+mQ} z>M!OEuy)pxcgz<<{Cz|GC0u}FhbpDfLsov{TnAe9J`HN1 za$1aaKcULuO}iD`>6xOm$wW+_K_~{}#cJyGb!F&r_u_WE*8>}sUhJ6ueSj+chaBTO z_5$EOo-Ic;$S9Ktg;7Yrv0}eqi8w*$7sq2td!fj=Cb#w8?(xBoqj;W#K&Bk`$}tA3 z9AGH_)V?G6ZC=jUdQlN6RDFWODgd0RQQ;0q(jfFwegfKM0~6S+>;@7olQV~&k49?f4c6ReTPQa($S^cob|b_kZ$#iX{C8Kz*x0%0 zo>cBW9N_VWlazSRa?1##MXSou-fxeD!_&QLemU3-p!Hs?V4m6Uct-_K_|&bHnK!W$ zV;63=dGgzIvcKFCOuQk~(75AeyWPI#G+g@N6{x%iJmUeHX;4Zap?8EBjG*?Rg>>ai z2KP;zLI>J)rrvOVNW5NFP3LK%e~$B;2#8-H>%?dKvqQey7_%N$0BA{1=_#M`>JpGj zx^=X=@Ue4rw&8wAx+E@QbDpFk)D;j9<|OP%PJua#2WVcDDKfA63c=(IOQ-ItOLyLj z#xi9OEcg{vTTL1PH0YM4?khk(&TzrkU^aY+ypr5 z{jp4uL+LRby+u5hgmq)J$>w4X_2hrqq;M%gOnCFRl<7qk=J7~NV(r#;uVaI=;k)yH z3s|;iNg&Le8;yH+`qw4sWA#bWtE1?ftr!s26wPW{TB4{eZ7}vcT{CttS+z#yeHZD` z!Dm{7xPVwM1jvxV5cImPfv~WUzB0lD0V?KmAfl1#yl9`E3o(FJ-W+yQ`0C&D)y6G7Fqei&raMZE$9ts7fa z4f4?J_L;XiwLe#tFZPq{Hi=d2HL_a#J6156HfF@TAh; z*?Y}c7mP70lKYjiy#yEAjAE=?L_%I!DCR2DHw8zdS^Oe`Q{pKe%3AToxCN@8lKi~y z{NBUBt1t6X6V9;2e1t)uN}rcE_dBkxip3*do}=#z;&-%u?-?GxK;Dbzs!>Q^*6ptj zm^eD>*BoA?nOOnx9cmrMao0O|mq-wu>SauA6^XMeyN#cZXde*AQjDKU-aV#`nCYM! zK93Mnh)oEUJD3C2u*7fg1Z6u(rIWt=TFIqI@vO6HP*2{$Nfzqqt)jply2Pr`P1<{K zAJze>9Iexn7%VzWXJ<9dI_s1qgpT?U{aFjU?#mtfXwP1}`wno0q-!-Ch4te$o&7NO zv0K{_tOX8j$%GwNi1XUiA4V4r(b+)i-C0MYc`g)V`!_Vllu=)fmSLWy3MWmjV{~>( z2}Qmx;l8gN7vOQhu1Ct|e;v2u<}Z#5f0Ri`pg-r)`~A!ONc0I6kHauS0UE#sMlq4I z%K6CTTyOG<7_>u(<5A(mz`ps}+2ji&AfFQ+KjMEIGm>t=ebp$kBvqJzq Mq_Ix57W&cu0AIB!=l}o! literal 0 HcmV?d00001 diff --git a/utilities/docs/script-dir/jquery-3.5.1.min.js b/utilities/docs/script-dir/jquery-3.5.1.min.js new file mode 100644 index 0000000..b061403 --- /dev/null +++ b/utilities/docs/script-dir/jquery-3.5.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,l=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};h>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),l.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-a-n;e.collisionWidth>a?l>0&&0>=h?(i=t.left+l+e.collisionWidth-a-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+a-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-a-n;e.collisionHeight>a?l>0&&0>=h?(i=t.top+l+e.collisionHeight-a-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+a-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-r-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-r-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.widget("ui.menu",{version:"1.12.1",defaultElement:"
    ",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,l=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=l.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=l.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("
      ").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("
      ").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("
      ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(t("
      ").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("
      ").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete}); \ No newline at end of file diff --git a/utilities/docs/script-dir/jquery-ui.structure.min.css b/utilities/docs/script-dir/jquery-ui.structure.min.css new file mode 100644 index 0000000..e880892 --- /dev/null +++ b/utilities/docs/script-dir/jquery-ui.structure.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.12.1 - 2018-12-06 +* http://jqueryui.com +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0} \ No newline at end of file diff --git a/utilities/docs/script.js b/utilities/docs/script.js new file mode 100644 index 0000000..864989c --- /dev/null +++ b/utilities/docs/script.js @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +var moduleSearchIndex; +var packageSearchIndex; +var typeSearchIndex; +var memberSearchIndex; +var tagSearchIndex; +function loadScripts(doc, tag) { + createElem(doc, tag, 'search.js'); + + createElem(doc, tag, 'module-search-index.js'); + createElem(doc, tag, 'package-search-index.js'); + createElem(doc, tag, 'type-search-index.js'); + createElem(doc, tag, 'member-search-index.js'); + createElem(doc, tag, 'tag-search-index.js'); +} + +function createElem(doc, tag, path) { + var script = doc.createElement(tag); + var scriptElement = doc.getElementsByTagName(tag)[0]; + script.src = pathtoroot + path; + scriptElement.parentNode.insertBefore(script, scriptElement); +} + +function show(tableId, selected, columns) { + if (tableId !== selected) { + document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') + .forEach(function(elem) { + elem.style.display = 'none'; + }); + } + document.querySelectorAll('div.' + selected) + .forEach(function(elem, index) { + elem.style.display = ''; + var isEvenRow = index % (columns * 2) < columns; + elem.classList.remove(isEvenRow ? oddRowColor : evenRowColor); + elem.classList.add(isEvenRow ? evenRowColor : oddRowColor); + }); + updateTabs(tableId, selected); +} + +function updateTabs(tableId, selected) { + document.querySelector('div#' + tableId +' .summary-table') + .setAttribute('aria-labelledby', selected); + document.querySelectorAll('button[id^="' + tableId + '"]') + .forEach(function(tab, index) { + if (selected === tab.id || (tableId === selected && index === 0)) { + tab.className = activeTableTab; + tab.setAttribute('aria-selected', true); + tab.setAttribute('tabindex',0); + } else { + tab.className = tableTab; + tab.setAttribute('aria-selected', false); + tab.setAttribute('tabindex',-1); + } + }); +} + +function switchTab(e) { + var selected = document.querySelector('[aria-selected=true]'); + if (selected) { + if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { + // left or up arrow key pressed: move focus to previous tab + selected.previousSibling.click(); + selected.previousSibling.focus(); + e.preventDefault(); + } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { + // right or down arrow key pressed: move focus to next tab + selected.nextSibling.click(); + selected.nextSibling.focus(); + e.preventDefault(); + } + } +} + +var updateSearchResults = function() {}; + +function indexFilesLoaded() { + return moduleSearchIndex + && packageSearchIndex + && typeSearchIndex + && memberSearchIndex + && tagSearchIndex; +} + +// Workaround for scroll position not being included in browser history (8249133) +document.addEventListener("DOMContentLoaded", function(e) { + var contentDiv = document.querySelector("div.flex-content"); + window.addEventListener("popstate", function(e) { + if (e.state !== null) { + contentDiv.scrollTop = e.state; + } + }); + window.addEventListener("hashchange", function(e) { + history.replaceState(contentDiv.scrollTop, document.title); + }); + contentDiv.addEventListener("scroll", function(e) { + var timeoutID; + if (!timeoutID) { + timeoutID = setTimeout(function() { + history.replaceState(contentDiv.scrollTop, document.title); + timeoutID = null; + }, 100); + } + }); + if (!location.hash) { + history.replaceState(contentDiv.scrollTop, document.title); + } +}); diff --git a/utilities/docs/search.js b/utilities/docs/search.js new file mode 100644 index 0000000..2246cdd --- /dev/null +++ b/utilities/docs/search.js @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +var noResult = {l: "No results found"}; +var loading = {l: "Loading search index..."}; +var catModules = "Modules"; +var catPackages = "Packages"; +var catTypes = "Types"; +var catMembers = "Members"; +var catSearchTags = "Search Tags"; +var highlight = "$&"; +var searchPattern = ""; +var fallbackPattern = ""; +var RANKING_THRESHOLD = 2; +var NO_MATCH = 0xffff; +var MIN_RESULTS = 3; +var MAX_RESULTS = 500; +var UNNAMED = ""; +function escapeHtml(str) { + return str.replace(//g, ">"); +} +function getHighlightedText(item, matcher, fallbackMatcher) { + var escapedItem = escapeHtml(item); + var highlighted = escapedItem.replace(matcher, highlight); + if (highlighted === escapedItem) { + highlighted = escapedItem.replace(fallbackMatcher, highlight) + } + return highlighted; +} +function getURLPrefix(ui) { + var urlPrefix=""; + var slash = "/"; + if (ui.item.category === catModules) { + return ui.item.l + slash; + } else if (ui.item.category === catPackages && ui.item.m) { + return ui.item.m + slash; + } else if (ui.item.category === catTypes || ui.item.category === catMembers) { + if (ui.item.m) { + urlPrefix = ui.item.m + slash; + } else { + $.each(packageSearchIndex, function(index, item) { + if (item.m && ui.item.p === item.l) { + urlPrefix = item.m + slash; + } + }); + } + } + return urlPrefix; +} +function createSearchPattern(term) { + var pattern = ""; + var isWordToken = false; + term.replace(/,\s*/g, ", ").trim().split(/\s+/).forEach(function(w, index) { + if (index > 0) { + // whitespace between identifiers is significant + pattern += (isWordToken && /^\w/.test(w)) ? "\\s+" : "\\s*"; + } + var tokens = w.split(/(?=[A-Z,.()<>[\/])/); + for (var i = 0; i < tokens.length; i++) { + var s = tokens[i]; + if (s === "") { + continue; + } + pattern += $.ui.autocomplete.escapeRegex(s); + isWordToken = /\w$/.test(s); + if (isWordToken) { + pattern += "([a-z0-9_$<>\\[\\]]*?)"; + } + } + }); + return pattern; +} +function createMatcher(pattern, flags) { + var isCamelCase = /[A-Z]/.test(pattern); + return new RegExp(pattern, flags + (isCamelCase ? "" : "i")); +} +var watermark = 'Search'; +$(function() { + var search = $("#search-input"); + var reset = $("#reset-button"); + search.val(''); + search.prop("disabled", false); + reset.prop("disabled", false); + search.val(watermark).addClass('watermark'); + search.blur(function() { + if ($(this).val().length === 0) { + $(this).val(watermark).addClass('watermark'); + } + }); + search.on('click keydown paste', function() { + if ($(this).val() === watermark) { + $(this).val('').removeClass('watermark'); + } + }); + reset.click(function() { + search.val('').focus(); + }); + search.focus()[0].setSelectionRange(0, 0); +}); +$.widget("custom.catcomplete", $.ui.autocomplete, { + _create: function() { + this._super(); + this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)"); + }, + _renderMenu: function(ul, items) { + var rMenu = this; + var currentCategory = ""; + rMenu.menu.bindings = $(); + $.each(items, function(index, item) { + var li; + if (item.category && item.category !== currentCategory) { + ul.append("
    • " + item.category + "
    • "); + currentCategory = item.category; + } + li = rMenu._renderItemData(ul, item); + if (item.category) { + li.attr("aria-label", item.category + " : " + item.l); + li.attr("class", "result-item"); + } else { + li.attr("aria-label", item.l); + li.attr("class", "result-item"); + } + }); + }, + _renderItem: function(ul, item) { + var label = ""; + var matcher = createMatcher(escapeHtml(searchPattern), "g"); + var fallbackMatcher = new RegExp(fallbackPattern, "gi") + if (item.category === catModules) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catPackages) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catTypes) { + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.l, matcher, fallbackMatcher) + : getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catMembers) { + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.c + "." + item.l, matcher, fallbackMatcher) + : getHighlightedText(item.c + "." + item.l, matcher, fallbackMatcher); + } else if (item.category === catSearchTags) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else { + label = item.l; + } + var li = $("
    • ").appendTo(ul); + var div = $("
      ").appendTo(li); + if (item.category === catSearchTags && item.h) { + if (item.d) { + div.html(label + " (" + item.h + ")
      " + + item.d + "
      "); + } else { + div.html(label + " (" + item.h + ")"); + } + } else { + if (item.m) { + div.html(item.m + "/" + label); + } else { + div.html(label); + } + } + return li; + } +}); +function rankMatch(match, category) { + if (!match) { + return NO_MATCH; + } + var index = match.index; + var input = match.input; + var leftBoundaryMatch = 2; + var periferalMatch = 0; + // make sure match is anchored on a left word boundary + if (index === 0 || /\W/.test(input[index - 1]) || "_" === input[index]) { + leftBoundaryMatch = 0; + } else if ("_" === input[index - 1] || (input[index] === input[index].toUpperCase() && !/^[A-Z0-9_$]+$/.test(input))) { + leftBoundaryMatch = 1; + } + var matchEnd = index + match[0].length; + var leftParen = input.indexOf("("); + var endOfName = leftParen > -1 ? leftParen : input.length; + // exclude peripheral matches + if (category !== catModules && category !== catSearchTags) { + var delim = category === catPackages ? "/" : "."; + if (leftParen > -1 && leftParen < index) { + periferalMatch += 2; + } else if (input.lastIndexOf(delim, endOfName) >= matchEnd) { + periferalMatch += 2; + } + } + var delta = match[0].length === endOfName ? 0 : 1; // rank full match higher than partial match + for (var i = 1; i < match.length; i++) { + // lower ranking if parts of the name are missing + if (match[i]) + delta += match[i].length; + } + if (category === catTypes) { + // lower ranking if a type name contains unmatched camel-case parts + if (/[A-Z]/.test(input.substring(matchEnd))) + delta += 5; + if (/[A-Z]/.test(input.substring(0, index))) + delta += 5; + } + return leftBoundaryMatch + periferalMatch + (delta / 200); + +} +function doSearch(request, response) { + var result = []; + searchPattern = createSearchPattern(request.term); + fallbackPattern = createSearchPattern(request.term.toLowerCase()); + if (searchPattern === "") { + return this.close(); + } + var camelCaseMatcher = createMatcher(searchPattern, ""); + var fallbackMatcher = new RegExp(fallbackPattern, "i"); + + function searchIndexWithMatcher(indexArray, matcher, category, nameFunc) { + if (indexArray) { + var newResults = []; + $.each(indexArray, function (i, item) { + item.category = category; + var ranking = rankMatch(matcher.exec(nameFunc(item)), category); + if (ranking < RANKING_THRESHOLD) { + newResults.push({ranking: ranking, item: item}); + } + return newResults.length <= MAX_RESULTS; + }); + return newResults.sort(function(e1, e2) { + return e1.ranking - e2.ranking; + }).map(function(e) { + return e.item; + }); + } + return []; + } + function searchIndex(indexArray, category, nameFunc) { + var primaryResults = searchIndexWithMatcher(indexArray, camelCaseMatcher, category, nameFunc); + result = result.concat(primaryResults); + if (primaryResults.length <= MIN_RESULTS && !camelCaseMatcher.ignoreCase) { + var secondaryResults = searchIndexWithMatcher(indexArray, fallbackMatcher, category, nameFunc); + result = result.concat(secondaryResults.filter(function (item) { + return primaryResults.indexOf(item) === -1; + })); + } + } + + searchIndex(moduleSearchIndex, catModules, function(item) { return item.l; }); + searchIndex(packageSearchIndex, catPackages, function(item) { + return (item.m && request.term.indexOf("/") > -1) + ? (item.m + "/" + item.l) : item.l; + }); + searchIndex(typeSearchIndex, catTypes, function(item) { + return request.term.indexOf(".") > -1 ? item.p + "." + item.l : item.l; + }); + searchIndex(memberSearchIndex, catMembers, function(item) { + return request.term.indexOf(".") > -1 + ? item.p + "." + item.c + "." + item.l : item.l; + }); + searchIndex(tagSearchIndex, catSearchTags, function(item) { return item.l; }); + + if (!indexFilesLoaded()) { + updateSearchResults = function() { + doSearch(request, response); + } + result.unshift(loading); + } else { + updateSearchResults = function() {}; + } + response(result); +} +$(function() { + $("#search-input").catcomplete({ + minLength: 1, + delay: 300, + source: doSearch, + response: function(event, ui) { + if (!ui.content.length) { + ui.content.push(noResult); + } else { + $("#search-input").empty(); + } + }, + autoFocus: true, + focus: function(event, ui) { + return false; + }, + position: { + collision: "flip" + }, + select: function(event, ui) { + if (ui.item.category) { + var url = getURLPrefix(ui); + if (ui.item.category === catModules) { + url += "module-summary.html"; + } else if (ui.item.category === catPackages) { + if (ui.item.u) { + url = ui.item.u; + } else { + url += ui.item.l.replace(/\./g, '/') + "/package-summary.html"; + } + } else if (ui.item.category === catTypes) { + if (ui.item.u) { + url = ui.item.u; + } else if (ui.item.p === UNNAMED) { + url += ui.item.l + ".html"; + } else { + url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html"; + } + } else if (ui.item.category === catMembers) { + if (ui.item.p === UNNAMED) { + url += ui.item.c + ".html" + "#"; + } else { + url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#"; + } + if (ui.item.u) { + url += ui.item.u; + } else { + url += ui.item.l; + } + } else if (ui.item.category === catSearchTags) { + url += ui.item.u; + } + if (top !== window) { + parent.classFrame.location = pathtoroot + url; + } else { + window.location.href = pathtoroot + url; + } + $("#search-input").focus(); + } + } + }); +}); diff --git a/utilities/docs/stylesheet.css b/utilities/docs/stylesheet.css new file mode 100644 index 0000000..836c62d --- /dev/null +++ b/utilities/docs/stylesheet.css @@ -0,0 +1,865 @@ +/* + * Javadoc style sheet + */ + +@import url('resources/fonts/dejavu.css'); + +/* + * Styles for individual HTML elements. + * + * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular + * HTML element throughout the page. + */ + +body { + background-color:#ffffff; + color:#353833; + font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:14px; + margin:0; + padding:0; + height:100%; + width:100%; +} +iframe { + margin:0; + padding:0; + height:100%; + width:100%; + overflow-y:scroll; + border:none; +} +a:link, a:visited { + text-decoration:none; + color:#4A6782; +} +a[href]:hover, a[href]:focus { + text-decoration:none; + color:#bb7a2a; +} +a[name] { + color:#353833; +} +pre { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; +} +h1 { + font-size:20px; +} +h2 { + font-size:18px; +} +h3 { + font-size:16px; +} +h4 { + font-size:15px; +} +h5 { + font-size:14px; +} +h6 { + font-size:13px; +} +ul { + list-style-type:disc; +} +code, tt { + font-family:'DejaVu Sans Mono', monospace; +} +:not(h1, h2, h3, h4, h5, h6) > code, +:not(h1, h2, h3, h4, h5, h6) > tt { + font-size:14px; + padding-top:4px; + margin-top:8px; + line-height:1.4em; +} +dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; +} +.summary-table dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + vertical-align:top; + padding-top:4px; +} +sup { + font-size:8px; +} +button { + font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size: 14px; +} +/* + * Styles for HTML generated by javadoc. + * + * These are style classes that are used by the standard doclet to generate HTML documentation. + */ + +/* + * Styles for document title and copyright. + */ +.clear { + clear:both; + height:0; + overflow:hidden; +} +.about-language { + float:right; + padding:0 21px 8px 8px; + font-size:11px; + margin-top:-9px; + height:2.9em; +} +.legal-copy { + margin-left:.5em; +} +.tab { + background-color:#0066FF; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* + * Styles for navigation bar. + */ +@media screen { + .flex-box { + position:fixed; + display:flex; + flex-direction:column; + height: 100%; + width: 100%; + } + .flex-header { + flex: 0 0 auto; + } + .flex-content { + flex: 1 1 auto; + overflow-y: auto; + } +} +.top-nav { + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + min-height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.sub-nav { + background-color:#dee3e9; + float:left; + width:100%; + overflow:hidden; + font-size:12px; +} +.sub-nav div { + clear:left; + float:left; + padding:0 0 5px 6px; + text-transform:uppercase; +} +.sub-nav .nav-list { + padding-top:5px; +} +ul.nav-list { + display:block; + margin:0 25px 0 0; + padding:0; +} +ul.sub-nav-list { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.nav-list li { + list-style:none; + float:left; + padding: 5px 6px; + text-transform:uppercase; +} +.sub-nav .nav-list-search { + float:right; + margin:0 0 0 0; + padding:5px 6px; + clear:none; +} +.nav-list-search label { + position:relative; + right:-16px; +} +ul.sub-nav-list li { + list-style:none; + float:left; + padding-top:10px; +} +.top-nav a:link, .top-nav a:active, .top-nav a:visited { + color:#FFFFFF; + text-decoration:none; + text-transform:uppercase; +} +.top-nav a:hover { + text-decoration:none; + color:#bb7a2a; + text-transform:uppercase; +} +.nav-bar-cell1-rev { + background-color:#F8981D; + color:#253441; + margin: auto 5px; +} +.skip-nav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; +} +/* + * Hide navigation links and search box in print layout + */ +@media print { + ul.nav-list, div.sub-nav { + display:none; + } +} +/* + * Styles for page header and footer. + */ +.title { + color:#2c4557; + margin:10px 0; +} +.sub-title { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 15px 0; + padding:0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:13px; +} +/* + * Styles for headings. + */ +body.class-declaration-page .summary h2, +body.class-declaration-page .details h2, +body.class-use-page h2, +body.module-declaration-page .block-list h2 { + font-style: italic; + padding:0; + margin:15px 0; +} +body.class-declaration-page .summary h3, +body.class-declaration-page .details h3, +body.class-declaration-page .summary .inherited-list h2 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +/* + * Styles for page layout containers. + */ +main { + clear:both; + padding:10px 20px; + position:relative; +} +dl.notes > dt { + font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:12px; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +dl.notes > dd { + margin:5px 10px 10px 0; + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} +dl.name-value > dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +dl.name-value > dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* + * Styles for lists. + */ +li.circle { + list-style:circle; +} +ul.horizontal li { + display:inline; + font-size:0.9em; +} +div.inheritance { + margin:0; + padding:0; +} +div.inheritance div.inheritance { + margin-left:2em; +} +ul.block-list, +ul.details-list, +ul.member-list, +ul.summary-list { + margin:10px 0 10px 0; + padding:0; +} +ul.block-list > li, +ul.details-list > li, +ul.member-list > li, +ul.summary-list > li { + list-style:none; + margin-bottom:15px; + line-height:1.4; +} +.summary-table dl, .summary-table dl dt, .summary-table dl dd { + margin-top:0; + margin-bottom:1px; +} +ul.see-list, ul.see-list-long { + padding-left: 0; + list-style: none; +} +ul.see-list li { + display: inline; +} +ul.see-list li:not(:last-child):after, +ul.see-list-long li:not(:last-child):after { + content: ", "; + white-space: pre-wrap; +} +/* + * Styles for tables. + */ +.summary-table, .details-table { + width:100%; + border-spacing:0; + border-left:1px solid #EEE; + border-right:1px solid #EEE; + border-bottom:1px solid #EEE; + padding:0; +} +.caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#253441; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0; + padding-top:10px; + padding-left:1px; + margin:0; + white-space:pre; +} +.caption a:link, .caption a:visited { + color:#1f389c; +} +.caption a:hover, +.caption a:active { + color:#FFFFFF; +} +.caption span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + padding-bottom:7px; + display:inline-block; + float:left; + background-color:#F8981D; + border: none; + height:16px; +} +div.table-tabs { + padding:10px 0 0 1px; + margin:0; +} +div.table-tabs > button { + border: none; + cursor: pointer; + padding: 5px 12px 7px 12px; + font-weight: bold; + margin-right: 3px; +} +div.table-tabs > button.active-table-tab { + background: #F8981D; + color: #253441; +} +div.table-tabs > button.table-tab { + background: #4D7A97; + color: #FFFFFF; +} +.two-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); +} +.three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(15%, max-content) minmax(15%, auto); +} +.four-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(10%, max-content) minmax(10%, max-content) minmax(10%, auto); +} +@media screen and (max-width: 600px) { + .two-column-summary { + display: grid; + grid-template-columns: 1fr; + } +} +@media screen and (max-width: 800px) { + .three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(25%, auto); + } + .three-column-summary .col-last { + grid-column-end: span 2; + } +} +@media screen and (max-width: 1000px) { + .four-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); + } +} +.summary-table > div, .details-table > div { + text-align:left; + padding: 8px 3px 3px 7px; +} +.col-first, .col-second, .col-last, .col-constructor-name, .col-summary-item-name { + vertical-align:top; + padding-right:0; + padding-top:8px; + padding-bottom:3px; +} +.table-header { + background:#dee3e9; + font-weight: bold; +} +.col-first, .col-first { + font-size:13px; +} +.col-second, .col-second, .col-last, .col-constructor-name, .col-summary-item-name, .col-last { + font-size:13px; +} +.col-first, .col-second, .col-constructor-name { + vertical-align:top; + overflow: auto; +} +.col-last { + white-space:normal; +} +.col-first a:link, .col-first a:visited, +.col-second a:link, .col-second a:visited, +.col-first a:link, .col-first a:visited, +.col-second a:link, .col-second a:visited, +.col-constructor-name a:link, .col-constructor-name a:visited, +.col-summary-item-name a:link, .col-summary-item-name a:visited, +.constant-values-container a:link, .constant-values-container a:visited, +.all-classes-container a:link, .all-classes-container a:visited, +.all-packages-container a:link, .all-packages-container a:visited { + font-weight:bold; +} +.table-sub-heading-color { + background-color:#EEEEFF; +} +.even-row-color, .even-row-color .table-header { + background-color:#FFFFFF; +} +.odd-row-color, .odd-row-color .table-header { + background-color:#EEEEEF; +} +/* + * Styles for contents. + */ +.deprecated-content { + margin:0; + padding:10px 0; +} +div.block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} +.col-last div { + padding-top:0; +} +.col-last a { + padding-bottom:3px; +} +.module-signature, +.package-signature, +.type-signature, +.member-signature { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + margin:14px 0; + white-space: pre-wrap; +} +.module-signature, +.package-signature, +.type-signature { + margin-top: 0; +} +.member-signature .type-parameters-long, +.member-signature .parameters, +.member-signature .exceptions { + display: inline-block; + vertical-align: top; + white-space: pre; +} +.member-signature .type-parameters { + white-space: normal; +} +/* + * Styles for formatting effect. + */ +.source-line-no { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:10px; +} +.block { + display:block; + margin:0 10px 5px 0; + color:#474747; +} +.deprecated-label, .descfrm-type-label, .implementation-label, .member-name-label, .member-name-link, +.module-label-in-package, .module-label-in-type, .override-specify-label, .package-label-in-type, +.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label { + font-weight:bold; +} +.deprecation-comment, .help-footnote, .preview-comment { + font-style:italic; +} +.deprecation-block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + border-style:solid; + border-width:thin; + border-radius:10px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +.preview-block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + border-style:solid; + border-width:thin; + border-radius:10px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +div.block div.deprecation-comment { + font-style:normal; +} +/* + * Styles specific to HTML5 elements. + */ +main, nav, header, footer, section { + display:block; +} +/* + * Styles for javadoc search. + */ +.ui-autocomplete-category { + font-weight:bold; + font-size:15px; + padding:7px 0 7px 3px; + background-color:#4D7A97; + color:#FFFFFF; +} +.result-item { + font-size:13px; +} +.ui-autocomplete { + max-height:85%; + max-width:65%; + overflow-y:scroll; + overflow-x:scroll; + white-space:nowrap; + box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); +} +ul.ui-autocomplete { + position:fixed; + z-index:999999; +} +ul.ui-autocomplete li { + float:left; + clear:both; + width:100%; +} +.result-highlight { + font-weight:bold; +} +#search-input { + background-image:url('resources/glass.png'); + background-size:13px; + background-repeat:no-repeat; + background-position:2px 3px; + padding-left:20px; + position:relative; + right:-18px; + width:400px; +} +#reset-button { + background-color: rgb(255,255,255); + background-image:url('resources/x.png'); + background-position:center; + background-repeat:no-repeat; + background-size:12px; + border:0 none; + width:16px; + height:16px; + position:relative; + left:-4px; + top:-4px; + font-size:0px; +} +.watermark { + color:#545454; +} +.search-tag-desc-result { + font-style:italic; + font-size:11px; +} +.search-tag-holder-result { + font-style:italic; + font-size:12px; +} +.search-tag-result:target { + background-color:yellow; +} +.module-graph span { + display:none; + position:absolute; +} +.module-graph:hover span { + display:block; + margin: -100px 0 0 100px; + z-index: 1; +} +.inherited-list { + margin: 10px 0 10px 0; +} +section.class-description { + line-height: 1.4; +} +.summary section[class$="-summary"], .details section[class$="-details"], +.class-uses .detail, .serialized-class-details { + padding: 0px 20px 5px 10px; + border: 1px solid #ededed; + background-color: #f8f8f8; +} +.inherited-list, section[class$="-details"] .detail { + padding:0 0 5px 8px; + background-color:#ffffff; + border:none; +} +.vertical-separator { + padding: 0 5px; +} +ul.help-section-list { + margin: 0; +} +ul.help-subtoc > li { + display: inline-block; + padding-right: 5px; + font-size: smaller; +} +ul.help-subtoc > li::before { + content: "\2022" ; + padding-right:2px; +} +span.help-note { + font-style: italic; +} +/* + * Indicator icon for external links. + */ +main a[href*="://"]::after { + content:""; + display:inline-block; + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); + background-size:100% 100%; + width:7px; + height:7px; + margin-left:2px; + margin-bottom:4px; +} +main a[href*="://"]:hover::after, +main a[href*="://"]:focus::after { + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); +} + +/* + * Styles for user-provided tables. + * + * borderless: + * No borders, vertical margins, styled caption. + * This style is provided for use with existing doc comments. + * In general, borderless tables should not be used for layout purposes. + * + * plain: + * Plain borders around table and cells, vertical margins, styled caption. + * Best for small tables or for complex tables for tables with cells that span + * rows and columns, when the "striped" style does not work well. + * + * striped: + * Borders around the table and vertical borders between cells, striped rows, + * vertical margins, styled caption. + * Best for tables that have a header row, and a body containing a series of simple rows. + */ + +table.borderless, +table.plain, +table.striped { + margin-top: 10px; + margin-bottom: 10px; +} +table.borderless > caption, +table.plain > caption, +table.striped > caption { + font-weight: bold; + font-size: smaller; +} +table.borderless th, table.borderless td, +table.plain th, table.plain td, +table.striped th, table.striped td { + padding: 2px 5px; +} +table.borderless, +table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th, +table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td { + border: none; +} +table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr { + background-color: transparent; +} +table.plain { + border-collapse: collapse; + border: 1px solid black; +} +table.plain > thead > tr, table.plain > tbody tr, table.plain > tr { + background-color: transparent; +} +table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th, +table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td { + border: 1px solid black; +} +table.striped { + border-collapse: collapse; + border: 1px solid black; +} +table.striped > thead { + background-color: #E3E3E3; +} +table.striped > thead > tr > th, table.striped > thead > tr > td { + border: 1px solid black; +} +table.striped > tbody > tr:nth-child(even) { + background-color: #EEE +} +table.striped > tbody > tr:nth-child(odd) { + background-color: #FFF +} +table.striped > tbody > tr > th, table.striped > tbody > tr > td { + border-left: 1px solid black; + border-right: 1px solid black; +} +table.striped > tbody > tr > th { + font-weight: normal; +} +/** + * Tweak font sizes and paddings for small screens. + */ +@media screen and (max-width: 1050px) { + #search-input { + width: 300px; + } +} +@media screen and (max-width: 800px) { + #search-input { + width: 200px; + } + .top-nav, + .bottom-nav { + font-size: 11px; + padding-top: 6px; + } + .sub-nav { + font-size: 11px; + } + .about-language { + padding-right: 16px; + } + ul.nav-list li, + .sub-nav .nav-list-search { + padding: 6px; + } + ul.sub-nav-list li { + padding-top: 5px; + } + main { + padding: 10px; + } + .summary section[class$="-summary"], .details section[class$="-details"], + .class-uses .detail, .serialized-class-details { + padding: 0 8px 5px 8px; + } + body { + -webkit-text-size-adjust: none; + } +} +@media screen and (max-width: 500px) { + #search-input { + width: 150px; + } + .top-nav, + .bottom-nav { + font-size: 10px; + } + .sub-nav { + font-size: 10px; + } + .about-language { + font-size: 10px; + padding-right: 12px; + } +} diff --git a/utilities/docs/tag-search-index.js b/utilities/docs/tag-search-index.js new file mode 100644 index 0000000..0367dae --- /dev/null +++ b/utilities/docs/tag-search-index.js @@ -0,0 +1 @@ +tagSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/utilities/docs/type-search-index.js b/utilities/docs/type-search-index.js new file mode 100644 index 0000000..d90ed03 --- /dev/null +++ b/utilities/docs/type-search-index.js @@ -0,0 +1 @@ +typeSearchIndex = [{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"org.ondc.crypto.util","l":"CryptoFunctions"},{"p":"org.ondc.crypto.util","l":"CryptoKeyPair"},{"p":"org.ondc.crypto.util","l":"CryptoTest"}];updateSearchResults(); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/LICENSE.txt b/utilities/ondc-crypto-utility-master/LICENSE.txt new file mode 100644 index 0000000..1aac1b6 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/LICENSE.txt @@ -0,0 +1,48 @@ +License +============ + +THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. + +BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. + +1. Definitions + +"Collective Work" means a work, such as a periodical issue, anthology or encyclopedia, in which the Work in its entirety in unmodified form, along with a number of other contributions, constituting separate and independent works in themselves, are assembled into a collective whole. A work that constitutes a Collective Work will not be considered a Derivative Work (as defined below) for the purposes of this License. +"Derivative Work" means a work based upon the Work or upon the Work and other pre-existing works, such as a translation, musical arrangement, dramatization, fictionalization, motion picture version, sound recording, art reproduction, abridgment, condensation, or any other form in which the Work may be recast, transformed, or adapted, except that a work that constitutes a Collective Work will not be considered a Derivative Work for the purpose of this License. For the avoidance of doubt, where the Work is a musical composition or sound recording, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered a Derivative Work for the purpose of this License. +"Licensor" means the individual or entity that offers the Work under the terms of this License. +"Original Author" means the individual or entity who created the Work. +"Work" means the copyrightable work of authorship offered under the terms of this License. +"You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. +2. Fair Use Rights. Nothing in this license is intended to reduce, limit, or restrict any rights arising from fair use, first sale or other limitations on the exclusive rights of the copyright owner under copyright law or other applicable laws. + +3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: + +to reproduce the Work, to incorporate the Work into one or more Collective Works, and to reproduce the Work as incorporated in the Collective Works; +to distribute copies or phonorecords of, display publicly, perform publicly, and perform publicly by means of a digital audio transmission the Work including as incorporated in Collective Works. +For the avoidance of doubt, where the work is a musical composition: + +Performance Royalties Under Blanket Licenses. Licensor waives the exclusive right to collect, whether individually or via a performance rights society (e.g. ASCAP, BMI, SESAC), royalties for the public performance or public digital performance (e.g. webcast) of the Work. +Mechanical Rights and Statutory Royalties. Licensor waives the exclusive right to collect, whether individually or via a music rights society or designated agent (e.g. Harry Fox Agency), royalties for any phonorecord You create from the Work ("cover version") and distribute, subject to the compulsory license created by 17 USC Section 115 of the US Copyright Act (or the equivalent in other jurisdictions). +Webcasting Rights and Statutory Royalties. For the avoidance of doubt, where the Work is a sound recording, Licensor waives the exclusive right to collect, whether individually or via a performance-rights society (e.g. SoundExchange), royalties for the public digital performance (e.g. webcast) of the Work, subject to the compulsory license created by 17 USC Section 114 of the US Copyright Act (or the equivalent in other jurisdictions). +The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats, but otherwise you have no rights to make Derivative Works. All rights not expressly granted by Licensor are hereby reserved. + +4. Restrictions.The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: + +You may distribute, publicly display, publicly perform, or publicly digitally perform the Work only under the terms of this License, and You must include a copy of, or the Uniform Resource Identifier for, this License with every copy or phonorecord of the Work You distribute, publicly display, publicly perform, or publicly digitally perform. You may not offer or impose any terms on the Work that alter or restrict the terms of this License or the recipients' exercise of the rights granted hereunder. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties. You may not distribute, publicly display, publicly perform, or publicly digitally perform the Work with any technological measures that control access or use of the Work in a manner inconsistent with the terms of this License Agreement. The above applies to the Work as incorporated in a Collective Work, but this does not require the Collective Work apart from the Work itself to be made subject to the terms of this License. If You create a Collective Work, upon notice from any Licensor You must, to the extent practicable, remove from the Collective Work any reference to such Licensor or the Original Author, as requested. +If you distribute, publicly display, publicly perform, or publicly digitally perform the Work or Collective Works, You must keep intact all copyright notices for the Work and give the Original Author credit reasonable to the medium or means You are utilizing by conveying the name (or pseudonym if applicable) of the Original Author if supplied; the title of the Work if supplied; and to the extent reasonably practicable, the Uniform Resource Identifier, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work. Such credit may be implemented in any reasonable manner; provided, however, that in the case of a Collective Work, at a minimum such credit will appear where any other comparable authorship credit appears and in a manner at least as prominent as such other comparable authorship credit. +5. Representations, Warranties and Disclaimer + +UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE MATERIALS, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. + +6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +7. Termination + +This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Collective Works from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. +Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. +8. Miscellaneous + +Each time You distribute or publicly digitally perform the Work, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. +If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. +No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. +This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/README.md b/utilities/ondc-crypto-utility-master/README.md new file mode 100644 index 0000000..987a3df --- /dev/null +++ b/utilities/ondc-crypto-utility-master/README.md @@ -0,0 +1,27 @@ +# ondc-crypto-utility +## Introduction +This project has been created with an intension to help and assist ONDC Network Participants to build their own crypto libraries that are required for interaction in ONDC Network +It covers key generation, signing, verification, encryption and decryption. + +## CryptoFunctions class +[CryptoFunctions](./src/main/java/org/ondc/crypto/util/CryptoFunctions.java) has all crypto functions implemented + +## Test class +[CryptoTest](./src/test/java/org/ondc/crypto/util/CryptoTest.java) Class has all test methods that can be referred to get an idea on how to use this library + +## Documentation + +[Java Docs](https://ondc-official.github.io/developer-docs/org/ondc/crypto/util/package-summary.html) + + +## Packaging +In root project folder issue below command. Ensure you have maven installed. +

      +``mvn package`` + +## Downloads +[Download 0.1-GA jar](./target/ondc-crypto-util-0.1-GA.jar) + +## License + +Creative Commons License
      This work is licensed under a Creative Commons Attribution-NoDerivs 2.0 Generic License. diff --git a/utilities/ondc-crypto-utility-master/docs/allclasses-index.html b/utilities/ondc-crypto-utility-master/docs/allclasses-index.html new file mode 100644 index 0000000..b353296 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/allclasses-index.html @@ -0,0 +1,76 @@ + + + + +All Classes and Interfaces + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      All Classes and Interfaces

      +
      +
      +
      Classes
      +
      +
      Class
      +
      Description
      + +
      +
      The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
      +
      + +
      +
      The Class CryptoKeyPair is used to store keypair
      +
      + +
      +
      The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
      +
      +
      +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/allpackages-index.html b/utilities/ondc-crypto-utility-master/docs/allpackages-index.html new file mode 100644 index 0000000..2a26cad --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/allpackages-index.html @@ -0,0 +1,64 @@ + + + + +All Packages + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      All Packages

      +
      +
      Package Summary
      +
      +
      Package
      +
      Description
      + +
       
      +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/element-list b/utilities/ondc-crypto-utility-master/docs/element-list new file mode 100644 index 0000000..4f36876 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/element-list @@ -0,0 +1 @@ +org.ondc.crypto.util diff --git a/utilities/ondc-crypto-utility-master/docs/help-doc.html b/utilities/ondc-crypto-utility-master/docs/help-doc.html new file mode 100644 index 0000000..f8b92e4 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/help-doc.html @@ -0,0 +1,176 @@ + + + + +API Help + + + + + + + + + + + + + + + +
      + +
      +
      +

      JavaDoc Help

      + +
      +
      +

      Navigation

      +Starting from the Overview page, you can browse the documentation using the links in each page, and in the navigation bar at the top of each page. The Index and Search box allow you to navigate to specific declarations and summary pages, including: All Packages, All Classes and Interfaces + +
      +
      +
      +

      Kinds of Pages

      +The following sections describe the different kinds of pages in this collection. +
      +

      Package

      +

      Each package has a page that contains a list of its classes and interfaces, with a summary for each. These pages may contain the following categories:

      +
        +
      • Interfaces
      • +
      • Classes
      • +
      • Enums
      • +
      • Exceptions
      • +
      • Errors
      • +
      • Annotation Types
      • +
      +
      +
      +

      Class or Interface

      +

      Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a declaration and description, member summary tables, and detailed member descriptions. Entries in each of these sections are omitted if they are empty or not applicable.

      +
        +
      • Class Inheritance Diagram
      • +
      • Direct Subclasses
      • +
      • All Known Subinterfaces
      • +
      • All Known Implementing Classes
      • +
      • Class or Interface Declaration
      • +
      • Class or Interface Description
      • +
      +
      +
        +
      • Nested Class Summary
      • +
      • Enum Constant Summary
      • +
      • Field Summary
      • +
      • Property Summary
      • +
      • Constructor Summary
      • +
      • Method Summary
      • +
      • Required Element Summary
      • +
      • Optional Element Summary
      • +
      +
      +
        +
      • Enum Constant Details
      • +
      • Field Details
      • +
      • Property Details
      • +
      • Constructor Details
      • +
      • Method Details
      • +
      • Element Details
      • +
      +

      Note: Annotation interfaces have required and optional elements, but not methods. Only enum classes have enum constants. The components of a record class are displayed as part of the declaration of the record class. Properties are a feature of JavaFX.

      +

      The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

      +
      +
      +

      Other Files

      +

      Packages and modules may contain pages with additional information related to the declarations nearby.

      +
      +
      +

      Use

      +

      Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the USE link in the navigation bar.

      +
      +
      +

      Tree (Class Hierarchy)

      +

      There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. Classes are organized by inheritance structure starting with java.lang.Object. Interfaces do not inherit from java.lang.Object.

      +
        +
      • When viewing the Overview page, clicking on TREE displays the hierarchy for all packages.
      • +
      • When viewing a particular package, class or interface page, clicking on TREE displays the hierarchy for only that package.
      • +
      +
      +
      +

      All Packages

      +

      The All Packages page contains an alphabetic index of all packages contained in the documentation.

      +
      +
      +

      All Classes and Interfaces

      +

      The All Classes and Interfaces page contains an alphabetic index of all classes and interfaces contained in the documentation, including annotation interfaces, enum classes, and record classes.

      +
      +
      +

      Index

      +

      The Index contains an alphabetic index of all classes, interfaces, constructors, methods, and fields in the documentation, as well as summary pages such as All Packages, All Classes and Interfaces.

      +
      +
      +
      +This help file applies to API documentation generated by the standard doclet.
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-1.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-1.html new file mode 100644 index 0000000..2afef9d --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-1.html @@ -0,0 +1,81 @@ + + + + +C-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      C

      +
      +
      CryptoFunctions - Class in org.ondc.crypto.util
      +
      +
      The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
      +
      +
      CryptoFunctions() - Constructor for class org.ondc.crypto.util.CryptoFunctions
      +
       
      +
      CryptoKeyPair - Class in org.ondc.crypto.util
      +
      +
      The Class CryptoKeyPair is used to store keypair
      +
      +
      CryptoKeyPair(byte[], byte[]) - Constructor for class org.ondc.crypto.util.CryptoKeyPair
      +
      +
      Instantiates a new crypto key pair.
      +
      +
      CryptoTest - Class in org.ondc.crypto.util
      +
      +
      The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
      +
      +
      CryptoTest() - Constructor for class org.ondc.crypto.util.CryptoTest
      +
       
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-2.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-2.html new file mode 100644 index 0000000..335f9e0 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-2.html @@ -0,0 +1,65 @@ + + + + +E-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      E

      +
      +
      encryptDecrypt(int, byte[], byte[], byte[]) - Static method in class org.ondc.crypto.util.CryptoFunctions
      +
      +
      This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm
      +
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-3.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-3.html new file mode 100644 index 0000000..338417b --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-3.html @@ -0,0 +1,81 @@ + + + + +G-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      G

      +
      +
      generateBlakeHash(String) - Static method in class org.ondc.crypto.util.CryptoFunctions
      +
      +
      Generate blake hash.
      +
      +
      generateEncDecKey() - Static method in class org.ondc.crypto.util.CryptoFunctions
      +
      +
      Generate encryption decryption key pair using x25519 key exchange algorithm.
      +
      +
      generateSigningKeyPair() - Static method in class org.ondc.crypto.util.CryptoFunctions
      +
      +
      This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing
      +
      +
      getPrivateKey() - Method in class org.ondc.crypto.util.CryptoKeyPair
      +
      +
      Gets the private key.
      +
      +
      getPublickKey() - Method in class org.ondc.crypto.util.CryptoKeyPair
      +
      +
      Gets the public key.
      +
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-4.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-4.html new file mode 100644 index 0000000..be0459f --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-4.html @@ -0,0 +1,63 @@ + + + + +O-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      O

      +
      +
      org.ondc.crypto.util - package org.ondc.crypto.util
      +
       
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-5.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-5.html new file mode 100644 index 0000000..a2744ff --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-5.html @@ -0,0 +1,73 @@ + + + + +S-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      S

      +
      +
      setPrivateKey(byte[]) - Method in class org.ondc.crypto.util.CryptoKeyPair
      +
      +
      Sets the private key.
      +
      +
      setPublicKey(byte[]) - Method in class org.ondc.crypto.util.CryptoKeyPair
      +
      +
      Sets the public key.
      +
      +
      sign(byte[], byte[]) - Static method in class org.ondc.crypto.util.CryptoFunctions
      +
      +
      This method generates signature using given ED25519 32 byte/ 256 bits Private key
      +
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-6.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-6.html new file mode 100644 index 0000000..b0f148c --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-6.html @@ -0,0 +1,75 @@ + + + + +T-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      T

      +
      +
      testGenerateBlakeHash() - Method in class org.ondc.crypto.util.CryptoTest
      +
       
      +
      testGenerateEncryptionDecryptionKeyPair_Normal() - Method in class org.ondc.crypto.util.CryptoTest
      +
      +
      Test generate encryption decryption key pair, encrypt and then decrypt.
      +
      +
      testGenerateSigningKeyPair_Normal() - Method in class org.ondc.crypto.util.CryptoTest
      +
      +
      Test generation of signing key pair
      +
      +
      testGenerateSigningKeyPair_Tampered() - Method in class org.ondc.crypto.util.CryptoTest
      +
      +
      Test to verify tampered message and signature
      +
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index-files/index-7.html b/utilities/ondc-crypto-utility-master/docs/index-files/index-7.html new file mode 100644 index 0000000..e500463 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index-files/index-7.html @@ -0,0 +1,65 @@ + + + + +V-Index + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Index

      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages +

      V

      +
      +
      verify(byte[], byte[], byte[]) - Static method in class org.ondc.crypto.util.CryptoFunctions
      +
      +
      Verify given signature using ED25519 Public Key
      +
      +
      +C E G O S T V 
      All Classes and Interfaces|All Packages
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/index.html b/utilities/ondc-crypto-utility-master/docs/index.html new file mode 100644 index 0000000..dfdba15 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/index.html @@ -0,0 +1,26 @@ + + + + +Generated Documentation (Untitled) + + + + + + + + + + + +
      + +

      org/ondc/crypto/util/package-summary.html

      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/jquery-ui.overrides.css b/utilities/ondc-crypto-utility-master/docs/jquery-ui.overrides.css new file mode 100644 index 0000000..f89acb6 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/jquery-ui.overrides.css @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +.ui-state-active, +.ui-widget-content .ui-state-active, +.ui-widget-header .ui-state-active, +a.ui-button:active, +.ui-button:active, +.ui-button.ui-state-active:hover { + /* Overrides the color of selection used in jQuery UI */ + background: #F8981D; +} diff --git a/utilities/ondc-crypto-utility-master/docs/legal/ADDITIONAL_LICENSE_INFO b/utilities/ondc-crypto-utility-master/docs/legal/ADDITIONAL_LICENSE_INFO new file mode 100644 index 0000000..b62cc3e --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/legal/ADDITIONAL_LICENSE_INFO @@ -0,0 +1 @@ +Please see ..\java.base\ADDITIONAL_LICENSE_INFO diff --git a/utilities/ondc-crypto-utility-master/docs/legal/ASSEMBLY_EXCEPTION b/utilities/ondc-crypto-utility-master/docs/legal/ASSEMBLY_EXCEPTION new file mode 100644 index 0000000..0d4cfb4 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/legal/ASSEMBLY_EXCEPTION @@ -0,0 +1 @@ +Please see ..\java.base\ASSEMBLY_EXCEPTION diff --git a/utilities/ondc-crypto-utility-master/docs/legal/LICENSE b/utilities/ondc-crypto-utility-master/docs/legal/LICENSE new file mode 100644 index 0000000..4ad9fe4 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/legal/LICENSE @@ -0,0 +1 @@ +Please see ..\java.base\LICENSE diff --git a/utilities/ondc-crypto-utility-master/docs/legal/jquery.md b/utilities/ondc-crypto-utility-master/docs/legal/jquery.md new file mode 100644 index 0000000..8054a34 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/legal/jquery.md @@ -0,0 +1,72 @@ +## jQuery v3.5.1 + +### jQuery License +``` +jQuery v 3.5.1 +Copyright JS Foundation and other contributors, https://js.foundation/ + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +****************************************** + +The jQuery JavaScript Library v3.5.1 also includes Sizzle.js + +Sizzle.js includes the following license: + +Copyright JS Foundation and other contributors, https://js.foundation/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/sizzle + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +********************* + +``` diff --git a/utilities/ondc-crypto-utility-master/docs/legal/jqueryUI.md b/utilities/ondc-crypto-utility-master/docs/legal/jqueryUI.md new file mode 100644 index 0000000..8031bdb --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/legal/jqueryUI.md @@ -0,0 +1,49 @@ +## jQuery UI v1.12.1 + +### jQuery UI License +``` +Copyright jQuery Foundation and other contributors, https://jquery.org/ + +This software consists of voluntary contributions made by many +individuals. For exact contribution history, see the revision history +available at https://github.com/jquery/jquery-ui + +The following license applies to all parts of this software except as +documented below: + +==== + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +==== + +Copyright and related rights for sample code are waived via CC0. Sample +code is defined as all source code contained within the demos directory. + +CC0: http://creativecommons.org/publicdomain/zero/1.0/ + +==== + +All files located in the node_modules and external directories are +externally maintained libraries used by this software which have their +own licenses; we recommend you read them, as their terms may differ from +the terms above. + +``` diff --git a/utilities/ondc-crypto-utility-master/docs/member-search-index.js b/utilities/ondc-crypto-utility-master/docs/member-search-index.js new file mode 100644 index 0000000..95d50ba --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/member-search-index.js @@ -0,0 +1 @@ +memberSearchIndex = [{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"CryptoFunctions()","u":"%3Cinit%3E()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"CryptoKeyPair(byte[], byte[])","u":"%3Cinit%3E(byte[],byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"CryptoTest()","u":"%3Cinit%3E()"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"encryptDecrypt(int, byte[], byte[], byte[])","u":"encryptDecrypt(int,byte[],byte[],byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"generateBlakeHash(String)","u":"generateBlakeHash(java.lang.String)"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"generateEncDecKey()"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"generateSigningKeyPair()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"getPrivateKey()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"getPublickKey()"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"setPrivateKey(byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoKeyPair","l":"setPublicKey(byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"sign(byte[], byte[])","u":"sign(byte[],byte[])"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateBlakeHash()"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateEncryptionDecryptionKeyPair_Normal()"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateSigningKeyPair_Normal()"},{"p":"org.ondc.crypto.util","c":"CryptoTest","l":"testGenerateSigningKeyPair_Tampered()"},{"p":"org.ondc.crypto.util","c":"CryptoFunctions","l":"verify(byte[], byte[], byte[])","u":"verify(byte[],byte[],byte[])"}];updateSearchResults(); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/docs/module-search-index.js b/utilities/ondc-crypto-utility-master/docs/module-search-index.js new file mode 100644 index 0000000..0d59754 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/module-search-index.js @@ -0,0 +1 @@ +moduleSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoFunctions.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoFunctions.html new file mode 100644 index 0000000..5775709 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoFunctions.html @@ -0,0 +1,419 @@ + + + + +CryptoFunctions + + + + + + + + + + + + + + + +
      + +
      +
      + +
      + +

      Class CryptoFunctions

      +
      +
      java.lang.Object +
      org.ondc.crypto.util.CryptoFunctions
      +
      +
      +
      +
      public class CryptoFunctions +extends Object
      +
      The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
      +
      +
      +
        + +
      • +
        +

        Constructor Summary

        +
        Constructors
        +
        +
        Constructor
        +
        Description
        + +
         
        +
        +
        +
      • + +
      • +
        +

        Method Summary

        +
        +
        +
        +
        +
        Modifier and Type
        +
        Method
        +
        Description
        +
        static byte[]
        +
        encryptDecrypt(int mode, + byte[] challenge_string, + byte[] privateKey, + byte[] publicKey)
        +
        +
        This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm
        +
        +
        static byte[]
        + +
        +
        Generate blake hash.
        +
        + + +
        +
        Generate encryption decryption key pair using x25519 key exchange algorithm.
        +
        + + +
        +
        This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing
        +
        +
        static byte[]
        +
        sign(byte[] privateKey, + byte[] message)
        +
        +
        This method generates signature using given ED25519 32 byte/ 256 bits Private key
        +
        +
        static boolean
        +
        verify(byte[] signature, + byte[] message, + byte[] publicKey)
        +
        +
        Verify given signature using ED25519 Public Key
        +
        +
        +
        +
        +
        +

        Methods inherited from class java.lang.Object

        +equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        +
        +
      • +
      +
      +
      +
        + +
      • +
        +

        Constructor Details

        +
          +
        • +
          +

          CryptoFunctions

          +
          public CryptoFunctions()
          +
          +
        • +
        +
        +
      • + +
      • +
        +

        Method Details

        +
          +
        • +
          +

          generateSigningKeyPair

          +
          public static CryptoKeyPair generateSigningKeyPair()
          +

          This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing +

          . +
          + 
          + System.out.println("Testing whether Signing Keys are generated::");
          + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
          + 
          + String message="message to be signed";
          + 
          + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
          + 
          + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
          + 
          +
          +
          Returns:
          +
          the crypto key pair
          +
          Since:
          +
          0.1
          +
          See Also:
          +
          + +
          +
          +
          +
        • +
        • +
          +

          sign

          +
          public static byte[] sign(byte[] privateKey, + byte[] message)
          +

          This method generates signature using given ED25519 32 byte/ 256 bits Private key +

          . +
          + 
          + System.out.println("Testing whether Signing Keys are generated::");
          + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
          +        
          + 
          + String message="message to be signed";
          + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
          + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
          + 
          +
          +
          Parameters:
          +
          privateKey - the private key that should be used to sign the message
          +
          message - the message that should be signed using given private key
          +
          Returns:
          +
          the byte[] signature of given message generated using given private key
          +
          Since:
          +
          0.1
          +
          See Also:
          +
          + +
          +
          +
          +
        • +
        • +
          +

          verify

          +
          public static boolean verify(byte[] signature, + byte[] message, + byte[] publicKey)
          +
          Verify given signature using ED25519 Public Key +
          + 
          + System.out.println("Testing whether Signing Keys are generated::");
          + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
          +        
          + 
          + String message="message to be signed";
          + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
          + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
          + 
          +
          +
          Parameters:
          +
          signature - the signature that needs to be verified
          +
          message - the message that needs to verified along with signature
          +
          publicKey - the public key to be used for verifying the signature
          +
          Returns:
          +
          true, if successful
          +
          See Also:
          +
          + +
          +
          +
          +
        • +
        • +
          +

          generateEncDecKey

          + +
          Generate encryption decryption key pair using x25519 key exchange algorithm.
          +
          +
          Returns:
          +
          the crypto key pair
          +
          Throws:
          +
          InvalidKeyException - the invalid key exception
          +
          NoSuchPaddingException - the no such padding exception
          +
          IllegalBlockSizeException - the illegal block size exception
          +
          BadPaddingException - the bad padding exception
          +
          NoSuchAlgorithmException - the no such algorithm exception
          +
          NoSuchProviderException - the no such provider exception
          +
          See Also:
          +
          + +
          +
          +
          +
        • +
        • +
          +

          encryptDecrypt

          +
          public static byte[] encryptDecrypt(int mode, + byte[] challenge_string, + byte[] privateKey, + byte[] publicKey) + throws NoSuchAlgorithmException, +NoSuchProviderException, +InvalidKeySpecException, +InvalidKeyException, +NoSuchPaddingException, +IllegalBlockSizeException, +BadPaddingException
          +
          This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm + + +
          +                CryptoKeyPair senderEncDecKeyPair=null;
          +                CryptoKeyPair receiverEncDecKeyPair=null;
          +                
          +                try {
          +                        senderEncDecKeyPair= CryptoFunctions.generateEncDecKey();
          +                        receiverEncDecKeyPair= CryptoFunctions.generateEncDecKey();
          +                } catch (Exception e) {
          +                        // TODO Auto-generated catch block
          +                        e.printStackTrace();
          +                } 
          +                String message="message to be encrypted";
          +                
          +                byte[] encrypted= CryptoFunctions.encryptDecrypt(Cipher.ENCRYPT_MODE,message.getBytes(),senderEncDecKeyPair.getPrivateKey(),receiverEncDecKeyPair.getPublickKey());
          +                
          +                System.out.println("\n\n/* Sender Side /");
          +                System.out.println("{");
          +                System.out.println("\t\"plainChallengeString \":\""+message +"\",");
          +                System.out.println("\t\"EncryptedChallengeString \":\""+Base64.getEncoder().encodeToString(encrypted)+"\",");
          +                System.out.println("\t\"senderPrivateKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPrivateKey()) +"\",");
          +                System.out.println("\t\"receiverPublicKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPublickKey()) +"\"");
          +                System.out.println("}\n\n");
          +                byte[] decrypted= CryptoFunctions.encryptDecrypt(Cipher.DECRYPT_MODE,encrypted,receiverEncDecKeyPair.getPrivateKey(),senderEncDecKeyPair.getPublickKey());
          +                String decryptedMessage=new String(decrypted);
          +                System.out.println("\n\n/** Receiver Side ");
          +                System.out.println("{");
          +                System.out.println("\t\"DecryptedChallengeString \":\""+decryptedMessage+"\",");
          +                System.out.println("\t\"receiverPrivateKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPrivateKey()) +"\",");
          +                System.out.println("\t\"senderPublicKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPublickKey()) +"\"");
          +                System.out.println("}");
          + 
          +
          +
          Parameters:
          +
          mode - the mode to set either encrypt (Cipher.ENCRYPT_MODE) or decrypt (Cipher.DECRYPT_MODE )
          +
          challenge_string - the challenge string that needs to be encrypted or decrypted depending on mode that is set. In case if mode is set to Cipher.ENCRYPT_MODE then this text shall be encrypted; whereas if mode is set to Cipher.DECRYPT_MODE, this text shall be decrypted
          +
          privateKey - the private key. +

          In case of mode=Cipher.ENCRYPT_MODE, it should be private key of the sender +
          In case of mode=Cipher.DECRYPT_MODE, it should be private key of the receiver

          +
          publicKey - the public key +

          In case of mode=Cipher.ENCRYPT_MODE, it should be public key of the receiver +
          In case of mode=Cipher.DECRYPT_MODE, it should be public key of the sender

          +
          Returns:
          +
          the byte[]
          +
          Throws:
          +
          NoSuchAlgorithmException - the no such algorithm exception
          +
          NoSuchProviderException - the no such provider exception
          +
          InvalidKeySpecException - the invalid key spec exception
          +
          InvalidKeyException - the invalid key exception
          +
          NoSuchPaddingException - the no such padding exception
          +
          IllegalBlockSizeException - the illegal block size exception
          +
          BadPaddingException - the bad padding exception
          +
          See Also:
          +
          + +
          +
          +
          +
        • +
        • +
          +

          generateBlakeHash

          +
          public static byte[] generateBlakeHash(String req) + throws Exception
          +
          Generate blake hash. + +
          + String message = "message to hash";
          + byte[] hash_1=CryptoFunctions.generateBlakeHash(message);
          + String bs64_1 = Base64.getEncoder().encodeToString(hash_1);
          + System.out.println(bs64_1);
          + 
          +
          +
          Parameters:
          +
          req - the message for which digest(blake2b hash) needs to be generated
          +
          Returns:
          +
          the byte[] hash value
          +
          Throws:
          +
          Exception - the exception
          +
          +
          +
        • +
        +
        +
      • +
      +
      + +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoKeyPair.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoKeyPair.html new file mode 100644 index 0000000..fd384a9 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoKeyPair.html @@ -0,0 +1,224 @@ + + + + +CryptoKeyPair + + + + + + + + + + + + + + + +
      + +
      +
      + +
      + +

      Class CryptoKeyPair

      +
      +
      java.lang.Object +
      org.ondc.crypto.util.CryptoKeyPair
      +
      +
      +
      +
      public class CryptoKeyPair +extends Object
      +
      The Class CryptoKeyPair is used to store keypair
      +
      +
      +
        + +
      • +
        +

        Constructor Summary

        +
        Constructors
        +
        +
        Constructor
        +
        Description
        +
        CryptoKeyPair(byte[] publicKey, + byte[] privateKey)
        +
        +
        Instantiates a new crypto key pair.
        +
        +
        +
        +
      • + +
      • +
        +

        Method Summary

        +
        +
        +
        +
        +
        Modifier and Type
        +
        Method
        +
        Description
        +
        byte[]
        + +
        +
        Gets the private key.
        +
        +
        byte[]
        + +
        +
        Gets the public key.
        +
        +
        void
        +
        setPrivateKey(byte[] privateKey)
        +
        +
        Sets the private key.
        +
        +
        void
        +
        setPublicKey(byte[] publicKey)
        +
        +
        Sets the public key.
        +
        +
        +
        +
        +
        +

        Methods inherited from class java.lang.Object

        +equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
        +
        +
      • +
      +
      +
      +
        + +
      • +
        +

        Constructor Details

        +
          +
        • +
          +

          CryptoKeyPair

          +
          public CryptoKeyPair(byte[] publicKey, + byte[] privateKey)
          +
          Instantiates a new crypto key pair.
          +
          +
          Parameters:
          +
          publicKey - the public key
          +
          privateKey - the private key
          +
          +
          +
        • +
        +
        +
      • + +
      • +
        +

        Method Details

        +
          +
        • +
          +

          getPrivateKey

          +
          public byte[] getPrivateKey()
          +
          Gets the private key.
          +
          +
          Returns:
          +
          the private key
          +
          +
          +
        • +
        • +
          +

          setPrivateKey

          +
          public void setPrivateKey(byte[] privateKey)
          +
          Sets the private key.
          +
          +
          Parameters:
          +
          privateKey - the new private key
          +
          +
          +
        • +
        • +
          +

          getPublickKey

          +
          public byte[] getPublickKey()
          +
          Gets the public key.
          +
          +
          Returns:
          +
          the public key
          +
          +
          +
        • +
        • +
          +

          setPublicKey

          +
          public void setPublicKey(byte[] publicKey)
          +
          Sets the public key.
          +
          +
          Parameters:
          +
          publicKey - the new public key
          +
          +
          +
        • +
        +
        +
      • +
      +
      + +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoTest.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoTest.html new file mode 100644 index 0000000..4c71ea0 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/CryptoTest.html @@ -0,0 +1,225 @@ + + + + +CryptoTest + + + + + + + + + + + + + + + +
      + +
      +
      + +
      + +

      Class CryptoTest

      +
      +
      java.lang.Object +
      org.ondc.crypto.util.CryptoTest
      +
      +
      +
      +
      public class CryptoTest +extends Object
      +
      The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
      +
      +
      + +
      +
      + +
      + +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html new file mode 100644 index 0000000..12378a3 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoFunctions.html @@ -0,0 +1,57 @@ + + + + +Uses of Class org.ondc.crypto.util.CryptoFunctions + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Uses of Class
      org.ondc.crypto.util.CryptoFunctions

      +
      +No usage of org.ondc.crypto.util.CryptoFunctions
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html new file mode 100644 index 0000000..74cc509 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoKeyPair.html @@ -0,0 +1,82 @@ + + + + +Uses of Class org.ondc.crypto.util.CryptoKeyPair + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Uses of Class
      org.ondc.crypto.util.CryptoKeyPair

      +
      +
      + +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoTest.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoTest.html new file mode 100644 index 0000000..e7cf79d --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/class-use/CryptoTest.html @@ -0,0 +1,57 @@ + + + + +Uses of Class org.ondc.crypto.util.CryptoTest + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Uses of Class
      org.ondc.crypto.util.CryptoTest

      +
      +No usage of org.ondc.crypto.util.CryptoTest
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-summary.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-summary.html new file mode 100644 index 0000000..7930046 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-summary.html @@ -0,0 +1,92 @@ + + + + +org.ondc.crypto.util + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Package org.ondc.crypto.util

      +
      +
      +
      package org.ondc.crypto.util
      +
      +
        +
      • +
        +
        Classes
        +
        +
        Class
        +
        Description
        + +
        +
        The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption.
        +
        + +
        +
        The Class CryptoKeyPair is used to store keypair
        +
        + +
        +
        The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions
        +
        +
        +
        +
      • +
      +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-tree.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-tree.html new file mode 100644 index 0000000..951ad2f --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-tree.html @@ -0,0 +1,69 @@ + + + + +org.ondc.crypto.util Class Hierarchy + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Hierarchy For Package org.ondc.crypto.util

      +
      +
      +

      Class Hierarchy

      + +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-use.html b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-use.html new file mode 100644 index 0000000..6c11a23 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/org/ondc/crypto/util/package-use.html @@ -0,0 +1,74 @@ + + + + +Uses of Package org.ondc.crypto.util + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Uses of Package
      org.ondc.crypto.util

      +
      +
      + +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/overview-tree.html b/utilities/ondc-crypto-utility-master/docs/overview-tree.html new file mode 100644 index 0000000..d775267 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/overview-tree.html @@ -0,0 +1,73 @@ + + + + +Class Hierarchy + + + + + + + + + + + + + + + +
      + +
      +
      +
      +

      Hierarchy For All Packages

      +Package Hierarchies: + +
      +
      +

      Class Hierarchy

      + +
      +
      +
      +
      + + diff --git a/utilities/ondc-crypto-utility-master/docs/package-search-index.js b/utilities/ondc-crypto-utility-master/docs/package-search-index.js new file mode 100644 index 0000000..7fe94ce --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/package-search-index.js @@ -0,0 +1 @@ +packageSearchIndex = [{"l":"All Packages","u":"allpackages-index.html"},{"l":"org.ondc.crypto.util"}];updateSearchResults(); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/docs/resources/glass.png b/utilities/ondc-crypto-utility-master/docs/resources/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..a7f591f467a1c0c949bbc510156a0c1afb860a6e GIT binary patch literal 499 zcmVJoRsvExf%rEN>jUL}qZ_~k#FbE+Q;{`;0FZwVNX2n-^JoI; zP;4#$8DIy*Yk-P>VN(DUKmPse7mx+ExD4O|;?E5D0Z5($mjO3`*anwQU^s{ZDK#Lz zj>~{qyaIx5K!t%=G&2IJNzg!ChRpyLkO7}Ry!QaotAHAMpbB3AF(}|_f!G-oI|uK6 z`id_dumai5K%C3Y$;tKS_iqMPHg<*|-@e`liWLAggVM!zAP#@l;=c>S03;{#04Z~5 zN_+ss=Yg6*hTr59mzMwZ@+l~q!+?ft!fF66AXT#wWavHt30bZWFCK%!BNk}LN?0Hg z1VF_nfs`Lm^DjYZ1(1uD0u4CSIr)XAaqW6IT{!St5~1{i=i}zAy76p%_|w8rh@@c0Axr!ns=D-X+|*sY6!@wacG9%)Qn*O zl0sa739kT-&_?#oVxXF6tOnqTD)cZ}2vi$`ZU8RLAlo8=_z#*P3xI~i!lEh+Pdu-L zx{d*wgjtXbnGX_Yf@Tc7Q3YhLhPvc8noGJs2DA~1DySiA&6V{5JzFt ojAY1KXm~va;tU{v7C?Xj0BHw!K;2aXV*mgE07*qoM6N<$f;4TDA^-pY literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png b/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_55_fbf9ee_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..34abd18f32d3a55a297fdcf93409bd033ae573e7 GIT binary patch literal 335 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&fCnc6a#?2AmP!?*K(O3p^r= zfwTu0yPeFo12TF&T^vI^j=w#x$i?I+((tf;UXnmgbH|3oY>pC!)f}(GR!16S-u+#{ ze6YEqRkW=8vGl=5qArKM<9}TC-}iEvB{zdaTcX5$wyRTK&ALRXUCGx5b?-VBQkUm|IuXOmYJrBRJgj{Vx zMbNnqUkncy+qa2-mWYc>swkcIuvGK#>(0d)B7)5f`@$Ei28nH~0h*~=;u=wsl30>z zm0Xkxq!^403@vmGjdTsnLJUl-Obo4zO|=aStPBhe<(7X!(U6;;l9^VCTf=69^L{`L N44$rjF6*2UngDu&PXPb` literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png b/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_75_e6e6e6_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..a90afb8bf8028404d206114965669b023dcb85ea GIT binary patch literal 262 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&0LWmFTHNUZq?nSt-Ch3w7g=q17Rci)@Q5r1 z(jH*!b~4)z#PD=+46!(!TrvH)L6@80)r*_cdCvDr%)6ghVL16=s@mbz7H!uRdGeDa z?kzLg)16i!f8fKx84s0>4hES%`s&m5HI1v5B^Uft7(lid2moiiX_$l+3hB+!{pPkNg5^ OVDNPHb6Mw<&;$T*0!_~V literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png b/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 0000000000000000000000000000000000000000..dbe091f6dc036fc1dc11b005738e951e27a43f7a GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^j6gI&fCnc6a#?2AmP!?*K(O3p^r= zfwTu0yPeFo12VciT^vI^j=w#>k(V)1qW$CZ|6)SVV-&*#dav<$DMuV&n0Dbpw@aE%W-S*bfB&J`pw9sa4-R?IGW?p~6`>jMSP&M+u3 zY@9al)zrvpHlQu4C9V-ADTyViR>?)FK#IZ0z|cb1&`8(7EX2UX%EZvh*hJgFz{Ot{4q9c^pg%OaK6Yqo^RG1puHty#h|2KYM!0=6Ogw z8K9N2ybORL_{i$}QxC&U!O-)`D*V04jXJ#n04P`#Wh8ZcmyUA%?QMqxhsEu>DC;^~ z{8O8G!7ta)D{l)9O_iD5-A{FwUpb*$IVfjou`0AAQAiyPXs{~wzE|2cZ&-acSF5PE zECGBcRRVEnRHOae;6NyU=IDOFj1wfusG0S<3Q6l>z)~KZvoIliF0!*y?O)1|ko7+n z>+zd%4dS;8>iMJUMwP(40V}{-=QZ#}vlkKtjgT?gI8R3`s`{eg^A0iB|9C;N3jtvV z-Ng~;#kXO^6$qh)N`faRB-+@-bRYixX&v+7cZ47thp08jNs?kcf|lu#~em zp9vU17gB)u1qJ$;?70533PMsKum#Eq1WJ#2?+bZ7pACeTd>j>;rVp1okB*+jU>j7I z%j60+UbCER>?m`t-k_0UMwtLk6PNMY=f5dhQ8l$!D_vWBr7CGPcDXr`NYC0uXipIi(5RZ4R25t$~o-$U3fdSZ+t8-MmF==ihWU zps_B2WTuZJSqfEd1jJTJmIrBIIwGFP-`8)$-Iqppx}nZ^1vgyQ|l#q!hDI^2df&H%uZ~e0(cO7rqdczX@s)(9Eo-vb-MZ9T{=?X2emAalsxjR} zDp-RS7ef2fYsNm|W!_~xs+U7sTjX>);xAM$zqqaVh4|Euxo{YB$Ue0yH`R1%LS$R3 z_E+lO@6`C-O(hNK66x`)5glEd?{N3v6k%2iXu|DB7JlD_tIlHzQyL8|YqSl}2YGDC zVO=PpVE0uei+57#cSm-&mw%S6mdRjiXxq5W{LsvhSJ)azPC6$j8(XY|f^_Z&*1)W@ zy3m>x-39!zm0@c~zOZVs=NV_}R#gjtmK1&jPTBe7AFZ@zbRGz_6UwWLFcH!wR&|Kh zZORU;Y=?b=mQgrwQ7Jg5s`cWOAy<{^y4=~BY|8kNP41J6stuM$_oKMaSoT+r{gE=%vLbm}y-G-s!n*{3q^tC?7saRyDEHx#C%bDVlF- zT{dLhAcKm7_JHGWuM**1_IMVdiq^ z7D85%apck0)*q}ipK9LUem#)m&v^B|Widn`=US)y=oK{$PHqJfvPxXB01zn#HFdLP zQ&f?0$}kSU6DYm1#Q#-wfTbj=yH!1g2x|0WP2z>tuyO>41bFp+m<`<8K(}e{bVRRc z;_)`s&>3Igl%b}j4U`xH6cyED;w`@e*RvZRe2WjElbi=jJ?KR2PO|E4(J3bsCK3K3 zO01O90g8f8lG@TKjOF|Rq%J+HV&UYOoY19`zLkp~FG{YsK8Ir~X$|7*;yB&_zla!o zjYA=|t$atYh-F)y4Yz_vl#Mfhr7?c5+w!f^NDNI!Z?A?TFj8jfkyqH$zWRai4c9qe^hVZXz8Ua{_Qt*H|88x@P1f|(u2`*pny^DSvt z0cPlYpbVeN$&S_0igz=*jS?B}QmUqqvPHqKaAx2G>fO4YRa{E>XB6Xs(Qzm?KF6{) zH*UG(7f?FngNv=%+Zmde2NyXUJG!M`!A5Mki?MT(W9PZmXv@ zmep!=;N_2(YH&j9mbmVOT4-HZILhZTNTy1NuR|!sWu45-D4y_D0QqJt{zs;jlrvoW zMFI`6#{NR91Oga_$sPvQT2>*W zRIBmn5wo&P6T=9La7LKS#PfEKzLL;iMp+{1Q`z*5zFAs*0Ls&H`$&3{Kj4$V_i@Y3 zQ5#cDOZZXP4LiO`exN`(4@q9eQ8uV|2&zu8c<`IAi}X>xjQ2rZjo9+7c~B?p(#|;v zer1U!kvAG8TJgQf$Vb%&$$*?mTT^8q!mb=&j!S9)P#ih$wSndg2IQ$5(%D4r5YvN6 zSlmi#A+9~6hT+SJhfNn)&@?dH$60LL#zBHZW2#jikLi?i+d6FT_TdaEj!3q>= zs3B{;qsuhOi~=T+n7bcnD>mKC9SPia&sf-S6=bWBZ&k_0DVVff(=-5WLMn9=GM7-h zI0uf;xB8kYZb^lJ0n~JvuvK$V>}r19I>e+O66f|wPr+;wZh})Gw^&qqYZA}x4c57y`^h7)C>5Z1%3*cW z)cL6g#o{A8TI2pxi@_j)Q_eBD)Y1zWnK6FCJ*Vusx`G!m)?EOSA0act>OlBcw2kno znt+5a_hNxdJ!=)?x{qU|#3A*G_rm|KnYzPYV{szQS;o+Vc_nTJny7jnL?4}g| zq}9Rn^^$O}pD>4Wzz073HN<|S{OaO`3SdI%H!gr$kE|3cZg#S#ZmtN6jU!-W@kLCX2^KjZN_cvo3qAj2yCB?L16iZiG(a`(MHoh@NuA?dUdwAZsu^p~Uhti2ZH!rb9pRfx3K8kW z_?}^DSUvk!SkI1_Ny((_yDi!;g+*N#ElFI*hGVTo^~6evaow^^-a3wu+^vYErC)MU zEPyLe@#)2))oWu=PU`!)g^X7j-n;da0;cWGPIx}|{5}0&Gqw&mh_FTI_8yp+ZyIs# zi~~~V0>b733>{kC2`xluGp9ko+Syq=cLVEdK6dYbAnqPQpJ0yP1^$LT-{4Y$I*shl-3{@hbXlEaQ{OVJr6@vM$U7%VXui z69mW&G~@=wLkd6GC5LthA@FO8P^{E$HP}ph8}5s#;Fxy2?&9$ADS==?cc9DBgZ^BP z_DJ*8;w>hq(8u#n@8pPzhy{cF{4*+k-5}N1fZ&QXpqw@-WKbl7G-h<-fqQ5cUWgtZ ziPTTk*ivA(LV;7lZd*s>eSsM}+`^Lx#d$*#KPXr1pVrK0_^RM)uk}!!5L8>TO42Ru)kIb>l@A`(fi(etM0m#G<>kwwV~O zw(xaW6da4~#^(Y}PMxbp(iU(Th3CZf}3l^;h0r| z=MBo3m?-`p-VaQZT{78zLHSWNm32oJxoy&ks72t34^d!Gj8=dH+swRGn`d&6|j&n&PXLhwd zY?@dYT9b2uRt2;Fk>XXgPObcg`WLnv)u0L7*LN9TQ!dI4(B!mp9~}26atgA|Vl-1g zG1Mt)k?;6P4~*b9-+9z*fz4Xirg8k=gdS5xM_x#bV2|fmb8UMyiN$jH6WDG-k&!?G z7St9U#R|{RkKRcgSQnjdIK`zJd)?yFvD(DPh5-hpASH|!dA=)}N`Sxzdd7x9cr;&x z0?>+V`+=QN8F#cdo=5>iLeFsFc?ywL+hR9-dzt%0?%k)DK`Q zQ)!Pt6Auj>-6d23k2rTJpgSt=6SoV46u@%xuQKC8?cPl+>*s=DEZVpN7$>q1boY5* zW0O0~;UO$-=GT`m&GNYD-B<_TuV1~NR7&M0g7vw8=6o*KiL1c-3(y&pYSCOg_bjc`cG%->f>UT`;z zd<`+z@DhiS8g3Ej`NeU079;}kV+@JEqw=S1M4S)vpZ>f#e9Sb7)?;J*jPQ$o%jcL( z9$^>WxCE2zM$4Kh%Eo-KYvU}3BuuOxw#eC!({l2D6&`xunIoF$i2=Gg0oOH^x|Al; ziE$^IzopsMH;7d|WB#*{?LS*KYZR`8vFpVXe0x7M7(cI?fu)Yy9Qf zJg5w2#h`;t_ksT~YSk0fp6bXA&oHh|`M_xKx|irpxo|F)x82hH58PF|R4t27)9cKqaDz~7a@Ub32?mq5-4r4x9%Iem7Lr&xv>xdzdT4a%LsTjG12W?qN^+ z@!iZ3G`0DLzjcvM4RBD?gd5nN<_J(I18CxC>BNi_)y31reLH!#llOMD_Bg16eH%Z+ zI@5tf6YFG76bE+OR-tMscC-@k{FJTg^1cx>`h^6`{VI4q?#JA4s=KcG>oiD^L_xi+ zB9fNx(}VD&&!0Vp)p;!Sq@biL&x|Y2nRO@szL>_T7f_d^t2f=H1rP6$*dNk9oAK?! zN8kT+^=Y)gvMi3OX~M4qet%`%xvxqm{V^J4{^~Hs3Q6-Ozj$q&l*nDAhHS?*SuBJT z>1JWh2gQ14CnBI6K5U@JQIZuh#0MSj4qreM_!q_$+5dMzf-WI`F#D0l6JQxO0w~nN zN+2rI*O$V^wBuB(e=TPm5fA@tIVG9)#Aa$#3gm`FIbATR^{iB-qf&ubqlbcZ1yjl| zD-G(`AB!|X{kCx~J&%J(tINbfI_uV-SBuuHe1`iI;+Fc-{}H>dI0Y8;hq-TLYGv#= zhtQaY6vT2bzz+NAc&43SvdjlIGFF&@ybK!Fw*HDu_i7fBlm1z0*!SY)u7<9ZY$O+TBqN|FN9Is93lc2hfxq9nTU-D+<)*)73G?0Tbyq-0-Cy$ptt z(t0Hr5qmTCUdNWnmw-k*AjEr&Our;Q8=j1&G=lNvQt&r`N(Za9h0Hi?xKemGQofjwQ6 zEfOUxr~hNrrOY=DeNV)MHAz2xVyBip17X`9g*GZTExdiraYcBBk4MP1N-uBUATzwL z(z076^l1D(WzqG?hXB;P+t~YZT{6!yRk<1RRh#?lrI~d^{5EioHD^r!QsGeT9$#Nb z=cJt4L(J8!Yu(LMHCXyUUA*XMAeb%To(5CqTah||6kx@DMr!X_#1p!dW0fQv&nulS zOv9Nvw>;;%zuZ&z>2W@Ns^9w*v8;KpQHLsLeN%B9pufo^@$Abp1*uxTLE-IYWFj2A zo?eRJCYJFH-lL(A0b6A2icAbemDxEoRkbBCSVS_#pQZc^@503DOu6mquJ*#i`7CSU zMLUE>+8QgcPYL34g1*$KkR6=qQRmqHEk5A1LG#i4S-PJ+D|g(Jh=NHlAfcI&rk`Bg_ySed@e8Hq&)UIEwY_S;&-MbLul^u<^-*}B?;p5!e6 z5#0kXU8Yj~oxOH^gOg$mH;Nk3ap)|~){hGPm0MolJMP^O6W{JFcGSzvT?l;Xk)@<@x=`k3Q*F8qv z;&cbNL}{uYIMz@oRd|#JJSZ&(jm~LzN~q&j#$eMOEX1PL&m{W^W+%XLYMki&Z$kJW z3%K>=u5Y0?M}#F))ibW!sD-!weE{?W7W#FTzQ-*BBc@RDU+x!dFQ4_as9bt?>+JL;8sTYo&@eAiY~+@<*P0<1~jO0P2;5hMtQ<13y0#*{n`AT zj!xOv50?u8TDy6x1^-ynNWte0LY)Htw>Vyb?a?C|D6~gIOy>lWpLKmbHtoGfBOUdN zNTcrHea*|K-6wfOB>G~L9QHlr^�_j6WK+Gj+xJRxVvl#lh7y-4uY);t)n47k4ot z9YsU`HVk7fg4;r{;)FHk7ZHyZJ+W|$aKwj=g&_$VCVFn5%XzSA`|z}+4ItZ|`hB}R z>h-6Be`d>nmv8;kQHJg!HMr^cCGG=T5;3HhZ_JRq0_4a3TsY7Pz{V+}z>;!R^U4*c zJ>wRI59B-)92Vi?b&EWvH(`<(G5A?W)z>EuDMG@VENAb7aHa`I#tKw{0uUc3(#J8& z*_S%A_ZxCIY385{%qN-b1K)TWmCjUA4nWKx_ZnKLSvEf0($&_0@DS~ zN8JOXJXXcaFm^OCYrz(R7N5DQkXKGnnt}yzfw^8s%=A?7hxza;ylJ;XQ&XtC`pM%b z6$5Ff0{(ALcSlTKvIbr@mR`0Z)*iM`2EfO|E5OMk$jQsE!^mat*drqV literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_2e83ff_256x240.png b/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..1f5f49756ca64bd20a1048bd7a3a584457d4bf00 GIT binary patch literal 4549 zcmeHK2U8PFw@yL`geFZ|P@*V;w1D&)N-z*QNarO;QRz)l2oR(yU5bE$@JbZ~M4A){ zMUW<7Xc|gHkY1#>kc)mZ-`x8j?lU`k&hG3pXZP8eGv_=pHoVEqz{dap0GM^r+NJ;i z@XQ5l($k#H6S{hbXB#ZW`sOH!2L%N^&k_wk58Uw#*BX~{9Oe{(!2H)ZKd9X_X#oyfU5m#1Q82_f^tw6O11(<7c zWrG0%qDlJqcA8#ZrRU7cn@;N9VJUYHk^lTY3j(~2xv33^rM-YYTR?r#*8XSqkBCLbg&Z9G zp-dC_BuoqAkc7;MJ$9jCDbZN_FFIp=mvYI8l)OlkJ2GcKGFRh03>eyeeRF`W3VO-< zC@;;5k3f&*z5C#XoxT-q8o(%^R8K&f=k{8C{Y0uqmWi%PaU6jYo(5);yFd`Pn(!El z9h1vEhwlH1Q*|5X!lGvH`BD!7(^?OdAd$XP8=x~O{-Q}sy<2@T8`8IN;o*)L;K1*C zz~`x^5S%i=-8fHXQ{cyPiZj`|pV*e}T1g-QFmGBzZJ}z9t&~LL?-9yqp3x_EMw?h% zR0P^RfsG7yxX`l^uHgxl8V3PJTxM-b@>%bt-xEPCC)WNC4L*~?BL_6;e`XLVLVOkZ zaY1crUf;C9r#r|ebAHIp$KdM#$G60s#+4?*)mH)^4Rrn^&ZPOyOvZQO09veRcnbCX zWQc5fEAPmQd7=aqrZPBYAy;!Ph{cmfC@z-hpTuotqr$Mt? zY7woww1bOdZZNt7uHxGKm9$w8ozW}U!S8~V?{0A^bi{^$t00v7M zy;S7sm>vMCBz+=8TH~>zJ3!E9INJ1E6=!x^{;q9Biu$){2DGEIbB=oh!`QMCEx$ds$)Rc&7P*}`pd3{PqA}tIjp&y&{w{YrsPqhxaO4qerTDpM`WTlW5 zu*{F5ID98N%XU%ltVphxZ4Tra!)bpNih&)&Xx+d#q1{G`5icBuvTfv^7X{W}JXD*B z5!u=L*x{^0TXODlF@ziPt+=ars9OiJOv1hU4sSKFa z=)|j@+%OFH1Oa3f>ffz{O6~wHhDJrN4=)Y|I6DD)9CPw@Ytx6M2-O;{GQTQG&gg?A zr_VPJ&6+f^hXn|7pvwa+o;bXAc{n)lTn{~TF;3#>=AS1_iaGZheU=*xbHD8CUNUCj z^3&DKA#op+3tPQa@eK1RUg%D!n%5J4ICni7xELQIvd$Qz&+%!EZ!S{js)F!S5x>3O zLCB>-TbYHXS1?}__Xfm{r>(wAU3INPvHaWIIYbsxO^Oe0h0xglZWFakn6z+$6`V(< zSimFunLw;GdHMnWx=-GqPeuvo)l|sHaFJ~`DxMN)4Y7U!J8D=^MqeQn$`lS|1%mdN zK^morEND%3ee@_Yb<>IVIW2*6NZ^*QDg@w`H$3}uYsbleFidycDox+uzraGexRKEV z)Wd(JYU$(enZkGJ3{9REQOJppi6EBrWrXU;Ho*EGRUG&RC-ceTd@*C1J$c=Jk~Ty0 zAJE}+ZgP611Nw}-*K%$Od}R)=^6W|sl);faH`l2OA>=zFmy@8vVK$&%4OTWEhnx^< zs6V-c51bUMvJ@`4zcieGu?{L+ z6(ZMYhQND%M5s7uB)($Pv`1e&xPRDwWGD>e&;;;sA;yn_>F>rJH-M!+=wbl1_|+h6ttu(NB3r*FCdU;|1QOB?AGaVz-O zFMj-^FpfDR$apG zp!5Ji|53`FLrz-d>YnYEv6T0wDN8?-+$@_Nk-6nai){TtA=w&Qa=^woXbB~azV{PSFnB7zJF-k|zJbp8E$W1!v#tcX8%TiKFo-n7uCut-v(fLn$6ypSnrZ z$*S34s_(`S1jtESyVuI|{3uW2BhK-{jQp05>-^UGi}#K$%3bE8bM>i8<~MKu=Z4e! zh0A#tX_IOB39o+SdnJzu7<`KoCri$9{I*mr4A2uJr&$q1-r=Lzfussme7r{sQYl;m0a`a^hI)69ux681k(h4* zN9|Ywb^i7xF=uPVr*az7RYlVWPxhKmOE)Fgo>mlB<7pYaz6VsBW7J04%DxENck4rx zgM6#>hT78o;>S1Jt8MqV+4Jng1ERmSoX9dGIW`CC2VaF9CwL8-Bi|83mD2!Dee`Lm zCU-luuD>aLYJU7ZD?3R8tYYSVzoEVM_7n=hEcv1FN{h`Dk*ik1Q)z?ie^&}a1;86B!(s%}s%T_y4o&Ilh~d4DHn(86bo>p-*Ct4!-v)W$h1{J?4IrLKT@^?`26FF*@(2A4^@6og<7ngtWmIBVp>g{gwCG=1WX4srm*>E(6gC>!E~o-<{=AHg;~h zr)4{j`glAMBt_n{+%n8))~tNAyYCizc)D8wlZ8(Mn(svkWSi{A*vq>kCT}fIzl|Cn zy>PR|9cIRx;PBE5*-4+O?~_|$F<}5ur(2S|FAw=N&4pNnTk#=xhxAK3L=6a{X{DRocw%r8utUc^U?}*_ zr(y*T#U}{tCh=GT-ig;Dn~K`ilK*9stV#@EBAC9TOf4ugkA;~Nt2ej0?du%%-=F_m zz_LA$2jOO2Xk0r}zAZwZs7;VwA4S}3#)0t0SXSerLIo`;%;<|0ji~+vl}hOk9i+zx zUuZGWeo-DskUoPx=uJ)C!2Ep5@-PzwsF1^fj6kXJV!gU9L;{+5Gue#|!$uOssQo@K zR+uvJS*YTwuIPpVsz4PRkj93f17`97b|eBhl?7-Z9~n0f6EDor>foo2fPb$h4?A7> zT%r7x%5bpcUlV8+ByvZ7G1za^zhKiWJonD$xaS#k!hAE4p;QgaM*&tH)GI*HnxRE` zKM&1Lk7kAdR0w0M^qbP-LBil+NXKi;ihqCio{6=#|O(C$v0m`Z##4NXD+__-g z(_-U=I?+`IvcD6z77?Nw;fys4D9CFwg)Aldh6fQ?7N5`ui7^y6CC!+Es(Gr9qTHPK z-0ma)tFN+?V$ZP1e1t=yi(Zs8_S&zkh{hmaoulswfZ1Dqa1RNYC-25^Rm!I<>GW3k zjUOHLY78yVOfQ4@4mA&>xohn_3&n{JwbI7c3dEV^o%%0Fv=51+iH6T4?jF;IPPfqw zokxnwN5uxo9?XI&Sz@-f12P;WQ%GNbFK1CCdDhs}sVDCdBr~;?W)WZ)U0iw42JJnB z7i*tnrsnBMBpw^Ay}gobnSM$V#D;&2_@aql^X86vylX4gc?Y;m(y8v2NuB;;wJQoV^z3UpIO6adgOK|rh`I83cQ92vN z*nDrN5bxLa^N8pN&PPh7e;t?O#;^ACf0T)hr9bD^{p0K0aKs6fP=#ZL0@Q)?jH1G4 zmGhC&x$cBzQD~bW$K$+5{ylRuGYJ=lL0%_3KE(evW+WZI`zqmN3H0Yi?*N0(R64#J z>}+>eAmE{uko29IXjycIN3NS#IqY;9$u>caW?(bvKw+_ zgG{F`FVBpFDwJwR~R;O-V!9D+Lphp>2% zCAeJPdrp0I&;9O?nVzZYuAY9Td#2`@Ff|ofJRC|K004j|F9+2C0DzA}z%e%ZV=t5G zEb%Bnri!vqfK1uzM9#CcN_%;z#n=8gA#PS3;tcI;~uofXisxsK~{&;VR#1 z!o>>A2X%jk6mmfdq0-jyMN=cu0=VG)#_Jf_>&KuMX8ti@lH{h`>lhL}=z0k4IB519 z2z+_ZC;46kNd^v6LH`zyWz zc=pCDRd~N_<2su2s8&{(HU!aVC@&H;3-}=D4 zmn4&Xqtz|N;fr4ZX*`x)O>~I#fDAFWbF}%9b@c^V1-YMxSf6U)DQRkB+43Xqb9MFy zjo;f7Zl(+0@U{ZOZ-5LtI^A(gphls-(I>bAO%b)X0%Rr}JgWGZvD+JlsTxN^% zxJBLbH-$q!0L=#%jxX5Vq_FKJ<2w!*===-Y@qzQ*_ z&ov@B+(5Xb?{lf2ViA!OfgI3o#$9BtFq%%7KSq&MDxi7pySJYoi*Mo(W6r!DLSMQT z5R^D?yx*g7)k}}4ziwHEoWI5K%3hPst6voipJkIw?!%9N$K$TWC4VuQM9)7yVq;a$ z=Z;n#4~)-1561t|Pxey=Qu^0P2#JYboJR5co5Ktl*iAC2?$BN>JINDo_+7dptH4MZ z=#a=xrMtj%`CVN()`GKp3RFADpy$xF7~O&&p0-yeG=xW8uhj9Af`YV6uf@~_v;;D#h=*T)D!O`_6(IwY zIw^B!$W|O05eRI*b>Pe%GGlOW`<(mkpbS$G@7HEko`s{=g~2c4kqO2D{R_c$HXzr|(vU9~bVZ9Zw90;2AsK2ig}XTGY6fY#HgGpEaxY zO`D_Z@O8%f#^@5G;myQ5fA(JXK{rgcieDr!{s`~{nU%CRe=1;4og^%^Ts{A8>Sq8@ z7MLFuiJ9lh@TXEbSXQb0;l#nbg^u{Ky;vCuCLR537HT%5FxM^fs5pS1gq3J(Tf!*6 zAc~!aiCB8(;cEmBeX<`V&xqvsk92&%dsXd*G@M$W7!TVsoD%c%!p~lGHEz(ckd{tR z##JAyc1)YR0b@JW|HWX=EIHNMaui<>jUPal5F|-#l#?ar-oHSbCyZG*EuqOC?V5Iz zROd8mBy{ukJ_DuzLTBsPdF^WZ7NW}CWcww?Uwp))_brh+D#JdL%%G}bh zEbmg}yJc_xX1_|6iSomOV4IgTV&UNVe-P4B!*v}&@hLXe=h7%`bcW^Eta_BE?bf*&82)UKj^6nE@ zA$RoKncM;1&!nmY^=yjr6=wgBr%e9BXAxKh^0A1=&iQhn5mfUB$_1N5DJ-DZ4!pLCChW*MHin>-!AX+Twe_SsV%)n#? z9m<01Z}*b;{SU$Rd-`axfZ;y8#-Dau@wD~tukEo#I1b5JhkDp%r;hf2&TH29Y`$=G zCT=}&CU#_(G5)E0y~*>piG@IHnT&WP>Bef5eoMnuRP?tb7aFH_AYy@I!S34oD{g9j zt&5vt`pheqh=GvgZDzlqDuidT)11qC;R35@PC4Z4(p=SICoeHq+3uEqgbmq)}q|_NRzcOHv0J`WLpt+1=j?0A{<5%OLxd!f~^V zfofe-Y;s4+yganmBlRs9L-MCkb@HkcIGzakx6p52sHx;MA}LA_@xo(MP} zDc);OVH(SgwrVlgqy!Vb7cIqe8X$!ECB5e#-)15warssOnkR%x%-o>1T_T=}^z83m z>?c?Vcl|}zH)Gve#!UTymO66c$B^I*%B*@2y23hf5=?aCeBzz7EJe|b9Sex0(wO>7 zRb>P4peOZ<5iwK?l!Imu++&w7Syj6VQ7HaGhAd%tr!?^1W9BpDb9K6w6&K*5X?Mg{ zJ-9!QlR>z>DK+)226mPe<+h_rzFAHI!mzVV#GU?Fzw~_RoaIT4yg6y4BAsT`&lzDE zN8&hg3mPdVnZE*z(B&{cUCbdEZcwCc!M07oJQWk{gQd-> zr9dqLy@o0}77srWq=#f}hD*4;Wr{`XhNy3(QRG7u=})1~*VvvJg7)}?r}&$RlQwv$ zXdGV%bswf)=onk3jFfL;P++Q%v8Zx@HLpgdXD??Rgfd0J7%TheMo&G8Ri zY%xQ58GYjiumJ@R#%;;*4f6=Jqyt;B^WLz4)&y*MwAuEm);Ad)VfKQ8Sr0CY@t@~> zUQjgZ#QB*y&{~9gc(!{BsVt<##<@4;&)IsJD6YtQmo_p%?&3O=8)wZazJdioWa<4X zlrD5`HRzYUVx9XSHNrRMeJbsZXE$L%`CjK>#AvI+17q)*ws2o~m+2h|RXRpuvZ;D* zQY%WR`fzBy@JjoZU*XW8`Fqv?ZRVOCeS4``J028Q{72zS6OggtuOq;?NrF=gLU{T1 z2Ey5bAX2R!_@I`V<&n7vuSD$!&t^oE$C16?6i^2+oXgJEQ^GRtyq7y|3J zjS5W(iH2Od&+O~1mD#qt_V(U2`D~yWIe}Wmh)Pz z`3B*tPj%Q1@@njj!dC^nL67Y3HjBux!~dkMt88TTtEyZ&gy!?kq=hW3X+P_Vrv0a= zk$G`d4jR#UC3q&uVr_NfxeAI|1?9Qb7nKH>x*7HzWEl1J7=Vy~_xZtg^d+=;~q6HX~P<3!HF61g_w>7y^ge1>z>0>CJBlwhy*m zu^e%|FDE`Pg>^K2tw_~`;#;lt;kHE=dWx%}d@{Ep`+}fUYEkRY@7R4z^Gi3a z%p3!^U0{T-%L?kl_g;>HbVbT_)6tT-&YtzE=5CeyU1!c&e8r`X(rWY(&&Hn$;!z<3 z@ZD^M|7w69ux8!!$a=u3Jm9vMnxk@c@;-#Vi;?20XYrZU4{Zg*wkL!!)33(XXlz1R zYdSCxbAF4VGcc|P>jR^>ye$Fvd;}`W;VnrnsgUp09az2h?}6$Hh^S}<)Tc=<&3>*uCLEyR_hY_tr{or zrLSkS#T^|h1|_TSdo$fLueegLlN{0i)^=e2EtbySBh*?saAY}fWW_pZPj89qIdGQG zuxq;}FZf}T8*ZUnyil7Q8o@Dmf8dp6l_IDkJXm0=&ivCe1tvmX*|Y9)KZx>*u)cj!gV3~eOWE0KE$Vd(C$NowTz3Z#GR58MoW7U>(7WibQR7zU zr(M+U)R3#cCD?IbC3MmtR7?nlyi9(d)Z8dBwm5Yv#gE zH~5Y@zD>tVcGN_vSwLt5=jvf;p2JDnXQDL55iWH_(o7-&$C@w1ezEAGF`loMo{^9s z+qL-4cT!g|bS7(^aDM{#4CP=QsdpQhA-B3WQ@8x}1Z~5_L6>yv41-IOKT3S%nn6e5 zjJw+eepy<9mtX+LaCH|?5I*+c*Y9Mnr%8@i5vn4Hu@i=9XtWGol{AM#ixz~m!Q15N zdc*o)e1I~VccQpl$M!|<;DHX$F%un;kJwM!;3X{(+24sQz;UoP+D;pG5OrK;NSpRJ zAoo7h4z`5^2%$YZK@il;j!YY-k-Zk}e^u&AqL*9qyz-Oxo3!(5hwER%GJ1>eeJHnI(0ne%RzAyI5mDgG%|(-4~b=*CY8r|1uLy`6pa z`a`AqLvAMzmPMnOi;v!%;Z#k2RPeMo!UaOYtBz2^Z@;8%ZuCM|L0q-P*6`3fqiw^L zL3`*T0~C5-#Fy`zV$lw~_4mI6WLZS@zu$b)@(M16E0J%hHBZ=3P0gJyo*6+fXZ0|) zB~_}943 z?Lc#&-_51qs+HcN0==Y{;S2E*(c#J}TF1dOq>+oBq7^BO)gtN36`@RskHQ1S3iYcE zdr^>R{%$WSvX(kRE8=0x3WtG3iW!hA)a`Qss{lN*6S62fAT80qpF>~U0K*^ef>uYa zroXwa>=4bE(Me{aSAcQ#S=$1-=uQTg;;=5KvvH5q>2fiJX)f+RsBB9uXVi%6<=o_J z;Fb|nE-|%J+QxjX*FPtOMZ0yTw$HWu++eB$65&pLY_$8rd6A`F5DZM&a@ox>EyZF; zI35+4PUyZ(Fq1PdiWWylndF0L`Bi&mEFQ4%ig#h6sXl- zY}`wuiiW&n92*N#!?nXU?R|&(llg1N@n!AqFF{IZ&>!ujl|0-wU5gGY2E08{lSjF4 zt|sNhwGNVmJc`EVWEc7S%r0=*uWj19qAzg@1=s-H)o&Wz<Lli7-+}2Ha{kq=!XZ~pZc&+Q=0Cr|?#_d2wy>XJyrz^0!NJym zO7^0TjMo8~-}C35db!jXTrFn2nwOg2p{IJ)TMKtnrmOTK9*AKe0{j(&<)*eqt8N!v zpq|U58&sl=USB36p%G@>`5=>n9`TBDZ+p}y$w2uADdGxvcz^~D|-g+X6KZ?b`a6w%sL2=P|o1#BP})wq9P6^I;EBnI=7-f6T*2aKAh(r zXjh?;*}}bE?&sMes#m4`20olUS!0kmkhy2DS0V9I zOVfN+i{L@-)F3v$JA2t)D}TAUs6WZNKJ{$kx`%Omgx%I7Je24zhTUZh(V%L!aHijs zeCcMA`}iNqfj%Fu?+*QOj<}bl1LV*Ss@{fNU5=lL+RyR}X`nw|5$c(I=~X%=VUF8A zjt6XyO6Eiq%OTZ+GJkTSuKVD2LWrlV!?~tMbg?upc?2iFnnE_oJ8?xt5w%`pFE$TSofbGY9Nn%^00N{i~> z!<-d}5xbK}N##I0*iFO8_PIgdMSVO=^HewXRYhMjzGFhagblsyGGu2-wW7GZZ{ zQoU1S*zc%l7-^UdxP0GxT<1fpCrTSsH9D$z?_|R6 z_Vg7Qh~N<#KqCEj{{Z9*u}7$G?~LK>=6PI~v3uf)l@UJV^0t@wG+ak)aZ`yOwUxZ0 ziHYw>>qDBv?tyTN>lry=XZ*IuTz=$P-6wpGW>1{a66PVs?H#@p6~=_6dhZ zQ_C6oC7I*oSKm7UI^y|S@_%pNF_jc0z9XL9|03`HyXxpE1D3c|=~P-|F$QK4)n|(p zysic<{o^^p=+kD)6#_wCVnRh3{vm;FfO(3hp^DhdCadwzK8XzOBXkoPy^at}Pap*v zBU(QN-y|aejaOi@kWw<2H}EDHC;A&JKG2L*Bi1ZUvuMuO9`swC=#*((@P6()>?sWt zSXDf0QV4qoH^Tn-f32+A7sI%V8~ZP)1~6@8g`2`)UUIaRX&f=wzC8&T0D+%B;88ZL z&{X@v#(SwT20&G$4|rq^D~AiK(oG-XF=1UsB7s4^AE5^`5hh(e;#fOR%+1EhfO@H| z^%1^X;6oC2lZX7+_QP$!5C2yH7CdlD4a*frVc;CDYPb|XeSReoPs*JS;SMlZ9?j#N z08l}h{pNsNINt0bkR@G~?a{{%xO{8T{LwZ*OrlaiqT}-+i-P#Wt~zlIz^>o7J46EY zIKG)9Tbm%h6~Cx4ESc-WZhQQJVs@2z?`m%1Y5_5Gws;f(UNDa!Cs>G+hwmK^7{bc~ z5fI@3gCSrr6)-H~KMd?0&220_|EB?11i~u_5#axq0cs?h@X_G;KOQt4EnVGBoGk#7 j=8mQoFXZh_tSmGvOw2u<1}#J%l>qWGD$oikWB>mG5~xOM literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_888888_256x240.png b/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_888888_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5e33f27235d1b5cf0259f63f3894a6be33c679 GIT binary patch literal 6999 zcmZvBWmsH6vi9I^!4hPU5L^Zs2n2T@2=4Cg4nwd3lHdeFfC<5aTkx4cu%N-+2@Dnp z?w8&DzUSG!cYmByefref{ZyTr&!bfS=cPE{A_)M{_^Qau=myRos0#;zfZ>Q;mcGYRie@({fXRC!lf?(~P}uA5O=^WkN6w$E?Bk(QZ@d56yF zvzCin``<%De?$=3f{5%D%>3Rj1G6Iggn@+A<^UREK7ar#ZuV1uR{tmF0D1KqJXc{A z%xfM%w}%vYbcT&PdfJXWqe{@F-Trf1G!PdObSLjZ_+aq%)c>XFRvZg-spg=oj_&;fOm^QKjzig4q;#%o~svm01A0n%NG{&+6qNHCHpjv5-Fjdm&ppQW@gOQc^ZHpV-IqO+^k-I=s7UxRF z-R`7Yak0kmg&9$h1hga2of%GS5j?9PZP3G8 zY0qVzY1dmU>_646Aaqp@=~(-1S>H3%0EF{C8r?%6R{leTHmW}L4@byn3zD(w<~E9O z=Fn0y) zY}2L1AsRK!Z$gx%=12t}dqV5_&hRH<7OR=c;+t`wxrz(}MSDEjxp{*oahH%kyf6V` zAo0S<{8~I3yH)g{!uPj5<8J|IT@-Tc^VzIyi?Tzb@L}&FlF5%e%5=Qa7^9eVC$*`A z82?nDIx;)K2d}6&TMusbX4q*~w<0H@sgZGE!VEh_&x+dXmDx|3XGE*TVtenrF_d@& zOU1DjvGy|ES4oRGhn5;zFm!vDs_}%x318u~U0qSGUuPr#>uUIi_kw&J*SY-yYi=+Y zSWKOfJiwcNofx>;_vN4L2ROpKgvHuiY9Bx)xB^t%?MF zP?PQuootUA?J1D>+&m*iHdeItn?^Q2;v3DFgbnkz4*vq({R&KBB3%!cV5_LAc2V8- z%u0X{E5>%S@Xqv9^EGx&wLfk}FC%4`U@@CmaTcu!eHJ*GV~aaFP>(5pa6C#n46Fa{ zL)oQX4`ZT>4YUe>7xww~^l$y45w{tA^R6X5E9FWBI~%}{6KQ_uk5|hIXc^T%=0M0<<#BJ0RRd_O;3 zsb-D8O$U4S5BOLl_;#4cj;)2Hw;;O_e`}b{FVzp-3IL54{lXt|va~$t(hFS=qc!L) z-3e~P6-a%iT5Ri_Lr?B+gKG~s+?*f;UVI_B^JO>bs$O@!q-4u7(Ml7m|0^KP0oU)W zKGt(FB7jKjw2q%eJLKSlr6|R_MXbz$Lo%+mpGFNp){u);^4_8Q@dp# z(C`~#{#iw$hiaH|e>D#7J1QrG#1@WlsC!qB+e+0yo@4d=SpTXkr--hWpbISfyP>Mc zYi2kQBa1khy84P)({Me9RIes%E`2#p2KKd*kKN1Q%(M|Y>o1(dB7l}m6tl%M{_Fc- zlLA37rfpNZGi_--$j?kmH>Ao0CMGF~4OIuoyBJeGYckr{@11Tf=O-0{8O!w>=)vwA ztf$Cr5BLRwW%tqR@{BrIoS1n(hReKhl7J@GP8|Zf-XdoS7Rn{}qED97tGi<4k7H9*9qX~33TOxusi*f(HP z&viDOR1te?v8OHDy4Pj1M2(q+$ELZQcTaHtGdXfknhJ2j-5AvL%4v$HRh0~PBL4N+ za)Hyn-KMJqXLDdZLy3~% zQze#I%SMB6QK>s`t`$If5J3%(O9R7zZ9!7WBrhq&sWhXw*%Vp!4Eey}bMe=Y??HU! zb)us6SBE=Ax*ulxk;mrf0T*OMQ8$rfO}qtCpd_?icx1?f8OWKKSv<}E=@$orqgn0$ zf1W(L`+WxsKnJDXJt;lDGWz|}V={IGOp1qeHTB{e($_>WB^Is3CQpnzN7ku-vgWz# zEPgAYrzU=WLN!xAEIf0P`5LphqD6{EC&@YQbIF2r7miQFZ?-~Hd`Wt}`#V!iV{U@T zdV{*T(|fvYAr*(4T`JMaY;~#>68=#ibONi$`qx`kTV0TP^EbTPS{ZF$+S%_Ud)3DO zM466a+aQJA%vb%~h)VOdU8#yO3NRcJo-%(8GI=&pb|Rn3hh9^j9b=-8+s`SuQ&T#C zG`x0elQvoRIyHRm%}r*NmJCMWxu~l#gL1zt92X?FvBzCq(!TY=%}T(M`2fk%*IK;L zBXT~eU|)AqjR&~?Fz|X7o3)jQBygoIaU$uRnV2WVA*`hie6NFj{fSYR$tSf6-H=*d zdg}V*#wU?b6zPJx_?i*)^2ZdWsa5|LJ@!W|k<1z1=y^2{->z_u{ii?p@!+*1 z{h8i=ictpi5|yFmiDrcW;%N!e{dA-3vMkJ6wh__#hsHxo;NDM7S9sqrR*Ea%B8bay z%X~oeF6AiMIIttj{)0rXEtx0%X!)!~g*1q(y!4>GqHs<~ni<`37IN#`5Y=we;sV48 z0^j>rz6pk@HOv9#P1osT_@$Rqji)f6X1^9>Z_zAx7ZYa@{Y<|wF-ZqzZ;N3*tvyWUlgZae9C@OZ_LDT2H`F?q&u z!k&TYj{q-6?lkD3=IGZNqwuV3sEQZglk180ch%^iZfE(@dqorO^(^oR2@#VUjpZ92 z*us5g!F35st14zVf55PT_N3~({Bvd_NP8L)=`w+^BdtEgl=jgASgv%&x1HhxA5DJI zz6c)lWhxJ6F7wU9r|m)ug)F^-AVN@O;4qgQPN2i#$La#d(AxaQE-p)9WvV}$aZXJ# zz)-VGidtmqQHL?Egt@AMsbz!!2?#$6J>2Z_?vp(u*f1Jy86l;U1fr|I&^Aw>lTt-r z<)_$xVFFdc`nS+{OiM!u^4E2?nETPkyl1m2;|2$E+_PRAPnKYr_#g8`WNKaK4F7^` z?Ubvq{W1>s1^7Y{HItAy&8^_JgrpO%s=DZp4tZCbahEi+1%pC0#fCYEu7hL3$tZ50 zXuFu6Yp-chB5r{mj(GFKp_Ly^d~x}|agLYR8*{vMq*5frzoTSB4MIX`VXWcT5J(p$ zvb|v$4c?8v;T!4IdUfGv>>H^7+@>gzX^B|paL3B~Eke}ziUGpPQ}dIn03g4gRNJh8wrgjZppN344yAl%PT>?dXQfM#P!sRwL z;KMIu(ce?sUkiv?!Vy1m=vGTp^K>83Yjo?d$#<=t-KkL}_==YbTSL3tgWR6)-Ro8r zg>cv=%3Rb9yeFBfD78$8J*?6gjy>9c`q1R8Qn(CxX}XM8Mj^JBOyR>=?rRKQXO9*gvJyjfbJrs0U~2168KVOU;jdTE zc^Mh^)?{DY*$cO1{5f&&9Bm`e-;2K6o#q?)^0k*DB`UkBhVcdDfrep|D->3J#MJp+ zXY1nE?S}HFz60zQiVNOD@25Sa*0SK_@r3 zC(tKK+*fXb0BXgdWEt29pxJlcGHzY zJkOun3<4jbr>1T_TTE+(G2fT~#EBMFE0%pmldkXeM2*ccV3jW|Q1%;GkEKr2f0jK$5CC(%my!&suy}Ege*D+mwSTsfwKm{=38iPdckt95#-u`Gvf%NB z;Jh9Y$q!*z#v9yQDy~nPEHhs8Qkw?&{9op;3~$xMQ7^lQ+Vhi5nq!hLeB_uq=fV`i z!E)geaw+Zv{3e01>Ja?YPHdnFy?gNc=tt*_9!=`7Pxa?6vDx7m z-0>Iz7kq>(phWuFYjg~71xPKq{iPwgaFzo`h735{1u|PL&;op4?W}XU z*Zy62q5Zpw>NWW%j9#6bduP-Wx-U7vc>pnX^^HJeuMF)nYzFL z%R|OuztH2Mvi-7KmK*i^jJvfjk^KvfFB=8yB`>Tf2m;=skPWJI`bo3orf~30518bt<-Gc+ep2#?If-gL z;_V5G4bEA`J=zvwI~Q@$Og=!W8uwTmkeO|h{T!d3G}TRwN4S(@6%mj>r>tEd-;I6xK}CyHNR z`W}vjd36p~^P67IHm7n0WplM~-h0G4d(^lQdh*;f$GS9QH}m7A_@SjdB<{Q@lSpks z#9Z>MGSepD!)70Z0=($IJ>f|tC992?O1@XfyaXPp;h$rKrsx6fGn7zu0DK-m%11pb zGs9l*hMI>!-euGLyZpfz$09N2tK7I|b;S-_#kFUjE5M#v)sglMJH-hP9PYzL!(X=C z&l?pTPZ)^!L+CzJldxTEnRX$U#7DonI=OJLC|?k4#%1GNfv4AB1Wnw!xI3XLtci;D z>-ZQ7cE%tm1TrT|p*;#G65?!pEWW|rV?DJVanShnI9f(F!n8!3pJz=ASgeotHM#nQlcCth-Uv8eYLIFq|3 z$8;wJtnCMzOA2y}?03AoxqP{&<<^LHq+AC=(zuu(*k+;i3vxtnzWwUcSRvqT@9p9U z6B$%<@gcw_XUet5{BmU@iP+3ij=x_$z4QHD)k`HvNGXwccALGY(cnw0iuw^T!X3kM zCPp%7p}~l8b7j81O$PF3Yj&4)EbM@*agLVppE|pzn$sS(tEqN45aMSbu8N?*|P}v74M2!K~C@*$2i}SB=KKK-lw5%5K-;( zx7f;>L=##Ydm&d@RA~naR#0%3 z%Jt(5o)V(kBwAXNS$kQ*X>zg{Hz$*p)jQ~CPvPAOXWSlU?UV&`;kEB#yUYYnQYm~( zM{Wz^qIPF1>EY9Qm zs(bJSW9*o|Vh+{F4kmXlq<#GjIhTPKk38K-n5^lF$9s-<)ehAI3h7s(%ZAM}PxI~BVn6$b^R>=qIM4`F$ zHJIDKBpfOts&!OC?+vc@YFza+(}>X6gGd#)^)Y1hg_B@0JN)W{o&aj8uTC07^&Ms0 z+%4m=-h-4rU;#PK3cr=COqN7gJd2o&8|~IR-aaTjI5t4v;163AT%imiB9*B`OHKYd z7NM%=d}-LtFW0pp5c*3wNhme>^b+O=nYY9$&%s0Sj+J~*BL>Kh_`#Nl)sIOAZg z@t&kUUg#t5=ox78pG2wvT1_sF)`xJ~q{34riYgi$4F=znBeG~miClofeMJwEaUBJtDa?9tQBUX0F$_zoU8SmzfCfb$uMED{p)utjDJe)DYI z|CEyh*7Tn9ST3$vSa2?msDZYHy%xc@6F?0j`BW54t!2@(cVeLa`6Iqa(Vt=&R~pre z+kdK%&@j?q&W~Vtepw;nuBC_|N39bWl{VjCMLK`6Dg076ctt`Gz>vl+96WWc@{?M> zSc-4f6T=QQ^XGcPBDe*8N z6p)h91fy@X^D`W}r!QrGa69d*j; z0IVCMHC8T5WH;YpbB8+~JA^kzJs&&r?!uzKV&i7BhyG;ZzAYoGHQ!UkNW2O?$))({W;@58;aMHIOGn@%AJsy8Vz3^2q^tH9}wG*@PwtEx+0T9114@iWE zUr?7HBqqQw1{UQ4fy6){TD17Y{{Xmo*gDw<{W}08DkdN-1{V4k;A9w1`UrUTj~R44 r?0o~QyzKxowjS1Yj4Ezc4tB5YtZak42JFNil>jOVn(|e$mT&$CkHH7} literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_cd0a0a_256x240.png b/utilities/ondc-crypto-utility-master/docs/script-dir/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 0000000000000000000000000000000000000000..7e8ebc180a2d2a74739059799407b8b7b57a9092 GIT binary patch literal 4549 zcmeHK2U8PFw@yL`geFb85=9ZD1*F$df}vOGyaXvKy$K2df>fnT5l|3bse%xZCPhLK zq(s2bG?a)Sy-1T5a?x+*n|uGmeP(CR*`0mn>^?hl=A6f-#y6Q6_!s~H0J9!S#~c6v zp1FW6dYZF&QcwTzY=gzr&=N^tVEF&>Uj<|d!K-Hi*#?;#TL5@jZ-D7d+aKjhUB2ay za7XiT$P6-HQsvS@8Ne>u30;%65Ra9O$98#q8tPF*3bZzTz*N?kB)u+wBUmd+0T!5D z*<^r#Xj1>ZovB|~<30Q0ri+GeWcuAh#6Q2zf&gzD+|&Ui&|W~DEuelV+rTsX$43El z`#jYFfOD>TI+~UbzO6elx{w;!AbqIU%Q;US-y3k0y&ZS`{PXJ9%GKuT? zA=YB~_}-7h}grk~UMM~1{IJu5z36&nH&VPs=tlLlQ$TWf}@j0@_1Mr{7PN}kZ@ zU@9N%V%HL9eSE z*BdLzdW%d9Pf1SA5`lAsx?6C@pGL*pIra&^83Gx%WYG^8aT%R?OG4Ou=0P3R5)KZ5 z2&PGFszDp$u%zsXBYLrEImJ}xFS--_mkY=#l)@OKCnEoMOo8S*eqcoB^(_J&4tmM< zs4&xp4^NNgy&HVP!O(^_6JQclp)V-Ib9=q9aWcaz*Gx~fED_HM%LFsYU%*S)OnQwc zjLYYoLk)hxsCi6qp^!9HRp8G%b|f68yfB?n<^DBz9!E*WgJ2gV*g5_E7alHp*g2_wbc8Pw7*-B9ToxV53c2rO-Vs4Px{7M!NqIXUcMSHv1cqfD&&RnMQs) z8771gCX+j09M{&*+~vB&SSU^b{}8I6?+$$T9I*OL*{LYxAHX;*iW?dX43jc> zp~TZQLjbC#e#FPvV$ou|K+q=`%KR&iGq0m)&%Qcc{(18s?cH)B<=dn&oKq#&CVm$KVlo#Io;OGBX$ckfqw0sl%9n2giktQ~NFXr`I; z@h650el?%I!6y~!d;+G2vdswoOkzni?&A=OT9T`SipWyQFEyIunl_G*e?HE^ zx7hkb*WF(Q-{^pB`|k8FH76TXH6UL4I}2h>bLnbqDDskSJx^zYBqL{y$Sn($8Qire zMAVY2aEEb~T~WwSd>Zm#SF3TtfRem42m@SaPkNC3#AX)UgT%TW=5u7S=dxp|3h~tk+8yZee}?!M9HI@f1WTU?%HqiNq#8O^RmBZ`M8nW z4|fZvl;5BN{Lb=BYDGdiZ)y8 zAJE}UL0VRg6Y7k--*#>qd}SW1`t(XXl);%iKi{ne!56tAR#KrNk#?YdO;$EPr~Ghg zL?F4G51g8yyaYA|gz0Frg48>AICegIAO6!sUwFPVn!UV}NVFIh?iYutyf9vPz5yy( z6DHSbg~R&3N2@w%ro3d+aztG`xPRDrWGn*Y&;syq!6%Nw=lpy*v1>S; zz{fdE9!dF+My~C&wlU5dQQi|liohaCEU{7=clSmk*wsDU+doSXunDD0ppEf~z7_WK zr+{Ip?==2A3sWeggPH~cD#9z$y`Scm$bJE%)>E|H9P>`Q=3WWq&5Gckv?(2+idix- z=}@U*Mw5z1u`6g?w5skq?WtvLzqBse`dg0I`$C5Hc0=;s zkPHED_%Qv>At$X$ZQoAYc=|i@^yMF^9@eeSh=MAFRi5FHuyr-LC*Z!C9W%qiV99!$ z+O4V2zvRN1wsMwg1WGvGv~LqgOA2pQZi~E#pY5Lj`j`sW1jcRidq&GPu(oq7&iz*W zKqyJ$uZ1uC=#zeW>zJF-nx-gt-}Ak+qN{)H+eFKjl(8fvzoS10rN}hbM=2ZHn7&EW z&8^#HYV0+@3zAc}_pVhH22dU+MW5s4HwjodZU|T(EZaZ2D1Vuc&fO1}CSck5&kdJ% zi5gTPGKuKSk8XiGTl>tjIdMWO%>rJ^?&*|Ie1H+ zQLN{pqOrow2FVb%V>X_jBIhzH6s6~oS_oYp;iE>C%Z8w|lf!Ev?jfhYkP?FOAJ=__ zr3Ndn*>IP;iK|Ccxw##$W6H7snuYuHC7o)bP}ir&X4B|!Zd3cDm`a244dW*}1CN%5 zXbw16r3xZMsYF85zpYIaVr} z?@&!YCHZY9Dhmzcwq`}f17^3P{$})GtY|@wRkgs2TGgSwUV|As8%gAY&4}SLTG6V7 zW4_tEA;9}Q!A@(ZaEcrzDlf2bSL%{R)ka6gH9z06;tUEGAxQhi>~Q}sg1^506i46bzM;PHOzX~mY*`jhIiS}ZN2&$pmjO9S=Mj>^wMj=hEu zl~8}2{%}WDK+?okXRZA{H+!LjL{Qw9wi7vK1jiPkap+~_ak9^lCE_h!OeGWGGC-f1 zVRpAm`}*sOCzi+Ga`RF(!KxOX_nSKFZ%-ou%u?^0ue8}s6S?Xo-QGlc{EYuH{+mQ} z>M!OEuy)pxcgz<<{Cz|GC0u}FhbpDfLsov{TnAe9J`HN1 za$1aaKcULuO}iD`>6xOm$wW+_K_~{}#cJyGb!F&r_u_WE*8>}sUhJ6ueSj+chaBTO z_5$EOo-Ic;$S9Ktg;7Yrv0}eqi8w*$7sq2td!fj=Cb#w8?(xBoqj;W#K&Bk`$}tA3 z9AGH_)V?G6ZC=jUdQlN6RDFWODgd0RQQ;0q(jfFwegfKM0~6S+>;@7olQV~&k49?f4c6ReTPQa($S^cob|b_kZ$#iX{C8Kz*x0%0 zo>cBW9N_VWlazSRa?1##MXSou-fxeD!_&QLemU3-p!Hs?V4m6Uct-_K_|&bHnK!W$ zV;63=dGgzIvcKFCOuQk~(75AeyWPI#G+g@N6{x%iJmUeHX;4Zap?8EBjG*?Rg>>ai z2KP;zLI>J)rrvOVNW5NFP3LK%e~$B;2#8-H>%?dKvqQey7_%N$0BA{1=_#M`>JpGj zx^=X=@Ue4rw&8wAx+E@QbDpFk)D;j9<|OP%PJua#2WVcDDKfA63c=(IOQ-ItOLyLj z#xi9OEcg{vTTL1PH0YM4?khk(&TzrkU^aY+ypr5 z{jp4uL+LRby+u5hgmq)J$>w4X_2hrqq;M%gOnCFRl<7qk=J7~NV(r#;uVaI=;k)yH z3s|;iNg&Le8;yH+`qw4sWA#bWtE1?ftr!s26wPW{TB4{eZ7}vcT{CttS+z#yeHZD` z!Dm{7xPVwM1jvxV5cImPfv~WUzB0lD0V?KmAfl1#yl9`E3o(FJ-W+yQ`0C&D)y6G7Fqei&raMZE$9ts7fa z4f4?J_L;XiwLe#tFZPq{Hi=d2HL_a#J6156HfF@TAh; z*?Y}c7mP70lKYjiy#yEAjAE=?L_%I!DCR2DHw8zdS^Oe`Q{pKe%3AToxCN@8lKi~y z{NBUBt1t6X6V9;2e1t)uN}rcE_dBkxip3*do}=#z;&-%u?-?GxK;Dbzs!>Q^*6ptj zm^eD>*BoA?nOOnx9cmrMao0O|mq-wu>SauA6^XMeyN#cZXde*AQjDKU-aV#`nCYM! zK93Mnh)oEUJD3C2u*7fg1Z6u(rIWt=TFIqI@vO6HP*2{$Nfzqqt)jply2Pr`P1<{K zAJze>9Iexn7%VzWXJ<9dI_s1qgpT?U{aFjU?#mtfXwP1}`wno0q-!-Ch4te$o&7NO zv0K{_tOX8j$%GwNi1XUiA4V4r(b+)i-C0MYc`g)V`!_Vllu=)fmSLWy3MWmjV{~>( z2}Qmx;l8gN7vOQhu1Ct|e;v2u<}Z#5f0Ri`pg-r)`~A!ONc0I6kHauS0UE#sMlq4I z%K6CTTyOG<7_>u(<5A(mz`ps}+2ji&AfFQ+KjMEIGm>t=ebp$kBvqJzq Mq_Ix57W&cu0AIB!=l}o! literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/jquery-3.5.1.min.js b/utilities/ondc-crypto-utility-master/docs/script-dir/jquery-3.5.1.min.js new file mode 100644 index 0000000..b061403 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/script-dir/jquery-3.5.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):l=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
      ",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,l=/top|center|bottom/,h=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("
      "),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.widthi?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};h>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),l.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,l=n-r,h=r+e.collisionWidth-a-n;e.collisionWidth>a?l>0&&0>=h?(i=t.left+l+e.collisionWidth-a-n,t.left+=l-i):t.left=h>0&&0>=l?n:l>h?n+a-e.collisionWidth:n:l>0?t.left+=l:h>0?t.left-=h:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,l=n-r,h=r+e.collisionHeight-a-n;e.collisionHeight>a?l>0&&0>=h?(i=t.top+l+e.collisionHeight-a-n,t.top+=l-i):t.top=h>0&&0>=l?n:l>h?n+a-e.collisionHeight:n:l>0?t.top+=l:h>0?t.top-=h:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,l=n.isWindow?n.scrollLeft:n.offset.left,h=t.left-e.collisionPosition.marginLeft,c=h-l,u=h+e.collisionWidth-r-l,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-l,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,l=n.isWindow?n.scrollTop:n.offset.top,h=t.top-e.collisionPosition.marginTop,c=h-l,u=h+e.collisionHeight-r-l,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,g=-2*e.offset[1];0>c?(s=t.top+p+f+g+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+g)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+g-l,(i>0||u>a(i))&&(t.top+=p+f+g))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.safeActiveElement=function(t){var e;try{e=t.activeElement}catch(i){e=t.body}return e||(e=t.body),e.nodeName||(e=t.body),e},t.widget("ui.menu",{version:"1.12.1",defaultElement:"
        ",delay:300,options:{icons:{submenu:"ui-icon-caret-1-e"},items:"> *",menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.mouseHandled=!1,this.element.uniqueId().attr({role:this.options.role,tabIndex:0}),this._addClass("ui-menu","ui-widget ui-widget-content"),this._on({"mousedown .ui-menu-item":function(t){t.preventDefault()},"click .ui-menu-item":function(e){var i=t(e.target),s=t(t.ui.safeActiveElement(this.document[0]));!this.mouseHandled&&i.not(".ui-state-disabled").length&&(this.select(e),e.isPropagationStopped()||(this.mouseHandled=!0),i.has(".ui-menu").length?this.expand(e):!this.element.is(":focus")&&s.closest(".ui-menu").length&&(this.element.trigger("focus",[!0]),this.active&&1===this.active.parents(".ui-menu").length&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(e){if(!this.previousFilter){var i=t(e.target).closest(".ui-menu-item"),s=t(e.currentTarget);i[0]===s[0]&&(this._removeClass(s.siblings().children(".ui-state-active"),null,"ui-state-active"),this.focus(e,s))}},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(t,e){var i=this.active||this.element.find(this.options.items).eq(0);e||this.focus(t,i)},blur:function(e){this._delay(function(){var i=!t.contains(this.element[0],t.ui.safeActiveElement(this.document[0]));i&&this.collapseAll(e)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){this._closeOnDocumentClick(t)&&this.collapseAll(t),this.mouseHandled=!1}})},_destroy:function(){var e=this.element.find(".ui-menu-item").removeAttr("role aria-disabled"),i=e.children(".ui-menu-item-wrapper").removeUniqueId().removeAttr("tabIndex role aria-haspopup");this.element.removeAttr("aria-activedescendant").find(".ui-menu").addBack().removeAttr("role aria-labelledby aria-expanded aria-hidden aria-disabled tabIndex").removeUniqueId().show(),i.children().each(function(){var e=t(this);e.data("ui-menu-submenu-caret")&&e.remove()})},_keydown:function(e){var i,s,n,o,a=!0;switch(e.keyCode){case t.ui.keyCode.PAGE_UP:this.previousPage(e);break;case t.ui.keyCode.PAGE_DOWN:this.nextPage(e);break;case t.ui.keyCode.HOME:this._move("first","first",e);break;case t.ui.keyCode.END:this._move("last","last",e);break;case t.ui.keyCode.UP:this.previous(e);break;case t.ui.keyCode.DOWN:this.next(e);break;case t.ui.keyCode.LEFT:this.collapse(e);break;case t.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(e);break;case t.ui.keyCode.ENTER:case t.ui.keyCode.SPACE:this._activate(e);break;case t.ui.keyCode.ESCAPE:this.collapse(e);break;default:a=!1,s=this.previousFilter||"",o=!1,n=e.keyCode>=96&&105>=e.keyCode?""+(e.keyCode-96):String.fromCharCode(e.keyCode),clearTimeout(this.filterTimer),n===s?o=!0:n=s+n,i=this._filterMenuItems(n),i=o&&-1!==i.index(this.active.next())?this.active.nextAll(".ui-menu-item"):i,i.length||(n=String.fromCharCode(e.keyCode),i=this._filterMenuItems(n)),i.length?(this.focus(e,i),this.previousFilter=n,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter}a&&e.preventDefault()},_activate:function(t){this.active&&!this.active.is(".ui-state-disabled")&&(this.active.children("[aria-haspopup='true']").length?this.expand(t):this.select(t))},refresh:function(){var e,i,s,n,o,a=this,r=this.options.icons.submenu,l=this.element.find(this.options.menus);this._toggleClass("ui-menu-icons",null,!!this.element.find(".ui-icon").length),s=l.filter(":not(.ui-menu)").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var e=t(this),i=e.prev(),s=t("").data("ui-menu-submenu-caret",!0);a._addClass(s,"ui-menu-icon","ui-icon "+r),i.attr("aria-haspopup","true").prepend(s),e.attr("aria-labelledby",i.attr("id"))}),this._addClass(s,"ui-menu","ui-widget ui-widget-content ui-front"),e=l.add(this.element),i=e.find(this.options.items),i.not(".ui-menu-item").each(function(){var e=t(this);a._isDivider(e)&&a._addClass(e,"ui-menu-divider","ui-widget-content")}),n=i.not(".ui-menu-item, .ui-menu-divider"),o=n.children().not(".ui-menu").uniqueId().attr({tabIndex:-1,role:this._itemRole()}),this._addClass(n,"ui-menu-item")._addClass(o,"ui-menu-item-wrapper"),i.filter(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!t.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},_setOption:function(t,e){if("icons"===t){var i=this.element.find(".ui-menu-icon");this._removeClass(i,null,this.options.icons.submenu)._addClass(i,null,e.submenu)}this._super(t,e)},_setOptionDisabled:function(t){this._super(t),this.element.attr("aria-disabled",t+""),this._toggleClass(null,"ui-state-disabled",!!t)},focus:function(t,e){var i,s,n;this.blur(t,t&&"focus"===t.type),this._scrollIntoView(e),this.active=e.first(),s=this.active.children(".ui-menu-item-wrapper"),this._addClass(s,null,"ui-state-active"),this.options.role&&this.element.attr("aria-activedescendant",s.attr("id")),n=this.active.parent().closest(".ui-menu-item").children(".ui-menu-item-wrapper"),this._addClass(n,null,"ui-state-active"),t&&"keydown"===t.type?this._close():this.timer=this._delay(function(){this._close()},this.delay),i=e.children(".ui-menu"),i.length&&t&&/^mouse/.test(t.type)&&this._startOpening(i),this.activeMenu=e.parent(),this._trigger("focus",t,{item:e})},_scrollIntoView:function(e){var i,s,n,o,a,r;this._hasScroll()&&(i=parseFloat(t.css(this.activeMenu[0],"borderTopWidth"))||0,s=parseFloat(t.css(this.activeMenu[0],"paddingTop"))||0,n=e.offset().top-this.activeMenu.offset().top-i-s,o=this.activeMenu.scrollTop(),a=this.activeMenu.height(),r=e.outerHeight(),0>n?this.activeMenu.scrollTop(o+n):n+r>a&&this.activeMenu.scrollTop(o+n-a+r))},blur:function(t,e){e||clearTimeout(this.timer),this.active&&(this._removeClass(this.active.children(".ui-menu-item-wrapper"),null,"ui-state-active"),this._trigger("blur",t,{item:this.active}),this.active=null)},_startOpening:function(t){clearTimeout(this.timer),"true"===t.attr("aria-hidden")&&(this.timer=this._delay(function(){this._close(),this._open(t)},this.delay))},_open:function(e){var i=t.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(e.parents(".ui-menu")).hide().attr("aria-hidden","true"),e.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(i)},collapseAll:function(e,i){clearTimeout(this.timer),this.timer=this._delay(function(){var s=i?this.element:t(e&&e.target).closest(this.element.find(".ui-menu"));s.length||(s=this.element),this._close(s),this.blur(e),this._removeClass(s.find(".ui-state-active"),null,"ui-state-active"),this.activeMenu=s},this.delay)},_close:function(t){t||(t=this.active?this.active.parent():this.element),t.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false")},_closeOnDocumentClick:function(e){return!t(e.target).closest(".ui-menu").length},_isDivider:function(t){return!/[^\-\u2014\u2013\s]/.test(t.text())},collapse:function(t){var e=this.active&&this.active.parent().closest(".ui-menu-item",this.element);e&&e.length&&(this._close(),this.focus(t,e))},expand:function(t){var e=this.active&&this.active.children(".ui-menu ").find(this.options.items).first();e&&e.length&&(this._open(e.parent()),this._delay(function(){this.focus(t,e)}))},next:function(t){this._move("next","first",t)},previous:function(t){this._move("prev","last",t)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(t,e,i){var s;this.active&&(s="first"===t||"last"===t?this.active["first"===t?"prevAll":"nextAll"](".ui-menu-item").eq(-1):this.active[t+"All"](".ui-menu-item").eq(0)),s&&s.length&&this.active||(s=this.activeMenu.find(this.options.items)[e]()),this.focus(i,s)},nextPage:function(e){var i,s,n;return this.active?(this.isLastItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return i=t(this),0>i.offset().top-s-n}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items)[this.active?"last":"first"]())),void 0):(this.next(e),void 0)},previousPage:function(e){var i,s,n;return this.active?(this.isFirstItem()||(this._hasScroll()?(s=this.active.offset().top,n=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return i=t(this),i.offset().top-s+n>0}),this.focus(e,i)):this.focus(e,this.activeMenu.find(this.options.items).first())),void 0):(this.next(e),void 0)},_hasScroll:function(){return this.element.outerHeight()",options:{appendTo:null,autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},requestIndex:0,pending:0,_create:function(){var e,i,s,n=this.element[0].nodeName.toLowerCase(),o="textarea"===n,a="input"===n;this.isMultiLine=o||!a&&this._isContentEditable(this.element),this.valueMethod=this.element[o||a?"val":"text"],this.isNewMenu=!0,this._addClass("ui-autocomplete-input"),this.element.attr("autocomplete","off"),this._on(this.element,{keydown:function(n){if(this.element.prop("readOnly"))return e=!0,s=!0,i=!0,void 0;e=!1,s=!1,i=!1;var o=t.ui.keyCode;switch(n.keyCode){case o.PAGE_UP:e=!0,this._move("previousPage",n);break;case o.PAGE_DOWN:e=!0,this._move("nextPage",n);break;case o.UP:e=!0,this._keyEvent("previous",n);break;case o.DOWN:e=!0,this._keyEvent("next",n);break;case o.ENTER:this.menu.active&&(e=!0,n.preventDefault(),this.menu.select(n));break;case o.TAB:this.menu.active&&this.menu.select(n);break;case o.ESCAPE:this.menu.element.is(":visible")&&(this.isMultiLine||this._value(this.term),this.close(n),n.preventDefault());break;default:i=!0,this._searchTimeout(n)}},keypress:function(s){if(e)return e=!1,(!this.isMultiLine||this.menu.element.is(":visible"))&&s.preventDefault(),void 0;if(!i){var n=t.ui.keyCode;switch(s.keyCode){case n.PAGE_UP:this._move("previousPage",s);break;case n.PAGE_DOWN:this._move("nextPage",s);break;case n.UP:this._keyEvent("previous",s);break;case n.DOWN:this._keyEvent("next",s)}}},input:function(t){return s?(s=!1,t.preventDefault(),void 0):(this._searchTimeout(t),void 0)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(t){return this.cancelBlur?(delete this.cancelBlur,void 0):(clearTimeout(this.searching),this.close(t),this._change(t),void 0)}}),this._initSource(),this.menu=t("
          ").appendTo(this._appendTo()).menu({role:null}).hide().menu("instance"),this._addClass(this.menu.element,"ui-autocomplete","ui-front"),this._on(this.menu.element,{mousedown:function(e){e.preventDefault(),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,this.element[0]!==t.ui.safeActiveElement(this.document[0])&&this.element.trigger("focus")})},menufocus:function(e,i){var s,n;return this.isNewMenu&&(this.isNewMenu=!1,e.originalEvent&&/^mouse/.test(e.originalEvent.type))?(this.menu.blur(),this.document.one("mousemove",function(){t(e.target).trigger(e.originalEvent)}),void 0):(n=i.item.data("ui-autocomplete-item"),!1!==this._trigger("focus",e,{item:n})&&e.originalEvent&&/^key/.test(e.originalEvent.type)&&this._value(n.value),s=i.item.attr("aria-label")||n.value,s&&t.trim(s).length&&(this.liveRegion.children().hide(),t("
          ").text(s).appendTo(this.liveRegion)),void 0)},menuselect:function(e,i){var s=i.item.data("ui-autocomplete-item"),n=this.previous;this.element[0]!==t.ui.safeActiveElement(this.document[0])&&(this.element.trigger("focus"),this.previous=n,this._delay(function(){this.previous=n,this.selectedItem=s})),!1!==this._trigger("select",e,{item:s})&&this._value(s.value),this.term=this._value(),this.close(e),this.selectedItem=s}}),this.liveRegion=t("
          ",{role:"status","aria-live":"assertive","aria-relevant":"additions"}).appendTo(this.document[0].body),this._addClass(this.liveRegion,null,"ui-helper-hidden-accessible"),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_destroy:function(){clearTimeout(this.searching),this.element.removeAttr("autocomplete"),this.menu.element.remove(),this.liveRegion.remove()},_setOption:function(t,e){this._super(t,e),"source"===t&&this._initSource(),"appendTo"===t&&this.menu.element.appendTo(this._appendTo()),"disabled"===t&&e&&this.xhr&&this.xhr.abort()},_isEventTargetInWidget:function(e){var i=this.menu.element[0];return e.target===this.element[0]||e.target===i||t.contains(i,e.target)},_closeOnClickOutside:function(t){this._isEventTargetInWidget(t)||this.close()},_appendTo:function(){var e=this.options.appendTo;return e&&(e=e.jquery||e.nodeType?t(e):this.document.find(e).eq(0)),e&&e[0]||(e=this.element.closest(".ui-front, dialog")),e.length||(e=this.document[0].body),e},_initSource:function(){var e,i,s=this;t.isArray(this.options.source)?(e=this.options.source,this.source=function(i,s){s(t.ui.autocomplete.filter(e,i.term))}):"string"==typeof this.options.source?(i=this.options.source,this.source=function(e,n){s.xhr&&s.xhr.abort(),s.xhr=t.ajax({url:i,data:e,dataType:"json",success:function(t){n(t)},error:function(){n([])}})}):this.source=this.options.source},_searchTimeout:function(t){clearTimeout(this.searching),this.searching=this._delay(function(){var e=this.term===this._value(),i=this.menu.element.is(":visible"),s=t.altKey||t.ctrlKey||t.metaKey||t.shiftKey;(!e||e&&!i&&!s)&&(this.selectedItem=null,this.search(null,t))},this.options.delay)},search:function(t,e){return t=null!=t?t:this._value(),this.term=this._value(),t.length").append(t("
          ").text(i.label)).appendTo(e)},_move:function(t,e){return this.menu.element.is(":visible")?this.menu.isFirstItem()&&/^previous/.test(t)||this.menu.isLastItem()&&/^next/.test(t)?(this.isMultiLine||this._value(this.term),this.menu.blur(),void 0):(this.menu[t](e),void 0):(this.search(null,e),void 0)},widget:function(){return this.menu.element},_value:function(){return this.valueMethod.apply(this.element,arguments)},_keyEvent:function(t,e){(!this.isMultiLine||this.menu.element.is(":visible"))&&(this._move(t,e),e.preventDefault())},_isContentEditable:function(t){if(!t.length)return!1;var e=t.prop("contentEditable");return"inherit"===e?this._isContentEditable(t.parent()):"true"===e}}),t.extend(t.ui.autocomplete,{escapeRegex:function(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")},filter:function(e,i){var s=RegExp(t.ui.autocomplete.escapeRegex(i),"i");return t.grep(e,function(t){return s.test(t.label||t.value||t)})}}),t.widget("ui.autocomplete",t.ui.autocomplete,{options:{messages:{noResults:"No search results.",results:function(t){return t+(t>1?" results are":" result is")+" available, use up and down arrow keys to navigate."}}},__response:function(e){var i;this._superApply(arguments),this.options.disabled||this.cancelSearch||(i=e&&e.length?this.options.messages.results(e.length):this.options.messages.noResults,this.liveRegion.children().hide(),t("
          ").text(i).appendTo(this.liveRegion))}}),t.ui.autocomplete}); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/docs/script-dir/jquery-ui.structure.min.css b/utilities/ondc-crypto-utility-master/docs/script-dir/jquery-ui.structure.min.css new file mode 100644 index 0000000..e880892 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/script-dir/jquery-ui.structure.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.12.1 - 2018-12-06 +* http://jqueryui.com +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-autocomplete{position:absolute;top:0;left:0;cursor:default}.ui-menu{list-style:none;padding:0;margin:0;display:block;outline:0}.ui-menu .ui-menu{position:absolute}.ui-menu .ui-menu-item{margin:0;cursor:pointer;list-style-image:url("data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7")}.ui-menu .ui-menu-item-wrapper{position:relative;padding:3px 1em 3px .4em}.ui-menu .ui-menu-divider{margin:5px 0;height:0;font-size:0;line-height:0;border-width:1px 0 0 0}.ui-menu .ui-state-focus,.ui-menu .ui-state-active{margin:-1px}.ui-menu-icons{position:relative}.ui-menu-icons .ui-menu-item-wrapper{padding-left:2em}.ui-menu .ui-icon{position:absolute;top:0;bottom:0;left:.2em;margin:auto 0}.ui-menu .ui-menu-icon{left:auto;right:0} \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/docs/script.js b/utilities/ondc-crypto-utility-master/docs/script.js new file mode 100644 index 0000000..864989c --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/script.js @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +var moduleSearchIndex; +var packageSearchIndex; +var typeSearchIndex; +var memberSearchIndex; +var tagSearchIndex; +function loadScripts(doc, tag) { + createElem(doc, tag, 'search.js'); + + createElem(doc, tag, 'module-search-index.js'); + createElem(doc, tag, 'package-search-index.js'); + createElem(doc, tag, 'type-search-index.js'); + createElem(doc, tag, 'member-search-index.js'); + createElem(doc, tag, 'tag-search-index.js'); +} + +function createElem(doc, tag, path) { + var script = doc.createElement(tag); + var scriptElement = doc.getElementsByTagName(tag)[0]; + script.src = pathtoroot + path; + scriptElement.parentNode.insertBefore(script, scriptElement); +} + +function show(tableId, selected, columns) { + if (tableId !== selected) { + document.querySelectorAll('div.' + tableId + ':not(.' + selected + ')') + .forEach(function(elem) { + elem.style.display = 'none'; + }); + } + document.querySelectorAll('div.' + selected) + .forEach(function(elem, index) { + elem.style.display = ''; + var isEvenRow = index % (columns * 2) < columns; + elem.classList.remove(isEvenRow ? oddRowColor : evenRowColor); + elem.classList.add(isEvenRow ? evenRowColor : oddRowColor); + }); + updateTabs(tableId, selected); +} + +function updateTabs(tableId, selected) { + document.querySelector('div#' + tableId +' .summary-table') + .setAttribute('aria-labelledby', selected); + document.querySelectorAll('button[id^="' + tableId + '"]') + .forEach(function(tab, index) { + if (selected === tab.id || (tableId === selected && index === 0)) { + tab.className = activeTableTab; + tab.setAttribute('aria-selected', true); + tab.setAttribute('tabindex',0); + } else { + tab.className = tableTab; + tab.setAttribute('aria-selected', false); + tab.setAttribute('tabindex',-1); + } + }); +} + +function switchTab(e) { + var selected = document.querySelector('[aria-selected=true]'); + if (selected) { + if ((e.keyCode === 37 || e.keyCode === 38) && selected.previousSibling) { + // left or up arrow key pressed: move focus to previous tab + selected.previousSibling.click(); + selected.previousSibling.focus(); + e.preventDefault(); + } else if ((e.keyCode === 39 || e.keyCode === 40) && selected.nextSibling) { + // right or down arrow key pressed: move focus to next tab + selected.nextSibling.click(); + selected.nextSibling.focus(); + e.preventDefault(); + } + } +} + +var updateSearchResults = function() {}; + +function indexFilesLoaded() { + return moduleSearchIndex + && packageSearchIndex + && typeSearchIndex + && memberSearchIndex + && tagSearchIndex; +} + +// Workaround for scroll position not being included in browser history (8249133) +document.addEventListener("DOMContentLoaded", function(e) { + var contentDiv = document.querySelector("div.flex-content"); + window.addEventListener("popstate", function(e) { + if (e.state !== null) { + contentDiv.scrollTop = e.state; + } + }); + window.addEventListener("hashchange", function(e) { + history.replaceState(contentDiv.scrollTop, document.title); + }); + contentDiv.addEventListener("scroll", function(e) { + var timeoutID; + if (!timeoutID) { + timeoutID = setTimeout(function() { + history.replaceState(contentDiv.scrollTop, document.title); + timeoutID = null; + }, 100); + } + }); + if (!location.hash) { + history.replaceState(contentDiv.scrollTop, document.title); + } +}); diff --git a/utilities/ondc-crypto-utility-master/docs/search.js b/utilities/ondc-crypto-utility-master/docs/search.js new file mode 100644 index 0000000..2246cdd --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/search.js @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +var noResult = {l: "No results found"}; +var loading = {l: "Loading search index..."}; +var catModules = "Modules"; +var catPackages = "Packages"; +var catTypes = "Types"; +var catMembers = "Members"; +var catSearchTags = "Search Tags"; +var highlight = "$&"; +var searchPattern = ""; +var fallbackPattern = ""; +var RANKING_THRESHOLD = 2; +var NO_MATCH = 0xffff; +var MIN_RESULTS = 3; +var MAX_RESULTS = 500; +var UNNAMED = ""; +function escapeHtml(str) { + return str.replace(//g, ">"); +} +function getHighlightedText(item, matcher, fallbackMatcher) { + var escapedItem = escapeHtml(item); + var highlighted = escapedItem.replace(matcher, highlight); + if (highlighted === escapedItem) { + highlighted = escapedItem.replace(fallbackMatcher, highlight) + } + return highlighted; +} +function getURLPrefix(ui) { + var urlPrefix=""; + var slash = "/"; + if (ui.item.category === catModules) { + return ui.item.l + slash; + } else if (ui.item.category === catPackages && ui.item.m) { + return ui.item.m + slash; + } else if (ui.item.category === catTypes || ui.item.category === catMembers) { + if (ui.item.m) { + urlPrefix = ui.item.m + slash; + } else { + $.each(packageSearchIndex, function(index, item) { + if (item.m && ui.item.p === item.l) { + urlPrefix = item.m + slash; + } + }); + } + } + return urlPrefix; +} +function createSearchPattern(term) { + var pattern = ""; + var isWordToken = false; + term.replace(/,\s*/g, ", ").trim().split(/\s+/).forEach(function(w, index) { + if (index > 0) { + // whitespace between identifiers is significant + pattern += (isWordToken && /^\w/.test(w)) ? "\\s+" : "\\s*"; + } + var tokens = w.split(/(?=[A-Z,.()<>[\/])/); + for (var i = 0; i < tokens.length; i++) { + var s = tokens[i]; + if (s === "") { + continue; + } + pattern += $.ui.autocomplete.escapeRegex(s); + isWordToken = /\w$/.test(s); + if (isWordToken) { + pattern += "([a-z0-9_$<>\\[\\]]*?)"; + } + } + }); + return pattern; +} +function createMatcher(pattern, flags) { + var isCamelCase = /[A-Z]/.test(pattern); + return new RegExp(pattern, flags + (isCamelCase ? "" : "i")); +} +var watermark = 'Search'; +$(function() { + var search = $("#search-input"); + var reset = $("#reset-button"); + search.val(''); + search.prop("disabled", false); + reset.prop("disabled", false); + search.val(watermark).addClass('watermark'); + search.blur(function() { + if ($(this).val().length === 0) { + $(this).val(watermark).addClass('watermark'); + } + }); + search.on('click keydown paste', function() { + if ($(this).val() === watermark) { + $(this).val('').removeClass('watermark'); + } + }); + reset.click(function() { + search.val('').focus(); + }); + search.focus()[0].setSelectionRange(0, 0); +}); +$.widget("custom.catcomplete", $.ui.autocomplete, { + _create: function() { + this._super(); + this.widget().menu("option", "items", "> :not(.ui-autocomplete-category)"); + }, + _renderMenu: function(ul, items) { + var rMenu = this; + var currentCategory = ""; + rMenu.menu.bindings = $(); + $.each(items, function(index, item) { + var li; + if (item.category && item.category !== currentCategory) { + ul.append("
        • " + item.category + "
        • "); + currentCategory = item.category; + } + li = rMenu._renderItemData(ul, item); + if (item.category) { + li.attr("aria-label", item.category + " : " + item.l); + li.attr("class", "result-item"); + } else { + li.attr("aria-label", item.l); + li.attr("class", "result-item"); + } + }); + }, + _renderItem: function(ul, item) { + var label = ""; + var matcher = createMatcher(escapeHtml(searchPattern), "g"); + var fallbackMatcher = new RegExp(fallbackPattern, "gi") + if (item.category === catModules) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catPackages) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catTypes) { + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.l, matcher, fallbackMatcher) + : getHighlightedText(item.l, matcher, fallbackMatcher); + } else if (item.category === catMembers) { + label = (item.p && item.p !== UNNAMED) + ? getHighlightedText(item.p + "." + item.c + "." + item.l, matcher, fallbackMatcher) + : getHighlightedText(item.c + "." + item.l, matcher, fallbackMatcher); + } else if (item.category === catSearchTags) { + label = getHighlightedText(item.l, matcher, fallbackMatcher); + } else { + label = item.l; + } + var li = $("
        • ").appendTo(ul); + var div = $("
          ").appendTo(li); + if (item.category === catSearchTags && item.h) { + if (item.d) { + div.html(label + " (" + item.h + ")
          " + + item.d + "
          "); + } else { + div.html(label + " (" + item.h + ")"); + } + } else { + if (item.m) { + div.html(item.m + "/" + label); + } else { + div.html(label); + } + } + return li; + } +}); +function rankMatch(match, category) { + if (!match) { + return NO_MATCH; + } + var index = match.index; + var input = match.input; + var leftBoundaryMatch = 2; + var periferalMatch = 0; + // make sure match is anchored on a left word boundary + if (index === 0 || /\W/.test(input[index - 1]) || "_" === input[index]) { + leftBoundaryMatch = 0; + } else if ("_" === input[index - 1] || (input[index] === input[index].toUpperCase() && !/^[A-Z0-9_$]+$/.test(input))) { + leftBoundaryMatch = 1; + } + var matchEnd = index + match[0].length; + var leftParen = input.indexOf("("); + var endOfName = leftParen > -1 ? leftParen : input.length; + // exclude peripheral matches + if (category !== catModules && category !== catSearchTags) { + var delim = category === catPackages ? "/" : "."; + if (leftParen > -1 && leftParen < index) { + periferalMatch += 2; + } else if (input.lastIndexOf(delim, endOfName) >= matchEnd) { + periferalMatch += 2; + } + } + var delta = match[0].length === endOfName ? 0 : 1; // rank full match higher than partial match + for (var i = 1; i < match.length; i++) { + // lower ranking if parts of the name are missing + if (match[i]) + delta += match[i].length; + } + if (category === catTypes) { + // lower ranking if a type name contains unmatched camel-case parts + if (/[A-Z]/.test(input.substring(matchEnd))) + delta += 5; + if (/[A-Z]/.test(input.substring(0, index))) + delta += 5; + } + return leftBoundaryMatch + periferalMatch + (delta / 200); + +} +function doSearch(request, response) { + var result = []; + searchPattern = createSearchPattern(request.term); + fallbackPattern = createSearchPattern(request.term.toLowerCase()); + if (searchPattern === "") { + return this.close(); + } + var camelCaseMatcher = createMatcher(searchPattern, ""); + var fallbackMatcher = new RegExp(fallbackPattern, "i"); + + function searchIndexWithMatcher(indexArray, matcher, category, nameFunc) { + if (indexArray) { + var newResults = []; + $.each(indexArray, function (i, item) { + item.category = category; + var ranking = rankMatch(matcher.exec(nameFunc(item)), category); + if (ranking < RANKING_THRESHOLD) { + newResults.push({ranking: ranking, item: item}); + } + return newResults.length <= MAX_RESULTS; + }); + return newResults.sort(function(e1, e2) { + return e1.ranking - e2.ranking; + }).map(function(e) { + return e.item; + }); + } + return []; + } + function searchIndex(indexArray, category, nameFunc) { + var primaryResults = searchIndexWithMatcher(indexArray, camelCaseMatcher, category, nameFunc); + result = result.concat(primaryResults); + if (primaryResults.length <= MIN_RESULTS && !camelCaseMatcher.ignoreCase) { + var secondaryResults = searchIndexWithMatcher(indexArray, fallbackMatcher, category, nameFunc); + result = result.concat(secondaryResults.filter(function (item) { + return primaryResults.indexOf(item) === -1; + })); + } + } + + searchIndex(moduleSearchIndex, catModules, function(item) { return item.l; }); + searchIndex(packageSearchIndex, catPackages, function(item) { + return (item.m && request.term.indexOf("/") > -1) + ? (item.m + "/" + item.l) : item.l; + }); + searchIndex(typeSearchIndex, catTypes, function(item) { + return request.term.indexOf(".") > -1 ? item.p + "." + item.l : item.l; + }); + searchIndex(memberSearchIndex, catMembers, function(item) { + return request.term.indexOf(".") > -1 + ? item.p + "." + item.c + "." + item.l : item.l; + }); + searchIndex(tagSearchIndex, catSearchTags, function(item) { return item.l; }); + + if (!indexFilesLoaded()) { + updateSearchResults = function() { + doSearch(request, response); + } + result.unshift(loading); + } else { + updateSearchResults = function() {}; + } + response(result); +} +$(function() { + $("#search-input").catcomplete({ + minLength: 1, + delay: 300, + source: doSearch, + response: function(event, ui) { + if (!ui.content.length) { + ui.content.push(noResult); + } else { + $("#search-input").empty(); + } + }, + autoFocus: true, + focus: function(event, ui) { + return false; + }, + position: { + collision: "flip" + }, + select: function(event, ui) { + if (ui.item.category) { + var url = getURLPrefix(ui); + if (ui.item.category === catModules) { + url += "module-summary.html"; + } else if (ui.item.category === catPackages) { + if (ui.item.u) { + url = ui.item.u; + } else { + url += ui.item.l.replace(/\./g, '/') + "/package-summary.html"; + } + } else if (ui.item.category === catTypes) { + if (ui.item.u) { + url = ui.item.u; + } else if (ui.item.p === UNNAMED) { + url += ui.item.l + ".html"; + } else { + url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.l + ".html"; + } + } else if (ui.item.category === catMembers) { + if (ui.item.p === UNNAMED) { + url += ui.item.c + ".html" + "#"; + } else { + url += ui.item.p.replace(/\./g, '/') + "/" + ui.item.c + ".html" + "#"; + } + if (ui.item.u) { + url += ui.item.u; + } else { + url += ui.item.l; + } + } else if (ui.item.category === catSearchTags) { + url += ui.item.u; + } + if (top !== window) { + parent.classFrame.location = pathtoroot + url; + } else { + window.location.href = pathtoroot + url; + } + $("#search-input").focus(); + } + } + }); +}); diff --git a/utilities/ondc-crypto-utility-master/docs/stylesheet.css b/utilities/ondc-crypto-utility-master/docs/stylesheet.css new file mode 100644 index 0000000..836c62d --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/stylesheet.css @@ -0,0 +1,865 @@ +/* + * Javadoc style sheet + */ + +@import url('resources/fonts/dejavu.css'); + +/* + * Styles for individual HTML elements. + * + * These are styles that are specific to individual HTML elements. Changing them affects the style of a particular + * HTML element throughout the page. + */ + +body { + background-color:#ffffff; + color:#353833; + font-family:'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:14px; + margin:0; + padding:0; + height:100%; + width:100%; +} +iframe { + margin:0; + padding:0; + height:100%; + width:100%; + overflow-y:scroll; + border:none; +} +a:link, a:visited { + text-decoration:none; + color:#4A6782; +} +a[href]:hover, a[href]:focus { + text-decoration:none; + color:#bb7a2a; +} +a[name] { + color:#353833; +} +pre { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; +} +h1 { + font-size:20px; +} +h2 { + font-size:18px; +} +h3 { + font-size:16px; +} +h4 { + font-size:15px; +} +h5 { + font-size:14px; +} +h6 { + font-size:13px; +} +ul { + list-style-type:disc; +} +code, tt { + font-family:'DejaVu Sans Mono', monospace; +} +:not(h1, h2, h3, h4, h5, h6) > code, +:not(h1, h2, h3, h4, h5, h6) > tt { + font-size:14px; + padding-top:4px; + margin-top:8px; + line-height:1.4em; +} +dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + padding-top:4px; +} +.summary-table dt code { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + vertical-align:top; + padding-top:4px; +} +sup { + font-size:8px; +} +button { + font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size: 14px; +} +/* + * Styles for HTML generated by javadoc. + * + * These are style classes that are used by the standard doclet to generate HTML documentation. + */ + +/* + * Styles for document title and copyright. + */ +.clear { + clear:both; + height:0; + overflow:hidden; +} +.about-language { + float:right; + padding:0 21px 8px 8px; + font-size:11px; + margin-top:-9px; + height:2.9em; +} +.legal-copy { + margin-left:.5em; +} +.tab { + background-color:#0066FF; + color:#ffffff; + padding:8px; + width:5em; + font-weight:bold; +} +/* + * Styles for navigation bar. + */ +@media screen { + .flex-box { + position:fixed; + display:flex; + flex-direction:column; + height: 100%; + width: 100%; + } + .flex-header { + flex: 0 0 auto; + } + .flex-content { + flex: 1 1 auto; + overflow-y: auto; + } +} +.top-nav { + background-color:#4D7A97; + color:#FFFFFF; + float:left; + padding:0; + width:100%; + clear:right; + min-height:2.8em; + padding-top:10px; + overflow:hidden; + font-size:12px; +} +.sub-nav { + background-color:#dee3e9; + float:left; + width:100%; + overflow:hidden; + font-size:12px; +} +.sub-nav div { + clear:left; + float:left; + padding:0 0 5px 6px; + text-transform:uppercase; +} +.sub-nav .nav-list { + padding-top:5px; +} +ul.nav-list { + display:block; + margin:0 25px 0 0; + padding:0; +} +ul.sub-nav-list { + float:left; + margin:0 25px 0 0; + padding:0; +} +ul.nav-list li { + list-style:none; + float:left; + padding: 5px 6px; + text-transform:uppercase; +} +.sub-nav .nav-list-search { + float:right; + margin:0 0 0 0; + padding:5px 6px; + clear:none; +} +.nav-list-search label { + position:relative; + right:-16px; +} +ul.sub-nav-list li { + list-style:none; + float:left; + padding-top:10px; +} +.top-nav a:link, .top-nav a:active, .top-nav a:visited { + color:#FFFFFF; + text-decoration:none; + text-transform:uppercase; +} +.top-nav a:hover { + text-decoration:none; + color:#bb7a2a; + text-transform:uppercase; +} +.nav-bar-cell1-rev { + background-color:#F8981D; + color:#253441; + margin: auto 5px; +} +.skip-nav { + position:absolute; + top:auto; + left:-9999px; + overflow:hidden; +} +/* + * Hide navigation links and search box in print layout + */ +@media print { + ul.nav-list, div.sub-nav { + display:none; + } +} +/* + * Styles for page header and footer. + */ +.title { + color:#2c4557; + margin:10px 0; +} +.sub-title { + margin:5px 0 0 0; +} +.header ul { + margin:0 0 15px 0; + padding:0; +} +.header ul li, .footer ul li { + list-style:none; + font-size:13px; +} +/* + * Styles for headings. + */ +body.class-declaration-page .summary h2, +body.class-declaration-page .details h2, +body.class-use-page h2, +body.module-declaration-page .block-list h2 { + font-style: italic; + padding:0; + margin:15px 0; +} +body.class-declaration-page .summary h3, +body.class-declaration-page .details h3, +body.class-declaration-page .summary .inherited-list h2 { + background-color:#dee3e9; + border:1px solid #d0d9e0; + margin:0 0 6px -8px; + padding:7px 5px; +} +/* + * Styles for page layout containers. + */ +main { + clear:both; + padding:10px 20px; + position:relative; +} +dl.notes > dt { + font-family: 'DejaVu Sans', Arial, Helvetica, sans-serif; + font-size:12px; + font-weight:bold; + margin:10px 0 0 0; + color:#4E4E4E; +} +dl.notes > dd { + margin:5px 10px 10px 0; + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} +dl.name-value > dt { + margin-left:1px; + font-size:1.1em; + display:inline; + font-weight:bold; +} +dl.name-value > dd { + margin:0 0 0 1px; + font-size:1.1em; + display:inline; +} +/* + * Styles for lists. + */ +li.circle { + list-style:circle; +} +ul.horizontal li { + display:inline; + font-size:0.9em; +} +div.inheritance { + margin:0; + padding:0; +} +div.inheritance div.inheritance { + margin-left:2em; +} +ul.block-list, +ul.details-list, +ul.member-list, +ul.summary-list { + margin:10px 0 10px 0; + padding:0; +} +ul.block-list > li, +ul.details-list > li, +ul.member-list > li, +ul.summary-list > li { + list-style:none; + margin-bottom:15px; + line-height:1.4; +} +.summary-table dl, .summary-table dl dt, .summary-table dl dd { + margin-top:0; + margin-bottom:1px; +} +ul.see-list, ul.see-list-long { + padding-left: 0; + list-style: none; +} +ul.see-list li { + display: inline; +} +ul.see-list li:not(:last-child):after, +ul.see-list-long li:not(:last-child):after { + content: ", "; + white-space: pre-wrap; +} +/* + * Styles for tables. + */ +.summary-table, .details-table { + width:100%; + border-spacing:0; + border-left:1px solid #EEE; + border-right:1px solid #EEE; + border-bottom:1px solid #EEE; + padding:0; +} +.caption { + position:relative; + text-align:left; + background-repeat:no-repeat; + color:#253441; + font-weight:bold; + clear:none; + overflow:hidden; + padding:0; + padding-top:10px; + padding-left:1px; + margin:0; + white-space:pre; +} +.caption a:link, .caption a:visited { + color:#1f389c; +} +.caption a:hover, +.caption a:active { + color:#FFFFFF; +} +.caption span { + white-space:nowrap; + padding-top:5px; + padding-left:12px; + padding-right:12px; + padding-bottom:7px; + display:inline-block; + float:left; + background-color:#F8981D; + border: none; + height:16px; +} +div.table-tabs { + padding:10px 0 0 1px; + margin:0; +} +div.table-tabs > button { + border: none; + cursor: pointer; + padding: 5px 12px 7px 12px; + font-weight: bold; + margin-right: 3px; +} +div.table-tabs > button.active-table-tab { + background: #F8981D; + color: #253441; +} +div.table-tabs > button.table-tab { + background: #4D7A97; + color: #FFFFFF; +} +.two-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); +} +.three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(15%, max-content) minmax(15%, auto); +} +.four-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(10%, max-content) minmax(10%, max-content) minmax(10%, auto); +} +@media screen and (max-width: 600px) { + .two-column-summary { + display: grid; + grid-template-columns: 1fr; + } +} +@media screen and (max-width: 800px) { + .three-column-summary { + display: grid; + grid-template-columns: minmax(10%, max-content) minmax(25%, auto); + } + .three-column-summary .col-last { + grid-column-end: span 2; + } +} +@media screen and (max-width: 1000px) { + .four-column-summary { + display: grid; + grid-template-columns: minmax(15%, max-content) minmax(15%, auto); + } +} +.summary-table > div, .details-table > div { + text-align:left; + padding: 8px 3px 3px 7px; +} +.col-first, .col-second, .col-last, .col-constructor-name, .col-summary-item-name { + vertical-align:top; + padding-right:0; + padding-top:8px; + padding-bottom:3px; +} +.table-header { + background:#dee3e9; + font-weight: bold; +} +.col-first, .col-first { + font-size:13px; +} +.col-second, .col-second, .col-last, .col-constructor-name, .col-summary-item-name, .col-last { + font-size:13px; +} +.col-first, .col-second, .col-constructor-name { + vertical-align:top; + overflow: auto; +} +.col-last { + white-space:normal; +} +.col-first a:link, .col-first a:visited, +.col-second a:link, .col-second a:visited, +.col-first a:link, .col-first a:visited, +.col-second a:link, .col-second a:visited, +.col-constructor-name a:link, .col-constructor-name a:visited, +.col-summary-item-name a:link, .col-summary-item-name a:visited, +.constant-values-container a:link, .constant-values-container a:visited, +.all-classes-container a:link, .all-classes-container a:visited, +.all-packages-container a:link, .all-packages-container a:visited { + font-weight:bold; +} +.table-sub-heading-color { + background-color:#EEEEFF; +} +.even-row-color, .even-row-color .table-header { + background-color:#FFFFFF; +} +.odd-row-color, .odd-row-color .table-header { + background-color:#EEEEEF; +} +/* + * Styles for contents. + */ +.deprecated-content { + margin:0; + padding:10px 0; +} +div.block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; +} +.col-last div { + padding-top:0; +} +.col-last a { + padding-bottom:3px; +} +.module-signature, +.package-signature, +.type-signature, +.member-signature { + font-family:'DejaVu Sans Mono', monospace; + font-size:14px; + margin:14px 0; + white-space: pre-wrap; +} +.module-signature, +.package-signature, +.type-signature { + margin-top: 0; +} +.member-signature .type-parameters-long, +.member-signature .parameters, +.member-signature .exceptions { + display: inline-block; + vertical-align: top; + white-space: pre; +} +.member-signature .type-parameters { + white-space: normal; +} +/* + * Styles for formatting effect. + */ +.source-line-no { + color:green; + padding:0 30px 0 0; +} +h1.hidden { + visibility:hidden; + overflow:hidden; + font-size:10px; +} +.block { + display:block; + margin:0 10px 5px 0; + color:#474747; +} +.deprecated-label, .descfrm-type-label, .implementation-label, .member-name-label, .member-name-link, +.module-label-in-package, .module-label-in-type, .override-specify-label, .package-label-in-type, +.package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label { + font-weight:bold; +} +.deprecation-comment, .help-footnote, .preview-comment { + font-style:italic; +} +.deprecation-block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + border-style:solid; + border-width:thin; + border-radius:10px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +.preview-block { + font-size:14px; + font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif; + border-style:solid; + border-width:thin; + border-radius:10px; + padding:10px; + margin-bottom:10px; + margin-right:10px; + display:inline-block; +} +div.block div.deprecation-comment { + font-style:normal; +} +/* + * Styles specific to HTML5 elements. + */ +main, nav, header, footer, section { + display:block; +} +/* + * Styles for javadoc search. + */ +.ui-autocomplete-category { + font-weight:bold; + font-size:15px; + padding:7px 0 7px 3px; + background-color:#4D7A97; + color:#FFFFFF; +} +.result-item { + font-size:13px; +} +.ui-autocomplete { + max-height:85%; + max-width:65%; + overflow-y:scroll; + overflow-x:scroll; + white-space:nowrap; + box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); +} +ul.ui-autocomplete { + position:fixed; + z-index:999999; +} +ul.ui-autocomplete li { + float:left; + clear:both; + width:100%; +} +.result-highlight { + font-weight:bold; +} +#search-input { + background-image:url('resources/glass.png'); + background-size:13px; + background-repeat:no-repeat; + background-position:2px 3px; + padding-left:20px; + position:relative; + right:-18px; + width:400px; +} +#reset-button { + background-color: rgb(255,255,255); + background-image:url('resources/x.png'); + background-position:center; + background-repeat:no-repeat; + background-size:12px; + border:0 none; + width:16px; + height:16px; + position:relative; + left:-4px; + top:-4px; + font-size:0px; +} +.watermark { + color:#545454; +} +.search-tag-desc-result { + font-style:italic; + font-size:11px; +} +.search-tag-holder-result { + font-style:italic; + font-size:12px; +} +.search-tag-result:target { + background-color:yellow; +} +.module-graph span { + display:none; + position:absolute; +} +.module-graph:hover span { + display:block; + margin: -100px 0 0 100px; + z-index: 1; +} +.inherited-list { + margin: 10px 0 10px 0; +} +section.class-description { + line-height: 1.4; +} +.summary section[class$="-summary"], .details section[class$="-details"], +.class-uses .detail, .serialized-class-details { + padding: 0px 20px 5px 10px; + border: 1px solid #ededed; + background-color: #f8f8f8; +} +.inherited-list, section[class$="-details"] .detail { + padding:0 0 5px 8px; + background-color:#ffffff; + border:none; +} +.vertical-separator { + padding: 0 5px; +} +ul.help-section-list { + margin: 0; +} +ul.help-subtoc > li { + display: inline-block; + padding-right: 5px; + font-size: smaller; +} +ul.help-subtoc > li::before { + content: "\2022" ; + padding-right:2px; +} +span.help-note { + font-style: italic; +} +/* + * Indicator icon for external links. + */ +main a[href*="://"]::after { + content:""; + display:inline-block; + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); + background-size:100% 100%; + width:7px; + height:7px; + margin-left:2px; + margin-bottom:4px; +} +main a[href*="://"]:hover::after, +main a[href*="://"]:focus::after { + background-image:url('data:image/svg+xml; utf8, \ + \ + \ + '); +} + +/* + * Styles for user-provided tables. + * + * borderless: + * No borders, vertical margins, styled caption. + * This style is provided for use with existing doc comments. + * In general, borderless tables should not be used for layout purposes. + * + * plain: + * Plain borders around table and cells, vertical margins, styled caption. + * Best for small tables or for complex tables for tables with cells that span + * rows and columns, when the "striped" style does not work well. + * + * striped: + * Borders around the table and vertical borders between cells, striped rows, + * vertical margins, styled caption. + * Best for tables that have a header row, and a body containing a series of simple rows. + */ + +table.borderless, +table.plain, +table.striped { + margin-top: 10px; + margin-bottom: 10px; +} +table.borderless > caption, +table.plain > caption, +table.striped > caption { + font-weight: bold; + font-size: smaller; +} +table.borderless th, table.borderless td, +table.plain th, table.plain td, +table.striped th, table.striped td { + padding: 2px 5px; +} +table.borderless, +table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th, +table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td { + border: none; +} +table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr { + background-color: transparent; +} +table.plain { + border-collapse: collapse; + border: 1px solid black; +} +table.plain > thead > tr, table.plain > tbody tr, table.plain > tr { + background-color: transparent; +} +table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th, +table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td { + border: 1px solid black; +} +table.striped { + border-collapse: collapse; + border: 1px solid black; +} +table.striped > thead { + background-color: #E3E3E3; +} +table.striped > thead > tr > th, table.striped > thead > tr > td { + border: 1px solid black; +} +table.striped > tbody > tr:nth-child(even) { + background-color: #EEE +} +table.striped > tbody > tr:nth-child(odd) { + background-color: #FFF +} +table.striped > tbody > tr > th, table.striped > tbody > tr > td { + border-left: 1px solid black; + border-right: 1px solid black; +} +table.striped > tbody > tr > th { + font-weight: normal; +} +/** + * Tweak font sizes and paddings for small screens. + */ +@media screen and (max-width: 1050px) { + #search-input { + width: 300px; + } +} +@media screen and (max-width: 800px) { + #search-input { + width: 200px; + } + .top-nav, + .bottom-nav { + font-size: 11px; + padding-top: 6px; + } + .sub-nav { + font-size: 11px; + } + .about-language { + padding-right: 16px; + } + ul.nav-list li, + .sub-nav .nav-list-search { + padding: 6px; + } + ul.sub-nav-list li { + padding-top: 5px; + } + main { + padding: 10px; + } + .summary section[class$="-summary"], .details section[class$="-details"], + .class-uses .detail, .serialized-class-details { + padding: 0 8px 5px 8px; + } + body { + -webkit-text-size-adjust: none; + } +} +@media screen and (max-width: 500px) { + #search-input { + width: 150px; + } + .top-nav, + .bottom-nav { + font-size: 10px; + } + .sub-nav { + font-size: 10px; + } + .about-language { + font-size: 10px; + padding-right: 12px; + } +} diff --git a/utilities/ondc-crypto-utility-master/docs/tag-search-index.js b/utilities/ondc-crypto-utility-master/docs/tag-search-index.js new file mode 100644 index 0000000..0367dae --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/tag-search-index.js @@ -0,0 +1 @@ +tagSearchIndex = [];updateSearchResults(); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/docs/type-search-index.js b/utilities/ondc-crypto-utility-master/docs/type-search-index.js new file mode 100644 index 0000000..d90ed03 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/docs/type-search-index.js @@ -0,0 +1 @@ +typeSearchIndex = [{"l":"All Classes and Interfaces","u":"allclasses-index.html"},{"p":"org.ondc.crypto.util","l":"CryptoFunctions"},{"p":"org.ondc.crypto.util","l":"CryptoKeyPair"},{"p":"org.ondc.crypto.util","l":"CryptoTest"}];updateSearchResults(); \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/pom.xml b/utilities/ondc-crypto-utility-master/pom.xml new file mode 100644 index 0000000..4934eb0 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/pom.xml @@ -0,0 +1,171 @@ + + + + 4.0.0 + + org.ondc + ondc-crypto-util + 0.1-GA + + + + ${project.groupId}:${project.artifactId} + This project has been created with an intension to help and assist ONDC Network Participants to build their own crypto libraries that are required for interaction in ONDC Network It covers key generation, signing, verification, encryption and decryption. + https://github.com/protean-ondc/ondc-crypto-utility + + + UTF-8 + 1.7 + 1.7 + + + + + org.junit.jupiter + junit-jupiter-api + 5.9.0 + test + + + + org.bouncycastle + bcprov-jdk15on + 1.69 + + + + + + ossrh + https://s01.oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + + maven-clean-plugin + 3.1.0 + + + + maven-resources-plugin + 3.0.2 + + + maven-compiler-plugin + 3.8.0 + + + maven-surefire-plugin + 2.22.1 + + + maven-jar-plugin + 3.0.2 + + + maven-install-plugin + 2.5.2 + + + maven-deploy-plugin + 2.8.2 + + + + maven-site-plugin + 3.7.1 + + + maven-project-info-reports-plugin + 3.0.0 + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://s01.oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + CC BY-ND 2.0 + https://creativecommons.org/licenses/by-nd/2.0/ + + + + + Sujeet Suryawanshi + sujeets@proteantech.in + ONDC + http://ondc.org + + + + scm:git:git://github.com/protean-ondc/ondc-crypto-utility.git + scm:git:ssh://github.com/protean-ondc/ondc-crypto-utility.git + https://github.com/protean-ondc/ondc-crypto-utility.git + + + diff --git a/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java b/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java new file mode 100644 index 0000000..3f30f82 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java @@ -0,0 +1,283 @@ +/* + * + */ + package org.ondc.crypto.util; + + import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; + import java.security.KeyFactory; + import java.security.KeyPair; + import java.security.KeyPairGenerator; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + import java.security.NoSuchProviderException; + import java.security.PrivateKey; + import java.security.PublicKey; + import java.security.SecureRandom; + import java.security.Security; + import java.security.spec.InvalidKeySpecException; + import java.security.spec.PKCS8EncodedKeySpec; + import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import javax.crypto.BadPaddingException; + import javax.crypto.Cipher; + import javax.crypto.IllegalBlockSizeException; + import javax.crypto.KeyAgreement; + import javax.crypto.NoSuchPaddingException; + import javax.crypto.SecretKey; + import javax.crypto.spec.SecretKeySpec; + import org.bouncycastle.jce.provider.BouncyCastleProvider; + import org.bouncycastle.math.ec.rfc8032.Ed25519; + + + +// TODO: Auto-generated Javadoc +/** + * The Class CryptoFunctions provides generation of key pairs for signing and encryption along with signing, verification, encryption and decryption. + */ +public class CryptoFunctions { + + + /** The Constant X25519. */ + private static final String X25519="X25519"; + + /** The Constant AES. */ + private static final String AES="AES"; + + /** The Constant BLAKE2B_512. */ + private static final String BLAKE2B_512="BLAKE2B-512"; + + /** + *

          This method generates ED25519 32 byte/256 bits key pair (Private and Public) for Signing + *

          . + *
          +		 * 
          +		 * System.out.println("Testing whether Signing Keys are generated::");
          +		 * CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
          +		 * 
          +		 * String message="message to be signed";
          +		 * 
          +		 * byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
          +		 * 
          +		 * boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
          +		 * 
          + + * @author SujeetS + * @return the crypto key pair + * @see CryptoFunctions#sign(byte[], byte[]) + * @see CryptoFunctions#verify(byte[], byte[], byte[]) + * @since 0.1 + */ + + + public static CryptoKeyPair generateSigningKeyPair() { + + // generate ed25519 keys + SecureRandom RANDOM = new SecureRandom(); + + byte[] privateKey = new byte[Ed25519.SECRET_KEY_SIZE]; //32 Byte or 256 bits + byte[] publicKey = new byte[Ed25519.PUBLIC_KEY_SIZE]; //32 Byte or 256 bits + + // generate private key using secure random + RANDOM.nextBytes(privateKey); + + // generate public key + Ed25519.generatePublicKey(privateKey, 0, publicKey, 0); + + // store generated key pair and return the same + CryptoKeyPair signingKeyPair=new CryptoKeyPair(publicKey,privateKey) ; + return signingKeyPair; + } + + + /** + *

          This method generates signature using given ED25519 32 byte/ 256 bits Private key + *

          . + *
          +		 * 
          +		 * System.out.println("Testing whether Signing Keys are generated::");
          +		 * CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
          +		 * 	
          +		 * 
          +		 * String message="message to be signed";
          +		 * byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
          +		 * boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
          +		 * 
          + + * @author SujeetS + * @param privateKey the private key that should be used to sign the message + * @param message the message that should be signed using given private key + * @return the byte[] signature of given message generated using given private key + * @see CryptoFunctions#generateSigningKeyPair() + * @see CryptoFunctions#verify(byte[], byte[], byte[]) + * @since 0.1 + */ + public static byte[] sign(byte[] privateKey,byte[] message) { + // initialise signature variable + byte[] signature = new byte[Ed25519.SIGNATURE_SIZE]; + + // sign the received message with given private key + Ed25519.sign(privateKey, 0, message, 0, message.length, signature, 0); + return signature; + } + + /** + * Verify given signature using ED25519 Public Key + *
          +		 * 
          +		 * System.out.println("Testing whether Signing Keys are generated::");
          +		 * CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair();
          +		 * 	
          +		 * 
          +		 * String message="message to be signed";
          +		 * byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes());
          +		 * boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey());
          +		 * 
          + * @author SujeetS + * @param signature the signature that needs to be verified + * @param message the message that needs to verified along with signature + * @param publicKey the public key to be used for verifying the signature + * @return true, if successful + * @see CryptoFunctions#generateSigningKeyPair() + * @see CryptoFunctions#sign(byte[], byte[]) * + */ + public static boolean verify(byte[] signature,byte[] message, byte[] publicKey) { + //verify the given signature with + return Ed25519.verify(signature, 0, publicKey, 0, message, 0, message.length); + } + + + /** + * Generate encryption decryption key pair using x25519 key exchange algorithm. + * + * @author SujeetS + * @return the crypto key pair + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchPaddingException the no such padding exception + * @throws IllegalBlockSizeException the illegal block size exception + * @throws BadPaddingException the bad padding exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchProviderException the no such provider exception + * @see CryptoFunctions#encryptDecrypt(int, byte[], byte[], byte[]) + */ + + public static CryptoKeyPair generateEncDecKey() throws InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + KeyPairGenerator kpg= KeyPairGenerator.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME); + kpg.initialize(256); // 32 Byte or 256 Bits + KeyPair kp = kpg.generateKeyPair(); + CryptoKeyPair encryptionDecryptionKeyPair=new CryptoKeyPair(kp.getPublic().getEncoded(),kp.getPrivate().getEncoded()); + return encryptionDecryptionKeyPair; + } + + + + /** + * This method can be used to do AES encryption and decryption using X25519 Key exchange algorithm + * + * + *
          +		 * 		CryptoKeyPair senderEncDecKeyPair=null;
          +		 * 		CryptoKeyPair receiverEncDecKeyPair=null;
          +		 * 		
          +		 * 		try {
          +		 * 			senderEncDecKeyPair= CryptoFunctions.generateEncDecKey();
          +		 * 			receiverEncDecKeyPair= CryptoFunctions.generateEncDecKey();
          +		 * 		} catch (Exception e) {
          +		 * 			// TODO Auto-generated catch block
          +		 * 			e.printStackTrace();
          +		 * 		} 
          +		 * 		String message="message to be encrypted";
          +		 * 		
          +		 * 		byte[] encrypted= CryptoFunctions.encryptDecrypt(Cipher.ENCRYPT_MODE,message.getBytes(),senderEncDecKeyPair.getPrivateKey(),receiverEncDecKeyPair.getPublickKey());
          +		 * 		
          +		 * 		System.out.println("\n\n/* Sender Side /");
          +		 * 		System.out.println("{");
          +		 * 		System.out.println("\t\"plainChallengeString \":\""+message +"\",");
          +		 * 		System.out.println("\t\"EncryptedChallengeString \":\""+Base64.getEncoder().encodeToString(encrypted)+"\",");
          +		 * 		System.out.println("\t\"senderPrivateKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPrivateKey()) +"\",");
          +		 * 		System.out.println("\t\"receiverPublicKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPublickKey()) +"\"");
          +		 * 		System.out.println("}\n\n");
          +		 * 		byte[] decrypted= CryptoFunctions.encryptDecrypt(Cipher.DECRYPT_MODE,encrypted,receiverEncDecKeyPair.getPrivateKey(),senderEncDecKeyPair.getPublickKey());
          +		 * 		String decryptedMessage=new String(decrypted);
          +		 * 		System.out.println("\n\n/** Receiver Side ");
          +		 * 		System.out.println("{");
          +		 * 		System.out.println("\t\"DecryptedChallengeString \":\""+decryptedMessage+"\",");
          +		 * 		System.out.println("\t\"receiverPrivateKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPrivateKey()) +"\",");
          +		 * 		System.out.println("\t\"senderPublicKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPublickKey()) +"\"");
          +		 * 		System.out.println("}");
          +		 * 
          + * @author SujeetS + * @param mode the mode to set either encrypt (Cipher.ENCRYPT_MODE) or decrypt (Cipher.DECRYPT_MODE ) + * @param challenge_string the challenge string that needs to be encrypted or decrypted depending on mode that is set. In case if mode is set to Cipher.ENCRYPT_MODE then this text shall be encrypted; whereas if mode is set to Cipher.DECRYPT_MODE, this text shall be decrypted + * @param privateKey the private key. + *

          In case of mode=Cipher.ENCRYPT_MODE, it should be private key of the sender + *
          In case of mode=Cipher.DECRYPT_MODE, it should be private key of the receiver

          + * @param publicKey the public key + *

          In case of mode=Cipher.ENCRYPT_MODE, it should be public key of the receiver + *
          In case of mode=Cipher.DECRYPT_MODE, it should be public key of the sender

          + * @return the byte[] + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchProviderException the no such provider exception + * @throws InvalidKeySpecException the invalid key spec exception + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchPaddingException the no such padding exception + * @throws IllegalBlockSizeException the illegal block size exception + * @throws BadPaddingException the bad padding exception + * @see Cipher#ENCRYPT_MODE + * @see Cipher#DECRYPT_MODE + * @see CryptoFunctions#generateEncDecKey() + * + */ + public static byte[] encryptDecrypt(int mode, byte[] challenge_string,byte[] privateKey, byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + KeyAgreement keyAgreement=KeyAgreement.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME); + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey); + PublicKey publickey = KeyFactory.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME) + .generatePublic(x509EncodedKeySpec); + PrivateKey privatekey = KeyFactory.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME) + .generatePrivate(new PKCS8EncodedKeySpec(privateKey)); + keyAgreement.init(privatekey); + keyAgreement.doPhase(publickey, true); + byte[] secret = keyAgreement.generateSecret(); + SecretKey originalKey = new SecretKeySpec(secret , 0, secret.length, AES); + Cipher cipher = Cipher.getInstance(AES, BouncyCastleProvider.PROVIDER_NAME); + cipher.init(mode, originalKey); + byte[] encryptedDecrypted = cipher.doFinal(challenge_string); + return encryptedDecrypted; + + } + + + + /** + * Generate blake hash. + * + *
          +		 * String message = "message to hash";
          +		 * byte[] hash_1=CryptoFunctions.generateBlakeHash(message);
          +		 * String bs64_1 = Base64.getEncoder().encodeToString(hash_1);
          +		 * System.out.println(bs64_1);
          +		 * 
          + * @param req the message for which digest(blake2b hash) needs to be generated + * @return the byte[] hash value + * @throws Exception the exception + */ + public static byte[] generateBlakeHash(String req) throws Exception { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + MessageDigest digest = MessageDigest.getInstance(BLAKE2B_512, BouncyCastleProvider.PROVIDER_NAME); + digest.reset(); + digest.update(req.getBytes(StandardCharsets.UTF_8)); + return digest.digest(); + } + + } + + diff --git a/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java b/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java new file mode 100644 index 0000000..0a3df09 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java @@ -0,0 +1,66 @@ +/* + * + */ +package org.ondc.crypto.util; + + +// TODO: Auto-generated Javadoc +/** + * The Class CryptoKeyPair is used to store keypair + */ +public class CryptoKeyPair { + + /** + * Instantiates a new crypto key pair. + * + * @param publicKey the public key + * @param privateKey the private key + */ + public CryptoKeyPair(byte[] publicKey,byte[] privateKey){ + this.setPrivateKey(privateKey); + this.setPublicKey(publicKey); + } + + /** The private key. */ + private byte[] privateKey; + + /** + * Gets the private key. + * + * @return the private key + */ + public byte[] getPrivateKey() { + return privateKey; + } + + /** + * Sets the private key. + * + * @param privateKey the new private key + */ + public void setPrivateKey(byte[] privateKey) { + this.privateKey = privateKey; + } + + /** + * Gets the public key. + * + * @return the public key + */ + public byte[] getPublickKey() { + return publicKey; + } + + /** + * Sets the public key. + * + * @param publicKey the new public key + */ + public void setPublicKey(byte[] publicKey) { + this.publicKey = publicKey; + } + + /** The public key. */ + private byte[] publicKey; + +} diff --git a/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java b/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java new file mode 100644 index 0000000..72c9c7f --- /dev/null +++ b/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java @@ -0,0 +1,228 @@ +package org.ondc.crypto.util; + +import static org.junit.jupiter.api.Assertions.*; + +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.spec.InvalidKeySpecException; +import java.util.Base64; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + + + +// TODO: Auto-generated Javadoc +/** + * The Class CryptoTest is used to test ondc.crypto.util.CryptoFunctions + */ +public class CryptoTest { + + /** The test case 1. */ + private final String testCase1="Positive flow of signing and verification"; + + /** + * Test generation of signing key pair + */ + @Test + @DisplayName(testCase1) + public void testGenerateSigningKeyPair_Normal() { + System.out.println("=========================================================================="); + System.out.println(testCase1); + System.out.println("=========================================================================="); + + //System.out.println(testCase1+": Start"); + System.out.println("\n"); + + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair(); + + System.out.println("Key Generation :: [OK]"); + + String message="message to be signed"; + + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes()); + + System.out.println("Signing :: [OK]"); + + System.out.println("\n\n/** Sender Side **/"); + System.out.println("{"); + System.out.println("\t\"message \":\""+message +"\","); + System.out.println("\t\"signature \":\""+Base64.getEncoder().encodeToString(signature)+"\","); + System.out.println("\t\"privateKey \":\""+Base64.getEncoder().encodeToString(signingKeyPair.getPrivateKey()) +"\","); + System.out.println("}\n\n"); + + + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey()); + + System.out.println("\n\n/** Receiver Side **/"); + System.out.println("{"); + System.out.println("\t\"message \":\""+message +"\","); + System.out.println("\t\"signature \":\""+Base64.getEncoder().encodeToString(signature)+"\","); + System.out.println("\t\"publicKey \":\""+Base64.getEncoder().encodeToString(signingKeyPair.getPublickKey()) +"\","); + System.out.println("\t\"verified \":\""+verificationResult +"\","); + System.out.println("}\n\n"); + if(verificationResult) + System.out.println("Verification :: [OK]"); + else + System.out.println("Verification :: [[NOT OK]]"); + + assertEquals(true, verificationResult); + + + } + + /** + * Test to verify tampered message and signature + */ + @Test + @DisplayName("Negative Flow to check whether tampered message is verified unsuccessfully") + public void testGenerateSigningKeyPair_Tampered() { + System.out.println("=========================================================================="); + System.out.println("Negative Flow to check whether tampered message is verified unsuccessfully"); + System.out.println("=========================================================================="); + System.out.println("\n"); + + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair(); + System.out.println("Key Generation :: [OK]"); + + + String message="message to be signed"; + + byte[] signature= CryptoFunctions.sign(signingKeyPair.getPrivateKey(), message.getBytes()); + System.out.println("Signing :: [OK]"); + + System.out.println("\n\n/** Sender Side **/"); + System.out.println("{"); + System.out.println("\t\"message \":\""+message +"\","); + System.out.println("\t\"signature \":\""+Base64.getEncoder().encodeToString(signature)+"\","); + System.out.println("\t\"privateKey \":\""+Base64.getEncoder().encodeToString(signingKeyPair.getPrivateKey()) +"\","); + System.out.println("}\n\n"); + + message="tampered message to be verified"; + + boolean verificationResult=CryptoFunctions.verify(signature, message.getBytes(), signingKeyPair.getPublickKey()); + + System.out.println("\n\n/** Receiver Side **/"); + System.out.println("{"); + System.out.println("\t\"message \":\""+message +"\","); + System.out.println("\t\"signature \":\""+Base64.getEncoder().encodeToString(signature)+"\","); + System.out.println("\t\"publicKey \":\""+Base64.getEncoder().encodeToString(signingKeyPair.getPublickKey()) +"\","); + System.out.println("\t\"verified \":\""+verificationResult +"\","); + System.out.println("}\n\n"); + + if(!verificationResult) + System.out.println("Verification Failed as expected :: [OK]"); + else + System.out.println("Verification Failed as expected :: [[NOT OK]]"); + + + assertEquals(false, verificationResult); + } + + /** + * Test generate encryption decryption key pair, encrypt and then decrypt. + * + * @throws InvalidKeyException the invalid key exception + * @throws NoSuchAlgorithmException the no such algorithm exception + * @throws NoSuchProviderException the no such provider exception + * @throws InvalidKeySpecException the invalid key spec exception + * @throws NoSuchPaddingException the no such padding exception + * @throws IllegalBlockSizeException the illegal block size exception + * @throws BadPaddingException the bad padding exception + */ + @Test + @DisplayName("To check normal flow of Encryption and Decryption") + public void testGenerateEncryptionDecryptionKeyPair_Normal() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { + System.out.println("================================================="); + System.out.println("To check normal flow of Encryption and Decryption"); + System.out.println("================================================="); + CryptoKeyPair senderEncDecKeyPair=null; + CryptoKeyPair receiverEncDecKeyPair=null; + + try { + senderEncDecKeyPair= CryptoFunctions.generateEncDecKey(); + receiverEncDecKeyPair= CryptoFunctions.generateEncDecKey(); + System.out.println("Key Generation :: [OK]"); + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String message="message to be encrypted"; + + byte[] encrypted= CryptoFunctions.encryptDecrypt(Cipher.ENCRYPT_MODE,message.getBytes(),senderEncDecKeyPair.getPrivateKey(),receiverEncDecKeyPair.getPublickKey()); + + System.out.println("Encryption :: [OK]"); + + System.out.println("\n\n/** Sender Side **/"); + System.out.println("{"); + System.out.println("\t\"plainChallengeString \":\""+message +"\","); + System.out.println("\t\"EncryptedChallengeString \":\""+Base64.getEncoder().encodeToString(encrypted)+"\","); + System.out.println("\t\"senderPrivateKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPrivateKey()) +"\","); + System.out.println("\t\"receiverPublicKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPublickKey()) +"\""); + System.out.println("}\n\n"); + + byte[] decrypted= CryptoFunctions.encryptDecrypt(Cipher.DECRYPT_MODE,encrypted,receiverEncDecKeyPair.getPrivateKey(),senderEncDecKeyPair.getPublickKey()); + System.out.println("Decryption :: [OK]"); + + String decryptedMessage=new String(decrypted); + + + System.out.println("\n\n/** Receiver Side **/"); + System.out.println("{"); + System.out.println("\t\"decryptedChallengeString \":\""+decryptedMessage+"\","); + System.out.println("\t\"receiverPrivateKey \":\""+Base64.getEncoder().encodeToString(receiverEncDecKeyPair.getPrivateKey()) +"\","); + System.out.println("\t\"senderPublicKey \":\""+Base64.getEncoder().encodeToString(senderEncDecKeyPair.getPublickKey()) +"\","); + System.out.println("\t\"match\":\""+message.equals(decryptedMessage)+"\""); + + System.out.println("}"); + + if(message.equals(decryptedMessage)) + System.out.println("Verification :: [OK]"); + else + System.out.println("Verification :: [[NOT OK]]"); + + assertEquals(message, decryptedMessage); + } + +@Test +@DisplayName("To check whether hashing is working") +public void testGenerateBlakeHash() throws Exception { + System.out.println("==================================="); + System.out.println("To check whether hashing is working"); + System.out.println("==================================="); + + String message = "message to hash"; + byte[] hash_1=CryptoFunctions.generateBlakeHash(message); + System.out.println("Message Hashed :: [OK]"); + + String bs64_1 = Base64.getEncoder().encodeToString(hash_1); + System.out.println("{"); + System.out.println("\t\"message to be hashed\":\""+message+"\","); + System.out.println("\t\"first_digest\":\""+bs64_1+"\","); + + byte[] hash_2=CryptoFunctions.generateBlakeHash(message); + System.out.println("Message Hashed :: [OK]"); + + String bs64_2 = Base64.getEncoder().encodeToString(hash_2); + System.out.println("\t\"second_digest\":\""+bs64_2+"\","); + System.out.println("\t\"match\":\""+bs64_2.equals(bs64_1)+"\""); + System.out.println("}"); + if(bs64_2.equals(bs64_1)) + System.out.println("Hash Matching :: [OK]"); + else + System.out.println("Hash Matching :: [[NOT OK]]"); + + assertEquals(bs64_1 , bs64_2); + + + +} + +} diff --git a/utilities/ondc-crypto-utility-master/target/ondc-crypto-util-0.1-GA.jar b/utilities/ondc-crypto-utility-master/target/ondc-crypto-util-0.1-GA.jar new file mode 100644 index 0000000000000000000000000000000000000000..7364b72a6083ef2a7c7b0bddfa3881454a03a72c GIT binary patch literal 6189 zcmb7JbySqw+Z`H)kS>WU-7O&@T|<{3-3$@~Gr-US3K9|`Al;3mpmc+DNOuTINk|IF z2YRpa-K(zkJG0(3=Z|Oa^E}Tv>pgq+sDY4>fdF)LbO4TX8PlUZdPk_QeL-N3uQV zU1tP<8VC*jdID8C+}RxhbNoXz(J!K1U|_pzkgHx_M*SE!E@wXqvNv_LbofIs>3@SSYvA}- z4gX$(`46ZoDEs%i*so=Jbt@BDB?UI1-8JA(}h+Iq61xqQa&p>EKm<= zKy;>)<~DDRyT4ZbS#-fm+zF;^1_E`_JpFh1N<4z`+{?{R&Q-oh^u6-Z4UZX~(MANS z4k&=Nh8~R~#(;TaadqGGxV`}SSF((miXz1Guzfy;rATYsrdBUiPpfZRC#bmT1EB8c$4Ho^jN|BsOdoZI0v@2~JkK`sQgobLWZ7lk?KSu- z$aW}ngK$6pW9P%BZj_HU2xP8|`xYZl6fqMb0<#%TwXv4E`ah*vstlp}jb`s9vCAz) z62jF?MkV>gu$CkJTZcVq+a!mRlc1tUwPvxVN~9RX!Nr}61?6m#z;K{}QIX=Ec4wzI z=F{56%_3ZFs$vw)*gOGo#}F)4%`^pUIS|_|_lO)`Wc2Azpr`b4Qt}}o1zZpV6DOxz z_-~wjRwoi_*JD@B`!|3c$oz3acP2>4rf$!#lR8A+4=a3Pp7GaxD9-%B@yJ`WfPI*T z3{cftsf*C`JbnN)+yx_(y)T0rU6eBPe&I!I&cdp5n_PDq7~~Nc63z1#%2obGPgb^> z+0R7=&un9RvqlH*L@TU*?OZ>K;DgWV4$^Xz>Ql@mu3M>r;0xE zj=V&D=RQ$M>jnz{L@t39PhJF=_^2yx)~F%_&zimV-~i1td~3;W&{%R4U%mh4E(40A z&Mt9XrOgOrgm9;=CSw2owWdbpVzRrtZZ5`sgU%o)?;*iRzYx+#Q!v*krsvuStr7LWP#92* z7NV!#y$!-qUN;X&ibpp6>7Se8`^4O&+4_Ii>ji?HQT>p652?QRb(Rz>@Csfp(9RYTwhUYt;IU*TRI+}-mGA-cf(6i0+^R0 zP7l2)mZ(=)Qqe&n{4WlO!6SR5$_zdO-^d22y})-h=N zQB&=k0&(GS0pcQ6==mrA12UtfM|F~WCsaNdd-rx;7g(Y$i6y?L5-Z$_(BCl<(+&b` zx1OHp2Y5QAdLHv@?NJZ%U|L$B-u8Ccpx!_1=@bV&Ahs>c?Sm4#ROpHgkKG9f^w!_* zQ_uy;JVbz(QHKf=j6-`3yW-8+WpNi~nCM?e){@+Gx+~T+N>kK~wtK6)xRb@=L`R|< z*t@`Hnzxv}lTR!F#=soL@ACf!z&cn!d$+4%$*iKVvs2Du5_?+Fb9@-s?c)Eq4 zZ$xA{Ftuk3ukad-aZYBHu}_cJXwxgIwx;rTBizxprz)MNXxL-l*gNM^e_47mr%*`m zo%OZ6;?3DDwv=|%jA;*I`=IsdmCj^ub`XlHYn6qQa^s^oo1g*H5`ghxaw~#_7CEXN zR1^g=FC)0!!P6m0kZDHSZolY25|gA^5geJ)DQEYgq(g3(yI@kLT}&mCbq6CcRX0#| z3SDPe6ONwR{$U5jE12I4#n{CTm*GfjI7x3Xa6_2Y+R4IV11n`%Z^g@_ppgZ$zGBL- zkA{DkABi`VAUULQxWpoALDj{Qc#H6ug^VD=OO1F9pUM~Q)Q0{DKcg+g82+b zfn~vlr`ucwuFp>0c16u9Nj!JF&mOAW34D2cOBJrrNPf2^B6x$Z@(jZVNKNm#!~1EB zxHcmkEgRD(1uBp26Kq_K;KGZM&C=}LUn;u)%*P)l_n_w-u1)Otc1eX}KB}`Yid=G} znKjmoOol&rMVC=0O@?nmkWX-P_W?0E*P~e8w?0x7A+VzNLGybTw5}l{Uwp5W>UB}{ zU10trmy#6QEbYn*Frrh;;O0(J1VhR+G(v+f6bahf0`4|ZTP7KdWzMh&zN_5)(@m;ABP(=t0%1X^=LZeJlXW2_xY$fAH{)I@w<*Ocsh#L=DuZf`eBI_)sczdwoc<%U635O$vQwBZ=P+HB<-KcUT3 zMx3c9&}MDIj3$~~VRAR{>uG;FlZ^Aslmcgy&R>t+KOISNyTi(uCh)^z?u&|$wzndo zvW&)SeGWp~p8HBZdl$}E?Y(jMGK=pEmPTi!#AFa!HFO2<17;aAQK&|iP}@}RNnsr0 zSttC7zr#E^d@2)@RsYMVEm6rQkM3QF;F52Wh;Kj6xFR2D=7qOd#6ZD1{IQT-4CIQ?ktMbqzyyP>UwP60^r@bM~}^t3|=N8 z=S$L39KE;OTc)MSHz8CsNkOQAzes7dVqnTWmrfJI8;{CG%nYX2vv5W2<5qzS5ECYL z6A~0)hqiOeZ5M)*)=@gqg>YFiigx=(6ke+ca*u%}rtrCdCJIYw;J}F>nyMNe<}>^+ zR!h?ii`3b>8taNO`igoFG3cVzy*L-A)u-PiaX}&a)rcV!3!*pHLzpEjNjt~#iOUZ^ z_$;PsE8aP4eEy={2o1|abYU$+oFrJofxmg792;jDZNxdwP+UGSBb@+kjK1#c*3)It z4cBSmQ6d@*Q$qx5Znp$8lh`3WSFt-I>$FwjOQ}@*%ClVgp2boLUIa2&eQkj}&iBy_ zM$Jh_o%ORx&R35T+LvTTIMJVqv90zl}yY zMQ}k=^ZB`CkrP2FO8;b-pkmTscbNvK4|=}6_BawkM3w+ML~#k0ig2ijAovVHmmr6= zXRIkKH|Exm=~~W|NgKKA%?}RhUK@{7#2nLJB0NP|9N8HCD_k%$VcoXT_0FM#NDYsn z4X*2oCz{lg8jcisZN!&8hi&e1O~AI2Rm`t6DxTVVhAuUWSW=%cU0JMemNbtd-Qsl%+z0Qj1Hd zv`+JD8}%sbkn>kOibF)KC5GLB+A6o=6x5k5tixopM?p=%5W|w^E8le=cYk zcH@SbHpKu}^=iYXp{c#XI}YPM9XB!piw8JZa*dH3a4;jR;oPDeuO6H1yBdu9G^_z6 zPW3Qxt5~7wH`m7|1U%Dg&P(S7>;o*G$X!ELP}cHBR=&{Vae&VXYnyNL zt5jwMKV!-6FPw&iL@K6)W81o&ots^$L!r5LN;f&{wB2Dxpq{%*UG$g!l;7%!#N6A} zcP?2x;b&WJMDgDFMdw?6@;thd5;rKThDIb2)5^A#T~HS$61$7q6`2xyQXW75@;H*z zSJm1Vr$h#4SR_ZWu#BCXoc;M(tr712tC$@s8&=bb0WS3YuhJ<;lXLO1D54xN%C#gZ zM7x?i--U9Gh15v~bm0Whhl}EaLn7Lj#-2~-1QD+c212(fgAfi0n$uHQX7 zb@>9VUs-mFoZX!4J4$7JoQmT;10aRf6-73dE+vo>2Lc8n3M@L51yga)1q9-O!mGPA zLPK~zf40Nk$8wpabg%yA=3UQI4TOM5h(!2XtMRgoZzId^>g$IYcFlPF&Hx1b&Jp~M z#|3OjBwlB@4*Qiu_!HK0IsNVzUZwhdp?@Q;9K-M9YN7X+(;sfwpBB1u5WkNr80Muq z`~mynC;ooXD@XAsTId((zg@eZ6#usWt{ldn6n2*sKU(~c-}rm*mE-sm9RFYNWikKw zkH2TRav*=Q4E%xR7k=aw?f1j;D@XDl;w(R6#Q(PT_x|MdLwUt}UDaJl_kTu~pA6<7 zdH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/target/surefire-reports/org.ondc.crypto.util.CryptoTest.txt b/utilities/ondc-crypto-utility-master/target/surefire-reports/org.ondc.crypto.util.CryptoTest.txt new file mode 100644 index 0000000..f492067 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/target/surefire-reports/org.ondc.crypto.util.CryptoTest.txt @@ -0,0 +1,4 @@ +------------------------------------------------------------------------------- +Test set: org.ondc.crypto.util.CryptoTest +------------------------------------------------------------------------------- +Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.411 s - in org.ondc.crypto.util.CryptoTest diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md new file mode 100644 index 0000000..4bb3eff --- /dev/null +++ b/utilities/signing_and_verification/README.md @@ -0,0 +1,51 @@ +# Signing and Verification +Steps for signing and verification + +1. Install pip3 and dependencies +``` +sudo apt update +sudo apt install python3-pip +pip3 install -r requirements.txt +``` + +2. Export request body json path: +this file should be a valid json file +``` +export REQUEST_BODY_PATH= +``` + eg for json file provided, export REQUEST_BODY_PATH=request_body.json + +3. Generate key-pairs +``` +python cryptic_utils.py generate_key_pairs +``` + output will be like + ``` + private_key: G0Pme72u8Y1MwxHqvY4iBW+7VPtJ7dsX7SGs6zZ5yvVIzdRAyHR6YkwHG2ufOE+12lsbJRwBF4Hqd7dUEOZZkg== + public_key: SM3UQMh0emJMBxtrnzhPtdpbGyUcAReB6ne3VBDmWZI= + ``` + +4. Export private and public keys +``` +export PRIVATE_KEY= +export PUBLIC_KEY= +``` + +5. Create authorisation header +``` +python cryptic_utils.py create_authorisation_header +``` +output will be like +```shell +Signature keyId="buyer-app.ondc.org|207|ed25519",algorithm="ed25519",created="1641287875",expires="1641291475",headers="(created) (expires) digest",signature="fKQWvXhln4UdyZdL87ViXQObdBme0dHnsclD2LvvnHoNxIgcvAwUZOmwAnH5QKi9Upg5tRaxpoGhCFGHD+d+Bw==" +``` + +6. Verify authorisation header +``` +python cryptic_utils.py verify_authorisation_header '' +``` +eg usage from output of point 5 +``` +python cryptic_utils.py verify_authorisation_header 'Signature keyId="buyer-app.ondc.org|207|ed25519",algorithm="ed25519",created="1641287875",expires="1641291475",headers="(created) (expires) digest",signature="fKQWvXhln4UdyZdL87ViXQObdBme0dHnsclD2LvvnHoNxIgcvAwUZOmwAnH5QKi9Upg5tRaxpoGhCFGHD+d+Bw=="' +``` +output will be true diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py new file mode 100644 index 0000000..2d6c56f --- /dev/null +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -0,0 +1,104 @@ +import base64 +import datetime +import os +import re +import json + +import fire as fire +import nacl.encoding +import nacl.hash +from nacl.bindings import crypto_sign_ed25519_sk_to_seed +from nacl.signing import SigningKey, VerifyKey + +f = open(os.getenv("REQUEST_BODY_PATH", "signing_and_verification/request_body.json")) +request_body_json = json.load(f) + + +def hash_message(msg: str): + HASHER = nacl.hash.blake2b + digest = HASHER(bytes(msg, 'utf-8'), digest_size=64, encoder=nacl.encoding.Base64Encoder) + digest_str = digest.decode("utf-8") + return digest_str + + +def create_signing_string(digest_base64, created=None, expires=None): + if created is None: + created = int(datetime.datetime.now().timestamp()) + if expires is None: + expires = int((datetime.datetime.now() + datetime.timedelta(hours=1)).timestamp()) + signing_string = f"""(created): {created} +(expires): {expires} +digest: BLAKE-512={digest_base64}""" + return signing_string + + +def sign_response(signing_key, private_key): + private_key64 = base64.b64decode(private_key) + seed = crypto_sign_ed25519_sk_to_seed(private_key64) + signer = SigningKey(seed) + signed = signer.sign(bytes(signing_key, encoding='utf8')) + signature = base64.b64encode(signed.signature).decode() + return signature + + +def verify_response(signature, signing_key, public_key): + try: + public_key64 = base64.b64decode(public_key) + VerifyKey(public_key64).verify(bytes(signing_key, 'utf8'), base64.b64decode(signature)) + return True + except Exception: + return False + + +def get_filter_dictionary_or_operation(filter_string): + filter_string_list = re.split(',', filter_string) + filter_string_list = [x.strip(' ') for x in filter_string_list] # to remove white spaces from list + filter_dictionary_or_operation = dict() + for fs in filter_string_list: + splits = fs.split('=', maxsplit=1) + key = splits[0].strip() + value = splits[1].strip() + filter_dictionary_or_operation[key] = value.replace("\"", "") + return filter_dictionary_or_operation + + +def create_authorisation_header(request_body=request_body_json, + created=os.getenv("CREATED", "1641287875"), + expires=os.getenv("EXPIRES", "1641291475")): + signing_key = create_signing_string(hash_message(json.dumps(request_body, separators=(',', ':'))), + created=created, expires=expires) + signature = sign_response(signing_key, private_key=os.getenv("PRIVATE_KEY")) + + subscriber_id = os.getenv("SUBSCRIBER_ID", "buyer-app.ondc.org") + unique_key_id = os.getenv("UNIQUE_KEY_ID", "207") + header = f'Signature keyId="{subscriber_id}|{unique_key_id}|ed25519",algorithm="ed25519",created=' \ + f'"{created}",expires="{expires}",headers="(created) (expires) digest",signature="{signature}"' + return header + + +def verify_authorisation_header(auth_header, request_body_str, public_key=os.getenv("PUBLIC_KEY")): + # `request_body_str` should request.data i.e. raw data string + + # `public_key` is sender's public key + # i.e. if Seller is verifying Buyer's request, then seller will first do lookup for buyer-app + # and will verify the request using buyer-app's public-key + header_parts = get_filter_dictionary_or_operation(auth_header.replace("Signature ", "")) + created = int(header_parts['created']) + expires = int(header_parts['expires']) + current_timestamp = int(datetime.datetime.now().timestamp()) + if created <= current_timestamp <= expires: + signing_key = create_signing_string(hash_message(request_body_str), created=created, expires=expires) + return verify_response(header_parts['signature'], signing_key, public_key=public_key) + else: + return False + + +def generate_key_pairs(): + signing_key = SigningKey.generate() + private_key = base64.b64encode(signing_key._signing_key).decode() + public_key = base64.b64encode(bytes(signing_key.verify_key)).decode() + return {"private_key": private_key, "public_key": public_key} + + +if __name__ == '__main__': + fire.Fire() diff --git a/utilities/signing_and_verification/request_body.json b/utilities/signing_and_verification/request_body.json new file mode 100644 index 0000000..8ad501a --- /dev/null +++ b/utilities/signing_and_verification/request_body.json @@ -0,0 +1,31 @@ +{ + "context": { + "domain": "nic2004:60212", + "country": "IND", + "city": "Kochi", + "action": "search", + "core_version": "0.9.1", + "bap_id": "bap.stayhalo.in", + "bap_uri": "https://8f9f-49-207-209-131.ngrok.io/protocol/", + "transaction_id": "e6d9f908-1d26-4ff3-a6d1-3af3d3721054", + "message_id": "a2fe6d52-9fe4-4d1a-9d0b-dccb8b48522d", + "timestamp": "2022-01-04T09:17:55.971Z", + "ttl": "P1M" + }, + "message": { + "intent": { + "fulfillment": { + "start": { + "location": { + "gps": "10.108768, 76.347517" + } + }, + "end": { + "location": { + "gps": "10.102997, 76.353480" + } + } + } + } + } +} \ No newline at end of file diff --git a/utilities/signing_and_verification/requirements.txt b/utilities/signing_and_verification/requirements.txt new file mode 100644 index 0000000..91b1324 --- /dev/null +++ b/utilities/signing_and_verification/requirements.txt @@ -0,0 +1,2 @@ +fire==0.4.0 +PyNaCl==1.5.0 \ No newline at end of file From 96bbf5dc9873747c56e61a5577ac0d421c17d7c7 Mon Sep 17 00:00:00 2001 From: Navdeep Date: Thu, 10 Nov 2022 10:45:42 +0530 Subject: [PATCH 004/228] Create LICENSE.md --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..cd36913 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 ONDC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 630a06fecfdf00aa83d5eea923657d42bd75df95 Mon Sep 17 00:00:00 2001 From: adityapatil123 Date: Thu, 8 Dec 2022 15:43:59 +0530 Subject: [PATCH 005/228] Fix signing and verification utility: - Remove unnecessary whitespaces removal from json dump - Replace json with text for which auth header created/verified - Update created and expires with recent timestamp --- utilities/signing_and_verification/README.md | 2 +- .../signing_and_verification/cryptic_utils.py | 16 ++++++++-------- ...quest_body.json => request_body_raw_text.txt} | 0 3 files changed, 9 insertions(+), 9 deletions(-) rename utilities/signing_and_verification/{request_body.json => request_body_raw_text.txt} (100%) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index 4bb3eff..fad8be7 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -11,7 +11,7 @@ pip3 install -r requirements.txt 2. Export request body json path: this file should be a valid json file ``` -export REQUEST_BODY_PATH= +export REQUEST_BODY_PATH= ``` eg for json file provided, export REQUEST_BODY_PATH=request_body.json diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py index 2d6c56f..92612b0 100644 --- a/utilities/signing_and_verification/cryptic_utils.py +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -10,9 +10,8 @@ from nacl.bindings import crypto_sign_ed25519_sk_to_seed from nacl.signing import SigningKey, VerifyKey -f = open(os.getenv("REQUEST_BODY_PATH", "signing_and_verification/request_body.json")) -request_body_json = json.load(f) - +f = open(os.getenv("REQUEST_BODY_PATH", "utilities/signing_and_verification/request_body_raw_text.txt"), "r") +request_body_raw_text = f.read() def hash_message(msg: str): HASHER = nacl.hash.blake2b @@ -62,10 +61,10 @@ def get_filter_dictionary_or_operation(filter_string): return filter_dictionary_or_operation -def create_authorisation_header(request_body=request_body_json, - created=os.getenv("CREATED", "1641287875"), - expires=os.getenv("EXPIRES", "1641291475")): - signing_key = create_signing_string(hash_message(json.dumps(request_body, separators=(',', ':'))), +def create_authorisation_header(request_body=request_body_raw_text, created=None, expires=None): + created = int(datetime.datetime.now().timestamp()) if created is None else created + expires = int((datetime.datetime.now() + datetime.timedelta(hours=1)).timestamp()) if expires is None else expires + signing_key = create_signing_string(hash_message(request_body), created=created, expires=expires) signature = sign_response(signing_key, private_key=os.getenv("PRIVATE_KEY")) @@ -76,7 +75,8 @@ def create_authorisation_header(request_body=request_body_json, return header -def verify_authorisation_header(auth_header, request_body_str, public_key=os.getenv("PUBLIC_KEY")): +def verify_authorisation_header(auth_header, request_body_str=request_body_raw_text, + public_key=os.getenv("PUBLIC_KEY")): # `request_body_str` should request.data i.e. raw data string # `public_key` is sender's public key diff --git a/utilities/signing_and_verification/request_body.json b/utilities/signing_and_verification/request_body_raw_text.txt similarity index 100% rename from utilities/signing_and_verification/request_body.json rename to utilities/signing_and_verification/request_body_raw_text.txt From 3cd4d68369961c32c02bd0eca9f3b525baa29988 Mon Sep 17 00:00:00 2001 From: nitinmish Date: Tue, 28 Feb 2023 13:22:45 +0530 Subject: [PATCH 006/228] Added Crypto encryption and Decryption the flow. --- utilities/signing_and_verification/README.md | 31 +++++++++- .../signing_and_verification/cryptic_utils.py | 60 ++++++++++++++++--- .../signing_and_verification/requirements.txt | 6 +- 3 files changed, 86 insertions(+), 11 deletions(-) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index fad8be7..84d7fad 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -21,14 +21,18 @@ python cryptic_utils.py generate_key_pairs ``` output will be like ``` - private_key: G0Pme72u8Y1MwxHqvY4iBW+7VPtJ7dsX7SGs6zZ5yvVIzdRAyHR6YkwHG2ufOE+12lsbJRwBF4Hqd7dUEOZZkg== - public_key: SM3UQMh0emJMBxtrnzhPtdpbGyUcAReB6ne3VBDmWZI= + Signing_private_key: G0Pme72u8Y1MwxHqvY4iBW+7VPtJ7dsX7SGs6zZ5yvVIzdRAyHR6YkwHG2ufOE+12lsbJRwBF4Hqd7dUEOZZkg== + Signing_public_key: SM3UQMh0emJMBxtrnzhPtdpbGyUcAReB6ne3VBDmWZI= + Crypto_Privatekey: MC4CAQAwBQYDK2VuBCIEIKi7NbXeN8QzXjN48XkjOiS/UaR6rumXep8VslMy4fRU + Crypto_Publickey: MCowBQYDK2VuAyEA9CEWxnLJkmwW/67QR739BEam7bbd3NsffjDa5HANf0Q= ``` 4. Export private and public keys ``` export PRIVATE_KEY= export PUBLIC_KEY= +export CRYPTO_PRIVATE_KEY= +export CRYPTO_PUBLIC_KEY= ``` 5. Create authorisation header @@ -49,3 +53,26 @@ eg usage from output of point 5 python cryptic_utils.py verify_authorisation_header 'Signature keyId="buyer-app.ondc.org|207|ed25519",algorithm="ed25519",created="1641287875",expires="1641291475",headers="(created) (expires) digest",signature="fKQWvXhln4UdyZdL87ViXQObdBme0dHnsclD2LvvnHoNxIgcvAwUZOmwAnH5QKi9Upg5tRaxpoGhCFGHD+d+Bw=="' ``` output will be true + +7. Encrypt Payload +``` +python cryptic_utils.py encrypt "PrivateKey" "PublicKey" +``` + +eg usage +``` +python cryptic_utils.py encrypt "MC4CAQAwBQYDK2VuBCIEIOgl3rf3arbk1PvIe0C9TZp7ImR71NSQdvuSu+zzY6xo" "MCowBQYDK2VuAyEAi801MjVpgFOXHjliyT6Nb14HkS5dj1p41qbeyU6/SC8=" +``` + +Output will be base64 encoded string like "MCowBQYDK2VuAyEAi801MjVpgFOXHjliyT6Nb14HkS5dj1p41qbeyU6/SC8=" + +8. Decrypt Payload +``` +python cryptic_utils.py decrypt "PrivateKey" "PublicKey" "Encrypted String" +``` +eg usage +``` +python cryptic_utils.py decrypt "MC4CAQAwBQYDK2VuBCIEIOgl3rf3arbk1PvIe0C9TZp7ImR71NSQdvuSu+zzY6xo" "MCowBQYDK2VuAyEAi801MjVpgFOXHjliyT6Nb14HkS5dj1p41qbeyU6/SC8=" "CrwN248HS4CIYsUvxtrK0pWCBaoyZh4LnWtGqeH7Mpc=" +``` + +Output will be a Plain Text decoded string "ONDC is a Great Initiative!" \ No newline at end of file diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py index 92612b0..c9105f4 100644 --- a/utilities/signing_and_verification/cryptic_utils.py +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -3,14 +3,17 @@ import os import re import json - import fire as fire import nacl.encoding import nacl.hash from nacl.bindings import crypto_sign_ed25519_sk_to_seed from nacl.signing import SigningKey, VerifyKey +from cryptography.hazmat.primitives.asymmetric.x25519 import X25519PrivateKey,X25519PublicKey +from cryptography.hazmat.primitives import serialization +from Cryptodome.Cipher import AES +from Cryptodome.Util.Padding import pad,unpad -f = open(os.getenv("REQUEST_BODY_PATH", "utilities/signing_and_verification/request_body_raw_text.txt"), "r") +f = open(os.getenv("REQUEST_BODY_PATH", "request_body_raw_text.txt"), "r") request_body_raw_text = f.read() def hash_message(msg: str): @@ -39,7 +42,6 @@ def sign_response(signing_key, private_key): signature = base64.b64encode(signed.signature).decode() return signature - def verify_response(signature, signing_key, public_key): try: public_key64 = base64.b64decode(public_key) @@ -67,11 +69,12 @@ def create_authorisation_header(request_body=request_body_raw_text, created=None signing_key = create_signing_string(hash_message(request_body), created=created, expires=expires) signature = sign_response(signing_key, private_key=os.getenv("PRIVATE_KEY")) + #signature = sign_response(signing_key, private_key="unkLJfHZRmKf88Ac5zv6Wb5caVbYN9Uav0XJ5OOyitdbVo4xZhS8g23JLKY9Ve66uAAL/zrl0PGjpwkvp0d3eA==") subscriber_id = os.getenv("SUBSCRIBER_ID", "buyer-app.ondc.org") unique_key_id = os.getenv("UNIQUE_KEY_ID", "207") - header = f'Signature keyId="{subscriber_id}|{unique_key_id}|ed25519",algorithm="ed25519",created=' \ - f'"{created}",expires="{expires}",headers="(created) (expires) digest",signature="{signature}"' + header = f'"Signature keyId=\\"{subscriber_id}|{unique_key_id}|ed25519\\",algorithm=\\"ed25519\\",created=' \ + f'\\"{created}\\",expires=\\"{expires}\\",headers=\\"(created) (expires) digest\\",signature=\\"{signature}\\""' return header @@ -96,9 +99,52 @@ def verify_authorisation_header(auth_header, request_body_str=request_body_raw_t def generate_key_pairs(): signing_key = SigningKey.generate() private_key = base64.b64encode(signing_key._signing_key).decode() + #print(private_key) public_key = base64.b64encode(bytes(signing_key.verify_key)).decode() - return {"private_key": private_key, "public_key": public_key} - + inst_private_key = X25519PrivateKey.generate() + #print(base64.b64encode(bytes(tcrypto_private_key.).decode())) + inst_public_key = inst_private_key.public_key() + bytes_private_key = inst_private_key.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() + ) + bytes_public_key = inst_public_key.public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo + ) + crypto_private_key = base64.b64encode(bytes_private_key).decode('utf-8') + crypto_public_key = base64.b64encode(bytes_public_key).decode('utf-8') + return {"Signing_private_key": private_key, + "Signing_public_key": public_key, + "Crypto_Privatekey": crypto_private_key, + "Crypto_Publickey": crypto_public_key} + +def encrypt(crypto_private_key, crypto_public_key): + private_key = serialization.load_der_private_key( + base64.b64decode(crypto_private_key), + password=None + ) + public_key = serialization.load_der_public_key( + base64.b64decode(crypto_public_key) + ) + shared_key = private_key.exchange(public_key) + cipher = AES.new(shared_key, AES.MODE_ECB) + text = b'ONDC is a Great Initiative!' + return base64.b64encode(cipher.encrypt(pad(text,AES.block_size))).decode('utf-8') + +def decrypt(crypto_private_key, crypto_public_key, cipherstring): + private_key = serialization.load_der_private_key( + base64.b64decode(crypto_private_key), + password=None + ) + public_key = serialization.load_der_public_key( + base64.b64decode(crypto_public_key) + ) + shared_key = private_key.exchange(public_key) + cipher = AES.new(shared_key, AES.MODE_ECB) + ciphertxt = base64.b64decode(cipherstring) + return cipher.decrypt(ciphertxt).decode('utf-8') if __name__ == '__main__': fire.Fire() diff --git a/utilities/signing_and_verification/requirements.txt b/utilities/signing_and_verification/requirements.txt index 91b1324..ad9bfd1 100644 --- a/utilities/signing_and_verification/requirements.txt +++ b/utilities/signing_and_verification/requirements.txt @@ -1,2 +1,4 @@ -fire==0.4.0 -PyNaCl==1.5.0 \ No newline at end of file +fire==0.5.0 +PyNaCl==1.5.0 +cryptography==39.0.1 +pycryptodomex==3.17 \ No newline at end of file From 2c9e073324121d56711cee50965f4cfa68d5034b Mon Sep 17 00:00:00 2001 From: bluecypher Date: Mon, 13 Mar 2023 14:19:58 +0530 Subject: [PATCH 007/228] log-validation-utility --- utilities/log-validation-utility/.gitignore | 13 + utilities/log-validation-utility/README.md | 108 ++++ .../log-validation-utility/config/config.js | 5 + utilities/log-validation-utility/dao/dao.js | 47 ++ utilities/log-validation-utility/index.js | 30 + utilities/log-validation-utility/package.json | 25 + .../log-validation-utility/routes/routes.js | 25 + .../log-validation-utility/schema/main.js | 10 + .../retail_api_json_schema/SchemaValidator.js | 179 +++++ .../retail_api_json_schema/cancelSchema.js | 86 +++ .../retail_api_json_schema/confirmSchema.js | 496 ++++++++++++++ .../retail_api_json_schema/initSchema.js | 273 ++++++++ .../retail_api_json_schema/onCancelSchema.js | 19 + .../retail_api_json_schema/onConfirmSchema.js | 473 ++++++++++++++ .../retail_api_json_schema/onInitSchema.js | 322 +++++++++ .../onSearchBPCSchema.js | 610 ++++++++++++++++++ .../onSearchGrocerySchema.js | 490 ++++++++++++++ .../onSearchItemValidations.js | 106 +++ .../retail_api_json_schema/onSearchSchema.js | 547 ++++++++++++++++ .../onSearchfashionSchema.js | 490 ++++++++++++++ .../retail_api_json_schema/onSelectSchema.js | 175 +++++ .../retail_api_json_schema/onStatusSchema.js | 548 ++++++++++++++++ .../retail_api_json_schema/onSupportSchema.js | 14 + .../retail_api_json_schema/onTrackSchema.js | 13 + .../retail_api_json_schema/onUpdateSchema.js | 486 ++++++++++++++ .../postConfirmValidations.js | 0 .../retail_api_json_schema/searchSchema.js | 140 ++++ .../retail_api_json_schema/selectSchema.js | 170 +++++ .../retail_api_json_schema/statusSchema.js | 79 +++ .../retail_api_json_schema/updateSchema.js | 199 ++++++ .../services/cbCheck.service.js | 40 ++ .../services/service.js | 58 ++ .../log-validation-utility/utils/constants.js | 23 + .../utils/ret.cbCheck.util.js | 7 + .../utils/retail/retCancel.js | 155 +++++ .../utils/retail/retConfirm.js | 415 ++++++++++++ .../utils/retail/retInit.js | 255 ++++++++ .../utils/retail/retOnCancel.js | 166 +++++ .../utils/retail/retOnConfirm.js | 480 ++++++++++++++ .../utils/retail/retOnInit.js | 399 ++++++++++++ .../utils/retail/retOnSearch.js | 129 ++++ .../utils/retail/retOnSelect.js | 466 +++++++++++++ .../utils/retail/retOnStatus.js | 200 ++++++ .../utils/retail/retOnSupport.js | 123 ++++ .../utils/retail/retOnTrack.js | 146 +++++ .../utils/retail/retOnUpdate.js | 300 +++++++++ .../utils/retail/retPostConfirm.js | 12 + .../utils/retail/retSearch.js | 99 +++ .../utils/retail/retSelect.js | 233 +++++++ .../utils/retail/retStatus.js | 130 ++++ .../utils/retail/retSupport.js | 111 ++++ .../utils/retail/retTrack.js | 118 ++++ .../utils/retail/retUpdate.js | 140 ++++ .../utils/schemaValidation.js | 47 ++ .../log-validation-utility/utils/utils.js | 229 +++++++ .../utils/validateLogUtil.js | 205 ++++++ 56 files changed, 10864 insertions(+) create mode 100644 utilities/log-validation-utility/.gitignore create mode 100644 utilities/log-validation-utility/README.md create mode 100644 utilities/log-validation-utility/config/config.js create mode 100644 utilities/log-validation-utility/dao/dao.js create mode 100644 utilities/log-validation-utility/index.js create mode 100644 utilities/log-validation-utility/package.json create mode 100644 utilities/log-validation-utility/routes/routes.js create mode 100644 utilities/log-validation-utility/schema/main.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onCancelSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onTrackSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/postConfirmValidations.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js create mode 100644 utilities/log-validation-utility/services/cbCheck.service.js create mode 100644 utilities/log-validation-utility/services/service.js create mode 100644 utilities/log-validation-utility/utils/constants.js create mode 100644 utilities/log-validation-utility/utils/ret.cbCheck.util.js create mode 100644 utilities/log-validation-utility/utils/retail/retCancel.js create mode 100644 utilities/log-validation-utility/utils/retail/retConfirm.js create mode 100644 utilities/log-validation-utility/utils/retail/retInit.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnCancel.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnConfirm.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnInit.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnSearch.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnSelect.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnStatus.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnSupport.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnTrack.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnUpdate.js create mode 100644 utilities/log-validation-utility/utils/retail/retPostConfirm.js create mode 100644 utilities/log-validation-utility/utils/retail/retSearch.js create mode 100644 utilities/log-validation-utility/utils/retail/retSelect.js create mode 100644 utilities/log-validation-utility/utils/retail/retStatus.js create mode 100644 utilities/log-validation-utility/utils/retail/retSupport.js create mode 100644 utilities/log-validation-utility/utils/retail/retTrack.js create mode 100644 utilities/log-validation-utility/utils/retail/retUpdate.js create mode 100644 utilities/log-validation-utility/utils/schemaValidation.js create mode 100644 utilities/log-validation-utility/utils/utils.js create mode 100644 utilities/log-validation-utility/utils/validateLogUtil.js diff --git a/utilities/log-validation-utility/.gitignore b/utilities/log-validation-utility/.gitignore new file mode 100644 index 0000000..1898f6d --- /dev/null +++ b/utilities/log-validation-utility/.gitignore @@ -0,0 +1,13 @@ +node_modules +package-lock.json +*.env +.vscode +/public/logs/*.json +verification-logs +/utils/*.json +/utils/*.txt +test_logs +dbfiles +log_report.md +test.js +public/ \ No newline at end of file diff --git a/utilities/log-validation-utility/README.md b/utilities/log-validation-utility/README.md new file mode 100644 index 0000000..952b9dc --- /dev/null +++ b/utilities/log-validation-utility/README.md @@ -0,0 +1,108 @@ +# ONDC-LOG-VALIDATION + +### APIs Log Validation tool for Pre-Prod participants + +The tool is a NODE.js based utility to check the conformance and compliance of the API logs for retail with the [API Contract](https://drive.google.com/file/d/1Z0eT1PZ8_tthEyxli8bLs-B9oCYAZIS0/view). + +### Tech + +- [[node.js](https://nodejs.org/en/)] +- [[lmdb](https://www.npmjs.com/package/lmdb)] +- [[lodash](https://www.npmjs.com/package/lodash)] +- [[ajv](https://ajv.js.org/)] + +## Steps to run the utility + +Log Validation Tool requires [Node.js](https://nodejs.org/) to run. + +1. Clone the repository, navigate to Log-Validation_Utility and install the dependencies. + +```sh + +cd log-validation-utility + +npm i +``` + +2. Move all the API payloads inside "/public/logs" folder or mention the path to the logs folder as demonstrated in the next step. + +3. Run the utility in the following format + + > node index.js "domain" "/path/to/logs/folder/" + +```sh +node index.js retail ./public/logs/ +``` + +4. A text report (log_report.md) will be generated upon successful execution of the utility. + + +_Notes:_ + +> There must be a separate payload for every API. + +> All the payloads should be named in the correct format as mentioned in the table below. + +> The utility validates all the 18 payloads as documented in the [API Contract](https://drive.google.com/file/d/1Z0eT1PZ8_tthEyxli8bLs-B9oCYAZIS0/view). + +| Payloads (Correct Format) | +| ------------------------- | +| search.json | +| on_search.json | +| select.json | +| on_select.json | +| init.json | +| on_init.json | +| confirm.json | +| on_confirm.json | +| cancel.json | +| on_cancel.json | +| track.json | +| on_track.json | +| status.json | +| on_status.json | +| update.json | +| on_update.json | +| support.json | +| on_support.json | + +> Sample payload for search.json is demonstrated below: + +```json +{ + "context": { + "domain": "nic2004:52110", + "country": "IND", + "city": "std:080", + "action": "search", + "core_version": "1.1.0", + "bap_id": "buyer-app-preprod.ondc.org", + "bap_uri": "https://buyer-app-preprod.ondc.org/protocol/v1", + "transaction_id": "7fc3bf55-2efc-442d-fda3-465d27a35d26", + "message_id": "89b0ffb1-5f49-4eb7-b319-ca02caecc059", + "timestamp": "2022-11-11T19:59:52.452Z", + "ttl": "PT30S" + }, + "message": { + "intent": { + "item": { + "descriptor": { + "name": "coffee" + } + }, + "fulfillment": { + "type": "Delivery", + "end": { + "location": { + "gps": "12.96774,77.58891" + } + } + }, + "payment": { + "@ondc/org/buyer_app_finder_fee_type": "percent", + "@ondc/org/buyer_app_finder_fee_amount": "3.0" + } + } + } +} +``` diff --git a/utilities/log-validation-utility/config/config.js b/utilities/log-validation-utility/config/config.js new file mode 100644 index 0000000..3d0d989 --- /dev/null +++ b/utilities/log-validation-utility/config/config.js @@ -0,0 +1,5 @@ +const config = { + port: process.env.PORT || 3000, +}; + +module.exports = config; diff --git a/utilities/log-validation-utility/dao/dao.js b/utilities/log-validation-utility/dao/dao.js new file mode 100644 index 0000000..a6dacba --- /dev/null +++ b/utilities/log-validation-utility/dao/dao.js @@ -0,0 +1,47 @@ +const { open } = require("lmdb"); +const constants = require("../utils/constants"); + +const getConnection = () => { + let myDB = open({ + path: constants.DB_PATH, + // maxReaders:200, //maxReaders limit + compression: true, + }); + + return myDB; +}; + +const setValue = (key, value) => { + let myDB = getConnection(); + + myDB.putSync(key, value); + myDB.close(); +}; +const getValue = (key) => { + let myDB = getConnection(); + let value = myDB.get(key); + myDB.close(); + return value; +}; + +const dropDB = () => { + let myDB = getConnection(); + return new Promise((resolve, reject) => { + myDB + .drop() + .then((res) => { + console.log("DB Dropped Successfully!!", res); + }) + .catch((err) => { + console.log("!!Error while removing LMDB"); + }); + }); +}; + +module.exports = { getValue, setValue, dropDB }; + +// or +// myDB.transaction(() => { +// myDB.put("greeting", { someText: "Hello, World!" }); +// myDB.get("greeting").someText; // 'Hello, World!' +// }); diff --git a/utilities/log-validation-utility/index.js b/utilities/log-validation-utility/index.js new file mode 100644 index 0000000..68d24cf --- /dev/null +++ b/utilities/log-validation-utility/index.js @@ -0,0 +1,30 @@ +const { validateLog } = require("./services/cbCheck.service"); +const fs = require("fs"); + +try { + if (process.argv.length < 3) { + console.log( + "Need arguments in the format: node index.js 'domain' '/path/to/logs/folder/'" + ); + return; + } + + const domain = process.argv[2] || "retail"; + const path = process.argv[3] || "./public/logs/"; + + fs.readdir(path, function (err, files) { + try { + if (err) { + console.log(`Some error occurred while reading files from ${path}`); + } else if (!files.length) { + console.log(`${path} folder is empty!!`); + } else { + validateLog(domain, path); + } + } catch (error) { + console.log(`Error while reading logs folder`, error); + } + }); +} catch (error) { + console.log("!!Some Unexpected Error Occurred", error); +} diff --git a/utilities/log-validation-utility/package.json b/utilities/log-validation-utility/package.json new file mode 100644 index 0000000..aa8484d --- /dev/null +++ b/utilities/log-validation-utility/package.json @@ -0,0 +1,25 @@ +{ + "name": "log-verification-ondc", + "version": "1.0.0", + "description": "Log Verification ONDC", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bluecypher/ONDC-Log-Verification.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/bluecypher/ONDC-Log-Verification/issues" + }, + "homepage": "https://github.com/bluecypher/ONDC-Log-Verification#readme", + "dependencies": { + "ajv": "^8.12.0", + "ajv-formats": "^2.1.1", + "lmdb": "^2.7.5", + "lodash": "^4.17.21" + } +} diff --git a/utilities/log-validation-utility/routes/routes.js b/utilities/log-validation-utility/routes/routes.js new file mode 100644 index 0000000..3863e17 --- /dev/null +++ b/utilities/log-validation-utility/routes/routes.js @@ -0,0 +1,25 @@ +const express = require("express"); +const router = express.Router(); +const service = require("../services/service"); +const { validateLog } = require("../services/cbCheck.service"); + +router.post("/validateSchema/:path", (req, res) => { + const path = req.params.path; + const data = req.body; + const result = service.schemaValidation(domain, data, path); + res.json(result); +}); + +router.post("/CheckContext/:path", (req, res) => { + const path = req.params.path; + const data = req.body.context; + const result = service.checkContext(data, path); + res.json(result); +}); + +router.post("/ValidateLog/:domain", (req, res) => { + const domain = req.params.domain; + validateLog(domain); +}); + +module.exports = router; diff --git a/utilities/log-validation-utility/schema/main.js b/utilities/log-validation-utility/schema/main.js new file mode 100644 index 0000000..73efe09 --- /dev/null +++ b/utilities/log-validation-utility/schema/main.js @@ -0,0 +1,10 @@ +const schemaValidator = require("./retail_api_json_schema/SchemaValidator"); + +const fs = require("fs"); + +const validate_schema_for_retail_json = (vertical, api, data) => { + res = schemaValidator[`validate_schema_${api}_${vertical}_for_json`](data); + return res; +}; + +module.exports = validate_schema_for_retail_json; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js new file mode 100644 index 0000000..fab6c3d --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -0,0 +1,179 @@ +const onConfirmSchema = require("./onConfirmSchema"); +const onInitSchema = require("./onInitSchema"); +const onSearchSchema = require("./onSearchSchema"); +const onSelectSchema = require("./onSelectSchema"); +const onTrackSchema = require("./onTrackSchema"); +const onSupportSchema = require("./onSupportSchema"); +const onStatusSchema = require("./onStatusSchema"); +const onCancelSchema = require("./onCancelSchema"); +const onUpdateSchema = require("./onUpdateSchema"); +const searchSchema = require("./searchSchema"); +const selectSchema = require("./selectSchema"); +const initSchema = require("./initSchema"); +const confirmSchema = require("./confirmSchema"); +const statusSchema = require("./statusSchema"); +const updateSchema = require("./updateSchema"); +const cancelSchema = require("./cancelSchema"); + +const Ajv = require("ajv"); +const ajv = new Ajv({ allErrors: true, strict: "log" }); +const addFormats = require("ajv-formats"); +addFormats(ajv); + +// transform_on_search_schema = (payload) => { +// transformed_payload = payload; +// bpp_providers = transformed_payload["message"]["catalog"]["bpp/providers"]; +// bpp_providers.forEach((provider) => { +// if (provider.hasOwnProperty("@ondc/org/fssai_license_no")) { +// fssai = provider["@ondc/org/fssai_license_no"]; +// items = provider["items"]; +// items.forEach((item) => { +// item["@ondc/org/fssai_license_no"] = fssai; +// }); +// } + +// return transformed_payload; +// }); +// }; +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { message: error.message, details: error.instancePath }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + +const validate_schema = (data, schema) => { + let error_list = []; + validate = ajv.compile(schema); + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + return error_list; +}; + +const validate_schema_search_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = searchSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_search_retail_for_json = (data) => { + // transformed_item_data = transform_on_search_schema(data); + error_list = validate_schema(data, (schema = onSearchSchema)); + return formatted_error(error_list); +}; + +const validate_schema_select_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = selectSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_select_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onSelectSchema)); + return formatted_error(error_list); +}; + +const validate_schema_init_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = initSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_init_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onInitSchema)); + return formatted_error(error_list); +}; + +const validate_schema_confirm_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = confirmSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_confirm_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onConfirmSchema)); + return formatted_error(error_list); +}; + +const validate_schema_status_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = statusSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_status_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onStatusSchema)); + return formatted_error(error_list); +}; + +const validate_schema_cancel_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = cancelSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_cancel_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onCancelSchema)); + return formatted_error(error_list); +}; + +const validate_schema_update_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = updateSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_update_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onUpdateSchema)); + return formatted_error(error_list); +}; + +const validate_schema_track_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = trackSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_track_retail_for_json = (data) => { + item_data = data["message"]; + error_list = validate_schema(item_data, (schema = onTrackSchema)); + return formatted_error(error_list); +}; + +const validate_schema_support_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = supportSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_support_retail_for_json = (data) => { + item_data = data["message"]; + error_list = validate_schema(item_data, (schema = onSupportSchema)); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_search_retail_for_json, + validate_schema_select_retail_for_json, + validate_schema_init_retail_for_json, + validate_schema_confirm_retail_for_json, + validate_schema_update_retail_for_json, + validate_schema_status_retail_for_json, + validate_schema_track_retail_for_json, + validate_schema_cancel_retail_for_json, + validate_schema_support_retail_for_json, + validate_schema_on_cancel_retail_for_json, + validate_schema_on_confirm_retail_for_json, + validate_schema_on_init_retail_for_json, + validate_schema_on_search_retail_for_json, + validate_schema_on_select_retail_for_json, + validate_schema_on_status_retail_for_json, + validate_schema_on_support_retail_for_json, + validate_schema_on_track_retail_for_json, + validate_schema_on_update_retail_for_json, +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js new file mode 100644 index 0000000..00127f1 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js @@ -0,0 +1,86 @@ +module.exports = { + $schema: "http://json-schema.org/draft-04/schema#", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "cancel", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + cancellation_reason_id: { + type: "string", + minLength: 3, + maxLength: 3, + }, + }, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js new file mode 100644 index 0000000..aab1bf7 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -0,0 +1,496 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "confirm", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + const: "Created", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: [ + { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + ], + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: [ + { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["id", "fulfillment_id", "quantity"], + }, + ], + }, + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + updated_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + required: [ + "name", + "address", + "phone", + "created_at", + "updated_at", + ], + }, + fulfillments: { + type: "array", + items: [ + { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + const: "Delivery", + }, + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + email: { + type: "string", + format: "email", + }, + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["person", "contact", "location"], + }, + }, + required: ["id", "type", "tracking", "end"], + }, + ], + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payment", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js new file mode 100644 index 0000000..b40fd73 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js @@ -0,0 +1,273 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "init", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + minLength: 1, + }, + fulfillment_id: { + type: "string", + minLength: 1, + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["id", "fulfillment_id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + phone: { + type: "string", + }, + created_at: { + type: "string", + format: "date-time", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + required: [ + "name", + "address", + "phone", + "created_at", + "updated_at", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + const: "Delivery", + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + }, + required: ["id", "type", "end"], + }, + }, + }, + required: ["provider", "items", "billing", "fulfillments"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onCancelSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onCancelSchema.js new file mode 100644 index 0000000..a594953 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onCancelSchema.js @@ -0,0 +1,19 @@ +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { type: "string", pattern: "^(?!s*$).+" }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + minLength: 3, + maxLength: 3, + }, + }, + required: ["cancellation_reason_id"], + }, + }, + required: ["id", "state", "tags"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js new file mode 100644 index 0000000..07b9243 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js @@ -0,0 +1,473 @@ +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { type: "string", enum: ["Created", "Accepted", "Cancelled"] }, + provider: { + type: "object", + properties: { + id: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + }, + rateable: { type: "boolean" }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + }, + required: ["id", "quantity", "fulfillment_id"], + }, + }, + + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + updated_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + required: ["name", "address", "phone", "created_at", "updated_at"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + "@ondc/org/provider_name": { type: "string" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { type: "string", const: "Pending" }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { type: "string", const: "Delivery" }, + tracking: { type: "boolean" }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + }, + required: ["name"], + }, + gps: { type: "string" }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + gps: { type: "string" }, + }, + required: ["address", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "tracking", + "start", + "end", + ], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + // allOf: [ + // { + // if: { + // properties: { + // status: { + // const: "PAID", + // }, + // }, + // atPath: "1", + // }, + // then: { properties: { type: { const: "ON-ORDER" } } }, + // }, + // ], + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + required: [ + "payment", + "fulfillments", + "quote", + "items", + "id", + "state", + "provider", + "billing", + "created_at", + "updated_at", + ], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js new file mode 100644 index 0000000..3c03116 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js @@ -0,0 +1,322 @@ +module.exports = { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + }, + required: ["id", "fulfillment_id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + required: ["name", "address", "phone", "created_at", "updated_at"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { type: "string", const: "Delivery" }, + tracking: { type: "boolean" }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string", format: "email" }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + }, + + required: ["id", "type", "end"], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + + payment: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + }, + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + }, + }, + required: [ + "payment", + "fulfillments", + "billing", + "quote", + "items", + "provider", + "provider_location", + ], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js new file mode 100644 index 0000000..861155d --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js @@ -0,0 +1,610 @@ +module.exports = { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { type: "string" }, + }, + required: ["id"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { type: "string" }, + }, + required: ["id"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + }, + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + code: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + }, + }, + rating: { type: "string" }, + ttl: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + gps: { type: "string" }, + address: { type: "string" }, + city: { + type: "object", + properties: { + code: { type: "string" }, + name: { type: "string" }, + }, + }, + state: { + type: "object", + properties: { + code: { type: "string" }, + }, + }, + country: { + type: "object", + properties: { + code: { type: "string" }, + }, + }, + area_code: { type: "string" }, + }, + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string" }, + value: { type: "string" }, + }, + }, + }, + }, + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + parent_item_id: { type: "string", pattern: "^(?!s*$).+" }, + descriptor: { + type: "object", + properties: { + name: { type: "string", pattern: "^(?!s*$).+" }, + code: { type: "string", pattern: "^(?!s*$).+" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + pattern: "^(?!s*$).+", + }, + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + }, + }, + }, + }, + manufacturer: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + }, + }, + }, + phone: { + type: "string", + pattern: + "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", + }, + }, + }, + price: { + type: "object", + properties: { + currency: { type: "string", pattern: "^(?!s*$).+" }, + value: { type: "string", pattern: "^d*.?d*$" }, + offered_value: { type: "string", pattern: "^d*.?d*$" }, + maximum_value: { type: "string", pattern: "^d*.?d*$" }, + }, + require: ["currency", "value"], + }, + + quantity: { + type: "object", + properties: { + unitized: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + pattern: "^d*$", + }, + }, + }, + maximum: { + type: "object", + properties: { + count: { type: "string", pattern: "^d*$" }, + }, + }, + }, + }, + category_ids: { + type: "array", + items: { + type: "string", + minItems: 1, + pattern: "^(?!s*$).+", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + minItems: 1, + pattern: "^(?!s*$).+", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + enum: ["1", "2"], + }, + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + pattern: "^(?!s*$).+", + }, + value: { + type: "string", + pattern: "^d*.?d*$", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + }, + }, + }, + }, + cancellation_terms: { + type: "array", + items: { + anyOf: [ + { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + }, + }, + }, + refund_eligible: { + type: "string", + }, + }, + required: ["fulfillment_state", "refund_eligible"], + }, + { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + }, + }, + }, + return_policy: { + type: "object", + properties: { + return_eligible: { + type: "string", + }, + return_within: { + type: "string", + }, + fulfillment_managed_by: { + type: "string", + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + }, + }, + required: [ + "return_eligible", + "return_within", + "return_location", + ], + }, + }, + required: ["fulfillment_state", "return_policy"], + }, + ], + }, + minLength: 2, + }, + + replacement_terms: { + type: "array", + items: { + type: "object", + properties: { + replace_within: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["replace_within"], + }, + }, + rating: { type: "string" }, + matched: { type: "string" }, + time: { + type: "object", + properties: { + label: { type: "string" }, + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + end: { + type: "string", + pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + }, + }, + }, + recommended: { type: "string" }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + }, + }, + }, + required: [ + "id", + "parent_item_id", + "descriptor", + "manufacturer", + "price", + "quantity", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "replacement_terms", + "matched", + "recommended", + "tags", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + pattern: + "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", + }, + email: { + type: "string", + pattern: + "^([a-zA-Z0-9_-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$", + }, + }, + }, + }, + }, + }, + + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + code: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + pattern: "^(?!s*$).+", + }, + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + }, + }, + }, + }, + time: { + type: "object", + properties: { + label: { type: "string" }, + range: { + type: "object", + properties: { + start: { type: "string" }, + end: { type: "string" }, + }, + }, + }, + }, + item_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + category_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + }, + }, + }, + }, + }, + }, + }, + required: ["fulfillments", "payments", "descriptor", "providers"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js new file mode 100644 index 0000000..91c4159 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js @@ -0,0 +1,490 @@ +onSearchGrocerySchema = { + "type": "object", + "properties": { + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "payments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "providers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "rating": {"type": "string"}, + "ttl": {"type": "string"}, + "locations": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "gps": {"type": "string"}, + "address": {"type": "string"}, + "city": {"type": "object", + "properties": { + "code": {"type": "string"}, + "name": {"type": "string"}, + } + }, + "state": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "country": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "area_code": {"type": "string"}, + } + } + }, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "value": {"type": "string"}, + } + }} + } + } + }, + "items": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "parent_item_id": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "code": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + }, + }, + "manufacturer": {"type": "object", + "properties": { + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + } + }, + "contact": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "address": { + "type": "object", + "properties": { + "full": { + "type": "string"}, + } + }, + } + }, + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} + } + }, + "price": {"type": "object", + "properties": { + "currency": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "maximum_value": {"type": "string", + "pattern": "^\d*\.?\d*$"} + }, + "require": ["currency", "value"], + }, + + "quantity": {"type": "object", + "properties": { + "unitized": {"type": "object", + "properties": { + "measure": { + "type": "object", + "properties": { + "unit": { + "type": "string"}, + "value": { + "type": "string"} + + } + }, + } + }, + "available": {"type": "object", + "properties": { + "count": { + "type": "string", + "pattern": "^\d*$"} + + } + }, + "maximum": {"type": "object", + "properties": { + "count": {"type": "string", + "pattern": "^\d*$"} + } + }, + } + }, + "category_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "fulfillment_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "payment_ids": {"type": "array", + "items": { + "type": "string", + "enum": ["1", "2"]}}, + "add-ons": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "code": { + "type": "string"}, + "short_desc": { + "type": "string"}, + "long_desc": { + "type": "string"}, + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "url"] + + } + } + } + }, + "price": {"type": "object", + "properties": { + "currency": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "value": { + "type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": { + "type": "string"}, + "maximum_value": { + "type": "string"} + } + }, + } + } + }, + "cancellation_terms": {"type": "array", + "items": {"anyOf": [ + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "refund_eligible": { + "type": "string"}, + }, + "required": [ + "fulfillment_state", + "refund_eligible"] + }, + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "return_policy": { + "type": "object", + "properties": { + "return_eligible": { + "type": "string"}, + "return_within": { + "type": "string"}, + "fulfillment_managed_by": { + "type": "string"}, + "return_location": { + "type": "object", + "properties": { + "address": { + "type": "string"}, + "gps": { + "type": "string"} + } + } + }, + "required": [ + "return_eligible", + "return_within", + "return_location", + ] + } + }, + "required": [ + "fulfillment_state", + "return_policy"] + } + ]}, + "minLength": 2 + }, + + "replacement_terms": {"type": "array", + "items": {"type": "object", + "properties": { + "replace_within": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "replace_within"] + } + }, + "rating": {"type": "string"}, + "matched": {"type": "string"}, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, + "end": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} + } + }, + } + }, + "recommended": {"type": "string"}, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": { + "type": "string"}, + "value": { + "type": "string"}, + }, + "required": [ + "code", + "value"] + } + }, + } + } + } + }, + "required": ["id", "parent_item_id", "descriptor", + "manufacturer", "price", "quantity", + "category_ids", "fulfillment_ids", "location_ids", + "payment_ids", + "cancellation_terms", "replacement_terms", + "matched", "recommended", "tags"], + } + }, + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "contact": {"type": "object", + "properties": { + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, + "email": {"type": "string", + "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} + } + } + }, + } + }, + + "offers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + } + }, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string"}, + "end": {"type": "string"} + } + }, + } + }, + "item_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "category_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + } + } + }, + + }, + + } + }, + + }, + "required": ["fulfillments", "payments", "descriptor", "providers"] + +} diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js new file mode 100644 index 0000000..2311ea7 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js @@ -0,0 +1,106 @@ +onSearchRules = [ + { + if: { properties: { "@ondc/org/returnable": { const: false } } }, + then: { + not: { + required: ["@ondc/org/return_window"], + error_message: "return window is available when returnable is false", + }, + }, + }, + + { + if: { properties: { category_id: { const: "F&B" } } }, + then: { + required: ["@ondc/org/fssai_license_no"], + }, + }, + { + if: { properties: { category_id: { const: "Packaged Foods" } } }, + then: { + required: ["@ondc/org/fssai_license_no"], + }, + }, + + { + if: { properties: { "@ondc/org/returnable": { const: false } } }, + then: { + required: ["@ondc/org/return_window"], + }, + }, + + { + if: { + properties: { + category_id: { + const: "Packaged Commodities", + }, + }, + }, + then: { + required: ["@ondc/org/statutory_reqs_packaged_commodities"], + }, + }, + + { + if: { + properties: { + category_id: { + const: "Packaged Foods", + }, + }, + }, + then: { + required: ["@ondc/org/statutory_reqs_prepackaged_food"], + }, + }, + { + if: { + properties: { + category_id: { + const: "fruits and vegetables", + }, + }, + }, + then: { + required: ["@ondc/org/mandatory_reqs_veggies_fruits"], + }, + }, + + { + if: { properties: { category_id: { const: "F&B" } } }, + then: { + required: ["tags"], + }, + }, + { + if: { properties: { category_id: { const: "Packaged Foods" } } }, + then: { + required: ["tags"], + }, + }, + { + if: { + properties: { + category_id: { + const: "f&b", + }, + }, + }, + then: { + properties: { + descriptor: { + required: ["name", "symbol", "short_desc", "long_desc"], + }, + }, + }, + else: { + properties: { + descriptor: { + required: ["name", "symbol", "short_desc", "long_desc", "images"], + }, + }, + }, + }, +]; +module.exports = { onSearchRules }; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js new file mode 100644 index 0000000..6cb69fd --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -0,0 +1,547 @@ +const onSearchItemValidations = require("./onSearchItemValidations"); + +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { type: "string" }, + country: { type: "string" }, + city: { type: "string" }, + action: { type: "string" }, + core_version: { type: "string" }, + bap_id: { type: "string" }, + bap_uri: { type: "string" }, + transaction_id: { type: "string", format: "uuid" }, + message_id: { type: "string" }, + timestamp: { type: "string", format: "date-time" }, + ttl: { type: "string", format: "duration" }, + bpp_uri: { type: "string" }, + bpp_id: { type: "string" }, + }, + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + "bpp/fulfillments": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { + type: "string", + enum: [ + "Delivery", + "Self-Pickup", + "Delivery and Self-Pickup", + ], + }, + }, + }, + }, + "bpp/descriptor": { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + pattern: "^(?!\\s*$).+\\.(jpeg|jpg|jfif|gif|png|ico)$", + }, + }, + }, + required: ["name", "symbol", "long_desc", "short_desc", "images"], + }, + "bpp/providers": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + time: { + type: "object", + properties: { + label: { type: "string", enum: ["enable", "disable"] }, + timestamp: { type: "string", format: "date-time" }, + }, + required: ["label", "timestamp"], + }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + pattern: + "^(?!\\s*$).+\\.(jpeg|jpg|jfif|gif|png|ico)$", + }, + }, + }, + required: [ + "name", + "symbol", + "long_desc", + "short_desc", + "images", + ], + }, + ttl: { type: "string", format: "duration" }, + "@ondc/org/fssai_license_no": { + type: "string", + minLength: 14, + maxLength: 14, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + gps: { type: "string" }, + address: { + type: "object", + properties: { + street: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["street", "city", "area_code", "state"], + }, + + circle: { + type: "object", + properties: { + gps: { + type: "string", + }, + radius: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + }, + }, + }, + time: { + type: "object", + properties: { + days: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + }, + required: ["days", "schedule"], + }, + }, + required: ["id", "address", "gps", "time"], + }, + }, + items: { + type: "array", + minItems: 1, + items: { + type: "object", + properties: { + id: { type: "string" }, + quantity: { + type: "object", + properties: { + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + }, + }, + category_id: { + type: "string", + enum: [ + "Fruits and Vegetables", + "Masala & Seasoning", + "Oil & Ghee", + "Gourmet & World Foods", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beverages", + "Beauty & Hygiene", + "Bakery, Cakes & Dairy", + "Kitchen Accessories", + "Baby Care", + "Snacks & Branded Foods", + "Pet Care", + "Stationery", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "Home Decor", + "Home Furnishings", + "Furniture", + "Garden and Outdoor Products", + "Home Improvement", + "Cookware and Dining", + "Storage and Organisation", + ], + }, + + // "@ondc/org/fssai_license_no": { + // type: "string", + // pattern: "^[a-zA-Z0-9]+$", + // }, + fulfillment_id: { type: "string" }, + location_id: { type: "string" }, + recommended: { type: "boolean" }, + "@ondc/org/returnable": { + type: "boolean", + }, + "@ondc/org/seller_pickup_return": { + type: "boolean", + }, + "@ondc/org/return_window": { + type: "string", + }, + "@ondc/org/cancellable": { + type: "boolean", + }, + "@ondc/org/time_to_ship": { + type: "string", + format: "duration", + }, + "@ondc/org/available_on_cod": { + type: "boolean", + }, + "@ondc/org/contact_details_consumer_care": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + not: { + type: "string", + pattern: "^0$", + }, + }, + + maximum_value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + not: { type: "string", pattern: "^0$" }, + }, + }, + required: ["value", "maximum_value", "currency"], + }, + tags: { + type: "object", + properties: { + veg: { + type: "string", + enum: ["yes", "no", "Yes", "No"], + }, + non_veg: { + type: "string", + enum: ["yes", "no", "Yes", "No"], + }, + }, + required: ["veg", "non_veg"], + }, + "@ondc/org/statutory_reqs_prepackaged_food": { + type: "object", + properties: { + nutritional_info: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + importer_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + brand_owner_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + other_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + additives_info: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + }, + required: ["nutritional_info", "additives_info"], + oneOf: [ + { + required: ["importer_FSSAI_license_no"], + properties: { + importer_FSSAI_license_no: { + type: "string", + }, + }, + }, + { + required: ["brand_owner_FSSAI_license_no"], + properties: { + brand_owner_FSSAI_license_no: { + type: "string", + }, + }, + }, + { + required: ["other_FSSAI_license_no"], + properties: { + other_FSSAI_license_no: { + type: "string", + }, + }, + }, + ], + }, + "@ondc/org/statutory_reqs_packaged_commodities": { + type: "object", + properties: { + manufacturer_or_packer_name: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + manufacturer_or_packer_address: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + common_or_generic_name_of_commodity: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + net_quantity_or_measure_of_commodity_in_pkg: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + month_year_of_manufacture_packing_import: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + }, + required: [ + "manufacturer_or_packer_name", + "manufacturer_or_packer_address", + "common_or_generic_name_of_commodity", + "month_year_of_manufacture_packing_import", + "net_quantity_or_measure_of_commodity_in_pkg", + ], + }, + "@ondc/org/mandatory_reqs_veggies_fruits": { + type: "object", + properties: { + net_quantity: { + type: "string", + minLength: 1, + }, + }, + required: ["net_quantity"], + }, + + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + minItems: 1, + items: { + type: "string", + }, + }, + }, + }, + }, + + allOf: onSearchItemValidations.on_search_rules, + required: [ + "id", + "category_id", + "@ondc/org/contact_details_consumer_care", + "price", + "descriptor", + "@ondc/org/returnable", + "location_id", + "fulfillment_id", + "@ondc/org/cancellable", + "@ondc/org/available_on_cod", + "@ondc/org/time_to_ship", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + minLength: 10, + maxLength: 11, + }, + email: { type: "string", format: "email" }, + }, + required: ["phone"], + }, + }, + required: ["contact"], + }, + }, + + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string", const: "serviceability" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "location", + "category", + "type", + "val", + "unit", + ], + }, + value: { type: "string" }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + }, + }, + required: [ + "items", + "id", + "time", + "descriptor", + "locations", + "fulfillments", + "tags", + "ttl", + ], + }, + }, + }, + required: ["bpp/fulfillments", "bpp/descriptor", "bpp/providers"], + }, + }, + required: ["catalog"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js new file mode 100644 index 0000000..599fb81 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js @@ -0,0 +1,490 @@ +onSearchFashionSchema = { + "type": "object", + "properties": { + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "payments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "providers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "rating": {"type": "string"}, + "ttl": {"type": "string"}, + "locations": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "gps": {"type": "string"}, + "address": {"type": "string"}, + "city": {"type": "object", + "properties": { + "code": {"type": "string"}, + "name": {"type": "string"}, + } + }, + "state": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "country": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "area_code": {"type": "string"}, + } + } + }, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "value": {"type": "string"}, + } + }} + } + } + }, + "items": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "parent_item_id": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "code": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + }, + }, + "manufacturer": {"type": "object", + "properties": { + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + } + }, + "contact": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "address": { + "type": "object", + "properties": { + "full": { + "type": "string"}, + } + }, + } + }, + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} + } + }, + "price": {"type": "object", + "properties": { + "currency": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "maximum_value": {"type": "string", + "pattern": "^\d*\.?\d*$"} + }, + "require": ["currency", "value"], + }, + + "quantity": {"type": "object", + "properties": { + "unitized": {"type": "object", + "properties": { + "measure": { + "type": "object", + "properties": { + "unit": { + "type": "string"}, + "value": { + "type": "string"} + + } + }, + } + }, + "available": {"type": "object", + "properties": { + "count": { + "type": "string", + "pattern": "^\d*$"} + + } + }, + "maximum": {"type": "object", + "properties": { + "count": {"type": "string", + "pattern": "^\d*$"} + } + }, + } + }, + "category_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "fulfillment_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "payment_ids": {"type": "array", + "items": { + "type": "string", + "enum": ["1", "2"]}}, + "add-ons": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "code": { + "type": "string"}, + "short_desc": { + "type": "string"}, + "long_desc": { + "type": "string"}, + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "url"] + + } + } + } + }, + "price": {"type": "object", + "properties": { + "currency": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "value": { + "type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": { + "type": "string"}, + "maximum_value": { + "type": "string"} + } + }, + } + } + }, + "cancellation_terms": {"type": "array", + "items": {"anyOf": [ + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "refund_eligible": { + "type": "string"}, + }, + "required": [ + "fulfillment_state", + "refund_eligible"] + }, + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "return_policy": { + "type": "object", + "properties": { + "return_eligible": { + "type": "string"}, + "return_within": { + "type": "string"}, + "fulfillment_managed_by": { + "type": "string"}, + "return_location": { + "type": "object", + "properties": { + "address": { + "type": "string"}, + "gps": { + "type": "string"} + } + } + }, + "required": [ + "return_eligible", + "return_within", + "return_location", + ] + } + }, + "required": [ + "fulfillment_state", + "return_policy"] + } + ]}, + "minLength": 2 + }, + + "replacement_terms": {"type": "array", + "items": {"type": "object", + "properties": { + "replace_within": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "replace_within"] + } + }, + "rating": {"type": "string"}, + "matched": {"type": "string"}, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, + "end": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} + } + }, + } + }, + "recommended": {"type": "string"}, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": { + "type": "string"}, + "value": { + "type": "string"}, + }, + "required": [ + "code", + "value"] + } + }, + } + } + } + }, + "required": ["id", "parent_item_id", "descriptor", + "manufacturer", "price", "quantity", + "category_ids", "fulfillment_ids", "location_ids", + "payment_ids", + "cancellation_terms", "replacement_terms", + "matched", "recommended", "tags"], + } + }, + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "contact": {"type": "object", + "properties": { + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, + "email": {"type": "string", + "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} + } + } + }, + } + }, + + "offers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + } + }, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string"}, + "end": {"type": "string"} + } + }, + } + }, + "item_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "category_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + } + } + }, + + }, + + } + }, + + }, + "required": ["fulfillments", "payments", "descriptor", "providers"] + +} diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js new file mode 100644 index 0000000..2dfa71a --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js @@ -0,0 +1,175 @@ +module.exports = { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", minLength: 1 }, + fulfillment_id: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["id", "fulfillment_id"], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + quantity: { + type: "object", + properties: { + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + }, + }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + }, + }, + required: ["price", "quantity"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + "@ondc/org/provider_name": { type: "string" }, + tracking: { type: "boolean" }, + "@ondc/org/category": { + type: "string", + enum: [ + "Express Delivery", + "Standard Delivery", + "Immediate Delivery", + "Same Day Delivery", + "Next Day Delivery", + ], + }, + "@ondc/org/TAT": { type: "string", format: "duration" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Serviceable", "Non-serviceable"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + }, + + required: [ + "id", + "@ondc/org/provider_name", + "state", + "@ondc/org/category", + "@ondc/org/TAT", + ], + }, + }, + }, + required: ["provider", "items", "fulfillments", "quote"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js new file mode 100644 index 0000000..dfe0fcb --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js @@ -0,0 +1,548 @@ +const postConfirmRules = require("./postConfirmValidations"); + +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress", "Completed", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + }, + rateable: { type: "boolean" }, + }, + required: ["id", "locations"], + }, + + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + status: { + type: "string", + enum: [ + "Return_Initiated", + "Return_Approved", + "Return_Rejected", + "Return_Picked", + "Return_Delivered", + "Liquidated", + "Cancelled", + ], + }, + }, + required: ["status"], + }, + }, + required: ["id", "quantity", "fulfillment_id"], + }, + }, + + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + updated_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + required: ["name", "address", "phone", "created_at", "updated_at"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + "@ondc/org/provider_name": { type: "string" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Reverse QC"], + }, + tracking: { type: "boolean" }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { type: "string" }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + gps: { type: "string" }, + }, + required: ["address", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "tracking", + "start", + "end", + ], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + // allOf: [ + // { + // if: { + // properties: { + // status: { + // const: "PAID", + // }, + // }, + // atPath: "1", + // }, + // then: { properties: { type: { const: "ON-ORDER" } } }, + // }, + // ], + }, + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { type: "string" }, + label: { type: "string", const: "Invoice" }, + }, + }, + }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + maxLength: 3, + minLength: 3, + }, + }, + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + // allOf: postConfirmRules, + required: [ + "payment", + "fulfillments", + "quote", + "items", + "id", + "state", + "provider", + "billing", + "created_at", + "updated_at", + ], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js new file mode 100644 index 0000000..73d2357 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js @@ -0,0 +1,14 @@ +module.exports = { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + uri: { type: "string" }, + }, + required: ["phone"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onTrackSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onTrackSchema.js new file mode 100644 index 0000000..3aa8cdd --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onTrackSchema.js @@ -0,0 +1,13 @@ +module.exports = { + type: "object", + properties: { + tracking: { + type: "object", + properties: { + url: { type: "string" }, + status: { type: "string", enum: ["active", "inactive"] }, + }, + required: ["status"], + }, + }, +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js new file mode 100644 index 0000000..ea0ebd7 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js @@ -0,0 +1,486 @@ +const postConfirmRules = require("./postConfirmValidations"); + +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress", "Completed", "Cancelled"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + status: { + type: "string", + enum: [ + "Return_Initiated", + "Return_Approved", + "Return_Rejected", + "Return_Picked", + "Return_Delivered", + "Liquidated", + "Cancelled", + ], + }, + }, + required: ["status"], + }, + }, + required: ["id", "quantity", "fulfillment_id"], + }, + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + "@ondc/org/provider_name": { type: "string" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Reverse QC"], + }, + tracking: { type: "boolean" }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { type: "string" }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + gps: { type: "string" }, + }, + required: ["address", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "tracking", + "start", + "end", + ], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + // allOf: [ + // { + // if: { + // properties: { + // status: { + // const: "PAID", + // }, + // }, + // atPath: "1", + // }, + // then: { properties: { type: { const: "ON-ORDER" } } }, + // }, + // ], + }, + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { type: "string" }, + label: { type: "string", const: "Invoice" }, + }, + }, + }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + maxLength: 3, + minLength: 3, + }, + }, + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + // allOf: postConfirmRules, + required: [ + "payment", + "fulfillments", + "quote", + "items", + "id", + "state", + "created_at", + "updated_at", + ], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/postConfirmValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/postConfirmValidations.js new file mode 100644 index 0000000..e69de29 diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js new file mode 100644 index 0000000..7cbff8c --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js @@ -0,0 +1,140 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "search", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["descriptor"], + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + const: "Delivery", + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + }, + required: ["type", "end"], + }, + payment: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + required: ["item", "fulfillment", "payment"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js new file mode 100644 index 0000000..6888f9c --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js @@ -0,0 +1,170 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "select", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + location_id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["id", "location_id", "quantity"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + }, + required: ["end"], + }, + }, + billing: { + type: "object", + properties: { + tax_number: { + type: "string", + }, + }, + required: ["tax_number"], + }, + }, + required: ["provider", "items", "fulfillments"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js new file mode 100644 index 0000000..f2d2f0d --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js @@ -0,0 +1,79 @@ +module.exports = { + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "status", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js new file mode 100644 index 0000000..c29bf6d --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js @@ -0,0 +1,199 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "update", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum: ["item", "payment"], + }, + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress", "Completed"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: [ + { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + update_type: { + type: "string", + enum: ["return", "cancel"], + }, + reason_code: { + type: "string", + minLength: 3, + maxLength: 3, + }, + ttl_approval: { + type: "string", + format: "duration", + }, + ttl_reverseqc: { + type: "string", + format: "duration", + }, + image: { + type: "string", + }, + }, + required: ["update_type"], + if: { + properties: { + update_type: { + const: "return", + }, + }, + }, + then: { required: ["reason_code"] }, + }, + }, + required: ["id", "quantity", "tags"], + }, + ], + }, + payment: { + type: "object", + properties: { + "@ondc/org/settlement_details": { + type: "array", + items: [ + { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + settlement_amount: { + type: "string", + }, + settlement_timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + "settlement_amount", + "settlement_timestamp", + ], + }, + ], + }, + }, + required: ["@ondc/org/settlement_details"], + }, + }, + required: ["id", "state", "provider", "items"], + }, + }, + required: ["update_target", "order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/log-validation-utility/services/cbCheck.service.js b/utilities/log-validation-utility/services/cbCheck.service.js new file mode 100644 index 0000000..cfe6d0a --- /dev/null +++ b/utilities/log-validation-utility/services/cbCheck.service.js @@ -0,0 +1,40 @@ +const path = require("path"); +const utils = require("../utils/utils"); +const vl = require("../utils/validateLogUtil"); + +const fs = require("fs"); + +const validateLog = async (domain, dirPath) => { + console.log("Inside Log Validation Service..."); + const logsPath = path.join(__dirname, "..", dirPath); + switch (domain) { + case "retail": + vl.validateLogs(logsPath); + break; + default: + console.log("Invalid Domain!!"); + } +}; + +// const saveSchema = (domain) => { +// console.log( +// `Inside Callback Check Service....\n*** Saving Schemas on DB for ${domain} domain ***` +// ); +// const logDir = path.join(utils.rootPath, "public", "logs"); + +// fs.readdir(logDir, (err, filenames) => { +// if (err) throw err; +// filenames.forEach((filename) => { +// fs.readFile(path.join(logDir, filename), "utf-8", (err, content) => { +// console.log(`reading file ${filename}`); +// if (err) throw new Error(err); +// content = JSON.parse(content); + +// retCbCheckUtil.saveSchema(content, domain); +// }); +// }); +// }); +// // console.log(txnId); +// }; + +module.exports = { validateLog }; diff --git a/utilities/log-validation-utility/services/service.js b/utilities/log-validation-utility/services/service.js new file mode 100644 index 0000000..d6bd91f --- /dev/null +++ b/utilities/log-validation-utility/services/service.js @@ -0,0 +1,58 @@ +const config = require("../config/config"); +const constants = require("../utils/constants"); +const validateSchema = require("../utils/schemaValidation"); +const utils = require("../utils/utils"); +const _ = require("lodash"); + +const checkContext = (data, path) => { + console.log( + `Inside Context Validation Check....\n*** Validating context for ${path} ***` + ); + + if (!data) return; + let errObj = {}; + + //Transaction ID - UUID Validity check + if (data.transaction_id) { + const result = utils.uuidCheck(data.transaction_id); + if (!result) { + errObj.tId_err = "Transaction id is not a valid uuid"; + } + } + + //Transaction ID != Message ID + if (data.transaction_id === data.message_id) { + errObj.id_err = "transaction_id and message id can't be same"; + } + if (data.action != path) { + errObj.action_err = `context.action should be ${path}`; + } + if (data.ttl && data.ttl != constants.RET_CONTEXT_TTL) { + { + errObj.ttl_err = `ttl = ${constants.RET_CONTEXT_TTL} as per the API Contract`; + } + } + + if (data.timestamp) { + let date = data.timestamp; + result = utils.timestampCheck(date); + if (result && result.err === "FORMAT_ERR") { + errObj.timestamp_err = + "Timestamp not in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format"; + } else if (result && result.err === "INVLD_DT") { + errObj.timestamp_err = "Timestamp should be in date-time format"; + } + } + + if (_.isEmpty(errObj)) { + const result = { valid: true, SUCCESS: "Context Valid" }; + console.log(result); + return result; + } else { + const result = { valid: false, ERRORS: errObj }; + console.error(result); + return result; + } +}; + +module.exports = { checkContext }; diff --git a/utilities/log-validation-utility/utils/constants.js b/utilities/log-validation-utility/utils/constants.js new file mode 100644 index 0000000..aad46cc --- /dev/null +++ b/utilities/log-validation-utility/utils/constants.js @@ -0,0 +1,23 @@ +module.exports = Object.freeze({ + RET_CONTEXT_TTL: "PT30S", + RET_CONTEXT_ACTION: "action", + DB_PATH: "dbfiles", + RET_SEARCH: "search", + RET_ONSEARCH: "on_search", + RET_SELECT: "select", + RET_ONSELECT: "on_select", + RET_INIT: "init", + RET_ONINIT: "on_init", + RET_CONFIRM: "confirm", + RET_ONCONFIRM: "on_confirm", + RET_TRACK: "track", + RET_ONTRACK: "on_track", + RET_CANCEL: "cancel", + RET_ONCANCEL: "on_cancel", + RET_UPDATE: "update", + RET_ONUPDATE: "on_update", + RET_STATUS: "status", + RET_ONSTATUS: "on_status", + RET_SUPPORT: "support", + RET_ONSUPPORT: "on_support", +}); diff --git a/utilities/log-validation-utility/utils/ret.cbCheck.util.js b/utilities/log-validation-utility/utils/ret.cbCheck.util.js new file mode 100644 index 0000000..466cb2b --- /dev/null +++ b/utilities/log-validation-utility/utils/ret.cbCheck.util.js @@ -0,0 +1,7 @@ +const { validateLogsUtil } = require("./validateLogUtil"); + +const validateLogs = (domain) => { + validateLogsUtil(domain); +}; + +module.exports = { validateLogs }; diff --git a/utilities/log-validation-utility/utils/retail/retCancel.js b/utilities/log-validation-utility/utils/retail/retCancel.js new file mode 100644 index 0000000..068f5ba --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retCancel.js @@ -0,0 +1,155 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const utils = require("../utils"); +const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); + +const checkCancel = (dirPath, msgIdSet) => { + let cnclObj = {}; + try { + var cancel = fs.readFileSync(dirPath + `/${constants.RET_CANCEL}.json`); + cancel = JSON.parse(cancel); + + try { + console.log(`Validating Schema for ${constants.RET_CANCEL} API`); + const vs = validateSchema("retail", constants.RET_CANCEL, cancel); + if (vs != "error") { + // console.log(vs); + Object.assign(cnclObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_CANCEL}`, + error + ); + } + + console.log(`Checking context for /${constants.RET_CANCEL} API`); //checking context + try { + res = checkContext(cancel.context, constants.RET_CANCEL); + if (!res.valid) { + cnclObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_CANCEL} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SELECT} and /${constants.RET_CANCEL}` + ); + if (!_.isEqual(dao.getValue("city"), cancel.context.city)) { + cnclObj.city = `City code mismatch in /${constants.RET_SELECT} and /${constants.RET_CANCEL}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SELECT} and /${constants.RET_CANCEL}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), cancel.context.timestamp)) { + dao.setValue("cnclTmpstmp", cancel.context.timestamp); + cnclObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_CANCEL} api`; + } + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_CANCEL} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_CANCEL}` + ); + if (!_.isEqual(dao.getValue("txnId"), cancel.context.transaction_id)) { + cnclObj.txnId = `Transaction Id for /${constants.RET_SELECT} and /${constants.RET_CANCEL} api should be same`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_CANCEL} api`, + error + ); + } + + try { + console.log(`Checking Message Id of /${constants.RET_CANCEL}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for /select and /on_select api should be same"; + // } + + if (msgIdSet.has(cancel.context.message_id)) { + cnclObj.msgId2 = `Message Id cannot be same for different sets of APIs`; + } + dao.setValue("msgId", cancel.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_CANCEL}`, + error + ); + } + + cancel = cancel.message; + + try { + console.log( + `Comparing order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + ); + if (cancel.order_id != dao.getValue("onCnfrmOrdrId")) { + cnclObj.cancelOrdrId = `Order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM} do not match`; + console.log( + `Order Id mismatch in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + ); + } + } catch (error) { + console.log( + `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}`, + error + ); + // cnclObj.cancelOrdrId = + // "Order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM} do not match"; + } + + try { + console.log("Checking the validity of cancellation reason id"); + if (!(cancel.cancellation_reason_id in utils.cancellation_rid)) { + console.log( + `Cancellation Reason Id in /${constants.RET_CANCEL} is not a valid reason id` + ); + + cnclObj.cancelRid = `Cancellation reason id in /${constants.RET_CANCEL} is not a valid reason id`; + } else dao.setValue("cnclRid", cancel.cancellation_reason_id); + } catch (error) { + // cnclObj.cancelRid = + // "Cancellation reason id in /${constants.RET_CANCEL} is not a valid reason id"; + console.log( + `Error while checking validity of cancellation reason id /${constants.RET_CANCEL}`, + error + ); + } + dao.setValue("cnclObj", cnclObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_CANCEL} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_CANCEL} API`, + err + ); + } + } +}; + +module.exports = checkCancel; diff --git a/utilities/log-validation-utility/utils/retail/retConfirm.js b/utilities/log-validation-utility/utils/retail/retConfirm.js new file mode 100644 index 0000000..389d5fc --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retConfirm.js @@ -0,0 +1,415 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); + +const checkConfirm = (dirPath, msgIdSet) => { + let cnfrmObj = {}; + try { + var confirm = fs.readFileSync(dirPath + `/${constants.RET_CONFIRM}.json`); + confirm = JSON.parse(confirm); + + try { + console.log(`Validating Schema for ${constants.RET_CONFIRM} API`); + const vs = validateSchema("retail", constants.RET_CONFIRM, confirm); + if (vs != "error") { + // console.log(vs); + Object.assign(cnfrmObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_CONFIRM} API`); //checking context + res = checkContext(confirm.context, constants.RET_CONFIRM); + if (!res.valid) { + cnfrmObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_CONFIRM} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}` + ); + if (!_.isEqual(dao.getValue("city"), confirm.context.city)) { + cnfrmObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_ONINIT} and /${constants.RET_CONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), confirm.context.timestamp)) { + cnfrmObj.tmpstmp = `Timestamp for /${constants.RET_ONINIT} api cannot be greater than or equal to /${constants.RET_CONFIRM} api`; + } + dao.setValue("tmpstmp", confirm.context.timestamp); + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_ONINIT} and /${constants.RET_CONFIRM} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_CONFIRM}` + ); + if (!_.isEqual(dao.getValue("txnId"), confirm.context.transaction_id)) { + cnfrmObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_CONFIRM} api`, + error + ); + } + + try { + console.log(`Checking Message Id of /${constants.RET_CONFIRM}`); + // if (!_.isEqual(msgId, on_init.context.message_id)) { + // onInitObj.msgId = "Message Ids for /init and /on_init api should be same"; + // } + + if (msgIdSet.has(confirm.context.message_id)) { + cnfrmObj.msgId2 = + "Message Id cannot be same for different sets of APIs"; + } + dao.setValue("msgId", confirm.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_CONFIRM}`, + error + ); + } + + confirm = confirm.message.order; + + const cnfrmOrdrId = confirm.id; + dao.setValue("cnfrmOrdrId", cnfrmOrdrId); + + try { + console.log(`Checking order state in /${constants.RET_CONFIRM}`); + if (confirm.state.toLowerCase() != "created") { + cnfrmObj.state = `Default order state should be used in /${constants.RET_CONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while checking order state in /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log( + `Checking provider id and location in /${constants.RET_CONFIRM}` + ); + if (confirm.provider.id != dao.getValue("providerId")) { + cnfrmObj.prvdrId = `Provider Id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_CONFIRM}`; + } + + if (confirm.provider.locations[0].id != dao.getValue("providerLoc")) { + cnfrmObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_CONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while checking provider id and location in /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing item Ids and fulfillment ids in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` + ); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + const itemsIdList = dao.getValue("itemsIdList"); + let i = 0; + const len = confirm.items.length; + while (i < len) { + let itemId = confirm.items[i].id; + if (itemId in itemFlfllmnts) { + if (confirm.items[i].fulfillment_id != itemFlfllmnts[itemId]) { + let itemkey = `item_FFErr${i}`; + cnfrmObj[ + itemkey + ] = `items[${i}].fulfillment_id mismatches for Item ${itemId} in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`; + } + } else { + let itemkey = `item_FFErr${i}`; + cnfrmObj[ + itemkey + ] = `Item Id ${itemId} does not exist in /${constants.RET_ONSELECT}`; + } + + if (itemId in itemsIdList) { + if (confirm.items[i].quantity.count != itemsIdList[itemId]) { + cnfrmObj.cntErr = `Warning: items[${i}].quantity.count for item ${itemId} mismatches with the items quantity selected in /${constants.RET_SELECT}`; + } + } + i++; + } + } catch (error) { + console.log( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing billing object in /${constants.RET_INIT} and /${constants.RET_CONFIRM}` + ); + const billing = dao.getValue("billing"); + if (!_.isEqual(billing, confirm.billing)) { + cnfrmObj.bill = `Billing object mismatches in /${constants.RET_INIT} and /${constants.RET_CONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_CONFIRM}` + ); + } + + try { + console.log(`Checking fulfillments objects in /${constants.RET_CONFIRM}`); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + let i = 0; + const len = confirm.fulfillments.length; + while (i < len) { + //Comparing fulfillment Ids + if (confirm.fulfillments[i].id) { + let id = confirm.fulfillments[i].id; + if (!Object.values(itemFlfllmnts).includes(id)) { + key = `ffID${id}`; + //MM->Mismatch + cnfrmObj[ + key + ] = `fulfillment id ${id} does not exist in /${constants.RET_ONSELECT}`; + } + } else { + cnfrmObj.ffId = `fulfillments[${i}].id is missing in /${constants.RET_CONFIRM}`; + } + + if ( + !confirm.fulfillments[i].end || + !confirm.fulfillments[i].end.person + ) { + cnfrmObj.ffprsn = `fulfillments[${i}].end.person object is missing`; + } + + if ( + !_.isEqual( + confirm.fulfillments[i].location.gps, + dao.getValue("buyerGps") + ) + ) { + cnfrmObj.gpsErr = `fulfillments[${i}].end.location gps is not matching with gps in /select`; + } + + if ( + !_.isEqual( + confirm.fulfillments[i].location.address.area_code, + dao.getValue("buyerAddr") + ) + ) { + cnfrmObj.gpsErr = `fulfillments[${i}].end.location.address.area_code is not matching with area_code in /select`; + } + + i++; + } + } catch (error) { + console.log( + `!!Error while checking fulfillments object in /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log(`Checking payment object in /${constants.RET_CONFIRM}`); + // if (dao.getValue("paymentType") === "ON-ORDER") { + if (confirm.payment.status != "PAID") { + cnfrmObj.pymntEr = `payment.status should be "PAID" in case of pre-paid order(ON-ORDER)`; + } else if ( + !confirm.payment.params || + !confirm.payment.params.transaction_id + ) { + cnfrmObj.pymntErrr = `payment.params.transaction_id is missing when status is PAID`; + } + + if (confirm.payment.type != "ON-ORDER") { + cnfrmObj.pymnttype = `payment.type is expected to be ON-ORDER`; + } + + if (confirm.payment.collected_by != `BAP`) { + cnfrmObj.pymntcollected = `payment.collected_by is expected to be BAP`; + } + + // if (!confirm.payment.uri) + // cnfrmObj.uri = `payment.uri is mandatory in /confirm`; + + // if (!confirm.payment.tl_method) + // cnfrmObj.tlmthd = `payment.tl_method is mandatory in /confirm`; + + if ( + parseFloat(confirm.payment.params.amount) != + parseFloat(confirm.quote.price.value) + ) { + cnfrmObj.confirmedAmount = + "Quoted price (/confirm) doesn't match with the amount in payment.params"; + } + + if ( + !_.isEqual( + confirm.payment["@ondc/org/settlement_details"], + dao.getValue("sttlmntdtls") + ) + ) { + cnfrmObj.sttlmntdtls = `payment settlement_details mismatch in /${constants.RET_ONINIT} & /${constants.RET_CONFIRM}`; + } + + if ( + !confirm.hasOwnProperty("created_at") || + !confirm.hasOwnProperty("updated_at") + ) { + cnfrmObj.ordertmpstmp = `order created and updated timestamps are mandatory in /${constants.RET_CONFIRM}`; + } else { + if (!_.isEqual(confirm.created_at, dao.getValue("tmpstmp"))) { + cnfrmObj.orderCrtd = `order.created_at timestamp should be the same as context.timestamp`; + } else { + dao.setValue("ordrcrtdtmpstmp", confirm.created_at); + } + + if (!_.isEqual(confirm.created_at, confirm.updated_at)) { + cnfrmObj.ordrupdtd = `order.updated_at timestamp should be the same as order.created_at timestamp`; + } else { + dao.setValue("ordrupdtdtmpstmp", confirm.updated_at); + } + } + } catch (error) { + console.log( + `!!Error while checking payment object in /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log(`storing payment object in /${constants.RET_CONFIRM}`); + dao.setValue("cnfrmpymnt", confirm.payment); + } catch (error) { + console.log( + `!!Error while storing payment object in /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` + ); + console.log("confirm quote", confirm.quote); + if (!_.isEqual(dao.getValue("quoteObj"), confirm.quote)) { + cnfrmObj.quoteObj = `Quote Objects in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM} do not match`; + } + } catch (error) { + console.log( + `!!Error while Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` + ); + // cnfrmObj.quoteObj = "Quote Object in /on_select and /confirm mismatch"; + } + + try { + console.log( + `Checking Buyer App finder fee amount in /${constants.RET_CONFIRM}` + ); + const buyerFF = dao.getValue("buyerFF"); + if ( + !confirm.payment["@ondc/org/buyer_app_finder_fee_amount"] || + parseFloat(confirm.payment["@ondc/org/buyer_app_finder_fee_amount"]) != + buyerFF + ) { + cnfrmObj.bapFinderFee = `Buyer App Finder fee can't change`; + console.log( + `Buyer app finder fee ${confirm.payment["@ondc/org/buyer_app_finder_fee_amount"]} can't change in /${constants.RET_CONFIRM}` + ); + } + } catch (error) { + console.log( + `!!Error while Checking Buyer App finder fee amount in /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log("storing order created and updated timestamps"); + if (confirm.created_at) dao.setValue("ordrCrtd", confirm.created_at); + + if (confirm.updated_at) dao.setValue("ordrUpdtd", confirm.updated_at); + } catch (error) { + console.log( + `!!Error while storing order created and updated timestamps in /${constants.RET_CONFIRM}` + ); + } + + try { + console.log( + `Comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` + ); + const onSelectPrice = dao.getValue("onSelectPrice"); + const confirmQuotePrice = parseFloat(confirm.quote.price.value); + if (onSelectPrice != confirmQuotePrice) { + console.log( + `order quote price in /${constants.RET_CONFIRM} is not equal to the quoted price in /${constants.RET_ONSELECT}` + ); + cnfrmObj.quoteErr = `Quoted Price in /${constants.RET_CONFIRM} INR ${confirmQuotePrice} does not match with the quoted price in /${constants.RET_ONSELECT} INR ${onSelectPrice}`; + } + } catch (error) { + console.log( + `!!Error while comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` + ); + } + + // try { + // console.log( + // `Checking and Storing buyer's T&C in /${constants.RET_CONFIRM}` + // ); + // if (confirm.hasOwnProperty("tags")) { + // dao.setValue("buyerT&C", confirm.tags); + // } + // } catch (error) { + // console.log( + // `!!Error while checking and storing buyer's T&C in /${constants.RET_CONFIRM}`, + // error + // ); + // } + + dao.setValue("cnfrmObj", cnfrmObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_CONFIRM} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_CONFIRM} API`, + err + ); + } + } +}; + +module.exports = checkConfirm; diff --git a/utilities/log-validation-utility/utils/retail/retInit.js b/utilities/log-validation-utility/utils/retail/retInit.js new file mode 100644 index 0000000..a465b14 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retInit.js @@ -0,0 +1,255 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); + +const checkInit = (dirPath, msgIdSet) => { + let initObj = {}; + try { + var init = fs.readFileSync(dirPath + `/${constants.RET_INIT}.json`); + init = JSON.parse(init); + + try { + console.log(`Validating Schema for ${constants.RET_INIT} API`); + const vs = validateSchema("retail", constants.RET_INIT, init); + if (vs != "error") { + // console.log(vs); + Object.assign(initObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_INIT}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_INIT} API`); //checking context + res = checkContext(init.context, constants.RET_INIT); + if (!res.valid) { + initObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_INIT} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_INIT}` + ); + + if (!_.isEqual(dao.getValue("city"), init.context.city)) { + initObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_INIT}`; + } + } catch (error) { + console.log( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_INIT}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_ONSELECT} and /${constants.RET_INIT}` + ); + if (_.gte(dao.getValue("tmpstmp"), init.context.timestamp)) { + initObj.tmpstmp = `Timestamp for /${constants.RET_ONSELECT} api cannot be greater than or equal to /init api`; + } + dao.setValue(dao.getValue("tmpstmp"), init.context.timestamp); + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_ONSELECT} and /${constants.RET_INIT} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_INIT}` + ); + if (!_.isEqual(dao.getValue("txnId"), init.context.transaction_id)) { + initObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_INIT} api`, + error + ); + } + + try { + console.log(`Checking Message Ids of /${constants.RET_INIT}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for /select and /on_select api should be same"; + // } + + if (msgIdSet.has(init.context.message_id)) { + initObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + } + dao.setValue("msgId", init.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `Error while checking message id for /${constants.RET_INIT}`, + error + ); + } + + init = init.message.order; + + try { + console.log( + `Comparing provider object in /${constants.RET_SELECT} and /${constants.RET_INIT}` + ); + + if (dao.getValue("providerId") != init.provider["id"]) { + initObj.prvdId = `Provider Id mismatches in /${constants.RET_SELECT} and /${constants.RET_INIT}`; + } + + if (dao.getValue("providerLoc") != init.provider.locations[0].id) { + initObj.prvdfrLoc = `Provider.locations[0].id mismatches in /${constants.RET_SELECT} and /${constants.RET_INIT}`; + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.RET_SELECT} and /${constants.RET_INIT}`, + error + ); + } + + try { + console.log(`Checking billing object in /${constants.RET_INIT}`); + if (!init["billing"]) { + initObj.bill = `Billing object missing in /${constants.RET_INIT}`; + } else { + dao.setValue("billing", init.billing); + if ( + !_.isEqual(init.billing.address.area_code, dao.getValue("buyerAddr")) + ) { + initObj.billAreaCode = `area_code in billing.address does not match with area_code in /${constants.RET_SELECT}`; + } + } + } catch (error) { + console.log( + `!!Error while checking billing object in /${constants.RET_INIT}`, + error + ); + } + + try { + console.log( + `Comparing item Ids and fulfillment ids in /${constants.RET_ONSELECT} and /${constants.RET_INIT}` + ); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + const itemsIdList = dao.getValue("itemsIdList"); + let i = 0; + const len = init.items.length; + while (i < len) { + let itemId = init.items[i].id; + if (itemId in itemFlfllmnts) { + if (init.items[i].fulfillment_id != itemFlfllmnts[itemId]) { + let itemkey = `item_FFErr${i}`; + initObj[ + itemkey + ] = `items[${i}].fulfillment_id mismatches for Item ${itemId} in /${constants.RET_ONSELECT} and /${constants.RET_INIT}`; + } + } else { + let itemkey = `item_FFErr${i}`; + initObj[itemkey] = `Item Id ${itemId} does not exist in /on_select`; + } + + if (itemId in itemsIdList) { + if (init.items[i].quantity.count != itemsIdList[itemId]) { + initObj.cntErr = `Warning: items[${i}].quantity.count for item ${itemId} mismatches with the items quantity selected in /${constants.RET_SELECT}`; + } + } + i++; + } + } catch (error) { + console.log( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_INIT}` + ); + } + + try { + console.log(`Checking fulfillments objects in /${constants.RET_INIT}`); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + let i = 0; + const len = init.fulfillments.length; + while (i < len) { + //Comparing fulfillment Ids + let id = init.fulfillments[i].id; + if (id) { + if (!Object.values(itemFlfllmnts).includes(id)) { + key = `ffID${id}`; + //MM->Mismatch + initObj[ + key + ] = `fulfillment id ${id} does not exist in /${constants.RET_ONSELECT}`; + } + + if ( + !_.isEqual( + init.fulfillments[i].end.location.gps, + dao.getValue("buyerGps") + ) + ) { + gpskey = `gpsKey${i}`; + initObj[ + gpskey + ] = `gps coordinates in fulfillments[${i}].end.location mismatch in /${constants.RET_SELECT} & /${constants.RET_INIT}`; + } + + if ( + !_.isEqual( + init.fulfillments[i].end.location.address.area_code, + dao.getValue("buyerAddr") + ) + ) { + addrkey = `addrKey${i}`; + initObj[ + addrkey + ] = `address.area_code in fulfillments[${i}].end.location mismatch in /${constants.RET_SELECT} & /${constants.RET_INIT}`; + } + + //Comparing Provider_id + // if (init.fulfillments[i].provider_id) { + // let prvdrId = init.fulfillments[i].provider_id; + // if (prvdrId != dao.getValue("bppId")) { + // let key = `ffPrvdrId${prvdrId}`; + // initObj[ + // key + // ] = `Provider Id for fulfillment ${id} should be the bpp_id as per the contract`; + // } + // } + } else { + initObj.ffId = `fulfillments[${i}].id is missing in /${constants.RET_INIT}`; + } + + i++; + } + } catch (error) { + console.log( + `!!Error while checking fulfillments object in /${constants.RET_INIT}`, + error + ); + } + + dao.setValue("initObj", initObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_INIT} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_INIT} API` + ); + } + } +}; + +module.exports = checkInit; diff --git a/utilities/log-validation-utility/utils/retail/retOnCancel.js b/utilities/log-validation-utility/utils/retail/retOnCancel.js new file mode 100644 index 0000000..294f894 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnCancel.js @@ -0,0 +1,166 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); + +const checkOnCancel = (dirPath, msgIdSet) => { + let onCnclObj = {}; + + try { + var on_cancel = fs.readFileSync( + dirPath + `/${constants.RET_ONCANCEL}.json` + ); + + on_cancel = JSON.parse(on_cancel); + + try { + console.log(`Validating Schema for /${constants.RET_ONCANCEL} API`); + const vs = validateSchema("retail", constants.RET_ONCANCEL, on_cancel); + if (vs != "error") { + // console.log(vs); + Object.assign(onCnclObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONCANCEL}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_ONCANCEL} API`); //checking context + res = checkContext(on_cancel.context, constants.RET_ONCANCEL); + if (!res.valid) { + onCnclObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONCANCEL} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}` + ); + if (!_.isEqual(dao.getValue("city"), on_cancel.context.city)) { + onCnclObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_cancel.context.timestamp)) { + onCnclObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONCANCEL} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONCANCEL} api`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL}` + ); + if (_.gte(dao.getValue("cnclTmpstmp"), on_cancel.context.timestamp)) { + onCnclObj.tmpstmp = `Timestamp for /${constants.RET_CANCEL} api cannot be greater than or equal to /${constants.RET_ONCANCEL} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONCANCEL}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_cancel.context.transaction_id)) { + onCnclObj.txnId = `Transaction Id for /${constants.RET_SELECT} and /${constants.RET_ONCANCEL} api should be same`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONCANCEL} api`, + error + ); + } + try { + console.log(`Checking Message Id of /${constants.RET_ONCANCEL}`); + if (!_.isEqual(dao.getValue("msgId"), on_cancel.context.message_id)) { + onCnclObj.msgId = `Message Id for /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} api should be same`; + } + // if (msgIdSet.has(status.context.message_id)) { + // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = status.context.message_id; + msgIdSet.add(on_cancel.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_ONCANCEL}`, + error + ); + } + on_cancel = on_cancel.message.order; + + try { + console.log( + `Comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}` + ); + if (on_cancel.id != dao.getValue("onCnfrmOrdrId")) { + onCnclObj.onCancelId = `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match`; + console.log( + `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match` + ); + } + } catch (error) { + // onCnclObj.onCancelId = + // "Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match"; + console.log( + `!!Error while comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing cancellation reason id in /${constants.RET_ONCANCEL} and /${constants.RET_CANCEL}` + ); + if (dao.getValue("cnclRid") != on_cancel.tags.cancellation_reason_id) { + onCnclObj.onCancelRID = `Cancellation Reason Id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} should be same`; + } + } catch (error) { + console.log( + `!!Error while comparing cancellation reason id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL}`, + error + ); + // onCnclObj.onCancelRID = + // "Cancellation reason Id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} (inside tags) should be same"; + } + + dao.setValue("onCnclObj", onCnclObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONCANCEL} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONCANCEL} API`, + err + ); + } + } +}; + +module.exports = checkOnCancel; diff --git a/utilities/log-validation-utility/utils/retail/retOnConfirm.js b/utilities/log-validation-utility/utils/retail/retOnConfirm.js new file mode 100644 index 0000000..40fe129 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnConfirm.js @@ -0,0 +1,480 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const validateSchema = require("../schemaValidation"); +const utils = require("../utils"); +const constants = require("../constants"); + +const checkOnConfirm = (dirPath, msgIdSet) => { + let onCnfrmObj = {}; + + try { + var on_confirm = fs.readFileSync( + dirPath + `/${constants.RET_ONCONFIRM}.json` + ); + on_confirm = JSON.parse(on_confirm); + + try { + console.log(`Validating Schema for /${constants.RET_ONCONFIRM} API`); + const vs = validateSchema("retail", constants.RET_ONCONFIRM, on_confirm); + if (vs != "error") { + // console.log(vs); + Object.assign(onCnfrmObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_ONCONFIRM} API`); //checking context + res = checkContext(on_confirm.context, constants.RET_ONCONFIRM); + if (!res.valid) { + onCnfrmObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONCONFIRM} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}` + ); + if (!_.isEqual(dao.getValue("city"), on_confirm.context.city)) { + onCnfrmObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}`; + } + } catch (error) { + console.log( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_confirm.context.timestamp)) { + onCnfrmObj.tmpstmp = `Timestamp for /${constants.RET_CONFIRM} api cannot be greater than or equal to /${constants.RET_ONCONFIRM} api`; + } + tmpstmp = on_confirm.context.timestamp; + dao.setValue("tmpstmp", tmpstmp); + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM}` + ); + if ( + !_.isEqual(dao.getValue("txnId"), on_confirm.context.transaction_id) + ) { + onCnfrmObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM} api`, + error + ); + } + + try { + console.log( + `Comparing Message Ids of /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` + ); + if (!_.isEqual(dao.getValue("msgId"), on_confirm.context.message_id)) { + onCnfrmObj.msgId = `Message Ids for /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM} apis should be same`; + } + // if (msgIdSet.has(confirm.context.message_id)) { + // cnfrmObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = confirm.context.message_id; + msgIdSet.add(on_confirm.context.message_id); + } catch (error) { + console.log( + `Error while checking message id for /${constants.RET_ONCONFIRM}`, + error + ); + } + + on_confirm = on_confirm.message.order; + + try { + console.log( + `Comparing order ids in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` + ); + if (dao.getValue("cnfrmOrdrId") != on_confirm.id) { + onCnfrmObj.orderID = `Order Id mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while trying to fetch order ids in /${constants.RET_ONCONFIRM}`, + error + ); + } + try { + console.log( + `checking created_at and updated_at timestamp in /${constants.RET_ONCONFIRM}` + ); + const cnfrmOrdrCrtd = dao.getValue("ordrCrtd"); + const cnfrmOrdrUpdtd = dao.getValue("ordrUpdtd"); + if ( + on_confirm.state.toLowerCase() === "created" || + on_confirm.state.toLowerCase() === "accepted" + ) { + if ( + cnfrmOrdrCrtd && + (!on_confirm.created_at || on_confirm.created_at != cnfrmOrdrCrtd) + ) { + onCnfrmObj.crtdtmstmp = `order.created_at timestamp mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`; + } + + if ( + cnfrmOrdrUpdtd && + (!on_confirm.updated_at || + _.gte(cnfrmOrdrUpdtd, on_confirm.updated_at)) + ) { + onCnfrmObj.updtdtmstmp = `order.updated_at timestamp should be updated (Default fulfillment state is added)`; + } + } + + // if (on_confirm.state.toLowerCase() === "accepted") { + // if ( + // cnfrmOrdrUpdtd && + // (!on_confirm.updated_at || + // _.gt(cnfrmOrdrUpdtd, on_confirm.updated_at)) + // ) { + // onCnfrmObj.updtdtmstmp = `order.updated_at timestamp can't be same when order state changes`; + // } + // } + } catch (error) { + console.log( + `!!Error while checking order timestamps in /${constants.RET_ONCONFIRM}`, + error + ); + } + + // dao.setValue("onCnfrmOrdrId", on_confirm.id); + + try { + console.log( + `Checking provider id and location in /${constants.RET_ONCONFIRM}` + ); + if (on_confirm.provider.id != dao.getValue("providerId")) { + onCnfrmObj.prvdrId = `Provider Id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONCONFIRM}`; + } + + if (on_confirm.provider.locations[0].id != dao.getValue("providerLoc")) { + onCnfrmObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONCONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while checking provider id and location in /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing item Ids and fulfillment ids in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` + ); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + const itemsIdList = dao.getValue("itemsIdList"); + let i = 0; + const len = on_confirm.items.length; + while (i < len) { + let itemId = on_confirm.items[i].id; + if (itemId in itemFlfllmnts) { + if (on_confirm.items[i].fulfillment_id != itemFlfllmnts[itemId]) { + let itemkey = `item_FFErr${i}`; + onCnfrmObj[ + itemkey + ] = `items[${i}].fulfillment_id mismatches for Item ${itemId} in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}`; + } + } else { + let itemkey = `item_FFErr${i}`; + onCnfrmObj[ + itemkey + ] = `Item Id ${itemId} does not exist in /${constants.RET_ONSELECT}`; + } + + if (itemId in itemsIdList) { + if (on_confirm.items[i].quantity.count != itemsIdList[itemId]) { + onCnfrmObj.cntErr = `Warning: items[${i}].quantity.count for item ${itemId} mismatches with the items quantity selected in /${constants.RET_SELECT}`; + } + } + i++; + } + } catch (error) { + console.log( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing billing object in ${constants.RET_INIT} and /${constants.RET_ONCONFIRM}` + ); + const billing = dao.getValue("billing"); + if (!_.isEqual(billing, on_confirm.billing)) { + onCnfrmObj.bill = `Billing object mismatches in /${constants.RET_INIT} and /${constants.RET_ONCONFIRM}`; + } + // dao.setValue("billing", on_confirm.billing); + } catch (error) { + console.log( + `!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONCONFIRM}` + ); + } + + // try { + // console.log("Comparing count of items in /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM}"); + // const itemsIdList = dao.getValue("itemsIdList"); + // on_confirm.items.forEach((item) => { + // if (item["id"] in itemsIdList) { + // if (itemsIdList[item["id"]] != item["quantity"].count) { + // onCnfrmObj.countErr = `Count of item ${item["id"]} in /${constants.RET_ONCONFIRM} does not match with the count in /${constants.RET_SELECT}`; + // } + // } + // }); + // } catch (error) { + // // onCnfrmObj.countErr = `Count of item in /${constants.RET_ONCONFIRM} does not match with the count in /${constants.RET_SELECT}`; + // console.log( + // "!!Error while comparing count items in /${constants.RET_ONCONFIRM} and /${constants.RET_SELECT}", + // error + // ); + // } + + try { + console.log( + `Checking fulfillments objects in /${constants.RET_ONCONFIRM}` + ); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + let i = 0; + const len = on_confirm.fulfillments.length; + while (i < len) { + //Comparing fulfillment Ids + if (on_confirm.fulfillments[i].id) { + let id = on_confirm.fulfillments[i].id; + if (!Object.values(itemFlfllmnts).includes(id)) { + key = `ffID${id}`; + //MM->Mismatch + onCnfrmObj[ + key + ] = `fulfillment id ${id} does not exist in /${constants.RET_ONSELECT}`; + } + } else { + onCnfrmObj.ffId = `fulfillments[${i}].id is missing in /${constants.RET_ONCONFIRM}`; + } + + console.log("Checking the fulfillments state"); + + const ffDesc = on_confirm.fulfillments[i].state.descriptor; + + const ffStateCheck = ffDesc.hasOwnProperty("code") + ? ffDesc.code.toLowerCase() === "pending" + : false; + + if (!ffStateCheck) { + let key = `ffState${i}`; + onCnfrmObj[ + key + ] = `default fulfillments state is missing in /${constants.RET_ONCONFIRM}`; + } + + if ( + !on_confirm.fulfillments[i].start || + !on_confirm.fulfillments[i].end + ) { + onCnfrmObj.ffstartend = `fulfillments[${i}] start and end locations are mandatory`; + } + if ( + !_.isEqual( + on_confirm.fulfillments[i].end.location.gps, + dao.getValue("buyerGps") + ) + ) { + onCnfrmObj.gpsErr = `fulfillments[${i}].end.location gps is not matching with gps in /select`; + } + + if ( + !_.isEqual( + on_confirm.fulfillments[i].location.address.area_code, + dao.getValue("buyerAddr") + ) + ) { + onCnfrmObj.gpsErr = `fulfillments[${i}].end.location.address.area_code is not matching with area_code in /select`; + } + + i++; + } + } catch (error) { + console.log( + `!!Error while checking fulfillments object in /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing /${constants.RET_ONCONFIRM} quoted Price and Payment Params amount` + ); + if ( + parseFloat(on_confirm.payment.params.amount) != + parseFloat(on_confirm.quote.price.value) + ) { + onCnfrmObj.onConfirmedAmount = `Quoted price (/${constants.RET_ONCONFIRM}) doesn't match with the amount in payment.params`; + } + } catch (error) { + console.log( + `!!Error while Comparing /${constants.RET_ONCONFIRM} quoted Price and Payment Params amount`, + error + ); + } + + try { + console.log( + `Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` + ); + if (!_.isEqual(dao.getValue("quoteObj"), on_confirm.quote)) { + onCnfrmObj.onQuoteObj = `Quote Object in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM} do not match`; + } + } catch (error) { + // onCnfrmObj.onQuoteObj = `Quote Object in /on_init and /${constants.RET_ONCONFIRM} mismatch`; + console.log( + `!!Error while comparing quote in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` + ); + } + + try { + console.log( + `Comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` + ); + const onSelectPrice = dao.getValue("onSelectPrice"); + const onConfirmQuotePrice = parseFloat(on_confirm.quote.price.value); + if (onSelectPrice != onConfirmQuotePrice) { + console.log( + `order quote price in /${constants.RET_ONCONFIRM} is not equal to the quoted price in /${constants.RET_ONSELECT}` + ); + onCnfrmObj.quoteErr = `Quoted Price in /${constants.RET_ONCONFIRM} ${onConfirmQuotePrice} does not match with the quoted price in /${constants.RET_ONSELECT} ${onSelectPrice}`; + } + } catch (error) { + console.log( + `!!Error while comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log( + `Comparing payment object in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}` + ); + + if (!_.isEqual(dao.getValue("cnfrmpymnt"), on_confirm.payment)) { + `payment object mismatches in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`; + } + } catch (error) { + console.log( + `!!Error while comparing payment object in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`, + error + ); + } + + try { + console.log( + `Checking Buyer App finder fee amount in /${constants.RET_ONCONFIRM}` + ); + const buyerFF = dao.getValue("buyerFF"); + if ( + on_confirm.payment["@ondc/org/buyer_app_finder_fee_amount"] && + parseFloat( + on_confirm.payment["@ondc/org/buyer_app_finder_fee_amount"] + ) != buyerFF + ) { + onCnfrmObj.buyerFF = `Buyer app finder fee can't change in /${constants.RET_ONCONFIRM}`; + console.log( + `Buyer app finder fee can't change in /${constants.RET_ONCONFIRM}` + ); + } + } catch (error) { + console.log( + `!Error while comparing buyer app finder fee in /${constants.RET_ONCONFIRM}`, + error + ); + } + + // try { + // console.log( + // `comparing created and updated order timestamps in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}` + // ); + + // if ( + // !on_confirm.hasOwnProperty("created_at") || + // !on_confirm.hasOwnProperty("updated_at") + // ) { + // onCnfrmObj.ordertmpstmp = `order created and updated timestamps are mandatory in /${constants.RET_ONCONFIRM}`; + // } else { + // const confirmTmpStmp = dao.getValue("ordrcrtdtmpstmp"); + // if ( + // confirmTmpStmp && + // !_.isEqual(on_confirm.created_at, confirmTmpStmp) + // ) { + // onCnfrmObj.orderCrtd = `order.created_at timestamp should be the same in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`; + // } + // const confirmUpdtTmpStmp = dao.getValue("ordrupdtdtmpstmp"); + // if ( + // confirmUpdtTmpStmp && + // !_.isEqual(on_confirm.updated_at, confirmUpdtTmpStmp) + // ) { + // onCnfrmObj.ordrupdtd = `order.updated_at timestamp should be same in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`; + // } + // } + // } catch (error) { + // console.log( + // `!!Error while comparing created and updated timestamps in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}` + // ); + // } + //TNC ARRAY OF OBJECTS DEEP COMPARISON WITH LODASH + // try { + // console.log( + // `Comparing buyer's T&C in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` + // ); + // const buyerTnc = dao.getValue("buyerT&C"); + + // if ( + // buyerTnc && + // (!on_confirm.tags || !utils.isArrayEqual(buyerTnc, on_confirm.tags)) + // ) { + // // console.log(buyerTnc); + // onCnfrmObj.buyertnc = `Buyer's T&C in tags mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`; + // } + // } catch (error) { + // console.log( + // `!!Error while checking buyer's T&C in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`, + // error + // ); + // } + + dao.setValue("onCnfrmObj", onCnfrmObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONCONFIRM} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONCONFIRM} API`, + err + ); + } + } +}; +module.exports = checkOnConfirm; diff --git a/utilities/log-validation-utility/utils/retail/retOnInit.js b/utilities/log-validation-utility/utils/retail/retOnInit.js new file mode 100644 index 0000000..6050707 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnInit.js @@ -0,0 +1,399 @@ +const fs = require("fs"); +const _ = require("lodash"); +const { checkContext } = require("../../services/service"); +const dao = require("../../dao/dao"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +const checkOnInit = (dirPath, msgIdSet) => { + let onInitObj = {}; + + try { + var on_init = fs.readFileSync(dirPath + `/${constants.RET_ONINIT}.json`); + + on_init = JSON.parse(on_init); + console.log(`Validating Schema for /${constants.RET_ONINIT} API`); + + try { + const vs = validateSchema("retail", constants.RET_ONINIT, on_init); + if (vs != "error") { + // console.log(vs); + Object.assign(onInitObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONINIT}`, + error + ); + } + + console.log(`Checking context for /${constants.RET_ONINIT} API`); //checking context + try { + res = checkContext(on_init.context, constants.RET_ONINIT); + if (!res.valid) { + onInitObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONINIT} context`, + error + ); + } + + try { + console.log( + `Comparing city of ${constants.RET_SEARCH} & ${constants.RET_ONINIT}` + ); + if (!_.isEqual(dao.getValue("city"), on_init.context.city)) { + onInitObj.city = `City code mismatch in ${constants.RET_SEARCH} & ${constants.RET_ONINIT}`; + } + } catch (error) { + console.log( + `Error while comparing city in ${constants.RET_SEARCH} & ${constants.RET_ONINIT}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of ${constants.RET_INIT} & ${constants.RET_ONINIT}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_init.context.timestamp)) { + onInitObj.tmpstmp = `Timestamp for ${constants.RET_INIT} api cannot be greater than or equal to ${constants.RET_ONINIT} api`; + } + dao.setValue("tmpstmp", on_init.context.timestamp); + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_INIT} and /${constants.RET_ONINIT} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} & /${constants.RET_ONINIT}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_init.context.transaction_id)) { + onInitObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} & /${constants.RET_ONINIT} api`, + error + ); + } + + try { + console.log( + `Comparing Message Ids of /${constants.RET_INIT} and /${constants.RET_ONINIT}` + ); + if (!_.isEqual(dao.getValue("msgId"), on_init.context.message_id)) { + onInitObj.msgId = `Message Ids for /${constants.RET_INIT} and /${constants.RET_ONINIT} api should be same`; + } + + // if (msgIdSet.has(init.context.message_id)) { + // initObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = select.context.message_id; + msgIdSet.add(on_init.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_INIT}`, + error + ); + } + + on_init = on_init.message.order; + + try { + console.log( + `Checking provider Id and provider_location Id in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}` + ); + if ( + !on_init.provider || + on_init.provider.id != dao.getValue("providerId") + ) { + onInitObj.prvdrId = `Provider Id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}`; + } + + if ( + on_init.hasOwnProperty("provider_location") && + (!on_init.provider_location.id || + on_init.provider_location.id != dao.getValue("providerLoc")) + ) { + onInitObj.prvdrLoc = `provider_location.id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}`; + } else if (!on_init.hasOwnProperty("provider_location")) { + onInitObj.prvdrloc = `provider_location object is missing in /${constants.RET_ONINIT}`; + } + } catch (error) { + console.log( + `!!Error while comparing provider Id and location Id in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}`, + error + ); + } + + try { + console.log( + `Comparing item Ids and fulfillment Ids in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` + ); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + const itemsIdList = dao.getValue("itemsIdList"); + let i = 0; + const len = on_init.items.length; + while (i < len) { + let itemId = on_init.items[i].id; + if (itemId in itemFlfllmnts) { + if (on_init.items[i].fulfillment_id != itemFlfllmnts[itemId]) { + let itemkey = `item_FFErr${i}`; + onInitObj[ + itemkey + ] = `items[${i}].fulfillment_id mismatches for Item ${itemId}} in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; + } + } else { + let itemkey = `item_FFErr${i}`; + onInitObj[itemkey] = `Item Id ${itemId} does not exist in /on_select`; + } + + if (itemId in itemsIdList) { + if (on_init.items[i].quantity.count != itemsIdList[itemId]) { + onInitObj.cntErr = `Warning: items[${i}].quantity.count for item ${itemId} mismatches with the items quantity selected in /${constants.RET_SELECT}`; + } + } + + i++; + } + } catch (error) { + console.log( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`, + error + ); + } + + try { + console.log( + `Comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONINIT}` + ); + const billing = dao.getValue("billing"); + if (!_.isEqual(billing, on_init.billing)) { + onInitObj.bill = `Billing object mismatches in /${constants.RET_INIT} and /${constants.RET_ONINIT}`; + } + } catch (error) { + console.log( + `!!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONINIT}`, + error + ); + } + + try { + console.log(`Checking fulfillments objects in /${constants.RET_ONINIT}`); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + let i = 0; + const len = on_init.fulfillments.length; + while (i < len) { + //Comparing fulfillment Ids + + if (on_init.fulfillments[i].id) { + let id = on_init.fulfillments[i].id; + if (!Object.values(itemFlfllmnts).includes(id)) { + key = `ffID${id}`; + //MM->Mismatch + onInitObj[ + key + ] = `fulfillment id ${id} does not exist in /${constants.RET_ONSELECT}`; + } + } else { + onInitObj.ffId = `fulfillments[].id is missing in /${constants.RET_ONINIT}`; + } + + if ( + !_.isEqual( + on_init.fulfillments[i].end.location.gps, + dao.getValue("buyerGps") + ) + ) { + gpskey = `gpsKey${i}`; + onInitObj[ + gpskey + ] = `gps coordinates in fulfillments[${i}].end.location mismatch in /${constants.RET_SELECT} & /${constants.RET_ONINIT}`; + } + + if ( + !_.isEqual( + on_init.fulfillments[i].end.location.address.area_code, + dao.getValue("buyerAddr") + ) + ) { + addrkey = `addrKey${i}`; + onInitObj[ + addrkey + ] = `address.area_code in fulfillments[${i}].end.location mismatch in /${constants.RET_SELECT} & /${constants.RET_ONINIT}`; + } + + //Comparing Provider_id + // if (on_init.fulfillments[i].provider_id) { + // let prvdrId = on_init.fulfillments[i].provider_id; + // if (prvdrId != dao.getValue("bppId")) { + // let key = `ffPrvdrId${prvdrId}`; + // onInitObj[key] = `Provider Id for fulfillment ${ + // on_init.fulfillments[i].id || "" + // } should be the bpp_id as per the contract`; + // } + // } + i++; + } + } catch (error) { + console.log( + `!!Error while checking fulfillments object in /${constants.RET_ONINIT}`, + error + ); + } + + let initQuotePrice = 0; + let initBreakupPrice = 0; + // dao.setValue("onInitQuote", on_init.quote); + console.log(`Calculating Net /${constants.RET_ONINIT} Price breakup`); + on_init.quote.breakup.forEach((element) => { + initBreakupPrice += parseFloat(element.price.value); + }); + console.log(`/${constants.RET_ONINIT} Price Breakup: ${initBreakupPrice}`); + + initQuotePrice = parseFloat(on_init.quote.price.value); + + console.log(`/${constants.RET_ONINIT} Quoted Price: ${initQuotePrice}`); + + console.log( + `Comparing /${constants.RET_ONINIT} Quoted Price and Net Price Breakup` + ); + if (initQuotePrice != initBreakupPrice) { + console.log( + `Quoted Price in /${constants.RET_ONINIT} is not equal to the Net Breakup Price` + ); + onInitObj.onInitPriceErr = `Quoted Price ${initQuotePrice} does not match with Net Breakup Price ${initBreakupPrice} in /${constants.RET_ONINIT}`; + } + + console.log( + `Comparing /${constants.RET_ONINIT} Quoted Price and /${constants.RET_ONSELECT} Quoted Price` + ); + const onSelectPrice = dao.getValue("onSelectPrice"); + if (onSelectPrice != initQuotePrice) { + console.log( + `Quoted Price in /${constants.RET_ONINIT} is not equal to the quoted price in /${constants.RET_ONSELECT}` + ); + onInitObj.onInitPriceErr2 = `Quoted Price in /${constants.RET_ONINIT} INR ${initQuotePrice} does not match with the quoted price in /${constants.RET_ONSELECT} INR ${onSelectPrice}`; + } + + console.log(`Checking Payment Object for /${constants.RET_ONINIT}`); + if (!on_init.payment) { + onInitObj.pymntOnInitObj = `Payment Object can't be null in /${constants.RET_ONINIT}`; + } + + try { + console.log( + `Checking Buyer App finder fee amount in /${constants.RET_ONINIT}` + ); + const buyerFF = dao.getValue("buyerFF"); + // if (on_init.payment["@ondc/org/buyer_app_finder_fee_amount"]) + if ( + !on_init.payment["@ondc/org/buyer_app_finder_fee_amount"] || + parseFloat(on_init.payment["@ondc/org/buyer_app_finder_fee_amount"]) != + buyerFF + ) { + onInitObj.buyerFF = `Buyer app finder fee can't change in /${constants.RET_ONINIT}`; + // console.log(`Buyer app finder fee amount can't change in /on_init`); + } + } catch (error) { + console.log( + `!!Error while checking buyer app finder fee in /${constants.RET_ONINIT}`, + error + ); + } + + try { + console.log( + `Checking Quote Object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` + ); + if (!_.isEqual(dao.getValue("quoteObj"), on_init.quote)) { + onInitObj.quoteErr = `Quote object mismatches in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; + } + } catch (error) { + console.log( + `!!Error while checking quote object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` + ); + } + + //CHECKING PAYMENT OBJECT IN /ON_INIT + // try { + // console.log("checking payment object in /on_init"); + // if ( + // on_init.payment.collected_by === "BAP" && + // on_init.payment["@ondc/org/settlement_details"][0][ + // "settlement_counterparty" + // ] != "seller-app" + // ) { + // onInitObj.sttlmntcntrparty = `settlement_counterparty should be 'seller-app' when payment.collected_by is BAP`; + // } + + // if ( + // on_init.payment.collected_by === "BPP" && + // on_init.payment["@ondc/org/settlement_details"][0][ + // "settlement_counterparty" + // ] != "buyer-app" + // ) { + // onInitObj.sttlmntcntrparty = `settlement_counterparty should be 'buyer-app' when payment.collected_by is BPP`; + // } + + // dao.setValue("paymentType", on_init.payment.type); + // dao.setValue("pymntCollectedBy", on_init.payment.collected_by); + // } catch (error) { + // console.log( + // `!!Error while checking payment object in /${constants.RET_ONINIT}`, + // error + // ); + // } + + try { + console.log(`checking payment object in /${constants.RET_ONINIT}`); + if ( + on_init.payment["@ondc/org/settlement_details"][0][ + "settlement_counterparty" + ] != "seller-app" + ) { + onInitObj.sttlmntcntrparty = `settlement_counterparty is expected to be 'seller-app' in @ondc/org/settlement_details`; + } + } catch (error) { + console.err( + `!!Error while checking payment object in /${constants.RET_ONINIT}` + ); + } + + try { + console.log( + `storing payment settlement details in /${constants.RET_ONINIT}` + ); + if (on_init.payment.hasOwnProperty("@ondc/org/settlement_details")) + dao.setValue( + "sttlmntdtls", + on_init.payment["@ondc/org/settlement_details"] + ); + else { + onInitObj.pymntSttlmntObj = `payment settlement_details missing in /${constants.RET_ONINIT}`; + } + } catch (error) { + console.log( + `!!Error while storing payment settlement details in /${constants.RET_ONINIT}` + ); + } + + dao.setValue("onInitObj", onInitObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONINIT} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONINIT} API` + ); + } + } +}; + +module.exports = checkOnInit; diff --git a/utilities/log-validation-utility/utils/retail/retOnSearch.js b/utilities/log-validation-utility/utils/retail/retOnSearch.js new file mode 100644 index 0000000..7c0bde1 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnSearch.js @@ -0,0 +1,129 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const { checkContext } = require("../../services/service"); +const validateSchema = require("../schemaValidation"); + +const checkOnSearch = (dirPath, msgIdSet) => { + let onSrchObj = {}; + + try { + let onSearch = fs.readFileSync(dirPath + `/${constants.RET_ONSEARCH}.json`); + onSearch = JSON.parse(onSearch); + try { + console.log(`Validating Schema for ${constants.RET_ONSEARCH} API`); + const vs = validateSchema("retail", constants.RET_ONSEARCH, onSearch); + if (vs != "error") { + // console.log(vs); + Object.assign(onSrchObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONSEARCH}`, + error + ); + } + + try { + console.log(`Storing BAP_ID and BPP_ID in /${constants.RET_ONSEARCH}`); + dao.setValue("bapId", onSearch.context.bap_id); + dao.setValue("bppId", onSearch.context.bpp_id); + } catch (error) { + console.log( + `!!Error while storing BAP and BPP Ids in /${constants.RET_ONSEARCH}`, + error + ); + } + + try { + console.log(`Checking context for ${constants.RET_ONSEARCH} API`); + res = checkContext(onSearch.context, constants.RET_ONSEARCH); + if (!res.valid) { + Object.assign(onSrchObj, res.ERRORS); + } + } catch (error) { + console.log( + `Some error occurred while checking /${constants.RET_ONSEARCH} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` + ); + if (!_.isEqual(dao.getValue("city"), onSearch.context.city)) { + onSrchObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}`; + } + } catch (error) { + console.log( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` + ); + if (_.gte(dao.getValue("tmpstmp"), onSearch.context.timestamp)) { + onSrchObj.tmpstmp = `Context timestamp for /${constants.RET_SEARCH} api cannot be greater than or equal to /${constants.RET_ONSEARCH} api`; + } + dao.setValue("tmpstmp", onSearch.context.timestamp); + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api` + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` + ); + if (!_.isEqual(dao.getValue("txnId"), onSearch.context.transaction_id)) { + onSrchObj.txnId = `Transaction Id for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api should be same`; + } + // dao.setValue("txnId", onSearch.context.transaction_id); + } catch (error) { + console.log( + `Error while comparing transaction ids for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api`, + error + ); + } + + try { + console.log( + `Comparing Message Ids of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` + ); + if (!_.isEqual(dao.getValue("msgId"), onSearch.context.message_id)) { + onSrchObj.msgId = `Message Id for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api should be same`; + } + msgIdSet.add(onSearch.context.message_id); + } catch (error) { + console.log( + `Error while comparing message ids for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api`, + error + ); + } + + onSearch = onSearch.message.catalog; + // console.log(onSearch["bpp/providers"]); + dao.setValue("onSearch", onSearch); + + // try { + // console.log("Checking available and max count in on_search catalog"); + // } catch (error) {} + dao.setValue("onSrchObj", onSrchObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for ${constants.RET_ONSEARCH} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSEARCH} API` + ); + } + } +}; + +module.exports = checkOnSearch; diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js new file mode 100644 index 0000000..12b3208 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -0,0 +1,466 @@ +const fs = require("fs"); +const _ = require("lodash"); +const { checkContext } = require("../../services/service"); +const dao = require("../../dao/dao"); +const utils = require("../utils"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +const checkOnSelect = (dirPath, msgIdSet) => { + let onSlctObj = {}; + try { + on_select = fs.readFileSync(dirPath + `/${constants.RET_ONSELECT}.json`); + + on_select = JSON.parse(on_select); + try { + console.log(`Validating Schema for /${constants.RET_ONSELECT} API`); + const vs = validateSchema("retail", constants.RET_ONSELECT, on_select); + if (vs != "error") { + // console.log(vs); + Object.assign(onSlctObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_ONSELECT} API`); //checking context + res = checkContext(on_select.context, constants.RET_ONSELECT); + if (!res.valid) { + onSlctObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSELECT} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}` + ); + if (!_.isEqual(dao.getValue("city"), on_select.context.city)) { + onSlctObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_select.context.timestamp)) { + onSlctObj.tmpstmp = `Timestamp for /${constants.RET_SELECT} api cannot be greater than or equal to /${constants.RET_ONSELECT} api`; + } + dao.setValue("tmpstmp", on_select.context.timestamp); + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_SELECT} and /${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_select.context.transaction_id)) { + onSlctObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api`, + error + ); + } + + try { + console.log( + `Comparing Message Ids of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` + ); + if (!_.isEqual(dao.getValue("msgId"), on_select.context.message_id)) { + onSlctObj.msgId = `Message Id for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api should be same`; + } + + if (msgIdSet.has(on_select.context.message_id)) { + onSlctObj.msgId2 = + "Message Id cannot be same for different sets of APIs"; + } + // msgId = select.context.message_id; + msgIdSet.add(on_select.context.message_id); + } catch (error) { + console.log( + `Error while comparing message ids for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api`, + error + ); + } + + let on_select_error = {}; + try { + console.log(`Checking domain-error in /${constants.RET_ONSELECT}`); + if (on_select.hasOwnProperty("error")) { + on_select_error = on_select.error; + } + } catch (error) { + console.log( + `Error while checking domain-error in /${constants.RET_ONSELECT}`, + error + ); + } + + on_select = on_select.message.order; + let itemFlfllmnts = {}; + + try { + console.log( + `Checking provider id in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}` + ); + if (dao.getValue("providerId") != on_select.provider.id) { + onSlctObj.prvdrId = `provider.id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}`; + } + } catch (error) { + console.log( + `Error while comparing provider ids in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log(`Item Id and Fulfillment Id Mapping in /on_select`); + let i = 0; + const len = on_select.items.length; + while (i < len) { + const found = on_select.fulfillments.some( + (fId) => fId.id === on_select.items[i].fulfillment_id + ); + if (!found) { + const key = `fId${i}`; + onSlctObj[ + key + ] = `fulfillment_id for item ${on_select.items[i].id} does not exist in order.fulfillments[]`; + } + i++; + } + } catch (error) { + console.log( + `!!Error while checking Item Id and Fulfillment Id Mapping in /${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log("Mapping and storing item Id and fulfillment Id"); + let i = 0; + const len = on_select.items.length; + while (i < len) { + let id = on_select.items[i].id; + itemFlfllmnts[id] = on_select.items[i].fulfillment_id; + i++; + } + dao.setValue("itemFlfllmnts", itemFlfllmnts); + } catch (error) { + console.log( + "!!Error occurred while mapping and storing item Id and fulfillment Id", + error + ); + } + + try { + console.log(`Checking fulfillments' state in ${constants.RET_ONSELECT}`); + let nonServiceableFlag = 0; + const ffState = on_select.fulfillments.every((ff) => { + const ffDesc = ff.state.descriptor; + if (ffDesc.code.toLowerCase() === "non-serviceable") { + nonServiceableFlag = 1; + } + return ffDesc.hasOwnProperty("code") + ? ffDesc.code.toLowerCase() === "serviceable" || + ffDesc.code.toLowerCase() === "non-serviceable" + : false; + }); + + if (!ffState) + onSlctObj.ffStateCode = `Pre-order fulfillment state codes should be used in fulfillments[].state.descriptor.code`; + else if ( + nonServiceableFlag && + (!on_select_error || + !on_select_error.type === "DOMAIN-ERROR" || + !on_select_error.code === "30009") + ) { + onSlctObj.notServiceable = `Non Serviceable Domain error should be provided when fulfillment is not serviceable`; + } + } catch (error) { + console.log( + `!!Error while checking fulfillments' state in /${constants.RET_ONSELECT}`, + error + ); + } + + let onSelectPrice = 0; //Net price after discounts and tax in /on_select + let onSelectItemsPrice = 0; //Price of only items in /on_select + + try { + console.log( + `Comparing count of items in ${constants.RET_SELECT} and ${constants.RET_ONSELECT}` + ); + let itemsIdList = dao.getValue("itemsIdList"); + console.log(itemsIdList); + on_select.quote.breakup.forEach((item) => { + if ( + item["@ondc/org/item_id"] in itemsIdList && + item["@ondc/org/title_type"] === "item" + ) { + if ( + itemsIdList[item["@ondc/org/item_id"]] === + item["@ondc/org/item_quantity"].count || + (itemsIdList[item["@ondc/org/item_id"]] > + item["@ondc/org/item_quantity"].count && + on_select_error && + on_select_error.type === "DOMAIN-ERROR" && + on_select_error.code === "400002") + ) { + console.log( + `count of item with id: ${item["@ondc/org/item_id"]} is as per the API contract` + ); + } else { + let cntkey = `cnt${item["@ondc/org/item_id"]}`; + onSlctObj[ + cntkey + ] = `Count of item with id: ${item["@ondc/org/item_id"]} does not match in ${constants.RET_SELECT} & ${constants.RET_ONSELECT} (suitable domain error should be provided)`; + } + } else if ( + item["@ondc/org/title_type"] === "item" && + !(item["@ondc/org/item_id"] in itemsIdList) + ) { + onSlctObj.itmBrkup = `item with id: ${item["@ondc/org/item_id"]} is not present in /${constants.RET_ONSEARCH}`; + } + }); + } catch (error) { + // onSlctObj.countErr = `Count of item does not match with the count in /select`; + console.log( + `!!Error while comparing count items in ${constants.RET_SELECT} and ${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log( + `-x-x-x-x-Quote Breakup ${constants.RET_ONSELECT} all checks-x-x-x-x` + ); + let itemsIdList = dao.getValue("itemsIdList"); + let itemsCtgrs = dao.getValue("itemsCtgrs"); + on_select.quote.breakup.forEach((element, i) => { + let titleType = element["@ondc/org/title_type"]; + // console.log(element.price.value); + + console.log( + `Calculating quoted Price Breakup for element ${element.title}` + ); + onSelectPrice += parseFloat(element.price.value); + + if (titleType === "item") { + if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { + let brkupitemid = `brkupitemid${i}`; + onSlctObj[ + brkupitemid + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; + } + + console.log( + `Comparing individual item's total price and unit price ` + ); + if (!element.hasOwnProperty("item")) { + onSlctObj.priceBreakup = `Item's unit price missing in quote.breakup for item id ${element["@ondc/org/item_id"]}`; + } else if ( + parseFloat(element.item.price.value) * + element["@ondc/org/item_quantity"].count != + element.price.value + ) { + onSlctObj.priceBreakup = `Item's unit and total price mismatch for id: ${element["@ondc/org/item_id"]}`; + } + + console.log( + `checking available and maximum count in ${constants.RET_ONSELECT}` + ); + + if (element.item.hasOwnProperty("quantity")) { + if ( + _.gt( + element.item.quantity.available.count, + element.item.quantity.maximum.count + ) + ) { + onSlctObj.qntCnt = `available count can't be greater than maximum count for item id: ${element["@ondc/org/item_id"]}`; + } + } + } + + console.log(`Calculating Items' prices in /${constants.RET_ONSELECT}`); + if (element["@ondc/org/item_id"] in itemsIdList) { + if ( + titleType === "item" || + (titleType === "tax" && + !utils.taxNotInlcusive.includes( + itemsCtgrs[element["@ondc/org/item_id"]] + )) + ) + onSelectItemsPrice += parseFloat(element.price.value); + } + + if (titleType === "tax" || titleType === "discount") { + if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { + let brkupitemsid = `brkupitemstitles${i}`; + onSlctObj[ + brkupitemsid + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; + } + } + + if ( + titleType === "packing" || + titleType === "delivery" || + titleType === "misc" + ) { + if ( + !Object.values(itemFlfllmnts).includes(element["@ondc/org/item_id"]) + ) { + let brkupffid = `brkupfftitles${i}`; + onSlctObj[ + brkupffid + ] = `${titleType} with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in fulfillments[]`; + } + } + }); + + dao.setValue("onSelectPrice", onSelectPrice); + + console.log( + `Matching quoted Price ${parseFloat( + on_select.quote.price.value + )} with Breakup Price ${onSelectPrice}` + ); + if (onSelectPrice != parseFloat(on_select.quote.price.value)) { + onSlctObj.quoteBrkup = `quote.price.value ${on_select.quote.price.value} does not match with the price breakup ${onSelectPrice}`; + } + let selectedPrice = dao.getValue("selectedPrice"); + console.log( + `Matching price breakup of items ${onSelectItemsPrice} (/${constants.RET_ONSELECT}) with selected items price ${selectedPrice} (${constants.RET_SELECT})` + ); + + if (onSelectItemsPrice != selectedPrice) { + onSlctObj.priceErr = `Warning: Quoted Price in /${constants.RET_ONSELECT} INR ${onSelectItemsPrice} does not match with the total price of items in /${constants.RET_SELECT} INR ${selectedPrice}`; + console.log("Quoted Price and Selected Items price mismatch"); + } + } catch (error) { + console.log( + `!!Error while checking and comparing the quoted price in /${constants.RET_ONSELECT}`, + error + ); + } + + try { + console.log( + `Checking payment breakup title & type in /${constants.RET_ONSELECT}` + ); + on_select.quote.breakup.forEach((item) => { + if ( + item["@ondc/org/title_type"] != "item" && + !Object.values(utils.retailPymntTtl).includes( + item["@ondc/org/title_type"] + ) + ) { + onSlctObj.pymntttltyp = `Quote breakup Payment title type "${item["@ondc/org/title_type"]}" is not as per the API contract`; + } + + if ( + item["@ondc/org/title_type"] != "item" && + !(item.title.toLowerCase().trim() in utils.retailPymntTtl) + ) { + onSlctObj.pymntttl = `Quote breakup Payment title "${item.title}" is not as per the API Contract`; + } else if ( + item["@ondc/org/title_type"] != "item" && + utils.retailPymntTtl[item.title.toLowerCase().trim()] != + item["@ondc/org/title_type"] + ) { + onSlctObj.pymntttlmap = `Quote breakup Payment title "${ + item.title + }" comes under the title type "${ + utils.retailPymntTtl[item.title.toLowerCase().trim()] + }"`; + } + }); + } catch (error) { + console.log( + `!!Error while checking payment breakup title & type in /${constants.RET_ONSELECT}`, + error + ); + } + + try { + //matching fulfillments TAT + console.log("Checking Fulfillment TAT..."); + on_select.fulfillments.forEach((ff) => { + if (!ff["@ondc/org/TAT"]) { + console.log( + `Fulfillment TAT must be present for Fulfillment ID: ${ff.id}` + ); + onSlctObj.ffTAT = `Fulfillment TAT must be present for fulfillment ID: ${ff.id}`; + } + }); + } catch (error) { + console.log( + `Error while checking fulfillments TAT in /${constants.RET_ONSELECT}` + ); + } + + try { + console.log("Checking quote validity quote.ttl"); + if (!on_select.quote.hasOwnProperty("ttl")) { + onSlctObj.qtTtl = "quote.ttl: Validity of the quote is missing"; + } + } catch (error) { + console.log( + `!!Error while checking quote.ttl in /${constants.RET_ONSELECT}` + ); + } + + try { + console.log(`Storing Quote object in /${constants.RET_ONSELECT}`); + on_select.quote.breakup.forEach((element) => { + if (element["@ondc/org/title_type"] === "item") { + if (element.hasOwnProperty("item")) { + delete element.item.quantity; + } + } + }); + //saving on select quote + dao.setValue("quoteObj", on_select.quote); + } catch (error) { + console.log( + `!!Error while storing quote object in /${constants.RET_ONSELECT}`, + error + ); + } + + dao.setValue("onSlctObj", onSlctObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONSELECT} API`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSELECT} API`, + error + ); + } + } +}; + +module.exports = checkOnSelect; diff --git a/utilities/log-validation-utility/utils/retail/retOnStatus.js b/utilities/log-validation-utility/utils/retail/retOnStatus.js new file mode 100644 index 0000000..5ab244e --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnStatus.js @@ -0,0 +1,200 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const utils = require("../utils"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +const checkOnStatus = (dirPath, msgIdSet) => { + let onStatObj = {}; + try { + let on_status = fs.readFileSync( + dirPath + `/${constants.RET_ONSTATUS}.json` + ); + + on_status = JSON.parse(on_status); + + try { + console.log(`Validating Schema for /${constants.RET_ONSTATUS} API`); + const vs = validateSchema("retail", constants.RET_ONSTATUS, on_status); + if (vs != "error") { + // console.log(vs); + Object.assign(onStatObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONSTATUS}`, + error + ); + } + + try { + console.log("Checking context for /${constants.RET_ONSTATUS} API"); //checking context + res = checkContext(on_status.context, "on_status"); + if (!res.valid) { + onStatObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSTATUS} context`, + error + ); + } + + try { + console.log( + `Comparing city of ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}` + ); + if (!_.isEqual(dao.getValue("city"), on_status.context.city)) { + onStatObj.city = `City code mismatch in ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_ONSTATUS} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_status.context.timestamp)) { + onStatObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONSTATUS} api`; + } + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS} api`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_STATUS} and /${constants.RET_ONSTATUS}` + ); + if (_.gte(dao.getValue("statTmpstmp"), on_status.context.timestamp)) { + onStatObj.tmpstmp = `Timestamp for /${constants.RET_STATUS} api cannot be greater than or equal to /${constants.RET_ONSTATUS} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_STATUS} and /${constants.RET_ONSTATUS} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /select and /${constants.RET_ONSTATUS}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_status.context.transaction_id)) { + onStatObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSTATUS} api`, + error + ); + } + + try { + console.log(`Checking Message Id of /${constants.RET_ONSTATUS}`); + if (!_.isEqual(dao.getValue("msgId"), on_status.context.message_id)) { + onStatObj.msgId = `Message Id for /${constants.RET_STATUS} and /${constants.RET_ONSTATUS} api should be same`; + } + + // if (msgIdSet.has(status.context.message_id)) { + // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = status.context.message_id; + msgIdSet.add(on_status.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_ONSTATUS}`, + error + ); + } + + on_status = on_status.message.order; + + try { + console.log( + `Comparing order Id in /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}` + ); + if (on_status.id != dao.getValue("cnfrmOrdrId")) { + console.log( + `Order id (/${constants.RET_ONSTATUS}) mismatches with /${constants.RET_CONFIRM})` + ); + onStatObj.onStatusOdrId = `Order id in /${constants.RET_CONFIRM} and /${constants.RET_ONSTATUS} do not match`; + } + } catch (error) { + console.log( + `!!Error while comparing order id in /${constants.RET_ONSTATUS} and /${constants.RET_CONFIRM}`, + error + ); + // onStatObj.onStatusOrdrId = + // "Order id mismatches in /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}"; + } + try { + console.log(`Checking order state in /${constants.RET_ONSTATUS}`); + if (!utils.retailOrderState.includes(on_status.state)) { + onStatObj.ordrSt = `Order State in /${constants.RET_ONSTATUS} is not as per the API Contract`; + } + } catch (error) { + // onStatObj.ordrSt = `Order State (/${constants.RET_ONSTATUS}) should be as per the API Contract`; + console.log( + `!!Error while checking order state in /${constants.RET_ONSTATUS}`, + error + ); + } + + try { + console.log( + `Checking provider id and location in /${constants.RET_ONSTATUS}` + ); + if (on_status.provider.id != dao.getValue("providerId")) { + onStatObj.prvdrId = `Provider Id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSTATUS}`; + } + + if (on_status.provider.locations[0].id != dao.getValue("providerLoc")) { + onStatObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSTATUS}`; + } + } catch (error) { + console.log( + `!!Error while checking provider id and location in /${constants.RET_ONSTATUS}`, + error + ); + } + + try { + console.log("Checking Fulfillments state"); + on_status.fulfillments.forEach((element) => { + console.log(`Checking fulfillment state for Id ${element.id}`); + if ( + !utils.retailFulfillmentState.includes(element.state.descriptor.code) + ) { + onStatObj.ffStatusState = `Fulfillment State Code in /${constants.RET_ONSTATUS} is not as per the API Contract`; + } + }); + } catch (error) { + console.log( + `Fulfillment state Code (/${constants.RET_ONSTATUS}) should be as per the API Contract.`, + error + ); + } + + dao.setValue("onStatObj", onStatObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONSTATUS} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSTATUS} API`, + err + ); + } + } +}; + +module.exports = checkOnStatus; diff --git a/utilities/log-validation-utility/utils/retail/retOnSupport.js b/utilities/log-validation-utility/utils/retail/retOnSupport.js new file mode 100644 index 0000000..ea4f561 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnSupport.js @@ -0,0 +1,123 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const utils = require("../utils"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +const checkOnSupport = (dirPath, msgIdSet) => { + let onSprtObj = {}; + + try { + let on_support = fs.readFileSync( + dirPath + `/${constants.RET_ONSUPPORT}.json` + ); + + console.log(`Validating Schema for /${constants.RET_ONSUPPORT} API`); + + try { + const vs = validateSchema("retail", constants.RET_ONSUPPORT, on_support); + if (vs != "error") { + // console.log(vs); + Object.assign(onSprtObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONSUPPORT}`, + error + ); + } + + on_support = JSON.parse(on_support); + + try { + console.log(`Checking context for /${constants.RET_ONSUPPORT} API`); //checking context + res = checkContext(on_support.context, constants.RET_ONSUPPORT); + if (!res.valid) { + onSprtObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSUPPORT} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}` + ); + if (!_.isEqual(dao.getValue("city"), on_support.context.city)) { + onSprtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_SUPPORT} and /${constants.RET_ONSUPPORT}` + ); + if (_.gte(dao.getValue("sprtTmpstmp"), on_support.context.timestamp)) { + onSprtObj.tmpstmp = `Timestamp for /${constants.RET_SUPPORT} api cannot be greater than or equal to /${constants.RET_ONSUPPORT} api`; + } + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_SUPPORT} and /${constants.RET_ONSUPPORT} api` + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONSUPPORT}` + ); + if ( + !_.isEqual(dao.getValue("txnId"), on_support.context.transaction_id) + ) { + onSprtObj.txnId = `transaction_id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSUPPORT} api`, + error + ); + } + + try { + console.log("Checking Message Id of /on_support"); + if (!_.isEqual(dao.getValue("msgId"), on_support.context.message_id)) { + onSprtObj.msgId = `Message Id for /${constants.RET_SUPPORT} and /${constants.RET_ONSUPPORT} api should be same`; + } + + // if (msgIdSet.has(status.context.message_id)) { + // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = status.context.message_id; + msgIdSet.add(on_support.context.message_id); + } catch (error) { + console.log( + `Error while checking message id for /${constants.RET_ONSUPPORT}`, + error + ); + } + + on_support = on_support.message; + + dao.setValue("onSprtObj", onSprtObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONSUPPORT} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONSUPPORT} API`, + err + ); + } + } +}; + +module.exports = checkOnSupport; diff --git a/utilities/log-validation-utility/utils/retail/retOnTrack.js b/utilities/log-validation-utility/utils/retail/retOnTrack.js new file mode 100644 index 0000000..88e5b81 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnTrack.js @@ -0,0 +1,146 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +const checkOnTrack = (dirPath, msgIdSet) => { + let onTrckObj = {}; + try { + let on_track = fs.readFileSync(dirPath + `/${constants.RET_ONTRACK}.json`); + + try { + console.log(`Validating Schema for /${constants.RET_ONTRACK} API`); + const vs = validateSchema("retail", constants.RET_ONTRACK, on_track); + if (vs != "error") { + // console.log(vs); + Object.assign(onTrckObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONTRACK}`, + error + ); + } + on_track = JSON.parse(on_track); + + console.log(`Checking context for /${constants.RET_ONTRACK} API`); //checking context + try { + res = checkContext(on_track.context, "on_track"); + if (!res.valid) { + onTrckObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONTRACK} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}` + ); + if (!_.isEqual(dao.getValue("city"), on_track.context.city)) { + onTrckObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_ONTRACK} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_track.context.timestamp)) { + onTrckObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONTRACK} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONTRACK} api` + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_TRACK} and /${constants.RET_ONTRACK}` + ); + if (_.gte(dao.getValue("trckTmpstmp"), on_track.context.timestamp)) { + onTrckObj.tmpstmp = `Timestamp for /${constants.RET_TRACK} api cannot be greater than or equal to /${constants.RET_ONTRACK} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_TRACK} and /${constants.RET_ONTRACK} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONTRACK}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_track.context.transaction_id)) { + onTrckObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONTRACK} api`, + error + ); + } + + try { + console.log(`Checking Message Id of /${constants.RET_ONTRACK}`); + if (!_.isEqual(dao.getValue("msgId"), on_track.context.message_id)) { + onTrckObj.msgId = `Message Id for /${constants.RET_TRACK} and /${constants.RET_ONTRACK} api should be same`; + } + + // if (msgIdSet.has(status.context.message_id)) { + // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = status.context.message_id; + msgIdSet.add(on_track.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_ONTRACK}`, + error + ); + } + + on_track = on_track.message.tracking; + + try { + console.log( + `Checking tracking URL when status is active (/${constants.RET_ONTRACK})` + ); + if (on_track.status === "active" && !on_track.url) { + onTrckObj.onTrackUrl = + "Tracking url can't be null when status is active"; + } + } catch (error) { + console.log( + `!!Error while checking tracking url in /${constants.RET_ONTRACK}`, + error + ); + // onTrckObj.onTrackUrl = + // "Tracking url can't be null in case status is active"; + } + + dao.setValue("onTrckObj", onTrckObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONTRACK} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONTRACK} API`, + err + ); + } + } +}; + +module.exports = checkOnTrack; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdate.js b/utilities/log-validation-utility/utils/retail/retOnUpdate.js new file mode 100644 index 0000000..7e6a213 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnUpdate.js @@ -0,0 +1,300 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const validateSchema = require("../schemaValidation"); +const utils = require("../utils"); +const constants = require("../constants"); +const { RET_ONUPDATE } = require("../constants"); + +const checkOnUpdate = (dirPath, msgIdSet) => { + let onUpdtObj = {}; + + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}.json` + ); + on_update = JSON.parse(on_update); + + try { + console.log(`Validating Schema for /${constants.RET_ONUPDATE} API`); + const vs = validateSchema("retail", constants.RET_ONUPDATE, on_update); + if (vs != "error") { + // console.log(vs); + Object.assign(onUpdtObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_ONUPDATE}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_ONUPDATE} API`); //checking context + res = checkContext(on_update.context, constants.RET_ONUPDATE); + if (!res.valid) { + onUpdtObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_ONUPDATE} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}` + ); + if (!_.isEqual(dao.getValue("city"), on_update.context.city)) { + onUpdtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}`; + } + } catch (error) { + console.log( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}` + ); + if (_.gte(dao.getValue("updtTmpstmp"), on_update.context.timestamp)) { + onUpdtObj.tmpstmp = `Timestamp for /${constants.RET_UPDATE} api cannot be greater than or equal to /${constants.RET_ONUPDATE} api`; + } + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONUPDATE}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_update.context.transaction_id)) { + onUpdtObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONUPDATE} API`, + error + ); + } + + try { + console.log( + `Comparing Message Ids of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}` + ); + if (!_.isEqual(dao.getValue("msgId"), on_update.context.message_id)) { + onUpdtObj.msgId = `Message Ids for /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE} apis should be same`; + } + // if (msgIdSet.has(confirm.context.message_id)) { + // cnfrmObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = confirm.context.message_id; + msgIdSet.add(on_update.context.message_id); + } catch (error) { + console.log( + `Error while checking message id for /${constants.RET_ONUPDATE}`, + error + ); + } + + on_update = on_update.message.order; + + try { + console.log( + `Comparing order ids in /${constants.RET_CONFIRM} and /${constants.RET_ONUPDATE}` + ); + if (dao.getValue("cnfrmOrdrId") != on_update.id) { + onUpdtObj.orderID = `Order Id mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONUPDATE}`; + } + } catch (error) { + console.log( + `!!Error while trying to fetch order ids in /${constants.RET_ONUPDATE}`, + error + ); + } + + try { + console.log(`Checking items update status`); + itemsUpdt = dao.getValue("itemsUpdt"); + for (item in itemsUpdt) { + let updatedItem = on_update.items.find((it) => it.id === item); + //Checking if item can be updated? (if update_type is return, fulfillment state should be Order-delivered and in case of cancel, fulfillment state should be cancelled) + if (itemsUpdt[item][1] === "return") { + let itemff = on_update.fulfillments.find( + (ff) => ff.id === updatedItem.fulfillment_id + ); + if (itemff.state.descriptor.code != "Order-delivered") { + onUpdtObj.updtTypFF = `item with id: ${item} can't be returned when order is not delivered (fulfillment state should be Order-delivered)`; + } + } else if (itemsUpdt[item][1] === "cancel") { + let itemff = on_update.fulfillments.find( + (ff) => ff.id === updatedItem.fulfillment_id + ); + if ( + itemff.state.descriptor.code != "Pending" || + itemff.state.descriptor.code != "Packed" + ) { + onUpdtObj.updtTypFF = `item with id: ${item} can't be cancelled when fulfillment state is not Pending/Packed`; + } + } + } + } catch (error) { + console.log( + `!!Error while checking items update status in /${constants.RET_ONUPDATE}`, + error + ); + } + + try { + console.log( + `Checking start/end time.timestamp in case of triggering fulfillment states` + ); + on_update.fulfillments.forEach((ff) => { + state = ff.state.descriptor.code; + if (state === "Order-picked-up" || state === "Out-for-delivery") { + if (!ff.start.time.timestamp) { + onUpdtObj.ffstrttimetmpstmp = `fulfillment start timestamp is mandatory when fulfillment state is ${state}`; + } + } else if (state === "Order-delivered") { + if (!ff.start.time.timestamp) { + onUpdtObj.ffstrttimetmpstmp = `fulfillment start timestamp is mandatory when fulfillment state is ${state}`; + } + if (!ff.end.time.timestamp) { + onUpdtObj.ffendtimetmpstmp = `fulfillment end timestamp is mandatory when fulfillment state is ${state}`; + } + } + }); + } catch (error) { + console.log( + `Error while checking timestamp in case of triggering fulfillment states in /${RET_ONUPDATE}`, + error + ); + } + + try { + console.log(`Quote Breakup ${constants.RET_ONUPDATE} all checks`); + // let itemsIdList = dao.getValue("itemsIdList"); + // let itemsCtgrs = dao.getValue("itemsCtgrs"); + let itemFlfllmnts = dao.getValue("itemFlfllmnts"); + let onUpdatePrice = 0; + + on_update.quote.breakup.forEach((element, i) => { + let titleType = element["@ondc/org/title_type"]; + // console.log(element.price.value); + + console.log( + `Calculating quoted Price Breakup for element ${element.title}` + ); + onUpdatePrice += parseFloat(element.price.value); + if (titleType === "item") { + if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { + let brkupitemid = `brkupitemid${i}`; + onUpdtObj[ + brkupitemid + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; + } + + console.log( + `Comparing individual item's total price and unit price ` + ); + if (!element.hasOwnProperty("item")) { + onSlctObj.priceBreakup = `Item's unit price missing in quote.breakup for item id ${element["@ondc/org/item_id"]}`; + } else if ( + parseFloat(element.item.price.value) * + element["@ondc/org/item_quantity"].count != + element.price.value + ) { + onUpdtObj.priceBreakup = `Item's unit and total price mismatch for id: ${element["@ondc/org/item_id"]}`; + } + + console.log( + `checking available and maximum count in ${constants.RET_ONUPDATE}` + ); + + if (element.item.hasOwnProperty("quantity")) { + if ( + _.gt( + element.item.quantity.available.count, + element.item.quantity.maximum.count + ) + ) { + onUpdtObj.qntCnt = `available count can't be greater than maximum count for item id: ${element["@ondc/org/item_id"]}`; + } + } + } + + // console.log(`Calculating Items' prices in /${constants.RET_ONUPDATE}`); + // if (element["@ondc/org/item_id"] in itemsIdList) { + // if ( + // titleType === "item" || + // (titleType === "tax" && + // !utils.taxNotInlcusive.includes( + // itemsCtgrs[element["@ondc/org/item_id"]] + // )) + // ) + // onUpdateItemsPrice += parseFloat(element.price.value); + // } + + if (titleType === "tax" || titleType === "discount") { + if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { + let brkupitemsid = `brkupitemstitles${i}`; + onUpdtObj[ + brkupitemsid + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; + } + } + + if ( + titleType === "packing" || + titleType === "delivery" || + titleType === "misc" + ) { + if ( + !Object.values(itemFlfllmnts).includes(element["@ondc/org/item_id"]) + ) { + let brkupffid = `brkupfftitles${i}`; + onUpdtObj[ + brkupffid + ] = `${titleType} with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in fulfillments[]`; + } + } + }); + + dao.setValue("onUpdatePrice", onUpdatePrice); + + console.log( + `Matching quoted Price ${parseFloat( + on_update.quote.price.value + )} with Breakup Price ${onUpdatePrice}` + ); + if (onUpdatePrice != parseFloat(on_update.quote.price.value)) { + onUpdtObj.quoteBrkup = `quote.price.value ${on_update.quote.price.value} does not match with the price breakup ${onUpdatePrice}`; + } + } catch (error) { + console.log( + `!!Error while checking and comparing the quoted price in /${constants.RET_ONUPDATE}`, + error + ); + } + + dao.setValue("onUpdtObj", onUpdtObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_ONUPDATE} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_ONUPDATE} API`, + err + ); + } + } +}; + +module.exports = checkOnUpdate; diff --git a/utilities/log-validation-utility/utils/retail/retPostConfirm.js b/utilities/log-validation-utility/utils/retail/retPostConfirm.js new file mode 100644 index 0000000..5046dc2 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retPostConfirm.js @@ -0,0 +1,12 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const utils = require("../utils"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +//helper function to check /on_status and /on_update +checkPostConfirm = (msgPyld) => {}; + +module.exports = checkPostConfirm; diff --git a/utilities/log-validation-utility/utils/retail/retSearch.js b/utilities/log-validation-utility/utils/retail/retSearch.js new file mode 100644 index 0000000..5bec2bc --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retSearch.js @@ -0,0 +1,99 @@ +const dao = require("../../dao/dao"); +const fs = require("fs"); +const utils = require("../utils"); +const constants = require("../constants"); +const { checkContext } = require("../../services/service"); +const validateSchema = require("../schemaValidation"); + +const checkSearch = (dirPath, msgIdSet) => { + let srchObj = {}; + try { + let search = fs.readFileSync(dirPath + `/${constants.RET_SEARCH}.json`); + search = JSON.parse(search); + try { + console.log(`Validating Schema for ${constants.RET_SEARCH} API`); + const vs = validateSchema("retail", constants.RET_SEARCH, search); + if (vs != "error") { + // console.log(vs); + Object.assign(srchObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_SEARCH}`, + error + ); + } + + console.log(`Checking context for ${constants.RET_SEARCH} API`); //context checking + + try { + res = checkContext(search.context, constants.RET_SEARCH); + dao.setValue("tmpstmp", search.context.timestamp); + dao.setValue("txnId", search.context.transaction_id); + dao.setValue("msgId", search.context.message_id); + dao.setValue("city", search.context.city); + msgIdSet.add(search.context.message_id); + if (!res.valid) { + srchObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_SEARCH} context`, + error + ); + } + + search = search.message.intent; + try { + console.log("Getting Buyer App finder fee amount"); + if (search.payment["@ondc/org/buyer_app_finder_fee_type"] != "percent") { + srchObj.bffTyp = `Buyer app finder fee type should be "percent"`; + } + var buyerFF = parseFloat( + search.payment["@ondc/org/buyer_app_finder_fee_amount"] + ); + dao.setValue("buyerFF", buyerFF); + } catch (error) { + console.log("!!Error while fetching buyer app finder fee amount", error); + } + + try { + console.log("Checking GPS Precision in /search"); + if (search.hasOwnProperty("item")) { + if (search.hasOwnProperty("fulfillment")) { + const gps = search.fulfillment.end.location.gps.split(","); + const gpsLat = gps[0]; + const gpsLong = gps[1]; + + if (!gpsLat || !gpsLong) { + srchObj.gpsErr = `location.gps is not as per the API contract`; + } else { + if ( + utils.countDecimalDigits(gpsLat) != + utils.countDecimalDigits(gpsLong) + ) { + srchObj.gpsErr = `GPS Lat/Long Precision should be same `; + } + } + } else { + srchObj.flfllmntObj = `Fulfillment object missing in /${constants.RET_SEARCH} API`; + } + } + } catch (error) { + console.log("!!Error while checking GPS Precision", error); + } + + dao.setValue("srchObj", srchObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_SEARCH} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_SEARCH} API`, + err + ); + } + } +}; + +module.exports = checkSearch; diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js new file mode 100644 index 0000000..eef6ae5 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -0,0 +1,233 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const utils = require("../utils"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); + +const checkSelect = (dirPath, msgIdSet) => { + //list to store selected items + + let selectedPrice = 0; + let itemsIdList = {}; + let itemsCtgrs = {}; + let itemsTat = {}; + let slctObj = {}; + + try { + select = fs.readFileSync(dirPath + `/${constants.RET_SELECT}.json`); //testing + select = JSON.parse(select); + try { + console.log(`Validating Schema for ${constants.RET_SELECT} API`); + const vs = validateSchema("retail", constants.RET_SELECT, select); + if (vs != "error") { + // console.log(vs); + Object.assign(slctObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_SELECT}`, + error + ); + } + + console.log(`Checking context for ${constants.RET_SELECT} API`); //checking context + try { + res = checkContext(select.context, constants.RET_SELECT); + if (!res.valid) { + slctObj = res.ERRORS; + } + } catch (error) { + console.log( + `Some error occurred while checking /${constants.RET_SELECT} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_SELECT}` + ); + if (!_.isEqual(dao.getValue("city"), select.context.city)) { + slctObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_SELECT}`; + } + } catch (error) { + console.log( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_SELECT}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + if (_.gte(dao.getValue("tmpstmp"), select.context.timestamp)) { + slctObj.tmpstmp = `Timestamp for /${constants.RET_ONSEARCH} api cannot be greater than or equal to /${constants.RET_SELECT} api`; + } + dao.setValue("tmpstmp", select.context.timestamp); + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + // if (_.isEqual(dao.getValue("txnId"), select.context.transaction_id)) { + // slctObj.txnId = `Transaction Id for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api cannot be same`; + // } + dao.setValue("txnId", select.context.transaction_id); + } catch (error) { + console.log( + `Error while comparing transaction ids for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api`, + error + ); + } + + try { + console.log( + `Comparing Message Ids of /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + if (_.isEqual(dao.getValue("msgId"), select.context.message_id)) { + slctObj.msgId = `Message Id for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api cannot be same`; + } + dao.setValue("msgId", select.context.message_id); + // msgIdSet.add(select.context.message_id); + } catch (error) { + console.log( + `Error while comparing message ids for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api`, + error + ); + } + + let order = select.message.order; + + let onSearch = dao.getValue("onSearch"); + + let provider = onSearch["bpp/providers"].filter( + (provider) => provider.id === order.provider.id + ); + + if (provider[0]) { + provider = provider[0]; + dao.setValue("providerId", provider.id); + dao.setValue("providerLoc", provider.locations[0].id); + + try { + console.log( + `Comparing provider location in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + if (provider.locations[0].id != order.provider.locations[0].id) { + slctObj.prvdLoc = `provider.locations[0].id ${provider.locations[0].id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; + } + } catch (error) { + console.log( + `!!Error while comparing provider.location id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, + error + ); + } + + console.log( + `Mapping Item Ids with their counts, categories and prices /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + try { + order.items.forEach((item) => { + let itemOnSearch = provider.items.find((it) => it.id === item.id); + + if (!itemOnSearch) { + key = `id${item.id}`; + slctObj[ + key + ] = `Item Id ${item.id} does not exist in /${constants.RET_ONSEARCH}`; + } else { + console.log( + `ITEM ID: ${item.id}, Price: ${itemOnSearch.price.value}, Count: ${item.quantity.count}` + ); + if ( + item.location_id && + itemOnSearch.location_id != item.location_id + ) { + slctObj.itemLocErr = `Location id for Item ${item.id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; + } + itemsIdList[item.id] = item.quantity.count; + itemsCtgrs[item.id] = itemOnSearch.category_id; + itemsTat[item.id] = itemOnSearch["@ondc/org/time_to_ship"]; + selectedPrice += itemOnSearch.price.value * item.quantity.count; + } + }); + dao.setValue("itemsIdList", itemsIdList); + dao.setValue("itemsCtgrs", itemsCtgrs); + dao.setValue("selectedPrice", selectedPrice); + dao.setValue("itemsTat", itemsTat); + console.log( + `Provider Id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} matched` + ); + } catch (error) { + console.log( + `!!Error while Comparing and Mapping Items in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, + error + ); + } + } else { + console.log( + `Provider Ids in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} mismatch` + ); + slctObj.prvdrIdMatch = `Provider Id ${order.provider.id} in /${constants.RET_SELECT} does not exist in /${constants.RET_ONSEARCH}`; + } + + try { + order.fulfillments.forEach((ff, indx) => { + console.log(`Checking GPS Precision in /${constants.RET_SELECT}`); + + if (ff.hasOwnProperty("end")) { + dao.setValue("buyerGps", ff.end.location.gps); + dao.setValue("buyerAddr", ff.end.location.address.area_code); + const gps = ff.end.location.gps.split(","); + const gpsLat = gps[0]; + const gpsLong = gps[1]; + // console.log(gpsLat, " sfsfdsf ", gpsLong); + if (!gpsLat || !gpsLong) { + slctObj.gpsErr = `fulfillments location.gps is not as per the API contract`; + } else { + if ( + utils.countDecimalDigits(gpsLat) != + utils.countDecimalDigits(gpsLong) + ) { + slctObj.gpsErr = `fulfillments GPS Lat/Long Precision should be same `; + } + } + + if (!ff.end.location.address.hasOwnProperty("area_code")) { + slctObj.areaCode = `address.area_code is required property in /${constants.RET_SELECT}`; + } + } else { + srchObj.endflfllmntObj = `fulfillments[${indx}].end object missing in /${constants.RET_SELECT} API`; + } + }); + } catch (error) { + console.log( + `!!Error while checking GPS Precision in /${constants.RET_SELECT}`, + error + ); + } + + console.log("Total Price of Selected Items:", selectedPrice); + dao.setValue("slctObj", slctObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_SELECT} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_SELECT} API`, + err + ); + } + } +}; + +module.exports = checkSelect; diff --git a/utilities/log-validation-utility/utils/retail/retStatus.js b/utilities/log-validation-utility/utils/retail/retStatus.js new file mode 100644 index 0000000..130794e --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retStatus.js @@ -0,0 +1,130 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); + +const checkStatus = (dirPath, msgIdSet) => { + let statObj = {}; + try { + let status = fs.readFileSync(dirPath + `/${constants.RET_STATUS}.json`); + status = JSON.parse(status); + + try { + console.log(`Validating Schema for ${constants.RET_STATUS} API`); + const vs = validateSchema("retail", constants.RET_STATUS, status); + if (vs != "error") { + // console.log(vs); + Object.assign(statObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_STATUS}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_STATUS} API`); //checking context + res = checkContext(status.context, constants.RET_STATUS); + if (!res.valid) { + statObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_STATUS} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_STATUS}` + ); + if (!_.isEqual(dao.getValue("city"), status.context.city)) { + statObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_STATUS}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_STATUS}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_STATUS} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), status.context.timestamp)) { + dao.setValue("statTmpstmp", status.context.timestamp); + statObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_STATUS} api`; + } + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_STATUS} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_STATUS}` + ); + if (!_.isEqual(dao.getValue("txnId"), status.context.transaction_id)) { + statObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_STATUS} api` + ); + } + + try { + console.log(`Checking Message Id of /${constants.RET_STATUS}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for ${constants.RET_SELECT} and /on_select api should be same"; + // } + + if (msgIdSet.has(status.context.message_id)) { + statObj.msgId2 = `Message Id cannot be same for different sets of APIs`; + } + dao.setValue("msgId", status.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_STATUS}` + ); + } + + status = status.message; + + try { + console.log( + `Comparing order id for /${constants.RET_CONFIRM} and /${constants.RET_STATUS}` + ); + if (dao.getValue("cnfrmOrdrId") != status.order_id) { + statObj.orderId = `Order ids in /${constants.RET_CONFIRM} and /${constants.RET_STATUS} do not match`; + } + } catch (error) { + console.log( + `!!Error occurred while comparing order ids /confirm and /${constants.RET_STATUS}`, + error + ); + } + + dao.setValue("statObj", statObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_STATUS} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_STATUS} API`, + err + ); + } + } +}; + +module.exports = checkStatus; diff --git a/utilities/log-validation-utility/utils/retail/retSupport.js b/utilities/log-validation-utility/utils/retail/retSupport.js new file mode 100644 index 0000000..5806036 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retSupport.js @@ -0,0 +1,111 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); + +const checkSupport = (dirPath, msgIdSet) => { + let sprtObj = {}; + try { + var support = fs.readFileSync(dirPath + `/${constants.RET_SUPPORT}.json`); + support = JSON.parse(support); + console.log(`Checking context for /${constants.RET_SUPPORT} API`); //checking context + try { + res = checkContext(support.context, constants.RET_SUPPORT); + if (!res.valid) { + sprtObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_SUPPORT} context`, + error + ); + } + + try { + console.log( + `Comparing city of ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}` + ); + if (!_.isEqual(dao.getValue("city"), support.context.city)) { + sprtObj.city = `City code mismatch in ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}`; + } + } catch (error) { + console.log( + `Error while comparing city in ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}`, + error + ); + } + console.log( + `Comparing timestamp of /${constants.RET_SUPPORT} and /${constants.RET_ONCONFIRM}` + ); + + try { + if (_.gte(dao.getValue("tmpstmp"), support.context.timestamp)) { + dao.setValue("sprtTmpstmp", support.context.timestamp); + sprtObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_SUPPORT} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_SUPPORT} api`, + error + ); + } + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_SUPPORT}` + ); + if (!_.isEqual(dao.getValue("txnId"), support.context.transaction_id)) { + sprtObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_SUPPORT} api`, + error + ); + } + try { + console.log(`Checking Message Id of /${constants.RET_SUPPORT}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for /${constants.RET_SELECT} and /on_select api should be same"; + // } + if (msgIdSet.has(support.context.message_id)) { + sprtObj.msgId2 = `Message Id cannot be same for different sets of APIs`; + } + dao.setValue("msgId", support.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_SUPPORT}`, + error + ); + } + support = support.message; + + try { + console.log(`Checking ref_id in /${constants.RET_SUPPORT}`); + if (!_.isEqual(dao.getValue("txnId"), support.ref_id)) { + sprtObj.refId = `Transaction Id should be provided as ref_id`; + } + } catch (error) { + sprtObj.refId = `Transaction Id should be provided as ref_id`; + console.log( + `!!Error while checking ref_id in /${constants.RET_SUPPORT}`, + error + ); + } + + dao.setValue("sprtObj", sprtObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_SUPPORT} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_SUPPORT} API`, + err + ); + } + } +}; + +module.exports = checkSupport; diff --git a/utilities/log-validation-utility/utils/retail/retTrack.js b/utilities/log-validation-utility/utils/retail/retTrack.js new file mode 100644 index 0000000..c2e26be --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retTrack.js @@ -0,0 +1,118 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const constants = require("../constants"); + +const checkTrack = (dirPath, msgIdSet) => { + let trckObj = {}; + try { + let track = fs.readFileSync(dirPath + `/${constants.RET_TRACK}.json`); + track = JSON.parse(track); + + console.log(`Checking context for /${constants.RET_TRACK}rack API`); //checking context + try { + res = checkContext(track.context, constants.RET_TRACK); + if (!res.valid) { + trckObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_TRACK} context` + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_TRACK}` + ); + if (!_.isEqual(dao.getValue("city"), track.context.city)) { + trckObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_TRACK}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_TRACK}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), track.context.timestamp)) { + dao.setValue("trckTmpstmp", track.context.timestamp); + trckObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_TRACK} api`; + } + } catch (error) { + console.log( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_TRACK} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /select and /${constants.RET_TRACK}` + ); + if (!_.isEqual(dao.getValue("txnId"), track.context.transaction_id)) { + trckObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /select and /${constants.RET_TRACK} api`, + error + ); + } + + try { + console.log(`Checking Message Id of /${constants.RET_TRACK}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for /select and /on_select api should be same"; + // } + + if (msgIdSet.has(track.context.message_id)) { + trckObj.msgId2 = `Message Id cannot be same for different sets of APIs`; + } + dao.setValue("msgId", track.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_TRACK}` + ); + } + + track = track.message; + + try { + console.log( + `Checking Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}` + ); + if (track.order_id != dao.getValue("onCnfrmOrdrId")) { + console.log( + `Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match` + ); + trckObj.trackOrdrId = `Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match`; + } + } catch (error) { + console.log( + `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}`, + error + ); + // trckObj.trackOrdrId = "Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match"; + } + dao.setValue("trckObj", trckObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_TRACK} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_TRACK} API`, + err + ); + } + } +}; + +module.exports = checkTrack; diff --git a/utilities/log-validation-utility/utils/retail/retUpdate.js b/utilities/log-validation-utility/utils/retail/retUpdate.js new file mode 100644 index 0000000..a41204b --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retUpdate.js @@ -0,0 +1,140 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const utils = require("../utils"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); + +const checkUpdate = (dirPath, msgIdSet) => { + let updtObj = {}; + let itemsUpdt = {}; + + try { + let update = fs.readFileSync(dirPath + `/${constants.RET_UPDATE}.json`); + update = JSON.parse(update); + + try { + console.log(`Validating Schema for ${constants.RET_UPDATE} API`); + const vs = validateSchema("retail", constants.RET_UPDATE, update); + if (vs != "error") { + // console.log(vs); + Object.assign(updtObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_UPDATE}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_UPDATE} API`); //checking context + res = checkContext(update.context, constants.RET_UPDATE); + if (!res.valid) { + updtObj = res.ERRORS; + } + } catch (error) { + console.log( + `!!Some error occurred while checking /${constants.RET_UPDATE} context`, + error + ); + } + + try { + console.log( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_UPDATE}` + ); + if (!_.isEqual(dao.getValue("city"), update.context.city)) { + updtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}`; + } + } catch (error) { + console.log( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}`, + error + ); + } + + try { + console.log( + `Comparing timestamp of /${constants.RET_UPDATE} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), update.context.timestamp)) { + dao.setValue("updtTmpstmp", update.context.timestamp); + updtObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_UPDATE} api`; + } + } catch (error) { + console.log( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_UPDATE} api`, + error + ); + } + + try { + console.log( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_UPDATE}` + ); + if (!_.isEqual(dao.getValue("txnId"), update.context.transaction_id)) { + statObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + console.log( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_UPDATE} api` + ); + } + try { + console.log(`Checking Message Id of /${constants.RET_UPDATE}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for ${constants.RET_SELECT} and /on_select api should be same"; + // } + + if (msgIdSet.has(update.context.message_id)) { + updtObj.msgId2 = `Message Id cannot be same for different sets of APIs`; + } + dao.setValue("msgId", update.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + console.log( + `!!Error while checking message id for /${constants.RET_UPDATE}` + ); + } + + update = update.message.order; + + try { + console.log(`Saving items update_type in /${constants.RET_UPDATE}`); + update.items.forEach((item, i) => { + if (item.hasOwnProperty("tags")) { + if ( + item.tags.update_type === "return" || + item.tags.update_type === "cancel" + ) { + itemsUpdt[item.id] = [item.quantity.count, item.tags.update_type]; + } else { + updtObj.updtTypeErr = `items[${i}].tags.update_type can't be ${item.tags.update_type}`; + } + } + }); + dao.setValue("itemsUpdt", itemsUpdt); + } catch (error) { + console.log( + `!!Error while saving items update_type in /${constants.RET_UPDATE}`, + error + ); + } + + dao.setValue("updtObj", updtObj); + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${constants.RET_UPDATE} API!`); + } else { + console.log( + `!!Some error occurred while checking /${constants.RET_UPDATE} API`, + err + ); + } + } +}; + +module.exports = checkUpdate; diff --git a/utilities/log-validation-utility/utils/schemaValidation.js b/utilities/log-validation-utility/utils/schemaValidation.js new file mode 100644 index 0000000..2316dd7 --- /dev/null +++ b/utilities/log-validation-utility/utils/schemaValidation.js @@ -0,0 +1,47 @@ +const schemaValidator = require("../schema/main"); +const path = require("path"); +const fs = require("fs"); + +const validateSchema = (domain, api, data) => { + console.log(`Inside Schema Validation for domain: ${domain}, api: ${api}`); + let errObj = {}; + // data = JSON.parse(data); + // const schemaValidator = path.join( + // __dirname, + // "..", + // "schema", + // "ondc-schema-validator", + // "main.py" + // ); + + // const pySchmaVldtr = spawnSync("python3", [ + // schemaValidator, + // "validate_schema_for_retail_json", + // domain, + // api, + // data, + // ]); + const schmaVldtr = schemaValidator(domain, api, data); + + const datavld = schmaVldtr; + if (datavld.status === "fail") { + let res = datavld.errors; + // res = res.map(({ type, ...rest }) => ({ ...rest })); + let i = 0; + const len = res.length; + while (i < len) { + let key = `schemaErr${i}`; + errObj[key] = `${res[i].details} ${res[i].message}`; + i++; + } + + return errObj; + } else return "error"; + + // pySchmaVldtr.stderr.on("data", (data) => { + // console.log(`ERROR validating schema for ${api} :`, data); + // return "error"; + // }); +}; + +module.exports = validateSchema; diff --git a/utilities/log-validation-utility/utils/utils.js b/utilities/log-validation-utility/utils/utils.js new file mode 100644 index 0000000..75edf80 --- /dev/null +++ b/utilities/log-validation-utility/utils/utils.js @@ -0,0 +1,229 @@ +const path = require("path"); +const _ = require("lodash"); +const rootPath = path.dirname(process.mainModule.filename); + +const retailAPI = [ + "search", + "on_search", + "select", + "on_select", + "init", + "on_init", + "confirm", + "on_confirm", + "status", + "on_status", + "track", + "on_track", + "cancel", + "on_cancel", + "update", + "on_update", + "support", + "on_support", +]; + +const taxNotInlcusive = ["F&B"]; + +const retailSttlmntPhase = ["sale-amount", "withholding-amount", "refund"]; + +const retailSttlmntCntrprty = [ + "buyer", + "buyer-app", + "seller-app", + "logistics-provider", +]; + +const retailPymntTtl = { + "delivery charges": "delivery", + "packing charges": "packing", + tax: "tax", + discount: "discount", + "convenience fee": "misc", +}; + +const retailPaymentType = [ + "ON-ORDER", + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", +]; +const retailFulfillmentState = [ + //pre-order fulfillment states + "Serviceable", + "Non-serviceable", + //post-order fulfillment states + "Pending", + "Packed", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", +]; + +const retailOrderState = [ + "Created", + "Accepted", + "In-progress", + "Completed", + "Cancelled", +]; + +const logFulfillmentState = [ + "Pending", + "Searching-for-Agent", + "Agent-assigned", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", +]; + +const logOrderState = [ + "Created", + "Accepted", + "In-progress", + "Completed", + "Cancelled", +]; + +const bpp_fulfillments = ["Delivery", "Pickup", "Delivery and Pickup"]; //id =1,2,3 +const bpp_provider_days = [ + "1", + "1,2", + "1,2,3", + "1,2,3,4", + "1,2,3,4,5", + "1,2,3,4,5,6", + "1,2,3,4,5,6,7", +]; + +const grocery_categories_id = [ + "Fruits and Vegetables", + "Masala & Seasoning", + "Oil & Ghee", + "Gourmet & World Foods", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beverages", + "Beauty & Hygiene", + "Bakery, Cakes & Dairy", + "Kitchen Accessories", + "Baby Care", + "Snacks & Branded Foods", + "Pet Care", + "Stationery", + "Packaged Commodities", + "Packaged Foods", +]; + +const fnb_categories_id = [ + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "F&B", +]; + +const fssai_nos = [ + "brand_owner_FSSAI_license_no", + "other_FSSAI_license_no", + "importer_FSSAI_license_no", +]; + +const cancellation_rid = { + "001": 0, + "002": 0, + "003": 0, + "004": 0, + "005": 0, + "006": 0, + "009": 1, + "010": 1, + "011": 1, + "012": 1, + "013": 1, + "014": 1, + "015": 1, + "016": 0, + "017": 0, + "018": 0, +}; + +const uuidCheck = (data) => { + console.log("***UUID Validation Utils***"); + let uuid = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + if (!uuid.test(data)) return false; + return true; +}; + +const timestampCheck = (date) => { + console.log("***Timestamp Check Utils***"); + let dateParsed = new Date(Date.parse(date)); + if (!isNaN(dateParsed)) { + if (dateParsed.toISOString() != date) { + //FORMAT_ERR= Valid date but not in RFC 3339 format + return { err: "FORMAT_ERR" }; + } + } else { + //INVLD_DT= Invalid date-time format + return { err: "INVLD_DT" }; + } +}; + +const getObjValues = (obj) => { + let values = ""; + Object.values(obj).forEach((value) => { + values += value + "\n"; + }); + return values; +}; + +const isArrayEqual = (x, y) => { + flag = _(x).xorWith(y, _.isEqual).isEmpty(); + console.log("FLAG*********", _(x).xorWith(y, _.isEqual).isEmpty()); + return flag; +}; + +const countDecimalDigits = (num) => { + return num.toString().split(".")[1].length; +}; + +module.exports = { + uuidCheck, + timestampCheck, + rootPath, + retailAPI, + retailFulfillmentState, + retailOrderState, + logFulfillmentState, + logOrderState, + bpp_fulfillments, + bpp_provider_days, + cancellation_rid, + getObjValues, + retailPaymentType, + retailPymntTtl, + taxNotInlcusive, + isArrayEqual, + countDecimalDigits, + grocery_categories_id, + fnb_categories_id, +}; diff --git a/utilities/log-validation-utility/utils/validateLogUtil.js b/utilities/log-validation-utility/utils/validateLogUtil.js new file mode 100644 index 0000000..eaa2a72 --- /dev/null +++ b/utilities/log-validation-utility/utils/validateLogUtil.js @@ -0,0 +1,205 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../dao/dao"); +// const path = require("path"); +const { getObjValues } = require("./utils"); +const checkSearch = require("./retail/retSearch"); +const checkOnSearch = require("./retail/retOnSearch"); +const checkSelect = require("./retail/retSelect"); +const checkOnSelect = require("./retail/retOnSelect"); +const checkInit = require("./retail/retInit"); +const checkOnInit = require("./retail/retOnInit"); +const checkConfirm = require("./retail/retConfirm"); +const checkOnConfirm = require("./retail/retOnConfirm"); +const checkStatus = require("./retail/retStatus"); +const checkOnStatus = require("./retail/retOnStatus"); +const checkTrack = require("./retail/retTrack"); +const checkOnTrack = require("./retail/retOnTrack"); +const checkCancel = require("./retail/retCancel"); +const checkOnCancel = require("./retail/retOnCancel"); +const checkSupport = require("./retail/retSupport"); +const checkOnSupport = require("./retail/retOnSupport"); +const checkUpdate = require("./retail/retUpdate"); +const checkOnUpdate = require("./retail/retOnUpdate"); + +//To be developed: TAT in on_select = sumof(time to ship in /on_search and TAT by LSP in logistics /on_search) +// If non-serviceable in /on_select, there should be domain-error + +const validateLogs = (dirPath) => { + // const dirPath = path.join(__dirname, "test_logs"); + + let msgIdSet = new Set(); + + //SEARCH API + + let srchResp = checkSearch(dirPath, msgIdSet); + + // ON_SEARCH API + + let onSrchResp = checkOnSearch(dirPath, msgIdSet); + + //SELECT API + + let slctResp = checkSelect(dirPath, msgIdSet); + + // //ON_SELECT API + + let onSlctResp = checkOnSelect(dirPath, msgIdSet); + + // //INIT API + + let initResp = checkInit(dirPath, msgIdSet); + + // //ON_INIT API + + let onInitResp = checkOnInit(dirPath, msgIdSet); + + // //CONFIRM API + + let cnfrmResp = checkConfirm(dirPath, msgIdSet); + + // //ON_CONFIRM API + + let onCnfrmResp = checkOnConfirm(dirPath, msgIdSet); + + // //STATUS API + let statResp = checkStatus(dirPath, msgIdSet); + + // //ON_STATUS API + + let onStatResp = checkOnStatus(dirPath, msgIdSet); + + // //UPDATE API + + let updtResp = checkUpdate(dirPath, msgIdSet); + + // //ON_UPDATE API + + let onUpdtResp = checkOnUpdate(dirPath, msgIdSet); + + // //TRACK API + + let trckResp = checkTrack(dirPath, msgIdSet); + + // //ON_TRACK API + + let onTrckResp = checkOnTrack(dirPath, msgIdSet); + + // //CANCEL API + + let cnclResp = checkCancel(dirPath, msgIdSet); + + // //ON_CANCEL API + + let onCnclResp = checkOnCancel(dirPath, msgIdSet); + + // //SUPPORT API + let sprtResp = checkSupport(dirPath, msgIdSet); + + // //ON_SUPPORT API + let onSprtResp = checkOnSupport(dirPath, msgIdSet); + + let logReport = ""; + + let srchObj = dao.getValue("srchObj"); + let onSrchObj = dao.getValue("onSrchObj"); + let slctObj = dao.getValue("slctObj"); + let onSlctObj = dao.getValue("onSlctObj"); + let initObj = dao.getValue("initObj"); + let onInitObj = dao.getValue("onInitObj"); + let cnfrmObj = dao.getValue("cnfrmObj"); + let onCnfrmObj = dao.getValue("onCnfrmObj"); + let cnclObj = dao.getValue("cnclObj"); + let onCnclObj = dao.getValue("onCnclObj"); + let trckObj = dao.getValue("trckObj"); + let onTrckObj = dao.getValue("onTrckObj"); + let sprtObj = dao.getValue("sprtObj"); + let onSprtObj = dao.getValue("onSprtObj"); + let updtObj = dao.getValue("updtObj"); + let onUpdtObj = dao.getValue("onUpdtObj"); + let statObj = dao.getValue("statObj"); + let onStatObj = dao.getValue("onStatObj"); + + try { + console.log("Flushing DB Data"); + dao.dropDB(); + } catch (error) { + console.log("Error while removing LMDB"); + } + + if (!_.isEmpty(srchObj)) { + logReport += `**/search**\n${getObjValues(srchObj)}\n`; + } + + if (!_.isEmpty(onSrchObj)) { + logReport += `**/on_search**\n${getObjValues(onSrchObj)}\n`; + } + + if (!_.isEmpty(slctObj)) { + logReport += `**/select**\n${getObjValues(slctObj)}\n`; + } + + if (!_.isEmpty(onSlctObj)) { + logReport += `**/on_select**\n${getObjValues(onSlctObj)}\n`; + } + + if (!_.isEmpty(initObj)) { + logReport += `**/init**\n${getObjValues(initObj)}\n`; + } + + if (!_.isEmpty(onInitObj)) { + logReport += `**/on_init**\n${getObjValues(onInitObj)}\n`; + } + + if (!_.isEmpty(cnfrmObj)) { + logReport += `**/confirm**\n${getObjValues(cnfrmObj)}\n`; + } + + if (!_.isEmpty(onCnfrmObj)) { + logReport += `**/on_confirm**\n${getObjValues(onCnfrmObj)}\n`; + } + + if (!_.isEmpty(cnclObj)) { + logReport += `**/cancel**\n${getObjValues(cnclObj)}\n`; + } + + if (!_.isEmpty(onCnclObj)) { + logReport += `**/on_cancel**\n${getObjValues(onCnclObj)}\n`; + } + + if (!_.isEmpty(trckObj)) { + logReport += `**/track**\n${getObjValues(trckObj)}\n`; + } + + if (!_.isEmpty(onTrckObj)) { + logReport += `**/on_track**\n${getObjValues(onTrckObj)}\n`; + } + + if (!_.isEmpty(statObj)) { + logReport += `**/status**\n${getObjValues(statObj)}\n`; + } + if (!_.isEmpty(onStatObj)) { + logReport += `**/on_status**\n${getObjValues(onStatObj)}\n`; + } + + if (!_.isEmpty(updtObj)) { + logReport += `**/update**\n${getObjValues(updtObj)}\n`; + } + if (!_.isEmpty(onUpdtObj)) { + logReport += `**/on_update**\n${getObjValues(onUpdtObj)}\n`; + } + + if (!_.isEmpty(sprtObj)) { + logReport += `**/support**\n${getObjValues(sprtObj)}\n`; + } + + if (!_.isEmpty(onSprtObj)) { + logReport += `**/on_support** \n${getObjValues(onSprtObj)}\n`; + } + + fs.writeFileSync("log_report.md", logReport); + + console.log("Report Generated Successfully!!"); +}; + +module.exports = { validateLogs }; From 91dc0bfa40b5eb78f3ec15e1b2edc9d09f38745a Mon Sep 17 00:00:00 2001 From: bluecypher Date: Mon, 13 Mar 2023 15:51:50 +0530 Subject: [PATCH 008/228] updated README.md --- utilities/log-validation-utility/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utilities/log-validation-utility/README.md b/utilities/log-validation-utility/README.md index 952b9dc..5ccc8e0 100644 --- a/utilities/log-validation-utility/README.md +++ b/utilities/log-validation-utility/README.md @@ -15,7 +15,7 @@ The tool is a NODE.js based utility to check the conformance and compliance of t Log Validation Tool requires [Node.js](https://nodejs.org/) to run. -1. Clone the repository, navigate to Log-Validation_Utility and install the dependencies. +1. Clone the repository, navigate to log-validation-utility and install the dependencies. ```sh @@ -66,6 +66,8 @@ _Notes:_ | support.json | | on_support.json | +> FAQs for Retail API Contract and Log Validation Utility ([FAQs](https://docs.google.com/document/d/1K-kqoOQ8IB-ywl_4pEiQKttTDk5Co381J07GldEUmD4/edit?usp=sharing)) + > Sample payload for search.json is demonstrated below: ```json From 7c7d70b01270bd7febb18ff7c071088a61271b84 Mon Sep 17 00:00:00 2001 From: Sandeep Shahi <40382144+bluecypher@users.noreply.github.com> Date: Mon, 13 Mar 2023 16:02:43 +0530 Subject: [PATCH 009/228] Update README.md --- utilities/log-validation-utility/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/utilities/log-validation-utility/README.md b/utilities/log-validation-utility/README.md index 952b9dc..c68b8ef 100644 --- a/utilities/log-validation-utility/README.md +++ b/utilities/log-validation-utility/README.md @@ -106,3 +106,4 @@ _Notes:_ } } ``` +### FAQs for Retail API Contract and Log Validation Utility ([FAQs](https://docs.google.com/document/d/1K-kqoOQ8IB-ywl_4pEiQKttTDk5Co381J07GldEUmD4/edit?usp=sharing)) From 541819e14ce9a756b80303d75cddbfcee6d86710 Mon Sep 17 00:00:00 2001 From: Kishor Date: Mon, 13 Mar 2023 21:52:28 +0530 Subject: [PATCH 010/228] Added signing, crypto next --- .../signing_and_verification/golang/crypto.go | 239 ++++++++++++++++++ .../signing_and_verification/golang/go.mod | 7 + .../signing_and_verification/golang/go.sum | 4 + .../golang/request_body_raw_text.txt | 31 +++ 4 files changed, 281 insertions(+) create mode 100644 utilities/signing_and_verification/golang/crypto.go create mode 100644 utilities/signing_and_verification/golang/go.mod create mode 100644 utilities/signing_and_verification/golang/go.sum create mode 100644 utilities/signing_and_verification/golang/request_body_raw_text.txt diff --git a/utilities/signing_and_verification/golang/crypto.go b/utilities/signing_and_verification/golang/crypto.go new file mode 100644 index 0000000..a219e14 --- /dev/null +++ b/utilities/signing_and_verification/golang/crypto.go @@ -0,0 +1,239 @@ +package main + +import ( + "bytes" + "crypto/aes" + "crypto/ecdh" + "crypto/ed25519" + "crypto/x509" + b64 "encoding/base64" + "errors" + "fmt" + "io" + "log" + "os" + "regexp" + "time" + + "golang.org/x/crypto/blake2b" +) + +func base64Decode(payload string) ([]byte, error) { + return b64.StdEncoding.DecodeString(payload) +} + +func base64Encode(payload []byte) string { + return b64.StdEncoding.EncodeToString(payload) +} + +func parsePrivateKey(key string) ([]byte, error) { + var keybytes []byte + decoded, err := base64Decode(key) + if err != nil { + log.Println("Error in base64 decoding private key", err) + return keybytes, err + } + + derKey, err := x509.ParsePKCS8PrivateKey(decoded) + if err != nil { + log.Println("Error getting x25519 key from base64 decoded key", err) + return keybytes, err + } + if privateKey, found := derKey.(*ecdh.PrivateKey); found { + return privateKey.Bytes(), nil + } else { + log.Println("Error type casting ecdh private key", err) + return keybytes, errors.New("unexpected error in private key type cast") + } +} + +func AESEncrypt(payload []byte, key []byte) ([]byte, error) { + cipher, err := aes.NewCipher(key) + blockSize := cipher.BlockSize() + if err != nil { + log.Println("Error creating AES cipher", err) + return nil, err + } + size := len(payload) + if size%blockSize != 0 { + remainder := blockSize - (size % blockSize) + pad := bytes.Repeat([]byte(" "), remainder) + payload = append(payload, pad...) + size = len(payload) + } + + buf := make([]byte, blockSize) + var encrypted []byte + for i := 0; i < size; i += blockSize { + cipher.Encrypt(buf, payload[i:i+blockSize]) + encrypted = append(encrypted, buf...) + } + return encrypted, nil +} + +func AESDecrypt(cipherText []byte, key []byte) ([]byte, error) { + cipher, err := aes.NewCipher(key) + blockSize := cipher.BlockSize() + if err != nil { + log.Println("Error creating AES cipher", err) + return nil, err + } + size := len(cipherText) + buf := make([]byte, blockSize) + var plainText []byte + for i := 0; i < size; i += blockSize { + cipher.Decrypt(buf, cipherText[i:i+blockSize]) + plainText = append(plainText, buf...) + } + return plainText, nil +} + +func generateSigningKeys() (string, string, error) { + publicKey, privateKey, err := ed25519.GenerateKey(nil) + if err != nil { + fmt.Println("Error generating signing keys", err) + return "", "", err + } + + return base64Encode(publicKey), base64Encode(privateKey), nil +} + +func signRequest(privateKey string, payload []byte, currentTime int, ttl int) (string, error) { + + //compute blake 512 hash over the payload + hash := blake2b.Sum512(payload) + digest := base64Encode(hash[:]) + + //create a signature and then sign with ed25519 private key + signatureBody := fmt.Sprintf("(created): %d\n(expires): %d\ndigest: BLAKE-512=%s", currentTime, (currentTime + ttl), digest) + decodedKey, err := base64Decode(privateKey) + if err != nil { + log.Println("Error decoding signing private key", err) + return "", err + } + signature := ed25519.Sign(decodedKey, []byte(signatureBody)) + return base64Encode(signature), nil +} + +func getRequestBody() ([]byte, error) { + var payload []byte + file, err := os.Open("request_body_raw_text.txt") + if err != nil { + fmt.Println("Error opening request body text file", err) + return payload, err + } + defer file.Close() + + payload, err = io.ReadAll(file) + if err != nil { + fmt.Println("Error reading request body text file", err) + return payload, err + } + + return payload, nil +} + +func getAuthHeader() (string, error) { + var authHeader string + + payload, err := getRequestBody() + if err != nil { + return authHeader, err + } + + privateKey := os.Getenv("PRIVATE_KEY") + currentTime := int(time.Now().Unix()) + + //ttl we are using is 30 seconds + ttl := 30 + + signature, err := signRequest(privateKey, payload, currentTime, ttl) + if err != nil { + fmt.Println("Could not compute signature", err) + return authHeader, err + } + + subscriberID := os.Getenv("SUBSCRIBER_ID") + if subscriberID == "" { + subscriberID = "buyer-app.ondc.org" + } + + uniqueKeyID := os.Getenv("UNIQUE_KEY_ID") + if uniqueKeyID == "" { + uniqueKeyID = "207" + } + authHeader = fmt.Sprintf(`Signature keyId="%s|%s|ed25519",algorithm="ed25519",created="%d",expires="%d",headers="(created) (expires) digest",signature="%s"`, subscriberID, uniqueKeyID, currentTime, currentTime+ttl, signature) + + return authHeader, nil +} + +func verifyRequest(authHeader string) bool { + + payload, err := getRequestBody() + if err != nil { + return false + } + + publicKey := os.Getenv("PUBLIC_KEY") + + _, created, expires, signature, err := parseAuthHeader(authHeader) + if err != nil { + return false + } + + //compute blake 512 hash over the payload + hash := blake2b.Sum512(payload) + digest := base64Encode(hash[:]) + + //create a signature and then sign with ed25519 private key + computedMessage := fmt.Sprintf("(created): %s\n(expires): %s\ndigest: BLAKE-512=%s", created, expires, digest) + publicKeyBytes, err := base64Decode(publicKey) + if err != nil { + log.Println("Error decoding public key", err) + return false + } + receivedSignature, err := base64Decode(signature) + if err != nil { + log.Println("Unable to base64 decode received signature", err) + return false + } + return ed25519.Verify(publicKeyBytes, []byte(computedMessage), receivedSignature) +} + +func main() { + + args := os.Args[1:] + if len(args) == 0 { + fmt.Println("Missing paramsters. Try ./crypto generate_key_pairs") + return + } + + switch args[0] { + case "generate_key_pairs": + signingPublicKey, signingPrivateKey, err := generateSigningKeys() + if err != nil { + fmt.Println("Could not generate signing keys") + return + } + fmt.Println("Signing_private_key:", signingPrivateKey) + fmt.Println("Signing_public_key:", signingPublicKey) + case "create_authorisation_header": + authHeader, err := getAuthHeader() + if err == nil { + fmt.Println(authHeader) + } + case "verify_authorisation_header": + authHeader := args[1] + fmt.Println(verifyRequest(authHeader)) + } +} + +func parseAuthHeader(authHeader string) (string, string, string, string, error) { + signatureRegex := regexp.MustCompile(`keyId=\"(.+?)\".+?created=\"(.+?)\".+?expires=\"(.+?)\".+?signature=\"(.+?)\"`) + groups := signatureRegex.FindAllStringSubmatch(authHeader, -1) + if len(groups) > 0 && len(groups[0]) > 4 { + return groups[0][1], groups[0][2], groups[0][3], groups[0][4], nil + } + fmt.Println("Error parsing auth header. Please make sure that the auh headers passed as command line argument is valid") + return "", "", "", "", errors.New("error parsing auth header") +} diff --git a/utilities/signing_and_verification/golang/go.mod b/utilities/signing_and_verification/golang/go.mod new file mode 100644 index 0000000..2ab4090 --- /dev/null +++ b/utilities/signing_and_verification/golang/go.mod @@ -0,0 +1,7 @@ +module shopalyst.com/opensource/ondccryptoutil + +go 1.20 + +require golang.org/x/crypto v0.7.0 + +require golang.org/x/sys v0.6.0 // indirect diff --git a/utilities/signing_and_verification/golang/go.sum b/utilities/signing_and_verification/golang/go.sum new file mode 100644 index 0000000..4d4d021 --- /dev/null +++ b/utilities/signing_and_verification/golang/go.sum @@ -0,0 +1,4 @@ +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/utilities/signing_and_verification/golang/request_body_raw_text.txt b/utilities/signing_and_verification/golang/request_body_raw_text.txt new file mode 100644 index 0000000..8ad501a --- /dev/null +++ b/utilities/signing_and_verification/golang/request_body_raw_text.txt @@ -0,0 +1,31 @@ +{ + "context": { + "domain": "nic2004:60212", + "country": "IND", + "city": "Kochi", + "action": "search", + "core_version": "0.9.1", + "bap_id": "bap.stayhalo.in", + "bap_uri": "https://8f9f-49-207-209-131.ngrok.io/protocol/", + "transaction_id": "e6d9f908-1d26-4ff3-a6d1-3af3d3721054", + "message_id": "a2fe6d52-9fe4-4d1a-9d0b-dccb8b48522d", + "timestamp": "2022-01-04T09:17:55.971Z", + "ttl": "P1M" + }, + "message": { + "intent": { + "fulfillment": { + "start": { + "location": { + "gps": "10.108768, 76.347517" + } + }, + "end": { + "location": { + "gps": "10.102997, 76.353480" + } + } + } + } + } +} \ No newline at end of file From 441e3da5e05f8045d5922772a5d4ad712b947647 Mon Sep 17 00:00:00 2001 From: Kishor Date: Mon, 13 Mar 2023 22:29:32 +0530 Subject: [PATCH 011/228] First draft --- .../signing_and_verification/golang/crypto.go | 255 +++++++++++++++--- .../signing_and_verification/golang/go.mod | 5 +- .../signing_and_verification/golang/go.sum | 2 + 3 files changed, 230 insertions(+), 32 deletions(-) diff --git a/utilities/signing_and_verification/golang/crypto.go b/utilities/signing_and_verification/golang/crypto.go index a219e14..3d8dcdd 100644 --- a/utilities/signing_and_verification/golang/crypto.go +++ b/utilities/signing_and_verification/golang/crypto.go @@ -3,21 +3,41 @@ package main import ( "bytes" "crypto/aes" - "crypto/ecdh" "crypto/ed25519" - "crypto/x509" + "crypto/rand" + "crypto/x509/pkix" + "encoding/asn1" b64 "encoding/base64" "errors" "fmt" "io" - "log" "os" "regexp" "time" "golang.org/x/crypto/blake2b" + "golang.org/x/crypto/curve25519" + "maze.io/x/crypto/x25519" ) +type pkcs8 struct { + Version int + Algo pkix.AlgorithmIdentifier + PrivateKey []byte + // optional attributes omitted. +} + +type publicKeyInfo struct { + Raw asn1.RawContent + Algorithm pkix.AlgorithmIdentifier + PublicKey asn1.BitString +} + +type pkixPublicKey struct { + Algo pkix.AlgorithmIdentifier + BitString asn1.BitString +} + func base64Decode(payload string) ([]byte, error) { return b64.StdEncoding.DecodeString(payload) } @@ -26,32 +46,116 @@ func base64Encode(payload []byte) string { return b64.StdEncoding.EncodeToString(payload) } -func parsePrivateKey(key string) ([]byte, error) { - var keybytes []byte +func generateEncryptionKeys() (string, string, error) { + //publicKey, privateKey, err := ed25519.GenerateKey(nil) + privateKey, err := x25519.GenerateKey(rand.Reader) + if err != nil { + fmt.Println("Error generating x25519 keys for encryption") + return "", "", err + } + + marshaledPrivateKey, err := marshalX25519PrivateKey(privateKey.Bytes()) + if err != nil { + fmt.Println("Error marshaling enc private key to x509.pkcs format", err) + return "", "", err + } + + marshaledPublicKey, err := marshalX25519PublicKey(privateKey.PublicKey.Bytes()) + if err != nil { + fmt.Println("Error marshaling enc public key to x509 format", err) + return "", "", err + } + + return base64Encode(marshaledPublicKey), base64Encode(marshaledPrivateKey), nil +} + +func marshalX25519PrivateKey(key []byte) ([]byte, error) { + var privateKey []byte + curveKey, err := asn1.Marshal(key[:32]) + if err != nil { + fmt.Println("Error asn1 marshaling private key") + return privateKey, err + } + pkcsKey := pkcs8{ + Version: 1, + Algo: pkix.AlgorithmIdentifier{ + Algorithm: asn1.ObjectIdentifier{1, 3, 101, 110}, + }, + PrivateKey: curveKey, + } + privateKey, err = asn1.Marshal(pkcsKey) + if err != nil { + fmt.Println("Error asn1 marshaling pkcs8 key", err) + return privateKey, err + } + return privateKey, nil +} + +func marshalX25519PublicKey(key []byte) ([]byte, error) { + x509Key := pkixPublicKey{ + Algo: pkix.AlgorithmIdentifier{ + Algorithm: asn1.ObjectIdentifier{1, 3, 101, 110}, + }, + BitString: asn1.BitString{ + Bytes: key, + BitLength: 8 * len(key), + }, + } + publicKey, err := asn1.Marshal(x509Key) + if err != nil { + fmt.Println("Error asn1 marshaling public key", err) + return publicKey, err + } + return publicKey, nil +} + +func parseX25519PrivateKey(key string) ([]byte, error) { + var parsedKey []byte decoded, err := base64Decode(key) if err != nil { - log.Println("Error in base64 decoding private key", err) - return keybytes, err + fmt.Println("Error base64 decoding x25519 private key", err) + return parsedKey, err } - derKey, err := x509.ParsePKCS8PrivateKey(decoded) + var pkcsKey pkcs8 + _, err = asn1.Unmarshal(decoded, &pkcsKey) if err != nil { - log.Println("Error getting x25519 key from base64 decoded key", err) - return keybytes, err + fmt.Println("Error asn1 unmarshaling x25519 private key", err) + return parsedKey, err } - if privateKey, found := derKey.(*ecdh.PrivateKey); found { - return privateKey.Bytes(), nil - } else { - log.Println("Error type casting ecdh private key", err) - return keybytes, errors.New("unexpected error in private key type cast") + + _, err = asn1.Unmarshal(pkcsKey.PrivateKey, &parsedKey) + if err != nil { + fmt.Println("Error asn1 unmashaling pkcs privat key", err) + return parsedKey, err } + return parsedKey, nil } -func AESEncrypt(payload []byte, key []byte) ([]byte, error) { +func parseX25519PublicKey(key string) ([]byte, error) { + var parsedKey []byte + + decoded, err := base64Decode(key) + if err != nil { + fmt.Println("Error base64 decoding x25519 public key", err) + return parsedKey, err + } + + var x509Key publicKeyInfo + _, err = asn1.Unmarshal(decoded, &x509Key) + if err != nil { + fmt.Println("Error asn1 unmarshaling x25519 public key", err) + return parsedKey, err + } + + return x509Key.PublicKey.RightAlign(), nil +} + +func aesEncrypt(payload []byte, key []byte) ([]byte, error) { cipher, err := aes.NewCipher(key) blockSize := cipher.BlockSize() if err != nil { - log.Println("Error creating AES cipher", err) + fmt.Println("Error creating AES cipher", err) return nil, err } size := len(payload) @@ -71,11 +175,11 @@ func AESEncrypt(payload []byte, key []byte) ([]byte, error) { return encrypted, nil } -func AESDecrypt(cipherText []byte, key []byte) ([]byte, error) { +func aesDecrypt(cipherText []byte, key []byte) ([]byte, error) { cipher, err := aes.NewCipher(key) blockSize := cipher.BlockSize() if err != nil { - log.Println("Error creating AES cipher", err) + fmt.Println("Error creating AES cipher", err) return nil, err } size := len(cipherText) @@ -108,7 +212,7 @@ func signRequest(privateKey string, payload []byte, currentTime int, ttl int) (s signatureBody := fmt.Sprintf("(created): %d\n(expires): %d\ndigest: BLAKE-512=%s", currentTime, (currentTime + ttl), digest) decodedKey, err := base64Decode(privateKey) if err != nil { - log.Println("Error decoding signing private key", err) + fmt.Println("Error decoding signing private key", err) return "", err } signature := ed25519.Sign(decodedKey, []byte(signatureBody)) @@ -189,17 +293,93 @@ func verifyRequest(authHeader string) bool { computedMessage := fmt.Sprintf("(created): %s\n(expires): %s\ndigest: BLAKE-512=%s", created, expires, digest) publicKeyBytes, err := base64Decode(publicKey) if err != nil { - log.Println("Error decoding public key", err) + fmt.Println("Error decoding public key", err) return false } receivedSignature, err := base64Decode(signature) if err != nil { - log.Println("Unable to base64 decode received signature", err) + fmt.Println("Unable to base64 decode received signature", err) return false } return ed25519.Verify(publicKeyBytes, []byte(computedMessage), receivedSignature) } +func parseAuthHeader(authHeader string) (string, string, string, string, error) { + signatureRegex := regexp.MustCompile(`keyId=\"(.+?)\".+?created=\"(.+?)\".+?expires=\"(.+?)\".+?signature=\"(.+?)\"`) + groups := signatureRegex.FindAllStringSubmatch(authHeader, -1) + if len(groups) > 0 && len(groups[0]) > 4 { + return groups[0][1], groups[0][2], groups[0][3], groups[0][4], nil + } + fmt.Println("Error parsing auth header. Please make sure that the auh headers passed as command line argument is valid") + return "", "", "", "", errors.New("error parsing auth header") +} + +func encrypt(privateKey string, publicKey string) (string, error) { + var encryptedText string + parsedPrivateKey, err := parseX25519PrivateKey(privateKey) + if err != nil { + fmt.Println("Error parsing private key.", err) + return encryptedText, err + } + + parsedPublicKey, err := parseX25519PublicKey(publicKey) + if err != nil { + fmt.Println("Error parsing public key.", err) + return encryptedText, err + } + + secretKey, err := curve25519.X25519(parsedPrivateKey, parsedPublicKey) + if err != nil { + fmt.Println("Error constructing secret key", err) + return encryptedText, nil + } + + plainText := "ONDC is a Great Initiative!" + cipherBytes, err := aesEncrypt([]byte(plainText), secretKey) + if err != nil { + fmt.Println("Error encrypting with AES", err) + return encryptedText, err + } + + encryptedText = base64Encode(cipherBytes) + return encryptedText, nil +} + +func decrypt(privateKey string, publicKey string, cipherText string) (string, error) { + var decryptedText string + parsedPrivateKey, err := parseX25519PrivateKey(privateKey) + if err != nil { + fmt.Println("Error parsing private key.", err) + return decryptedText, err + } + + parsedPublicKey, err := parseX25519PublicKey(publicKey) + if err != nil { + fmt.Println("Error parsing public key.", err) + return decryptedText, err + } + + secretKey, err := curve25519.X25519(parsedPrivateKey, parsedPublicKey) + if err != nil { + fmt.Println("Error constructing secret key", err) + return decryptedText, nil + } + + cipherBytes, err := base64Decode(cipherText) + if err != nil { + fmt.Println("Error base64 decoding cipher text", err) + return decryptedText, err + } + plainBytes, err := aesDecrypt(cipherBytes, secretKey) + if err != nil { + fmt.Println("Error decrypting with AES", err) + return decryptedText, err + } + + decryptedText = string(plainBytes) + return decryptedText, nil +} + func main() { args := os.Args[1:] @@ -215,8 +395,15 @@ func main() { fmt.Println("Could not generate signing keys") return } + encPublicKey, encPrivateKey, err := generateEncryptionKeys() + if err != nil { + fmt.Println("Could not generate encryption keys") + return + } fmt.Println("Signing_private_key:", signingPrivateKey) fmt.Println("Signing_public_key:", signingPublicKey) + fmt.Println("Crypto_Privatekey:", encPrivateKey) + fmt.Println("Crypto_Publickey:", encPublicKey) case "create_authorisation_header": authHeader, err := getAuthHeader() if err == nil { @@ -225,15 +412,21 @@ func main() { case "verify_authorisation_header": authHeader := args[1] fmt.Println(verifyRequest(authHeader)) - } -} + case "encrypt": + privateKey := args[1] + publicKey := args[2] + cipherText, err := encrypt(privateKey, publicKey) + if err == nil { + fmt.Println(cipherText) + } + case "decrypt": + privateKey := args[1] + publicKey := args[2] + cipherText := args[3] + plainText, err := decrypt(privateKey, publicKey, cipherText) + if err == nil { + fmt.Println(plainText) + } -func parseAuthHeader(authHeader string) (string, string, string, string, error) { - signatureRegex := regexp.MustCompile(`keyId=\"(.+?)\".+?created=\"(.+?)\".+?expires=\"(.+?)\".+?signature=\"(.+?)\"`) - groups := signatureRegex.FindAllStringSubmatch(authHeader, -1) - if len(groups) > 0 && len(groups[0]) > 4 { - return groups[0][1], groups[0][2], groups[0][3], groups[0][4], nil } - fmt.Println("Error parsing auth header. Please make sure that the auh headers passed as command line argument is valid") - return "", "", "", "", errors.New("error parsing auth header") } diff --git a/utilities/signing_and_verification/golang/go.mod b/utilities/signing_and_verification/golang/go.mod index 2ab4090..5f8bcf2 100644 --- a/utilities/signing_and_verification/golang/go.mod +++ b/utilities/signing_and_verification/golang/go.mod @@ -2,6 +2,9 @@ module shopalyst.com/opensource/ondccryptoutil go 1.20 -require golang.org/x/crypto v0.7.0 +require ( + golang.org/x/crypto v0.7.0 + maze.io/x/crypto v0.0.0-20190131090603-9b94c9afe066 +) require golang.org/x/sys v0.6.0 // indirect diff --git a/utilities/signing_and_verification/golang/go.sum b/utilities/signing_and_verification/golang/go.sum index 4d4d021..c7bf69f 100644 --- a/utilities/signing_and_verification/golang/go.sum +++ b/utilities/signing_and_verification/golang/go.sum @@ -2,3 +2,5 @@ golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +maze.io/x/crypto v0.0.0-20190131090603-9b94c9afe066 h1:UrD21H1Ue5Nl8f2x/NQJBRdc49YGmla3mRStinH8CCE= +maze.io/x/crypto v0.0.0-20190131090603-9b94c9afe066/go.mod h1:DEvumi+swYmlKxSlnsvPwS15tRjoypCCeJFXswU5FfQ= From 17b38cdcf9ef08c7bfd1cf6e7e061f1d8402496b Mon Sep 17 00:00:00 2001 From: bluecypher Date: Tue, 14 Mar 2023 19:21:24 +0530 Subject: [PATCH 012/228] on_search bugfixes --- utilities/log-validation-utility/README.md | 2 - .../onSearchItemValidations.js | 111 ++++++++++++++++-- .../retail_api_json_schema/onSearchSchema.js | 88 +++++++++----- 3 files changed, 162 insertions(+), 39 deletions(-) diff --git a/utilities/log-validation-utility/README.md b/utilities/log-validation-utility/README.md index 5ccc8e0..cdaf985 100644 --- a/utilities/log-validation-utility/README.md +++ b/utilities/log-validation-utility/README.md @@ -66,8 +66,6 @@ _Notes:_ | support.json | | on_support.json | -> FAQs for Retail API Contract and Log Validation Utility ([FAQs](https://docs.google.com/document/d/1K-kqoOQ8IB-ywl_4pEiQKttTDk5Co381J07GldEUmD4/edit?usp=sharing)) - > Sample payload for search.json is demonstrated below: ```json diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js index 2311ea7..a991740 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js @@ -10,13 +10,45 @@ onSearchRules = [ }, { - if: { properties: { category_id: { const: "F&B" } } }, + if: { + properties: { + category_id: { + enum: [ + "F&B", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + ], + }, + }, + }, then: { required: ["@ondc/org/fssai_license_no"], }, }, { - if: { properties: { category_id: { const: "Packaged Foods" } } }, + if: { + properties: { + category_id: { + enum: [ + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ], + }, + }, + }, then: { required: ["@ondc/org/fssai_license_no"], }, @@ -33,7 +65,18 @@ onSearchRules = [ if: { properties: { category_id: { - const: "Packaged Commodities", + enum: [ + "Masala & Seasoning", + "Oil & Ghee", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beauty & Hygiene", + "Kitchen Accessories", + "Baby Care", + "Pet Care", + "Stationery", + ], }, }, }, @@ -46,7 +89,12 @@ onSearchRules = [ if: { properties: { category_id: { - const: "Packaged Foods", + enum: [ + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ], }, }, }, @@ -58,7 +106,7 @@ onSearchRules = [ if: { properties: { category_id: { - const: "fruits and vegetables", + const: "Fruits and Vegetables", }, }, }, @@ -68,13 +116,45 @@ onSearchRules = [ }, { - if: { properties: { category_id: { const: "F&B" } } }, + if: { + properties: { + category_id: { + enum: [ + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "F&B", + ], + }, + }, + }, then: { required: ["tags"], }, }, { - if: { properties: { category_id: { const: "Packaged Foods" } } }, + if: { + properties: { + category_id: { + enum: [ + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ], + }, + }, + }, then: { required: ["tags"], }, @@ -83,7 +163,22 @@ onSearchRules = [ if: { properties: { category_id: { - const: "f&b", + enum: [ + "F&B", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + ], }, }, }, diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index 6cb69fd..c1e5d12 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -152,50 +152,80 @@ module.exports = { }, time: { type: "object", - properties: { - days: { - type: "string", - }, - range: { + + oneOf: [ + { type: "object", properties: { - start: { + days: { type: "string", - minLength: 4, - maxLength: 4, }, - end: { - type: "string", - minLength: 4, - maxLength: 4, + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + additionalProperties: false, }, }, - required: ["start", "end"], + required: ["days", "range", "schedule"], }, - schedule: { + { type: "object", properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - frequency: { + days: { type: "string", - format: "duration", }, - times: { - type: "array", - items: { - type: "string", + + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, }, + required: ["holidays", "frequency", "times"], }, }, - required: ["holidays"], + required: ["days", "schedule"], + additionalProperties: false, }, - }, - required: ["days", "schedule"], + ], }, }, required: ["id", "address", "gps", "time"], From 20de3c78efeb6ea57b4b43ea1948459acf409c74 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Thu, 16 Mar 2023 13:07:17 +0530 Subject: [PATCH 013/228] bug fixes /init --- .../schema/retail_api_json_schema/searchSchema.js | 2 +- .../log-validation-utility/utils/retail/retInit.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js index 7cbff8c..50a1806 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js @@ -105,7 +105,7 @@ module.exports = { required: ["area_code"], }, }, - required: ["gps", "address"], + required: ["gps"], }, }, required: ["location"], diff --git a/utilities/log-validation-utility/utils/retail/retInit.js b/utilities/log-validation-utility/utils/retail/retInit.js index a465b14..fa71c35 100644 --- a/utilities/log-validation-utility/utils/retail/retInit.js +++ b/utilities/log-validation-utility/utils/retail/retInit.js @@ -128,11 +128,11 @@ const checkInit = (dirPath, msgIdSet) => { initObj.bill = `Billing object missing in /${constants.RET_INIT}`; } else { dao.setValue("billing", init.billing); - if ( - !_.isEqual(init.billing.address.area_code, dao.getValue("buyerAddr")) - ) { - initObj.billAreaCode = `area_code in billing.address does not match with area_code in /${constants.RET_SELECT}`; - } + // if ( + // !_.isEqual(init.billing.address.area_code, dao.getValue("buyerAddr")) + // ) { + // initObj.billAreaCode = `area_code in billing.address does not match with area_code in /${constants.RET_SELECT}`; + // } } } catch (error) { console.log( From 7aedf8e69f0a970e1e1bea3af541ea04707157a3 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Thu, 16 Mar 2023 13:33:30 +0530 Subject: [PATCH 014/228] custom error message --- utilities/log-validation-utility/package.json | 1 + .../schema/retail_api_json_schema/SchemaValidator.js | 1 + .../schema/retail_api_json_schema/onSearchSchema.js | 2 ++ 3 files changed, 4 insertions(+) diff --git a/utilities/log-validation-utility/package.json b/utilities/log-validation-utility/package.json index aa8484d..fc84ba1 100644 --- a/utilities/log-validation-utility/package.json +++ b/utilities/log-validation-utility/package.json @@ -18,6 +18,7 @@ "homepage": "https://github.com/bluecypher/ONDC-Log-Verification#readme", "dependencies": { "ajv": "^8.12.0", + "ajv-errors": "^3.0.0", "ajv-formats": "^2.1.1", "lmdb": "^2.7.5", "lodash": "^4.17.21" diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index fab6c3d..e0621c4 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -19,6 +19,7 @@ const Ajv = require("ajv"); const ajv = new Ajv({ allErrors: true, strict: "log" }); const addFormats = require("ajv-formats"); addFormats(ajv); +require("ajv-errors")(ajv); // transform_on_search_schema = (payload) => { // transformed_payload = payload; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index c1e5d12..3aa22a8 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -226,6 +226,8 @@ module.exports = { additionalProperties: false, }, ], + errorMessage: + "either one of fixed or split timings should be provided", }, }, required: ["id", "address", "gps", "time"], From f64ddec607b8f1faabf69ec9be60e49450ff3399 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Sat, 18 Mar 2023 19:54:44 +0530 Subject: [PATCH 015/228] bug fixes --- .../log-validation-utility/config/config.js | 4 +- utilities/log-validation-utility/dao/dao.js | 6 - .../retail_api_json_schema/SchemaValidator.js | 16 +- .../retail_api_json_schema/confirmSchema.js | 2 +- .../retail_api_json_schema/onSearchSchema.js | 147 +++++++++--------- .../utils/retail/retCancel.js | 10 +- .../utils/retail/retOnCancel.js | 8 +- .../utils/retail/retOnSupport.js | 6 +- .../utils/retail/retOnTrack.js | 3 +- .../utils/retail/retTrack.js | 10 +- .../utils/validateLogUtil.js | 2 +- 11 files changed, 111 insertions(+), 103 deletions(-) diff --git a/utilities/log-validation-utility/config/config.js b/utilities/log-validation-utility/config/config.js index 3d0d989..71f11a9 100644 --- a/utilities/log-validation-utility/config/config.js +++ b/utilities/log-validation-utility/config/config.js @@ -1,5 +1,3 @@ -const config = { - port: process.env.PORT || 3000, -}; +const config = {}; module.exports = config; diff --git a/utilities/log-validation-utility/dao/dao.js b/utilities/log-validation-utility/dao/dao.js index a6dacba..af6e9fd 100644 --- a/utilities/log-validation-utility/dao/dao.js +++ b/utilities/log-validation-utility/dao/dao.js @@ -39,9 +39,3 @@ const dropDB = () => { }; module.exports = { getValue, setValue, dropDB }; - -// or -// myDB.transaction(() => { -// myDB.put("greeting", { someText: "Hello, World!" }); -// myDB.get("greeting").someText; // 'Hello, World!' -// }); diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index e0621c4..5dc6f19 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -16,7 +16,10 @@ const updateSchema = require("./updateSchema"); const cancelSchema = require("./cancelSchema"); const Ajv = require("ajv"); -const ajv = new Ajv({ allErrors: true, strict: "log" }); +const ajv = new Ajv({ + allErrors: true, + strict: "log", +}); const addFormats = require("ajv-formats"); addFormats(ajv); require("ajv-errors")(ajv); @@ -40,7 +43,16 @@ const formatted_error = (errors) => { error_list = []; let status = ""; errors.forEach((error) => { - error_dict = { message: error.message, details: error.instancePath }; + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; error_list.push(error_dict); }); if (error_list.length === 0) status = "pass"; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js index aab1bf7..65fed71 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -185,10 +185,10 @@ module.exports = { }, type: { type: "string", + const: "Delivery", }, tracking: { type: "boolean", - const: "Delivery", }, end: { type: "object", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index 3aa22a8..314fa0a 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -152,82 +152,14 @@ module.exports = { }, time: { type: "object", - oneOf: [ { - type: "object", - properties: { - days: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - minLength: 4, - maxLength: 4, - }, - end: { - type: "string", - minLength: 4, - maxLength: 4, - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays"], - additionalProperties: false, - }, - }, - required: ["days", "range", "schedule"], + $ref: "#/components/schemas/fixedTimings", }, { - type: "object", - properties: { - days: { - type: "string", - }, - - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - frequency: { - type: "string", - format: "duration", - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays", "frequency", "times"], - }, - }, - required: ["days", "schedule"], - additionalProperties: false, + $ref: "#/components/schemas/splitTimings", }, ], - errorMessage: - "either one of fixed or split timings should be provided", }, }, required: ["id", "address", "gps", "time"], @@ -576,4 +508,79 @@ module.exports = { }, }, required: ["context", "message"], + components: { + schemas: { + fixedTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + additionalProperties: false, + }, + }, + required: ["days", "range", "schedule"], + }, + splitTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays", "frequency", "times"], + }, + }, + required: ["days", "schedule"], + additionalProperties: false, + }, + }, + }, }; diff --git a/utilities/log-validation-utility/utils/retail/retCancel.js b/utilities/log-validation-utility/utils/retail/retCancel.js index 068f5ba..7869a4b 100644 --- a/utilities/log-validation-utility/utils/retail/retCancel.js +++ b/utilities/log-validation-utility/utils/retail/retCancel.js @@ -105,17 +105,17 @@ const checkCancel = (dirPath, msgIdSet) => { try { console.log( - `Comparing order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + `Comparing order Id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}` ); - if (cancel.order_id != dao.getValue("onCnfrmOrdrId")) { - cnclObj.cancelOrdrId = `Order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM} do not match`; + if (cancel.order_id != dao.getValue("cnfrmOrdrId")) { + cnclObj.cancelOrdrId = `Order Id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM} do not match`; console.log( - `Order Id mismatch in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + `Order Id mismatch in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}` ); } } catch (error) { console.log( - `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}`, + `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}`, error ); // cnclObj.cancelOrdrId = diff --git a/utilities/log-validation-utility/utils/retail/retOnCancel.js b/utilities/log-validation-utility/utils/retail/retOnCancel.js index 294f894..fec973b 100644 --- a/utilities/log-validation-utility/utils/retail/retOnCancel.js +++ b/utilities/log-validation-utility/utils/retail/retOnCancel.js @@ -117,12 +117,12 @@ const checkOnCancel = (dirPath, msgIdSet) => { try { console.log( - `Comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}` + `Comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM}` ); - if (on_cancel.id != dao.getValue("onCnfrmOrdrId")) { - onCnclObj.onCancelId = `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match`; + if (on_cancel.id != dao.getValue("cnfrmOrdrId")) { + onCnclObj.onCancelId = `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM} do not match`; console.log( - `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match` + `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM} do not match` ); } } catch (error) { diff --git a/utilities/log-validation-utility/utils/retail/retOnSupport.js b/utilities/log-validation-utility/utils/retail/retOnSupport.js index ea4f561..a9ec41a 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSupport.js +++ b/utilities/log-validation-utility/utils/retail/retOnSupport.js @@ -13,10 +13,10 @@ const checkOnSupport = (dirPath, msgIdSet) => { let on_support = fs.readFileSync( dirPath + `/${constants.RET_ONSUPPORT}.json` ); - - console.log(`Validating Schema for /${constants.RET_ONSUPPORT} API`); + on_support = JSON.parse(on_support); try { + console.log(`Validating Schema for /${constants.RET_ONSUPPORT} API`); const vs = validateSchema("retail", constants.RET_ONSUPPORT, on_support); if (vs != "error") { // console.log(vs); @@ -29,8 +29,6 @@ const checkOnSupport = (dirPath, msgIdSet) => { ); } - on_support = JSON.parse(on_support); - try { console.log(`Checking context for /${constants.RET_ONSUPPORT} API`); //checking context res = checkContext(on_support.context, constants.RET_ONSUPPORT); diff --git a/utilities/log-validation-utility/utils/retail/retOnTrack.js b/utilities/log-validation-utility/utils/retail/retOnTrack.js index 88e5b81..ab8ff04 100644 --- a/utilities/log-validation-utility/utils/retail/retOnTrack.js +++ b/utilities/log-validation-utility/utils/retail/retOnTrack.js @@ -9,7 +9,7 @@ const checkOnTrack = (dirPath, msgIdSet) => { let onTrckObj = {}; try { let on_track = fs.readFileSync(dirPath + `/${constants.RET_ONTRACK}.json`); - + on_track = JSON.parse(on_track); try { console.log(`Validating Schema for /${constants.RET_ONTRACK} API`); const vs = validateSchema("retail", constants.RET_ONTRACK, on_track); @@ -23,7 +23,6 @@ const checkOnTrack = (dirPath, msgIdSet) => { error ); } - on_track = JSON.parse(on_track); console.log(`Checking context for /${constants.RET_ONTRACK} API`); //checking context try { diff --git a/utilities/log-validation-utility/utils/retail/retTrack.js b/utilities/log-validation-utility/utils/retail/retTrack.js index c2e26be..ce66708 100644 --- a/utilities/log-validation-utility/utils/retail/retTrack.js +++ b/utilities/log-validation-utility/utils/retail/retTrack.js @@ -87,17 +87,17 @@ const checkTrack = (dirPath, msgIdSet) => { try { console.log( - `Checking Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}` + `Checking Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}` ); - if (track.order_id != dao.getValue("onCnfrmOrdrId")) { + if (track.order_id != dao.getValue("cnfrmOrdrId")) { console.log( - `Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match` + `Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM} do not match` ); - trckObj.trackOrdrId = `Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match`; + trckObj.trackOrdrId = `Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM} do not match`; } } catch (error) { console.log( - `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}`, + `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}`, error ); // trckObj.trackOrdrId = "Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match"; diff --git a/utilities/log-validation-utility/utils/validateLogUtil.js b/utilities/log-validation-utility/utils/validateLogUtil.js index eaa2a72..1cad472 100644 --- a/utilities/log-validation-utility/utils/validateLogUtil.js +++ b/utilities/log-validation-utility/utils/validateLogUtil.js @@ -22,7 +22,7 @@ const checkOnSupport = require("./retail/retOnSupport"); const checkUpdate = require("./retail/retUpdate"); const checkOnUpdate = require("./retail/retOnUpdate"); -//To be developed: TAT in on_select = sumof(time to ship in /on_search and TAT by LSP in logistics /on_search) +//TAT in on_select = sumof(time to ship in /on_search and TAT by LSP in logistics /on_search) // If non-serviceable in /on_select, there should be domain-error const validateLogs = (dirPath) => { From 9c85d9a5ad8955fabe5723423d8c79196fa3a819 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Sat, 18 Mar 2023 20:18:47 +0530 Subject: [PATCH 016/228] bug fixes --- .../retail_api_json_schema/confirmSchema.js | 36 ++++---- .../retail_api_json_schema/updateSchema.js | 86 +++++++++---------- 2 files changed, 59 insertions(+), 63 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js index 65fed71..b210fd6 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -104,29 +104,27 @@ module.exports = { }, items: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, - fulfillment_id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", }, - required: ["count"], }, + required: ["count"], }, - required: ["id", "fulfillment_id", "quantity"], }, - ], + required: ["id", "fulfillment_id", "quantity"], + }, }, billing: { type: "object", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js index c29bf6d..8c62c5c 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js @@ -94,60 +94,58 @@ module.exports = { }, items: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + update_type: { + type: "string", + enum: ["return", "cancel"], + }, + reason_code: { + type: "string", + minLength: 3, + maxLength: 3, + }, + ttl_approval: { + type: "string", + format: "duration", + }, + ttl_reverseqc: { + type: "string", + format: "duration", + }, + image: { + type: "string", }, - required: ["count"], }, - tags: { - type: "object", + required: ["update_type"], + if: { properties: { update_type: { - type: "string", - enum: ["return", "cancel"], - }, - reason_code: { - type: "string", - minLength: 3, - maxLength: 3, - }, - ttl_approval: { - type: "string", - format: "duration", - }, - ttl_reverseqc: { - type: "string", - format: "duration", - }, - image: { - type: "string", + const: "return", }, }, - required: ["update_type"], - if: { - properties: { - update_type: { - const: "return", - }, - }, - }, - then: { required: ["reason_code"] }, }, + then: { required: ["reason_code"] }, }, - required: ["id", "quantity", "tags"], }, - ], + required: ["id", "quantity", "tags"], + }, }, payment: { type: "object", From c166e8c83159d2211777224ab6700052cb273c80 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Sat, 18 Mar 2023 20:36:15 +0530 Subject: [PATCH 017/228] schema fixes --- .../retail_api_json_schema/confirmSchema.js | 170 +++++++++--------- .../retail_api_json_schema/statusSchema.js | 1 + .../retail_api_json_schema/updateSchema.js | 72 ++++---- 3 files changed, 122 insertions(+), 121 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js index b210fd6..2cc23c8 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -87,17 +87,15 @@ module.exports = { }, locations: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, + items: { + type: "object", + properties: { + id: { + type: "string", }, - required: ["id"], }, - ], + required: ["id"], + }, }, }, required: ["id", "locations"], @@ -174,96 +172,94 @@ module.exports = { }, fulfillments: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - const: "Delivery", - }, - tracking: { - type: "boolean", - }, - end: { - type: "object", - properties: { - person: { - type: "object", - properties: { - name: { - type: "string", - }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + const: "Delivery", + }, + tracking: { + type: "boolean", + }, + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", }, - required: ["name"], }, - contact: { - type: "object", - properties: { - email: { - type: "string", - format: "email", - }, - phone: { - type: "string", - }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + email: { + type: "string", + format: "email", + }, + phone: { + type: "string", }, - required: ["phone"], }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "object", - properties: { - name: { - type: "string", - }, - building: { - type: "string", - }, - locality: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - country: { - type: "string", - }, - area_code: { - type: "string", - }, + required: ["phone"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], }, - required: ["gps", "address"], }, + required: ["gps", "address"], }, - required: ["person", "contact", "location"], }, + required: ["person", "contact", "location"], }, - required: ["id", "type", "tracking", "end"], }, - ], + required: ["id", "type", "tracking", "end"], + }, }, quote: { type: "object", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js index f2d2f0d..70ccfca 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js @@ -1,4 +1,5 @@ module.exports = { + type: "object", properties: { context: { type: "object", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js index 8c62c5c..2aee70a 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js @@ -134,14 +134,20 @@ module.exports = { }, }, required: ["update_type"], - if: { - properties: { - update_type: { - const: "return", + allOf: [ + { + if: { + properties: { + update_type: { + const: "return", + }, + reason_code: { type: "string" }, + }, + required: ["update_type"], }, + then: { required: ["reason_code"] }, }, - }, - then: { required: ["reason_code"] }, + ], }, }, required: ["id", "quantity", "tags"], @@ -152,36 +158,34 @@ module.exports = { properties: { "@ondc/org/settlement_details": { type: "array", - items: [ - { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - }, - settlement_amount: { - type: "string", - }, - settlement_timestamp: { - type: "string", - format: "date-time", - }, + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + settlement_amount: { + type: "string", + }, + settlement_timestamp: { + type: "string", + format: "date-time", }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - "settlement_amount", - "settlement_timestamp", - ], }, - ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + "settlement_amount", + "settlement_timestamp", + ], + }, }, }, required: ["@ondc/org/settlement_details"], From 2246e5c330c0adafc1fa58fa8f0bcacbdfb66181 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Thu, 16 Mar 2023 13:33:30 +0530 Subject: [PATCH 018/228] bug fixes --- .../log-validation-utility/config/config.js | 4 +- utilities/log-validation-utility/dao/dao.js | 6 - .../retail_api_json_schema/SchemaValidator.js | 16 +- .../retail_api_json_schema/confirmSchema.js | 206 +++++++++--------- .../retail_api_json_schema/onSearchSchema.js | 145 ++++++------ .../retail_api_json_schema/statusSchema.js | 1 + .../retail_api_json_schema/updateSchema.js | 150 ++++++------- .../utils/retail/retCancel.js | 10 +- .../utils/retail/retOnCancel.js | 8 +- .../utils/retail/retOnSupport.js | 6 +- .../utils/retail/retOnTrack.js | 3 +- .../utils/retail/retTrack.js | 10 +- .../utils/validateLogUtil.js | 2 +- 13 files changed, 287 insertions(+), 280 deletions(-) diff --git a/utilities/log-validation-utility/config/config.js b/utilities/log-validation-utility/config/config.js index 3d0d989..71f11a9 100644 --- a/utilities/log-validation-utility/config/config.js +++ b/utilities/log-validation-utility/config/config.js @@ -1,5 +1,3 @@ -const config = { - port: process.env.PORT || 3000, -}; +const config = {}; module.exports = config; diff --git a/utilities/log-validation-utility/dao/dao.js b/utilities/log-validation-utility/dao/dao.js index a6dacba..af6e9fd 100644 --- a/utilities/log-validation-utility/dao/dao.js +++ b/utilities/log-validation-utility/dao/dao.js @@ -39,9 +39,3 @@ const dropDB = () => { }; module.exports = { getValue, setValue, dropDB }; - -// or -// myDB.transaction(() => { -// myDB.put("greeting", { someText: "Hello, World!" }); -// myDB.get("greeting").someText; // 'Hello, World!' -// }); diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index fab6c3d..ed85dc9 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -16,7 +16,10 @@ const updateSchema = require("./updateSchema"); const cancelSchema = require("./cancelSchema"); const Ajv = require("ajv"); -const ajv = new Ajv({ allErrors: true, strict: "log" }); +const ajv = new Ajv({ + allErrors: true, + strict: "log", +}); const addFormats = require("ajv-formats"); addFormats(ajv); @@ -39,7 +42,16 @@ const formatted_error = (errors) => { error_list = []; let status = ""; errors.forEach((error) => { - error_dict = { message: error.message, details: error.instancePath }; + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; error_list.push(error_dict); }); if (error_list.length === 0) status = "pass"; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js index aab1bf7..2cc23c8 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -87,46 +87,42 @@ module.exports = { }, locations: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, + items: { + type: "object", + properties: { + id: { + type: "string", }, - required: ["id"], }, - ], + required: ["id"], + }, }, }, required: ["id", "locations"], }, items: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, - fulfillment_id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", }, - required: ["count"], }, + required: ["count"], }, - required: ["id", "fulfillment_id", "quantity"], }, - ], + required: ["id", "fulfillment_id", "quantity"], + }, }, billing: { type: "object", @@ -176,96 +172,94 @@ module.exports = { }, fulfillments: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - const: "Delivery", - }, - end: { - type: "object", - properties: { - person: { - type: "object", - properties: { - name: { - type: "string", - }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + const: "Delivery", + }, + tracking: { + type: "boolean", + }, + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", }, - required: ["name"], }, - contact: { - type: "object", - properties: { - email: { - type: "string", - format: "email", - }, - phone: { - type: "string", - }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + email: { + type: "string", + format: "email", + }, + phone: { + type: "string", }, - required: ["phone"], }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "object", - properties: { - name: { - type: "string", - }, - building: { - type: "string", - }, - locality: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - country: { - type: "string", - }, - area_code: { - type: "string", - }, + required: ["phone"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], }, - required: ["gps", "address"], }, + required: ["gps", "address"], }, - required: ["person", "contact", "location"], }, + required: ["person", "contact", "location"], }, - required: ["id", "type", "tracking", "end"], }, - ], + required: ["id", "type", "tracking", "end"], + }, }, quote: { type: "object", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index c1e5d12..314fa0a 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -152,78 +152,12 @@ module.exports = { }, time: { type: "object", - oneOf: [ { - type: "object", - properties: { - days: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - minLength: 4, - maxLength: 4, - }, - end: { - type: "string", - minLength: 4, - maxLength: 4, - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays"], - additionalProperties: false, - }, - }, - required: ["days", "range", "schedule"], + $ref: "#/components/schemas/fixedTimings", }, { - type: "object", - properties: { - days: { - type: "string", - }, - - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - frequency: { - type: "string", - format: "duration", - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays", "frequency", "times"], - }, - }, - required: ["days", "schedule"], - additionalProperties: false, + $ref: "#/components/schemas/splitTimings", }, ], }, @@ -574,4 +508,79 @@ module.exports = { }, }, required: ["context", "message"], + components: { + schemas: { + fixedTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + additionalProperties: false, + }, + }, + required: ["days", "range", "schedule"], + }, + splitTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays", "frequency", "times"], + }, + }, + required: ["days", "schedule"], + additionalProperties: false, + }, + }, + }, }; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js index f2d2f0d..70ccfca 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js @@ -1,4 +1,5 @@ module.exports = { + type: "object", properties: { context: { type: "object", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js index c29bf6d..2aee70a 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js @@ -94,96 +94,98 @@ module.exports = { }, items: { type: "array", - items: [ - { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", }, - required: ["count"], }, - tags: { - type: "object", - properties: { - update_type: { - type: "string", - enum: ["return", "cancel"], - }, - reason_code: { - type: "string", - minLength: 3, - maxLength: 3, - }, - ttl_approval: { - type: "string", - format: "duration", - }, - ttl_reverseqc: { - type: "string", - format: "duration", - }, - image: { - type: "string", - }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + update_type: { + type: "string", + enum: ["return", "cancel"], + }, + reason_code: { + type: "string", + minLength: 3, + maxLength: 3, + }, + ttl_approval: { + type: "string", + format: "duration", + }, + ttl_reverseqc: { + type: "string", + format: "duration", + }, + image: { + type: "string", }, - required: ["update_type"], - if: { - properties: { - update_type: { - const: "return", + }, + required: ["update_type"], + allOf: [ + { + if: { + properties: { + update_type: { + const: "return", + }, + reason_code: { type: "string" }, }, + required: ["update_type"], }, + then: { required: ["reason_code"] }, }, - then: { required: ["reason_code"] }, - }, + ], }, - required: ["id", "quantity", "tags"], }, - ], + required: ["id", "quantity", "tags"], + }, }, payment: { type: "object", properties: { "@ondc/org/settlement_details": { type: "array", - items: [ - { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - }, - settlement_amount: { - type: "string", - }, - settlement_timestamp: { - type: "string", - format: "date-time", - }, + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + settlement_amount: { + type: "string", + }, + settlement_timestamp: { + type: "string", + format: "date-time", }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - "settlement_amount", - "settlement_timestamp", - ], }, - ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + "settlement_amount", + "settlement_timestamp", + ], + }, }, }, required: ["@ondc/org/settlement_details"], diff --git a/utilities/log-validation-utility/utils/retail/retCancel.js b/utilities/log-validation-utility/utils/retail/retCancel.js index 068f5ba..7869a4b 100644 --- a/utilities/log-validation-utility/utils/retail/retCancel.js +++ b/utilities/log-validation-utility/utils/retail/retCancel.js @@ -105,17 +105,17 @@ const checkCancel = (dirPath, msgIdSet) => { try { console.log( - `Comparing order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + `Comparing order Id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}` ); - if (cancel.order_id != dao.getValue("onCnfrmOrdrId")) { - cnclObj.cancelOrdrId = `Order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM} do not match`; + if (cancel.order_id != dao.getValue("cnfrmOrdrId")) { + cnclObj.cancelOrdrId = `Order Id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM} do not match`; console.log( - `Order Id mismatch in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` + `Order Id mismatch in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}` ); } } catch (error) { console.log( - `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}`, + `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}`, error ); // cnclObj.cancelOrdrId = diff --git a/utilities/log-validation-utility/utils/retail/retOnCancel.js b/utilities/log-validation-utility/utils/retail/retOnCancel.js index 294f894..fec973b 100644 --- a/utilities/log-validation-utility/utils/retail/retOnCancel.js +++ b/utilities/log-validation-utility/utils/retail/retOnCancel.js @@ -117,12 +117,12 @@ const checkOnCancel = (dirPath, msgIdSet) => { try { console.log( - `Comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}` + `Comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM}` ); - if (on_cancel.id != dao.getValue("onCnfrmOrdrId")) { - onCnclObj.onCancelId = `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match`; + if (on_cancel.id != dao.getValue("cnfrmOrdrId")) { + onCnclObj.onCancelId = `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM} do not match`; console.log( - `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match` + `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM} do not match` ); } } catch (error) { diff --git a/utilities/log-validation-utility/utils/retail/retOnSupport.js b/utilities/log-validation-utility/utils/retail/retOnSupport.js index ea4f561..a9ec41a 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSupport.js +++ b/utilities/log-validation-utility/utils/retail/retOnSupport.js @@ -13,10 +13,10 @@ const checkOnSupport = (dirPath, msgIdSet) => { let on_support = fs.readFileSync( dirPath + `/${constants.RET_ONSUPPORT}.json` ); - - console.log(`Validating Schema for /${constants.RET_ONSUPPORT} API`); + on_support = JSON.parse(on_support); try { + console.log(`Validating Schema for /${constants.RET_ONSUPPORT} API`); const vs = validateSchema("retail", constants.RET_ONSUPPORT, on_support); if (vs != "error") { // console.log(vs); @@ -29,8 +29,6 @@ const checkOnSupport = (dirPath, msgIdSet) => { ); } - on_support = JSON.parse(on_support); - try { console.log(`Checking context for /${constants.RET_ONSUPPORT} API`); //checking context res = checkContext(on_support.context, constants.RET_ONSUPPORT); diff --git a/utilities/log-validation-utility/utils/retail/retOnTrack.js b/utilities/log-validation-utility/utils/retail/retOnTrack.js index 88e5b81..ab8ff04 100644 --- a/utilities/log-validation-utility/utils/retail/retOnTrack.js +++ b/utilities/log-validation-utility/utils/retail/retOnTrack.js @@ -9,7 +9,7 @@ const checkOnTrack = (dirPath, msgIdSet) => { let onTrckObj = {}; try { let on_track = fs.readFileSync(dirPath + `/${constants.RET_ONTRACK}.json`); - + on_track = JSON.parse(on_track); try { console.log(`Validating Schema for /${constants.RET_ONTRACK} API`); const vs = validateSchema("retail", constants.RET_ONTRACK, on_track); @@ -23,7 +23,6 @@ const checkOnTrack = (dirPath, msgIdSet) => { error ); } - on_track = JSON.parse(on_track); console.log(`Checking context for /${constants.RET_ONTRACK} API`); //checking context try { diff --git a/utilities/log-validation-utility/utils/retail/retTrack.js b/utilities/log-validation-utility/utils/retail/retTrack.js index c2e26be..ce66708 100644 --- a/utilities/log-validation-utility/utils/retail/retTrack.js +++ b/utilities/log-validation-utility/utils/retail/retTrack.js @@ -87,17 +87,17 @@ const checkTrack = (dirPath, msgIdSet) => { try { console.log( - `Checking Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}` + `Checking Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}` ); - if (track.order_id != dao.getValue("onCnfrmOrdrId")) { + if (track.order_id != dao.getValue("cnfrmOrdrId")) { console.log( - `Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match` + `Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM} do not match` ); - trckObj.trackOrdrId = `Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match`; + trckObj.trackOrdrId = `Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM} do not match`; } } catch (error) { console.log( - `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}`, + `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}`, error ); // trckObj.trackOrdrId = "Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match"; diff --git a/utilities/log-validation-utility/utils/validateLogUtil.js b/utilities/log-validation-utility/utils/validateLogUtil.js index eaa2a72..1cad472 100644 --- a/utilities/log-validation-utility/utils/validateLogUtil.js +++ b/utilities/log-validation-utility/utils/validateLogUtil.js @@ -22,7 +22,7 @@ const checkOnSupport = require("./retail/retOnSupport"); const checkUpdate = require("./retail/retUpdate"); const checkOnUpdate = require("./retail/retOnUpdate"); -//To be developed: TAT in on_select = sumof(time to ship in /on_search and TAT by LSP in logistics /on_search) +//TAT in on_select = sumof(time to ship in /on_search and TAT by LSP in logistics /on_search) // If non-serviceable in /on_select, there should be domain-error const validateLogs = (dirPath) => { From 79698fb7580ddf99489cb3d49c461de4f40abbfe Mon Sep 17 00:00:00 2001 From: bluecypher Date: Wed, 22 Mar 2023 20:31:31 +0530 Subject: [PATCH 019/228] patch --- utilities/log-validation-utility/.gitignore | 6 ++++-- utilities/log-validation-utility/README.md | 1 + .../utils/retail/retConfirm.js | 8 ++++---- .../log-validation-utility/utils/retail/retInit.js | 13 +++++++++++-- .../utils/retail/retOnConfirm.js | 2 +- .../utils/retail/retOnSelect.js | 2 +- 6 files changed, 22 insertions(+), 10 deletions(-) diff --git a/utilities/log-validation-utility/.gitignore b/utilities/log-validation-utility/.gitignore index 1898f6d..e848144 100644 --- a/utilities/log-validation-utility/.gitignore +++ b/utilities/log-validation-utility/.gitignore @@ -8,6 +8,8 @@ verification-logs /utils/*.txt test_logs dbfiles -log_report.md test.js -public/ \ No newline at end of file +public/ +!README.md +!LICENSE.md +*.md \ No newline at end of file diff --git a/utilities/log-validation-utility/README.md b/utilities/log-validation-utility/README.md index 069c239..4a78bc1 100644 --- a/utilities/log-validation-utility/README.md +++ b/utilities/log-validation-utility/README.md @@ -106,4 +106,5 @@ _Notes:_ } } ``` + ### FAQs for Retail API Contract and Log Validation Utility ([FAQs](https://docs.google.com/document/d/1K-kqoOQ8IB-ywl_4pEiQKttTDk5Co381J07GldEUmD4/edit?usp=sharing)) diff --git a/utilities/log-validation-utility/utils/retail/retConfirm.js b/utilities/log-validation-utility/utils/retail/retConfirm.js index 389d5fc..67151f3 100644 --- a/utilities/log-validation-utility/utils/retail/retConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retConfirm.js @@ -216,7 +216,7 @@ const checkConfirm = (dirPath, msgIdSet) => { if ( !_.isEqual( - confirm.fulfillments[i].location.gps, + confirm.fulfillments[i].end.location.gps, dao.getValue("buyerGps") ) ) { @@ -225,7 +225,7 @@ const checkConfirm = (dirPath, msgIdSet) => { if ( !_.isEqual( - confirm.fulfillments[i].location.address.area_code, + confirm.fulfillments[i].end.location.address.area_code, dao.getValue("buyerAddr") ) ) { @@ -291,13 +291,13 @@ const checkConfirm = (dirPath, msgIdSet) => { cnfrmObj.ordertmpstmp = `order created and updated timestamps are mandatory in /${constants.RET_CONFIRM}`; } else { if (!_.isEqual(confirm.created_at, dao.getValue("tmpstmp"))) { - cnfrmObj.orderCrtd = `order.created_at timestamp should be the same as context.timestamp`; + cnfrmObj.orderCrtd = `order.created_at timestamp should match context.timestamp`; } else { dao.setValue("ordrcrtdtmpstmp", confirm.created_at); } if (!_.isEqual(confirm.created_at, confirm.updated_at)) { - cnfrmObj.ordrupdtd = `order.updated_at timestamp should be the same as order.created_at timestamp`; + cnfrmObj.ordrupdtd = `order.updated_at timestamp should match order.created_at timestamp`; } else { dao.setValue("ordrupdtdtmpstmp", confirm.updated_at); } diff --git a/utilities/log-validation-utility/utils/retail/retInit.js b/utilities/log-validation-utility/utils/retail/retInit.js index fa71c35..add1126 100644 --- a/utilities/log-validation-utility/utils/retail/retInit.js +++ b/utilities/log-validation-utility/utils/retail/retInit.js @@ -60,7 +60,7 @@ const checkInit = (dirPath, msgIdSet) => { if (_.gte(dao.getValue("tmpstmp"), init.context.timestamp)) { initObj.tmpstmp = `Timestamp for /${constants.RET_ONSELECT} api cannot be greater than or equal to /init api`; } - dao.setValue(dao.getValue("tmpstmp"), init.context.timestamp); + dao.setValue("tmpstmp", init.context.timestamp); } catch (error) { console.log( `!!Error while comparing timestamp for /${constants.RET_ONSELECT} and /${constants.RET_INIT} api`, @@ -127,7 +127,16 @@ const checkInit = (dirPath, msgIdSet) => { if (!init["billing"]) { initObj.bill = `Billing object missing in /${constants.RET_INIT}`; } else { - dao.setValue("billing", init.billing); + const billing = init.billing; + const tmpstmp = dao.getValue("tmpstmp"); + dao.setValue("billing", billing); + if (!_.isEqual(billing.created_at, tmpstmp)) { + initObj.bllngCrtd = `billing.created_at should match context.timestamp`; + } + + if (!_.isEqual(init.billing.updated_at, tmpstmp)) { + initObj.bllngUptd = `billing.updated_at should match context.timestamp`; + } // if ( // !_.isEqual(init.billing.address.area_code, dao.getValue("buyerAddr")) // ) { diff --git a/utilities/log-validation-utility/utils/retail/retOnConfirm.js b/utilities/log-validation-utility/utils/retail/retOnConfirm.js index 40fe129..69796c7 100644 --- a/utilities/log-validation-utility/utils/retail/retOnConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retOnConfirm.js @@ -309,7 +309,7 @@ const checkOnConfirm = (dirPath, msgIdSet) => { if ( !_.isEqual( - on_confirm.fulfillments[i].location.address.area_code, + on_confirm.fulfillments[i].end.location.address.area_code, dao.getValue("buyerAddr") ) ) { diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index 12b3208..bdbc89b 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -340,7 +340,7 @@ const checkOnSelect = (dirPath, msgIdSet) => { } }); - dao.setValue("onSelectPrice", onSelectPrice); + dao.setValue("onSelectPrice", on_select.quote.price.value); console.log( `Matching quoted Price ${parseFloat( From 3edf19ad7d33248562816aef06eb4b7684b1cff3 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Mon, 27 Mar 2023 10:07:41 +0530 Subject: [PATCH 020/228] bug fixes --- utilities/log-validation-utility/.gitignore | 1 - .../public/.placeholder | 0 .../public/logs/.placeholder | 0 .../retail_api_json_schema/SchemaValidator.js | 15 --------- .../retail_api_json_schema/cancelSchema.js | 1 - .../utils/retail/retCancel.js | 2 +- .../utils/retail/retConfirm.js | 6 ++-- .../utils/retail/retInit.js | 7 ++-- .../utils/retail/retOnCancel.js | 2 +- .../utils/retail/retOnConfirm.js | 11 ++++--- .../utils/retail/retOnInit.js | 13 ++++---- .../utils/retail/retOnSelect.js | 33 ++++++++++--------- .../utils/retail/retOnStatus.js | 2 +- .../utils/retail/retOnSupport.js | 2 +- .../utils/retail/retOnTrack.js | 2 +- .../utils/retail/retOnUpdate.js | 4 +-- .../utils/retail/retSearch.js | 32 +++++++++--------- .../utils/retail/retSelect.js | 2 +- .../utils/retail/retStatus.js | 2 +- .../utils/retail/retSupport.js | 18 ++++++++-- .../utils/retail/retTrack.js | 18 ++++++++-- .../utils/retail/retUpdate.js | 2 +- .../utils/schemaValidation.js | 21 ------------ 23 files changed, 96 insertions(+), 100 deletions(-) create mode 100644 utilities/log-validation-utility/public/.placeholder create mode 100644 utilities/log-validation-utility/public/logs/.placeholder diff --git a/utilities/log-validation-utility/.gitignore b/utilities/log-validation-utility/.gitignore index e848144..20d954d 100644 --- a/utilities/log-validation-utility/.gitignore +++ b/utilities/log-validation-utility/.gitignore @@ -9,7 +9,6 @@ verification-logs test_logs dbfiles test.js -public/ !README.md !LICENSE.md *.md \ No newline at end of file diff --git a/utilities/log-validation-utility/public/.placeholder b/utilities/log-validation-utility/public/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/utilities/log-validation-utility/public/logs/.placeholder b/utilities/log-validation-utility/public/logs/.placeholder new file mode 100644 index 0000000..e69de29 diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index 5dc6f19..8981d71 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -24,21 +24,6 @@ const addFormats = require("ajv-formats"); addFormats(ajv); require("ajv-errors")(ajv); -// transform_on_search_schema = (payload) => { -// transformed_payload = payload; -// bpp_providers = transformed_payload["message"]["catalog"]["bpp/providers"]; -// bpp_providers.forEach((provider) => { -// if (provider.hasOwnProperty("@ondc/org/fssai_license_no")) { -// fssai = provider["@ondc/org/fssai_license_no"]; -// items = provider["items"]; -// items.forEach((item) => { -// item["@ondc/org/fssai_license_no"] = fssai; -// }); -// } - -// return transformed_payload; -// }); -// }; const formatted_error = (errors) => { error_list = []; let status = ""; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js index 00127f1..f9ef729 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js @@ -1,5 +1,4 @@ module.exports = { - $schema: "http://json-schema.org/draft-04/schema#", type: "object", properties: { context: { diff --git a/utilities/log-validation-utility/utils/retail/retCancel.js b/utilities/log-validation-utility/utils/retail/retCancel.js index 7869a4b..9eb97ae 100644 --- a/utilities/log-validation-utility/utils/retail/retCancel.js +++ b/utilities/log-validation-utility/utils/retail/retCancel.js @@ -30,7 +30,7 @@ const checkCancel = (dirPath, msgIdSet) => { try { res = checkContext(cancel.context, constants.RET_CANCEL); if (!res.valid) { - cnclObj = res.ERRORS; + Object.assign(cnclObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retConfirm.js b/utilities/log-validation-utility/utils/retail/retConfirm.js index 67151f3..93294bd 100644 --- a/utilities/log-validation-utility/utils/retail/retConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retConfirm.js @@ -29,7 +29,7 @@ const checkConfirm = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_CONFIRM} API`); //checking context res = checkContext(confirm.context, constants.RET_CONFIRM); if (!res.valid) { - cnfrmObj = res.ERRORS; + Object.assign(cnfrmObj, res.ERRORS); } } catch (error) { console.log( @@ -277,7 +277,7 @@ const checkConfirm = (dirPath, msgIdSet) => { if ( !_.isEqual( - confirm.payment["@ondc/org/settlement_details"], + confirm.payment["@ondc/org/settlement_details"][0], dao.getValue("sttlmntdtls") ) ) { @@ -325,7 +325,7 @@ const checkConfirm = (dirPath, msgIdSet) => { ); console.log("confirm quote", confirm.quote); if (!_.isEqual(dao.getValue("quoteObj"), confirm.quote)) { - cnfrmObj.quoteObj = `Quote Objects in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM} do not match`; + cnfrmObj.quoteObj = `Discrepancies between the quote object in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`; } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retInit.js b/utilities/log-validation-utility/utils/retail/retInit.js index add1126..c5b6ee1 100644 --- a/utilities/log-validation-utility/utils/retail/retInit.js +++ b/utilities/log-validation-utility/utils/retail/retInit.js @@ -14,8 +14,8 @@ const checkInit = (dirPath, msgIdSet) => { try { console.log(`Validating Schema for ${constants.RET_INIT} API`); const vs = validateSchema("retail", constants.RET_INIT, init); + console.log("DEBUGGG", vs); if (vs != "error") { - // console.log(vs); Object.assign(initObj, vs); } } catch (error) { @@ -29,7 +29,7 @@ const checkInit = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_INIT} API`); //checking context res = checkContext(init.context, constants.RET_INIT); if (!res.valid) { - initObj = res.ERRORS; + Object.assign(initObj, res.ERRORS); } } catch (error) { console.log( @@ -255,7 +255,8 @@ const checkInit = (dirPath, msgIdSet) => { console.log(`!!File not found for /${constants.RET_INIT} API!`); } else { console.log( - `!!Some error occurred while checking /${constants.RET_INIT} API` + `!!Some error occurred while checking /${constants.RET_INIT} API`, + err ); } } diff --git a/utilities/log-validation-utility/utils/retail/retOnCancel.js b/utilities/log-validation-utility/utils/retail/retOnCancel.js index fec973b..2b8cdd9 100644 --- a/utilities/log-validation-utility/utils/retail/retOnCancel.js +++ b/utilities/log-validation-utility/utils/retail/retOnCancel.js @@ -33,7 +33,7 @@ const checkOnCancel = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_ONCANCEL} API`); //checking context res = checkContext(on_cancel.context, constants.RET_ONCANCEL); if (!res.valid) { - onCnclObj = res.ERRORS; + Object.assign(onCnclObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retOnConfirm.js b/utilities/log-validation-utility/utils/retail/retOnConfirm.js index 69796c7..317ec21 100644 --- a/utilities/log-validation-utility/utils/retail/retOnConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retOnConfirm.js @@ -33,7 +33,7 @@ const checkOnConfirm = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_ONCONFIRM} API`); //checking context res = checkContext(on_confirm.context, constants.RET_ONCONFIRM); if (!res.valid) { - onCnfrmObj = res.ERRORS; + Object.assign(onCnfrmObj, res.ERRORS); } } catch (error) { console.log( @@ -142,9 +142,10 @@ const checkOnConfirm = (dirPath, msgIdSet) => { if ( cnfrmOrdrUpdtd && (!on_confirm.updated_at || - _.gte(cnfrmOrdrUpdtd, on_confirm.updated_at)) + _.gte(cnfrmOrdrUpdtd, on_confirm.updated_at) || + on_confirm.updated_at != dao.getValue("tmpstmp")) ) { - onCnfrmObj.updtdtmstmp = `order.updated_at timestamp should be updated (Default fulfillment state is added)`; + onCnfrmObj.updtdtmstmp = `order.updated_at timestamp should be updated as per the context.timestamp (since default fulfillment state is added)`; } } @@ -347,7 +348,7 @@ const checkOnConfirm = (dirPath, msgIdSet) => { `Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` ); if (!_.isEqual(dao.getValue("quoteObj"), on_confirm.quote)) { - onCnfrmObj.onQuoteObj = `Quote Object in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM} do not match`; + onCnfrmObj.onQuoteObj = `Discrepancies between the quote object /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}`; } } catch (error) { // onCnfrmObj.onQuoteObj = `Quote Object in /on_init and /${constants.RET_ONCONFIRM} mismatch`; @@ -381,7 +382,7 @@ const checkOnConfirm = (dirPath, msgIdSet) => { ); if (!_.isEqual(dao.getValue("cnfrmpymnt"), on_confirm.payment)) { - `payment object mismatches in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`; + onCnfrmObj.pymntObj = `payment object mismatches in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`; } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retOnInit.js b/utilities/log-validation-utility/utils/retail/retOnInit.js index 6050707..233bba4 100644 --- a/utilities/log-validation-utility/utils/retail/retOnInit.js +++ b/utilities/log-validation-utility/utils/retail/retOnInit.js @@ -12,9 +12,9 @@ const checkOnInit = (dirPath, msgIdSet) => { var on_init = fs.readFileSync(dirPath + `/${constants.RET_ONINIT}.json`); on_init = JSON.parse(on_init); - console.log(`Validating Schema for /${constants.RET_ONINIT} API`); try { + console.log(`Validating Schema for /${constants.RET_ONINIT} API`); const vs = validateSchema("retail", constants.RET_ONINIT, on_init); if (vs != "error") { // console.log(vs); @@ -31,7 +31,7 @@ const checkOnInit = (dirPath, msgIdSet) => { try { res = checkContext(on_init.context, constants.RET_ONINIT); if (!res.valid) { - onInitObj = res.ERRORS; + Object.assign(onInitObj, res.ERRORS); } } catch (error) { console.log( @@ -313,7 +313,7 @@ const checkOnInit = (dirPath, msgIdSet) => { `Checking Quote Object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` ); if (!_.isEqual(dao.getValue("quoteObj"), on_init.quote)) { - onInitObj.quoteErr = `Quote object mismatches in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; + onInitObj.quoteErr = `Discrepancies between the quote object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; } } catch (error) { console.log( @@ -361,7 +361,7 @@ const checkOnInit = (dirPath, msgIdSet) => { onInitObj.sttlmntcntrparty = `settlement_counterparty is expected to be 'seller-app' in @ondc/org/settlement_details`; } } catch (error) { - console.err( + console.log( `!!Error while checking payment object in /${constants.RET_ONINIT}` ); } @@ -373,7 +373,7 @@ const checkOnInit = (dirPath, msgIdSet) => { if (on_init.payment.hasOwnProperty("@ondc/org/settlement_details")) dao.setValue( "sttlmntdtls", - on_init.payment["@ondc/org/settlement_details"] + on_init.payment["@ondc/org/settlement_details"][0] ); else { onInitObj.pymntSttlmntObj = `payment settlement_details missing in /${constants.RET_ONINIT}`; @@ -390,7 +390,8 @@ const checkOnInit = (dirPath, msgIdSet) => { console.log(`!!File not found for /${constants.RET_ONINIT} API!`); } else { console.log( - `!!Some error occurred while checking /${constants.RET_ONINIT} API` + `!!Some error occurred while checking /${constants.RET_ONINIT} API`, + err ); } } diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index bdbc89b..b8c4466 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -12,29 +12,29 @@ const checkOnSelect = (dirPath, msgIdSet) => { on_select = fs.readFileSync(dirPath + `/${constants.RET_ONSELECT}.json`); on_select = JSON.parse(on_select); + try { - console.log(`Validating Schema for /${constants.RET_ONSELECT} API`); - const vs = validateSchema("retail", constants.RET_ONSELECT, on_select); - if (vs != "error") { - // console.log(vs); - Object.assign(onSlctObj, vs); + console.log(`Checking context for /${constants.RET_ONSELECT} API`); //checking context + res = checkContext(on_select.context, constants.RET_ONSELECT); + if (!res.valid) { + Object.assign(onSlctObj, res.ERRORS); } } catch (error) { console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONSELECT}`, + `!!Some error occurred while checking /${constants.RET_ONSELECT} context`, error ); } - try { - console.log(`Checking context for /${constants.RET_ONSELECT} API`); //checking context - res = checkContext(on_select.context, constants.RET_ONSELECT); - if (!res.valid) { - onSlctObj = res.ERRORS; + console.log(`Validating Schema for /${constants.RET_ONSELECT} API`); + const vs = validateSchema("retail", constants.RET_ONSELECT, on_select); + if (vs != "error") { + // console.log(vs); + Object.assign(onSlctObj, vs); } } catch (error) { console.log( - `!!Some error occurred while checking /${constants.RET_ONSELECT} context`, + `!!Error occurred while performing schema validation for /${constants.RET_ONSELECT}`, error ); } @@ -294,11 +294,14 @@ const checkOnSelect = (dirPath, msgIdSet) => { if (element.item.hasOwnProperty("quantity")) { if ( _.gt( - element.item.quantity.available.count, - element.item.quantity.maximum.count + parseFloat(element.item.quantity.available.count), + parseFloat(element.item.quantity.maximum.count) ) ) { - onSlctObj.qntCnt = `available count can't be greater than maximum count for item id: ${element["@ondc/org/item_id"]}`; + let key = `qntcnt${i}`; + onSlctObj[ + key + ] = `available count can't be greater than maximum count for item id: ${element["@ondc/org/item_id"]}`; } } } diff --git a/utilities/log-validation-utility/utils/retail/retOnStatus.js b/utilities/log-validation-utility/utils/retail/retOnStatus.js index 5ab244e..8566510 100644 --- a/utilities/log-validation-utility/utils/retail/retOnStatus.js +++ b/utilities/log-validation-utility/utils/retail/retOnStatus.js @@ -33,7 +33,7 @@ const checkOnStatus = (dirPath, msgIdSet) => { console.log("Checking context for /${constants.RET_ONSTATUS} API"); //checking context res = checkContext(on_status.context, "on_status"); if (!res.valid) { - onStatObj = res.ERRORS; + Object.assign(onStatObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retOnSupport.js b/utilities/log-validation-utility/utils/retail/retOnSupport.js index a9ec41a..37bd6cf 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSupport.js +++ b/utilities/log-validation-utility/utils/retail/retOnSupport.js @@ -33,7 +33,7 @@ const checkOnSupport = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_ONSUPPORT} API`); //checking context res = checkContext(on_support.context, constants.RET_ONSUPPORT); if (!res.valid) { - onSprtObj = res.ERRORS; + Object.assign(onSprtObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retOnTrack.js b/utilities/log-validation-utility/utils/retail/retOnTrack.js index ab8ff04..edfe0ca 100644 --- a/utilities/log-validation-utility/utils/retail/retOnTrack.js +++ b/utilities/log-validation-utility/utils/retail/retOnTrack.js @@ -28,7 +28,7 @@ const checkOnTrack = (dirPath, msgIdSet) => { try { res = checkContext(on_track.context, "on_track"); if (!res.valid) { - onTrckObj = res.ERRORS; + Object.assign(onTrckObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdate.js b/utilities/log-validation-utility/utils/retail/retOnUpdate.js index 7e6a213..e8365d4 100644 --- a/utilities/log-validation-utility/utils/retail/retOnUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retOnUpdate.js @@ -34,7 +34,7 @@ const checkOnUpdate = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_ONUPDATE} API`); //checking context res = checkContext(on_update.context, constants.RET_ONUPDATE); if (!res.valid) { - onUpdtObj = res.ERRORS; + Object.assign(onUpdtObj, res.ERRORS); } } catch (error) { console.log( @@ -205,7 +205,7 @@ const checkOnUpdate = (dirPath, msgIdSet) => { `Comparing individual item's total price and unit price ` ); if (!element.hasOwnProperty("item")) { - onSlctObj.priceBreakup = `Item's unit price missing in quote.breakup for item id ${element["@ondc/org/item_id"]}`; + onUpdtObj.priceBreakup = `Item's unit price missing in quote.breakup for item id ${element["@ondc/org/item_id"]}`; } else if ( parseFloat(element.item.price.value) * element["@ondc/org/item_quantity"].count != diff --git a/utilities/log-validation-utility/utils/retail/retSearch.js b/utilities/log-validation-utility/utils/retail/retSearch.js index 5bec2bc..312d465 100644 --- a/utilities/log-validation-utility/utils/retail/retSearch.js +++ b/utilities/log-validation-utility/utils/retail/retSearch.js @@ -10,23 +10,9 @@ const checkSearch = (dirPath, msgIdSet) => { try { let search = fs.readFileSync(dirPath + `/${constants.RET_SEARCH}.json`); search = JSON.parse(search); - try { - console.log(`Validating Schema for ${constants.RET_SEARCH} API`); - const vs = validateSchema("retail", constants.RET_SEARCH, search); - if (vs != "error") { - // console.log(vs); - Object.assign(srchObj, vs); - } - } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_SEARCH}`, - error - ); - } - - console.log(`Checking context for ${constants.RET_SEARCH} API`); //context checking try { + console.log(`Checking context for ${constants.RET_SEARCH} API`); //context checking res = checkContext(search.context, constants.RET_SEARCH); dao.setValue("tmpstmp", search.context.timestamp); dao.setValue("txnId", search.context.transaction_id); @@ -34,7 +20,7 @@ const checkSearch = (dirPath, msgIdSet) => { dao.setValue("city", search.context.city); msgIdSet.add(search.context.message_id); if (!res.valid) { - srchObj = res.ERRORS; + Object.assign(srchObj, res.ERRORS); } } catch (error) { console.log( @@ -43,6 +29,20 @@ const checkSearch = (dirPath, msgIdSet) => { ); } + try { + console.log(`Validating Schema for ${constants.RET_SEARCH} API`); + const vs = validateSchema("retail", constants.RET_SEARCH, search); + if (vs != "error") { + // console.log(vs); + Object.assign(srchObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_SEARCH}`, + error + ); + } + search = search.message.intent; try { console.log("Getting Buyer App finder fee amount"); diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index eef6ae5..8be4e1b 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -36,7 +36,7 @@ const checkSelect = (dirPath, msgIdSet) => { try { res = checkContext(select.context, constants.RET_SELECT); if (!res.valid) { - slctObj = res.ERRORS; + Object.assign(slctObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retStatus.js b/utilities/log-validation-utility/utils/retail/retStatus.js index 130794e..cbf4014 100644 --- a/utilities/log-validation-utility/utils/retail/retStatus.js +++ b/utilities/log-validation-utility/utils/retail/retStatus.js @@ -29,7 +29,7 @@ const checkStatus = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_STATUS} API`); //checking context res = checkContext(status.context, constants.RET_STATUS); if (!res.valid) { - statObj = res.ERRORS; + Object.assign(statObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retSupport.js b/utilities/log-validation-utility/utils/retail/retSupport.js index 5806036..5ebfd92 100644 --- a/utilities/log-validation-utility/utils/retail/retSupport.js +++ b/utilities/log-validation-utility/utils/retail/retSupport.js @@ -9,11 +9,25 @@ const checkSupport = (dirPath, msgIdSet) => { try { var support = fs.readFileSync(dirPath + `/${constants.RET_SUPPORT}.json`); support = JSON.parse(support); - console.log(`Checking context for /${constants.RET_SUPPORT} API`); //checking context + + try { + console.log(`Validating Schema for ${constants.RET_SUPPORT} API`); + const vs = validateSchema("retail", constants.RET_SUPPORT, support); + if (vs != "error") { + // console.log(vs); + Object.assign(sprtObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_SUPPORT}`, + error + ); + } try { + console.log(`Checking context for /${constants.RET_SUPPORT} API`); //checking context res = checkContext(support.context, constants.RET_SUPPORT); if (!res.valid) { - sprtObj = res.ERRORS; + Object.assign(sprtObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retTrack.js b/utilities/log-validation-utility/utils/retail/retTrack.js index ce66708..856224f 100644 --- a/utilities/log-validation-utility/utils/retail/retTrack.js +++ b/utilities/log-validation-utility/utils/retail/retTrack.js @@ -10,11 +10,25 @@ const checkTrack = (dirPath, msgIdSet) => { let track = fs.readFileSync(dirPath + `/${constants.RET_TRACK}.json`); track = JSON.parse(track); - console.log(`Checking context for /${constants.RET_TRACK}rack API`); //checking context try { + console.log(`Validating Schema for ${constants.RET_TRACK} API`); + const vs = validateSchema("retail", constants.RET_TRACK, track); + if (vs != "error") { + // console.log(vs); + Object.assign(trckObj, vs); + } + } catch (error) { + console.log( + `!!Error occurred while performing schema validation for /${constants.RET_TRACK}`, + error + ); + } + + try { + console.log(`Checking context for /${constants.RET_TRACK}rack API`); //checking context res = checkContext(track.context, constants.RET_TRACK); if (!res.valid) { - trckObj = res.ERRORS; + Object.assign(trckObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retUpdate.js b/utilities/log-validation-utility/utils/retail/retUpdate.js index a41204b..3a47516 100644 --- a/utilities/log-validation-utility/utils/retail/retUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retUpdate.js @@ -32,7 +32,7 @@ const checkUpdate = (dirPath, msgIdSet) => { console.log(`Checking context for /${constants.RET_UPDATE} API`); //checking context res = checkContext(update.context, constants.RET_UPDATE); if (!res.valid) { - updtObj = res.ERRORS; + Object.assign(updtObj, res.ERRORS); } } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/schemaValidation.js b/utilities/log-validation-utility/utils/schemaValidation.js index 2316dd7..8cfe7a2 100644 --- a/utilities/log-validation-utility/utils/schemaValidation.js +++ b/utilities/log-validation-utility/utils/schemaValidation.js @@ -5,22 +5,7 @@ const fs = require("fs"); const validateSchema = (domain, api, data) => { console.log(`Inside Schema Validation for domain: ${domain}, api: ${api}`); let errObj = {}; - // data = JSON.parse(data); - // const schemaValidator = path.join( - // __dirname, - // "..", - // "schema", - // "ondc-schema-validator", - // "main.py" - // ); - // const pySchmaVldtr = spawnSync("python3", [ - // schemaValidator, - // "validate_schema_for_retail_json", - // domain, - // api, - // data, - // ]); const schmaVldtr = schemaValidator(domain, api, data); const datavld = schmaVldtr; @@ -34,14 +19,8 @@ const validateSchema = (domain, api, data) => { errObj[key] = `${res[i].details} ${res[i].message}`; i++; } - return errObj; } else return "error"; - - // pySchmaVldtr.stderr.on("data", (data) => { - // console.log(`ERROR validating schema for ${api} :`, data); - // return "error"; - // }); }; module.exports = validateSchema; From b5256b0e8681158f544f93127753cdd12547a95a Mon Sep 17 00:00:00 2001 From: bluecypher Date: Tue, 28 Mar 2023 10:37:39 +0530 Subject: [PATCH 021/228] patch fixes --- .../retail_api_json_schema/onSearchSchema.js | 3 --- .../utils/retail/retSearch.js | 15 ++++++++------- .../utils/retail/retSelect.js | 15 ++++++++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index 314fa0a..63e8279 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -55,7 +55,6 @@ module.exports = { type: "array", items: { type: "string", - pattern: "^(?!\\s*$).+\\.(jpeg|jpg|jfif|gif|png|ico)$", }, }, }, @@ -86,8 +85,6 @@ module.exports = { type: "array", items: { type: "string", - pattern: - "^(?!\\s*$).+\\.(jpeg|jpg|jfif|gif|png|ico)$", }, }, }, diff --git a/utilities/log-validation-utility/utils/retail/retSearch.js b/utilities/log-validation-utility/utils/retail/retSearch.js index 312d465..a5f6854 100644 --- a/utilities/log-validation-utility/utils/retail/retSearch.js +++ b/utilities/log-validation-utility/utils/retail/retSearch.js @@ -67,14 +67,15 @@ const checkSearch = (dirPath, msgIdSet) => { if (!gpsLat || !gpsLong) { srchObj.gpsErr = `location.gps is not as per the API contract`; - } else { - if ( - utils.countDecimalDigits(gpsLat) != - utils.countDecimalDigits(gpsLong) - ) { - srchObj.gpsErr = `GPS Lat/Long Precision should be same `; - } } + // else { + // if ( + // utils.countDecimalDigits(gpsLat) != + // utils.countDecimalDigits(gpsLong) + // ) { + // srchObj.gpsErr = `GPS Lat/Long Precision should be same `; + // } + // } } else { srchObj.flfllmntObj = `Fulfillment object missing in /${constants.RET_SEARCH} API`; } diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index 8be4e1b..01473f1 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -193,14 +193,15 @@ const checkSelect = (dirPath, msgIdSet) => { // console.log(gpsLat, " sfsfdsf ", gpsLong); if (!gpsLat || !gpsLong) { slctObj.gpsErr = `fulfillments location.gps is not as per the API contract`; - } else { - if ( - utils.countDecimalDigits(gpsLat) != - utils.countDecimalDigits(gpsLong) - ) { - slctObj.gpsErr = `fulfillments GPS Lat/Long Precision should be same `; - } } + // else { + // if ( + // utils.countDecimalDigits(gpsLat) != + // utils.countDecimalDigits(gpsLong) + // ) { + // slctObj.gpsErr = `fulfillments GPS Lat/Long Precision should be same `; + // } + // } if (!ff.end.location.address.hasOwnProperty("area_code")) { slctObj.areaCode = `address.area_code is required property in /${constants.RET_SELECT}`; From 29abb601e72eaf50f55e791e9e5749913ca3b80b Mon Sep 17 00:00:00 2001 From: bluecypher Date: Sat, 15 Apr 2023 21:55:52 +0530 Subject: [PATCH 022/228] schema update --- .../retail_api_json_schema/SchemaValidator.js | 1 + .../retail_api_json_schema/cancelSchema.js | 1 - .../retail_api_json_schema/confirmSchema.js | 3 +- .../retail_api_json_schema/initSchema.js | 1 - .../retail_api_json_schema/onConfirmSchema.js | 12 +++---- .../onSearchItemValidations.js | 18 +++++----- .../retail_api_json_schema/onSearchSchema.js | 6 ++-- .../retail_api_json_schema/searchSchema.js | 1 - .../retail_api_json_schema/selectSchema.js | 1 - .../retail_api_json_schema/statusSchema.js | 1 - .../retail_api_json_schema/updateSchema.js | 1 - .../services/service.js | 12 +++---- .../utils/retail/retOnSelect.js | 33 +++++++++++++------ .../utils/retail/retSelect.js | 8 ----- .../log-validation-utility/utils/utils.js | 15 ++++----- 15 files changed, 56 insertions(+), 58 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index 8981d71..6dd23c3 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -64,6 +64,7 @@ const validate_schema_search_retail_for_json = (data) => { const validate_schema_on_search_retail_for_json = (data) => { // transformed_item_data = transform_on_search_schema(data); error_list = validate_schema(data, (schema = onSearchSchema)); + console.log(error_list); return formatted_error(error_list); }; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js index f9ef729..8abc5e1 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/cancelSchema.js @@ -36,7 +36,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js index 2cc23c8..c4ef9ab 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -36,7 +36,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", @@ -385,7 +384,7 @@ module.exports = { type: "string", enum: ["upi", "neft", "rtgs"], }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, + upi_address: { type: "string" }, settlement_bank_account_no: { type: "string", pattern: "^(?!s*$).+", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js index b40fd73..b931365 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js @@ -36,7 +36,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js index 07b9243..27fbd31 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js @@ -136,10 +136,10 @@ module.exports = { format: "date-time", }, }, - required: ["start", "end"], + // required: ["start", "end"], }, }, - required: ["range"], + // required: ["range"], }, instructions: { type: "object", @@ -157,7 +157,7 @@ module.exports = { required: ["phone"], }, }, - required: ["location", "time", "contact"], + required: ["location", "contact"], }, end: { type: "object", @@ -205,10 +205,10 @@ module.exports = { format: "date-time", }, }, - required: ["start", "end"], + // required: ["start", "end"], }, }, - required: ["range"], + // required: ["range"], }, instructions: { type: "object", @@ -225,7 +225,7 @@ module.exports = { required: ["phone"], }, }, - required: ["location", "time", "contact"], + required: ["location", "contact"], }, }, required: [ diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js index a991740..50f730b 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js @@ -1,13 +1,13 @@ onSearchRules = [ - { - if: { properties: { "@ondc/org/returnable": { const: false } } }, - then: { - not: { - required: ["@ondc/org/return_window"], - error_message: "return window is available when returnable is false", - }, - }, - }, + // { + // if: { properties: { "@ondc/org/returnable": { const: false } } }, + // then: { + // not: { + // required: ["@ondc/org/return_window"], + // errorMessage: "return window is available when returnable is false", + // }, + // }, + // }, { if: { diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index 63e8279..a7f0aa4 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -13,7 +13,7 @@ module.exports = { core_version: { type: "string" }, bap_id: { type: "string" }, bap_uri: { type: "string" }, - transaction_id: { type: "string", format: "uuid" }, + transaction_id: { type: "string" }, message_id: { type: "string" }, timestamp: { type: "string", format: "date-time" }, ttl: { type: "string", format: "duration" }, @@ -324,7 +324,7 @@ module.exports = { }, }, required: ["nutritional_info", "additives_info"], - oneOf: [ + anyOf: [ { required: ["importer_FSSAI_license_no"], properties: { @@ -416,7 +416,7 @@ module.exports = { }, }, - allOf: onSearchItemValidations.on_search_rules, + allOf: onSearchItemValidations.onSearchRules, required: [ "id", "category_id", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js index 50a1806..8f0ea0d 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js @@ -30,7 +30,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js index 6888f9c..62e8aae 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/selectSchema.js @@ -36,7 +36,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js index 70ccfca..31ada71 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/statusSchema.js @@ -36,7 +36,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js index 2aee70a..dbf0a8d 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js @@ -36,7 +36,6 @@ module.exports = { }, transaction_id: { type: "string", - format: "uuid", }, message_id: { type: "string", diff --git a/utilities/log-validation-utility/services/service.js b/utilities/log-validation-utility/services/service.js index d6bd91f..edf9add 100644 --- a/utilities/log-validation-utility/services/service.js +++ b/utilities/log-validation-utility/services/service.js @@ -13,12 +13,12 @@ const checkContext = (data, path) => { let errObj = {}; //Transaction ID - UUID Validity check - if (data.transaction_id) { - const result = utils.uuidCheck(data.transaction_id); - if (!result) { - errObj.tId_err = "Transaction id is not a valid uuid"; - } - } + // if (data.transaction_id) { + // const result = utils.uuidCheck(data.transaction_id); + // if (!result) { + // errObj.tId_err = "Transaction id is not a valid uuid"; + // } + // } //Transaction ID != Message ID if (data.transaction_id === data.message_id) { diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index b8c4466..a081585 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -218,19 +218,32 @@ const checkOnSelect = (dirPath, msgIdSet) => { item["@ondc/org/item_id"] in itemsIdList && item["@ondc/org/title_type"] === "item" ) { + // if ( + // itemsIdList[item["@ondc/org/item_id"]] === + // item["@ondc/org/item_quantity"].count || + // (itemsIdList[item["@ondc/org/item_id"]] > + // item["@ondc/org/item_quantity"].count && + // on_select_error && + // on_select_error.type === "DOMAIN-ERROR" && + // on_select_error.code === "400002") + // ) { + // console.log( + // `count of item with id: ${item["@ondc/org/item_id"]} is as per the API contract` + // ); + // } else { + // let cntkey = `cnt${item["@ondc/org/item_id"]}`; + // onSlctObj[ + // cntkey + // ] = `Warning: Count of item with id: ${item["@ondc/org/item_id"]} does not match in ${constants.RET_SELECT} & ${constants.RET_ONSELECT} (suitable domain error should be provided)`; + // } + if ( - itemsIdList[item["@ondc/org/item_id"]] === - item["@ondc/org/item_quantity"].count || - (itemsIdList[item["@ondc/org/item_id"]] > + itemsIdList[item["@ondc/org/item_id"]] != item["@ondc/org/item_quantity"].count && - on_select_error && - on_select_error.type === "DOMAIN-ERROR" && - on_select_error.code === "400002") + (!on_select_error || + on_select_error.type != "DOMAIN-ERROR" || + on_select_error.code != "40002") ) { - console.log( - `count of item with id: ${item["@ondc/org/item_id"]} is as per the API contract` - ); - } else { let cntkey = `cnt${item["@ondc/org/item_id"]}`; onSlctObj[ cntkey diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index 01473f1..1e8a743 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -194,14 +194,6 @@ const checkSelect = (dirPath, msgIdSet) => { if (!gpsLat || !gpsLong) { slctObj.gpsErr = `fulfillments location.gps is not as per the API contract`; } - // else { - // if ( - // utils.countDecimalDigits(gpsLat) != - // utils.countDecimalDigits(gpsLong) - // ) { - // slctObj.gpsErr = `fulfillments GPS Lat/Long Precision should be same `; - // } - // } if (!ff.end.location.address.hasOwnProperty("area_code")) { slctObj.areaCode = `address.area_code is required property in /${constants.RET_SELECT}`; diff --git a/utilities/log-validation-utility/utils/utils.js b/utilities/log-validation-utility/utils/utils.js index 75edf80..1a17faf 100644 --- a/utilities/log-validation-utility/utils/utils.js +++ b/utilities/log-validation-utility/utils/utils.js @@ -166,13 +166,13 @@ const cancellation_rid = { "018": 0, }; -const uuidCheck = (data) => { - console.log("***UUID Validation Utils***"); - let uuid = - /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - if (!uuid.test(data)) return false; - return true; -}; +// const uuidCheck = (data) => { +// console.log("***UUID Validation Utils***"); +// let uuid = +// /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; +// if (!uuid.test(data)) return false; +// return true; +// }; const timestampCheck = (date) => { console.log("***Timestamp Check Utils***"); @@ -207,7 +207,6 @@ const countDecimalDigits = (num) => { }; module.exports = { - uuidCheck, timestampCheck, rootPath, retailAPI, From e5957f83b06cb07b2b71210d2a5e6acfb374c343 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Sun, 23 Apr 2023 22:37:52 +0530 Subject: [PATCH 023/228] on_search catalog checks --- .DS_Store | Bin 0 -> 8196 bytes utilities/.DS_Store | Bin 0 -> 8196 bytes utilities/log-validation-utility/.gitignore | 3 +- .../retail_api_json_schema/SchemaValidator.js | 1 - .../onSearchBPCSchema.js | 610 ------------------ .../onSearchGrocerySchema.js | 490 -------------- .../onSearchSchema copy.js | 583 +++++++++++++++++ .../retail_api_json_schema/onSearchSchema.js | 128 ++-- .../onSearchfashionSchema.js | 490 -------------- .../utils/retail/retConfirm.js | 1 - .../utils/retail/retOnConfirm.js | 13 +- .../utils/retail/retOnInit.js | 11 +- .../utils/retail/retOnSearch.js | 464 ++++++++++++- .../utils/retail/retOnSelect.js | 9 +- .../utils/retail/retSelect.js | 12 +- .../log-validation-utility/utils/utils.js | 55 +- 16 files changed, 1165 insertions(+), 1705 deletions(-) create mode 100644 .DS_Store create mode 100644 utilities/.DS_Store delete mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js delete mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema copy.js delete mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..110fa6c79bec6582f7a18cb356ed248cbdd93a15 GIT binary patch literal 8196 zcmeHMPfrs;6n_IKTM)WZKr~UCG$tMZ3-~95gQY+S@ehO&gaFoUJFOeGGtKT6L_*TD zTur=r@dN15FW@II@upuvk9yKKGh6;_OFSti&P!%~Z)e_b-p;Sh&b}4^NV-}W0T=)P z1Dimz6T2oR=0$6;mS9Bi2=Zah;rX1yb9ikwMC$>qfL1^&pcT*xXa)WS1@O!kW}I;D zt6AM^1+)VHr2^vl5XUAk6<|%Fd~{$ZO8~?+9F~T@eDz0+ivh$`fHj3Uf<_b-QBg@y zVvwM6Ac~IjsUW_lP|< zNt}EAQ<@}p*5jZI912hc2Pk+U*4qYF5nPOC;A1pH-VieF5KH75K9Z{g?!z2R!3;cv z4EDpAvk>BlOh-B0P?4E@%$CRIU?vAF*ulK+aW1(W;znQ*vrNJ?JZPSc?1vaJ@Wi^X zCHo<~vT<(|bLKItjh@(XNFDMcv`PfE@G)921UBf|Qu;k3x9wGe-(BA4Dvs^>$>b-} z(%N?BY`f8JbQ&9(r+ho(TYl9`Tke{;TH@Tv)qN|sY}4(m**nFVZ`q8xl3*7ohO9rb zS%Gh-d6gAB$<3$G_7IuCs*co|Q-`SV?&LSP1=eoM1=J{w(G#2aa>%Y){F>A(h zR(`YOio2cS4tLW|m9CXsyO60^d7G71eEQ7K*w1O!>0mZ|F@Za7wsI`b^eeV>j+XoGrLi@K$W}#eF93ep50fQupf4b>*0lP!7Ju_tw1tNo0vxWg1DOR)P@& zuE7M%!UBHFeAtIq@CM$&2lxn|;VXP6gmjP?=_6OjRgxqlfjf1+)TxTmjNH zotaK!n))#x&M0c_IJPI)go(JCLP^0+mg9)B97jC(!w~&Ah6+w9z?woFLDMe+QU={= J1^%i6zW|D_Fg5@H literal 0 HcmV?d00001 diff --git a/utilities/.DS_Store b/utilities/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6fcbfc147a316916a88c3d045fc32f6c2691787b GIT binary patch literal 8196 zcmeHM&2AGh5FVF8Hx%d=8VG+p|B+JU|DTWtYFZ#mI2GaRt8k=-b*!-RHdjZf4_>c z)8BN_j%#+6rKp+Y`EM%Cz>ng5{sZgT(Yte3pVQ~`I}b~bWlhx z%%8?3{~0g4`@2l<^4gAWabD`%OpP!F-JY9ANqG~9EU_wTI>`O7T zVRYs}ggrhM^TwE%m$>30_V;*GnMG4PjDTDGrymAhg$LuJDC1Z*X1p-;M4cCxm8F`k zD#b*|)lAbqWVM#ul`q&}D7nJzj&RZlF6E4XH~OKDlpsq@3a`Oaxxz%Eap)9Xr8_i5 z3-pX$(kpsRZ|OaKq|fw~^|8b31Utpfv&-xXyT!)XeKyPHm}k6uI#G3O^L5x0^tbiv zcSYV29bq+`MI)#oEmIRQCc9$}{RSd3!WgG;a|E*ExQC4qn1P*-XclM%unbRuh%O_# z;SKFPYIQxryXI3T#m4zIFWL4i1Ai+6JIsw|RQ`YC=imST*5%pzwhUMXet`kjd%bkM z2*b`}z1v6S+F8^&R8^E++n{zqqtkJqPRD_3e;7i}!c_Sb5^NiU2IaSZ2(Zt8&AV;> HZw9^tj<#-p literal 0 HcmV?d00001 diff --git a/utilities/log-validation-utility/.gitignore b/utilities/log-validation-utility/.gitignore index 20d954d..bd7347f 100644 --- a/utilities/log-validation-utility/.gitignore +++ b/utilities/log-validation-utility/.gitignore @@ -11,4 +11,5 @@ dbfiles test.js !README.md !LICENSE.md -*.md \ No newline at end of file +*.md +.DS_Store \ No newline at end of file diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index 6dd23c3..8981d71 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -64,7 +64,6 @@ const validate_schema_search_retail_for_json = (data) => { const validate_schema_on_search_retail_for_json = (data) => { // transformed_item_data = transform_on_search_schema(data); error_list = validate_schema(data, (schema = onSearchSchema)); - console.log(error_list); return formatted_error(error_list); }; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js deleted file mode 100644 index 861155d..0000000 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchBPCSchema.js +++ /dev/null @@ -1,610 +0,0 @@ -module.exports = { - type: "object", - properties: { - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - type: { type: "string" }, - }, - required: ["id"], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - type: { type: "string" }, - }, - required: ["id"], - }, - }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - }, - }, - providers: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", pattern: "^(?!s*$).+" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - code: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - }, - }, - rating: { type: "string" }, - ttl: { type: "string" }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - gps: { type: "string" }, - address: { type: "string" }, - city: { - type: "object", - properties: { - code: { type: "string" }, - name: { type: "string" }, - }, - }, - state: { - type: "object", - properties: { - code: { type: "string" }, - }, - }, - country: { - type: "object", - properties: { - code: { type: "string" }, - }, - }, - area_code: { type: "string" }, - }, - }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string" }, - list: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string" }, - value: { type: "string" }, - }, - }, - }, - }, - }, - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", pattern: "^(?!s*$).+" }, - parent_item_id: { type: "string", pattern: "^(?!s*$).+" }, - descriptor: { - type: "object", - properties: { - name: { type: "string", pattern: "^(?!s*$).+" }, - code: { type: "string", pattern: "^(?!s*$).+" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - media: { - type: "array", - items: { - type: "object", - properties: { - mimetype: { - type: "string", - pattern: "^(?!s*$).+", - }, - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - }, - }, - }, - }, - manufacturer: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - }, - contact: { - type: "object", - properties: { - name: { - type: "string", - }, - address: { - type: "object", - properties: { - full: { - type: "string", - }, - }, - }, - }, - }, - phone: { - type: "string", - pattern: - "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", - }, - }, - }, - price: { - type: "object", - properties: { - currency: { type: "string", pattern: "^(?!s*$).+" }, - value: { type: "string", pattern: "^d*.?d*$" }, - offered_value: { type: "string", pattern: "^d*.?d*$" }, - maximum_value: { type: "string", pattern: "^d*.?d*$" }, - }, - require: ["currency", "value"], - }, - - quantity: { - type: "object", - properties: { - unitized: { - type: "object", - properties: { - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - }, - }, - }, - available: { - type: "object", - properties: { - count: { - type: "string", - pattern: "^d*$", - }, - }, - }, - maximum: { - type: "object", - properties: { - count: { type: "string", pattern: "^d*$" }, - }, - }, - }, - }, - category_ids: { - type: "array", - items: { - type: "string", - minItems: 1, - pattern: "^(?!s*$).+", - }, - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - minItems: 1, - pattern: "^(?!s*$).+", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - payment_ids: { - type: "array", - items: { - type: "string", - enum: ["1", "2"], - }, - }, - "add-ons": { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - code: { - type: "string", - }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - pattern: "^(?!s*$).+", - }, - value: { - type: "string", - pattern: "^d*.?d*$", - }, - offered_value: { - type: "string", - }, - maximum_value: { - type: "string", - }, - }, - }, - }, - }, - }, - cancellation_terms: { - type: "array", - items: { - anyOf: [ - { - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - }, - }, - }, - refund_eligible: { - type: "string", - }, - }, - required: ["fulfillment_state", "refund_eligible"], - }, - { - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - }, - }, - }, - return_policy: { - type: "object", - properties: { - return_eligible: { - type: "string", - }, - return_within: { - type: "string", - }, - fulfillment_managed_by: { - type: "string", - }, - return_location: { - type: "object", - properties: { - address: { - type: "string", - }, - gps: { - type: "string", - }, - }, - }, - }, - required: [ - "return_eligible", - "return_within", - "return_location", - ], - }, - }, - required: ["fulfillment_state", "return_policy"], - }, - ], - }, - minLength: 2, - }, - - replacement_terms: { - type: "array", - items: { - type: "object", - properties: { - replace_within: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["replace_within"], - }, - }, - rating: { type: "string" }, - matched: { type: "string" }, - time: { - type: "object", - properties: { - label: { type: "string" }, - range: { - type: "object", - properties: { - start: { - type: "string", - pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - end: { - type: "string", - pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - }, - }, - }, - }, - recommended: { type: "string" }, - tags: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string" }, - list: { - type: "array", - items: { - type: "object", - properties: { - code: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["code", "value"], - }, - }, - }, - }, - }, - }, - required: [ - "id", - "parent_item_id", - "descriptor", - "manufacturer", - "price", - "quantity", - "category_ids", - "fulfillment_ids", - "location_ids", - "payment_ids", - "cancellation_terms", - "replacement_terms", - "matched", - "recommended", - "tags", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - contact: { - type: "object", - properties: { - phone: { - type: "string", - pattern: - "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", - }, - email: { - type: "string", - pattern: - "^([a-zA-Z0-9_-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$", - }, - }, - }, - }, - }, - }, - - offers: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - code: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - media: { - type: "array", - items: { - type: "object", - properties: { - mimetype: { - type: "string", - pattern: "^(?!s*$).+", - }, - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - }, - }, - }, - }, - time: { - type: "object", - properties: { - label: { type: "string" }, - range: { - type: "object", - properties: { - start: { type: "string" }, - end: { type: "string" }, - }, - }, - }, - }, - item_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - category_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - }, - }, - }, - }, - }, - }, - }, - required: ["fulfillments", "payments", "descriptor", "providers"], -}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js deleted file mode 100644 index 91c4159..0000000 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js +++ /dev/null @@ -1,490 +0,0 @@ -onSearchGrocerySchema = { - "type": "object", - "properties": { - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "payments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "providers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "rating": {"type": "string"}, - "ttl": {"type": "string"}, - "locations": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "gps": {"type": "string"}, - "address": {"type": "string"}, - "city": {"type": "object", - "properties": { - "code": {"type": "string"}, - "name": {"type": "string"}, - } - }, - "state": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "country": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "area_code": {"type": "string"}, - } - } - }, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "value": {"type": "string"}, - } - }} - } - } - }, - "items": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "parent_item_id": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "code": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - }, - }, - "manufacturer": {"type": "object", - "properties": { - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - } - }, - "contact": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "address": { - "type": "object", - "properties": { - "full": { - "type": "string"}, - } - }, - } - }, - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} - } - }, - "price": {"type": "object", - "properties": { - "currency": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "maximum_value": {"type": "string", - "pattern": "^\d*\.?\d*$"} - }, - "require": ["currency", "value"], - }, - - "quantity": {"type": "object", - "properties": { - "unitized": {"type": "object", - "properties": { - "measure": { - "type": "object", - "properties": { - "unit": { - "type": "string"}, - "value": { - "type": "string"} - - } - }, - } - }, - "available": {"type": "object", - "properties": { - "count": { - "type": "string", - "pattern": "^\d*$"} - - } - }, - "maximum": {"type": "object", - "properties": { - "count": {"type": "string", - "pattern": "^\d*$"} - } - }, - } - }, - "category_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "fulfillment_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "payment_ids": {"type": "array", - "items": { - "type": "string", - "enum": ["1", "2"]}}, - "add-ons": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "code": { - "type": "string"}, - "short_desc": { - "type": "string"}, - "long_desc": { - "type": "string"}, - "images": { - "type": "array", - "items": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "url"] - - } - } - } - }, - "price": {"type": "object", - "properties": { - "currency": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "value": { - "type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": { - "type": "string"}, - "maximum_value": { - "type": "string"} - } - }, - } - } - }, - "cancellation_terms": {"type": "array", - "items": {"anyOf": [ - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "refund_eligible": { - "type": "string"}, - }, - "required": [ - "fulfillment_state", - "refund_eligible"] - }, - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "return_policy": { - "type": "object", - "properties": { - "return_eligible": { - "type": "string"}, - "return_within": { - "type": "string"}, - "fulfillment_managed_by": { - "type": "string"}, - "return_location": { - "type": "object", - "properties": { - "address": { - "type": "string"}, - "gps": { - "type": "string"} - } - } - }, - "required": [ - "return_eligible", - "return_within", - "return_location", - ] - } - }, - "required": [ - "fulfillment_state", - "return_policy"] - } - ]}, - "minLength": 2 - }, - - "replacement_terms": {"type": "array", - "items": {"type": "object", - "properties": { - "replace_within": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "replace_within"] - } - }, - "rating": {"type": "string"}, - "matched": {"type": "string"}, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, - "end": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} - } - }, - } - }, - "recommended": {"type": "string"}, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": { - "type": "string"}, - "value": { - "type": "string"}, - }, - "required": [ - "code", - "value"] - } - }, - } - } - } - }, - "required": ["id", "parent_item_id", "descriptor", - "manufacturer", "price", "quantity", - "category_ids", "fulfillment_ids", "location_ids", - "payment_ids", - "cancellation_terms", "replacement_terms", - "matched", "recommended", "tags"], - } - }, - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "contact": {"type": "object", - "properties": { - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, - "email": {"type": "string", - "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} - } - } - }, - } - }, - - "offers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - } - }, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string"}, - "end": {"type": "string"} - } - }, - } - }, - "item_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "category_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - } - } - }, - - }, - - } - }, - - }, - "required": ["fulfillments", "payments", "descriptor", "providers"] - -} diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema copy.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema copy.js new file mode 100644 index 0000000..a7f0aa4 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema copy.js @@ -0,0 +1,583 @@ +const onSearchItemValidations = require("./onSearchItemValidations"); + +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { type: "string" }, + country: { type: "string" }, + city: { type: "string" }, + action: { type: "string" }, + core_version: { type: "string" }, + bap_id: { type: "string" }, + bap_uri: { type: "string" }, + transaction_id: { type: "string" }, + message_id: { type: "string" }, + timestamp: { type: "string", format: "date-time" }, + ttl: { type: "string", format: "duration" }, + bpp_uri: { type: "string" }, + bpp_id: { type: "string" }, + }, + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + "bpp/fulfillments": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { + type: "string", + enum: [ + "Delivery", + "Self-Pickup", + "Delivery and Self-Pickup", + ], + }, + }, + }, + }, + "bpp/descriptor": { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name", "symbol", "long_desc", "short_desc", "images"], + }, + "bpp/providers": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + time: { + type: "object", + properties: { + label: { type: "string", enum: ["enable", "disable"] }, + timestamp: { type: "string", format: "date-time" }, + }, + required: ["label", "timestamp"], + }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "name", + "symbol", + "long_desc", + "short_desc", + "images", + ], + }, + ttl: { type: "string", format: "duration" }, + "@ondc/org/fssai_license_no": { + type: "string", + minLength: 14, + maxLength: 14, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + gps: { type: "string" }, + address: { + type: "object", + properties: { + street: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["street", "city", "area_code", "state"], + }, + + circle: { + type: "object", + properties: { + gps: { + type: "string", + }, + radius: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + }, + }, + }, + time: { + type: "object", + oneOf: [ + { + $ref: "#/components/schemas/fixedTimings", + }, + { + $ref: "#/components/schemas/splitTimings", + }, + ], + }, + }, + required: ["id", "address", "gps", "time"], + }, + }, + items: { + type: "array", + minItems: 1, + items: { + type: "object", + properties: { + id: { type: "string" }, + quantity: { + type: "object", + properties: { + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + }, + }, + category_id: { + type: "string", + enum: [ + "Fruits and Vegetables", + "Masala & Seasoning", + "Oil & Ghee", + "Gourmet & World Foods", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beverages", + "Beauty & Hygiene", + "Bakery, Cakes & Dairy", + "Kitchen Accessories", + "Baby Care", + "Snacks & Branded Foods", + "Pet Care", + "Stationery", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "Home Decor", + "Home Furnishings", + "Furniture", + "Garden and Outdoor Products", + "Home Improvement", + "Cookware and Dining", + "Storage and Organisation", + ], + }, + + // "@ondc/org/fssai_license_no": { + // type: "string", + // pattern: "^[a-zA-Z0-9]+$", + // }, + fulfillment_id: { type: "string" }, + location_id: { type: "string" }, + recommended: { type: "boolean" }, + "@ondc/org/returnable": { + type: "boolean", + }, + "@ondc/org/seller_pickup_return": { + type: "boolean", + }, + "@ondc/org/return_window": { + type: "string", + }, + "@ondc/org/cancellable": { + type: "boolean", + }, + "@ondc/org/time_to_ship": { + type: "string", + format: "duration", + }, + "@ondc/org/available_on_cod": { + type: "boolean", + }, + "@ondc/org/contact_details_consumer_care": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + not: { + type: "string", + pattern: "^0$", + }, + }, + + maximum_value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + not: { type: "string", pattern: "^0$" }, + }, + }, + required: ["value", "maximum_value", "currency"], + }, + tags: { + type: "object", + properties: { + veg: { + type: "string", + enum: ["yes", "no", "Yes", "No"], + }, + non_veg: { + type: "string", + enum: ["yes", "no", "Yes", "No"], + }, + }, + required: ["veg", "non_veg"], + }, + "@ondc/org/statutory_reqs_prepackaged_food": { + type: "object", + properties: { + nutritional_info: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + importer_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + brand_owner_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + other_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + additives_info: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + }, + required: ["nutritional_info", "additives_info"], + anyOf: [ + { + required: ["importer_FSSAI_license_no"], + properties: { + importer_FSSAI_license_no: { + type: "string", + }, + }, + }, + { + required: ["brand_owner_FSSAI_license_no"], + properties: { + brand_owner_FSSAI_license_no: { + type: "string", + }, + }, + }, + { + required: ["other_FSSAI_license_no"], + properties: { + other_FSSAI_license_no: { + type: "string", + }, + }, + }, + ], + }, + "@ondc/org/statutory_reqs_packaged_commodities": { + type: "object", + properties: { + manufacturer_or_packer_name: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + manufacturer_or_packer_address: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + common_or_generic_name_of_commodity: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + net_quantity_or_measure_of_commodity_in_pkg: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + month_year_of_manufacture_packing_import: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + }, + required: [ + "manufacturer_or_packer_name", + "manufacturer_or_packer_address", + "common_or_generic_name_of_commodity", + "month_year_of_manufacture_packing_import", + "net_quantity_or_measure_of_commodity_in_pkg", + ], + }, + "@ondc/org/mandatory_reqs_veggies_fruits": { + type: "object", + properties: { + net_quantity: { + type: "string", + minLength: 1, + }, + }, + required: ["net_quantity"], + }, + + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + minItems: 1, + items: { + type: "string", + }, + }, + }, + }, + }, + + allOf: onSearchItemValidations.onSearchRules, + required: [ + "id", + "category_id", + "@ondc/org/contact_details_consumer_care", + "price", + "descriptor", + "@ondc/org/returnable", + "location_id", + "fulfillment_id", + "@ondc/org/cancellable", + "@ondc/org/available_on_cod", + "@ondc/org/time_to_ship", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + minLength: 10, + maxLength: 11, + }, + email: { type: "string", format: "email" }, + }, + required: ["phone"], + }, + }, + required: ["contact"], + }, + }, + + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string", const: "serviceability" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "location", + "category", + "type", + "val", + "unit", + ], + }, + value: { type: "string" }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + }, + }, + required: [ + "items", + "id", + "time", + "descriptor", + "locations", + "fulfillments", + "tags", + "ttl", + ], + }, + }, + }, + required: ["bpp/fulfillments", "bpp/descriptor", "bpp/providers"], + }, + }, + required: ["catalog"], + }, + }, + required: ["context", "message"], + components: { + schemas: { + fixedTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + additionalProperties: false, + }, + }, + required: ["days", "range", "schedule"], + }, + splitTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays", "frequency", "times"], + }, + }, + required: ["days", "schedule"], + additionalProperties: false, + }, + }, + }, +}; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index a7f0aa4..fb54338 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -149,14 +149,51 @@ module.exports = { }, time: { type: "object", - oneOf: [ - { - $ref: "#/components/schemas/fixedTimings", + + properties: { + days: { + type: "string", }, - { - $ref: "#/components/schemas/splitTimings", + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], }, - ], + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + }, + required: ["days", "schedule"], }, }, required: ["id", "address", "gps", "time"], @@ -231,10 +268,6 @@ module.exports = { ], }, - // "@ondc/org/fssai_license_no": { - // type: "string", - // pattern: "^[a-zA-Z0-9]+$", - // }, fulfillment_id: { type: "string" }, location_id: { type: "string" }, recommended: { type: "boolean" }, @@ -505,79 +538,4 @@ module.exports = { }, }, required: ["context", "message"], - components: { - schemas: { - fixedTimings: { - type: "object", - properties: { - days: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - minLength: 4, - maxLength: 4, - }, - end: { - type: "string", - minLength: 4, - maxLength: 4, - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays"], - additionalProperties: false, - }, - }, - required: ["days", "range", "schedule"], - }, - splitTimings: { - type: "object", - properties: { - days: { - type: "string", - }, - - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - frequency: { - type: "string", - format: "duration", - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays", "frequency", "times"], - }, - }, - required: ["days", "schedule"], - additionalProperties: false, - }, - }, - }, }; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js deleted file mode 100644 index 599fb81..0000000 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchfashionSchema.js +++ /dev/null @@ -1,490 +0,0 @@ -onSearchFashionSchema = { - "type": "object", - "properties": { - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "payments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "providers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "rating": {"type": "string"}, - "ttl": {"type": "string"}, - "locations": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "gps": {"type": "string"}, - "address": {"type": "string"}, - "city": {"type": "object", - "properties": { - "code": {"type": "string"}, - "name": {"type": "string"}, - } - }, - "state": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "country": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "area_code": {"type": "string"}, - } - } - }, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "value": {"type": "string"}, - } - }} - } - } - }, - "items": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "parent_item_id": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "code": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - }, - }, - "manufacturer": {"type": "object", - "properties": { - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - } - }, - "contact": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "address": { - "type": "object", - "properties": { - "full": { - "type": "string"}, - } - }, - } - }, - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} - } - }, - "price": {"type": "object", - "properties": { - "currency": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "maximum_value": {"type": "string", - "pattern": "^\d*\.?\d*$"} - }, - "require": ["currency", "value"], - }, - - "quantity": {"type": "object", - "properties": { - "unitized": {"type": "object", - "properties": { - "measure": { - "type": "object", - "properties": { - "unit": { - "type": "string"}, - "value": { - "type": "string"} - - } - }, - } - }, - "available": {"type": "object", - "properties": { - "count": { - "type": "string", - "pattern": "^\d*$"} - - } - }, - "maximum": {"type": "object", - "properties": { - "count": {"type": "string", - "pattern": "^\d*$"} - } - }, - } - }, - "category_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "fulfillment_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "payment_ids": {"type": "array", - "items": { - "type": "string", - "enum": ["1", "2"]}}, - "add-ons": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "code": { - "type": "string"}, - "short_desc": { - "type": "string"}, - "long_desc": { - "type": "string"}, - "images": { - "type": "array", - "items": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "url"] - - } - } - } - }, - "price": {"type": "object", - "properties": { - "currency": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "value": { - "type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": { - "type": "string"}, - "maximum_value": { - "type": "string"} - } - }, - } - } - }, - "cancellation_terms": {"type": "array", - "items": {"anyOf": [ - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "refund_eligible": { - "type": "string"}, - }, - "required": [ - "fulfillment_state", - "refund_eligible"] - }, - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "return_policy": { - "type": "object", - "properties": { - "return_eligible": { - "type": "string"}, - "return_within": { - "type": "string"}, - "fulfillment_managed_by": { - "type": "string"}, - "return_location": { - "type": "object", - "properties": { - "address": { - "type": "string"}, - "gps": { - "type": "string"} - } - } - }, - "required": [ - "return_eligible", - "return_within", - "return_location", - ] - } - }, - "required": [ - "fulfillment_state", - "return_policy"] - } - ]}, - "minLength": 2 - }, - - "replacement_terms": {"type": "array", - "items": {"type": "object", - "properties": { - "replace_within": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "replace_within"] - } - }, - "rating": {"type": "string"}, - "matched": {"type": "string"}, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, - "end": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} - } - }, - } - }, - "recommended": {"type": "string"}, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": { - "type": "string"}, - "value": { - "type": "string"}, - }, - "required": [ - "code", - "value"] - } - }, - } - } - } - }, - "required": ["id", "parent_item_id", "descriptor", - "manufacturer", "price", "quantity", - "category_ids", "fulfillment_ids", "location_ids", - "payment_ids", - "cancellation_terms", "replacement_terms", - "matched", "recommended", "tags"], - } - }, - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "contact": {"type": "object", - "properties": { - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, - "email": {"type": "string", - "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} - } - } - }, - } - }, - - "offers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - } - }, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string"}, - "end": {"type": "string"} - } - }, - } - }, - "item_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "category_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - } - } - }, - - }, - - } - }, - - }, - "required": ["fulfillments", "payments", "descriptor", "providers"] - -} diff --git a/utilities/log-validation-utility/utils/retail/retConfirm.js b/utilities/log-validation-utility/utils/retail/retConfirm.js index 93294bd..3fa3251 100644 --- a/utilities/log-validation-utility/utils/retail/retConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retConfirm.js @@ -323,7 +323,6 @@ const checkConfirm = (dirPath, msgIdSet) => { console.log( `Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` ); - console.log("confirm quote", confirm.quote); if (!_.isEqual(dao.getValue("quoteObj"), confirm.quote)) { cnfrmObj.quoteObj = `Discrepancies between the quote object in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`; } diff --git a/utilities/log-validation-utility/utils/retail/retOnConfirm.js b/utilities/log-validation-utility/utils/retail/retOnConfirm.js index 317ec21..4c7e056 100644 --- a/utilities/log-validation-utility/utils/retail/retOnConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retOnConfirm.js @@ -60,11 +60,18 @@ const checkOnConfirm = (dirPath, msgIdSet) => { console.log( `Comparing timestamp of /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` ); - if (_.gte(dao.getValue("tmpstmp"), on_confirm.context.timestamp)) { + const tmpstmp = dao.getValue("tmpstmp"); + if (_.gte(tmpstmp, on_confirm.context.timestamp)) { onCnfrmObj.tmpstmp = `Timestamp for /${constants.RET_CONFIRM} api cannot be greater than or equal to /${constants.RET_ONCONFIRM} api`; + } else { + const timeDiff = utils.timeDiff(on_confirm.context.timestamp, tmpstmp); + console.log(timeDiff); + if (timeDiff > 5000) { + onCnfrmObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONCONFIRM} and /${constants.RET_CONFIRM} should be smaller than 5 sec`; + } } - tmpstmp = on_confirm.context.timestamp; - dao.setValue("tmpstmp", tmpstmp); + + dao.setValue("tmpstmp", on_confirm.context.timestamp); } catch (error) { console.log( `Error while comparing timestamp for /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM} api`, diff --git a/utilities/log-validation-utility/utils/retail/retOnInit.js b/utilities/log-validation-utility/utils/retail/retOnInit.js index 233bba4..32b22ab 100644 --- a/utilities/log-validation-utility/utils/retail/retOnInit.js +++ b/utilities/log-validation-utility/utils/retail/retOnInit.js @@ -2,6 +2,7 @@ const fs = require("fs"); const _ = require("lodash"); const { checkContext } = require("../../services/service"); const dao = require("../../dao/dao"); +const utils = require("../utils"); const validateSchema = require("../schemaValidation"); const constants = require("../constants"); @@ -58,9 +59,17 @@ const checkOnInit = (dirPath, msgIdSet) => { console.log( `Comparing timestamp of ${constants.RET_INIT} & ${constants.RET_ONINIT}` ); - if (_.gte(dao.getValue("tmpstmp"), on_init.context.timestamp)) { + const tmpstmp = dao.getValue("tmpstmp"); + if (_.gte(tmpstmp, on_init.context.timestamp)) { onInitObj.tmpstmp = `Timestamp for ${constants.RET_INIT} api cannot be greater than or equal to ${constants.RET_ONINIT} api`; + } else { + const timeDiff = utils.timeDiff(on_init.context.timestamp, tmpstmp); + console.log(timeDiff); + if (timeDiff > 5000) { + onInitObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONINIT} and /${constants.RET_INIT} should be smaller than 5 sec`; + } } + dao.setValue("tmpstmp", on_init.context.timestamp); } catch (error) { console.log( diff --git a/utilities/log-validation-utility/utils/retail/retOnSearch.js b/utilities/log-validation-utility/utils/retail/retOnSearch.js index 7c0bde1..b21b8b8 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSearch.js +++ b/utilities/log-validation-utility/utils/retail/retOnSearch.js @@ -2,6 +2,7 @@ const fs = require("fs"); const _ = require("lodash"); const dao = require("../../dao/dao"); const constants = require("../constants"); +const utils = require("../utils"); const { checkContext } = require("../../services/service"); const validateSchema = require("../schemaValidation"); @@ -67,9 +68,17 @@ const checkOnSearch = (dirPath, msgIdSet) => { console.log( `Comparing timestamp of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` ); - if (_.gte(dao.getValue("tmpstmp"), onSearch.context.timestamp)) { + const tmpstmp = dao.getValue("tmpstmp"); + if (_.gte(tmpstmp, onSearch.context.timestamp)) { onSrchObj.tmpstmp = `Context timestamp for /${constants.RET_SEARCH} api cannot be greater than or equal to /${constants.RET_ONSEARCH} api`; + } else { + const timeDiff = utils.timeDiff(onSearch.context.timestamp, tmpstmp); + console.log(timeDiff); + if (timeDiff > 5000) { + onSrchObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONSEARCH} and /${constants.RET_SEARCH} should be smaller than 5 sec`; + } } + dao.setValue("tmpstmp", onSearch.context.timestamp); } catch (error) { console.log( @@ -108,12 +117,455 @@ const checkOnSearch = (dirPath, msgIdSet) => { } onSearch = onSearch.message.catalog; - // console.log(onSearch["bpp/providers"]); - dao.setValue("onSearch", onSearch); + let onSearchFFIds = new Set(); + let prvdrsId = new Set(); + + try { + console.log( + `Saving static fulfillment ids in /${constants.RET_ONSEARCH}` + ); + + let i = 0; + const bppFF = onSearch["bpp/fulfillments"]; + const len = bppFF.length; + while (i < len) { + onSearchFFIds.add(bppFF[i].id); + i++; + } + } catch (error) { + console.log( + `Error while saving static fulfillment ids in /${constants.RET_ONSEARCH}`, + error + ); + } + + try { + console.log( + `Checking Providers info (bpp/providers) in /${constants.RET_ONSEARCH}` + ); + let i = 0; + const bppPrvdrs = onSearch["bpp/providers"]; + const len = bppPrvdrs.length; + const tmpstmp = dao.getValue("tmpstmp"); + while (i < len) { + let itemsId = new Set(); + let prvdrLocId = new Set(); + let ctgryId = new Set(); + + console.log( + `Validating uniqueness for provider id in bpp/providers[${i}]...` + ); + let prvdr = bppPrvdrs[i]; + + if (prvdrsId.has(prvdr.id)) { + const key = `prvdr${i}id`; + onSrchObj[ + key + ] = `duplicate provider id: ${prvdr.id} in bpp/providers`; + } else { + prvdrsId.add(prvdr.id); + } + + console.log( + `Checking store enable/disable timestamp in bpp/providers[${i}]` + ); + if (!_.isEqual(prvdr.time.timestamp, tmpstmp)) { + onSrchObj.storeEnblDsbl = `store enable/disable timestamp (/bpp/providers/time/timestamp) must match context.timestamp`; + } + console.log(`Checking store timings in bpp/providers[${i}]`); + + prvdr.locations.forEach((loc, iter) => { + if (prvdrLocId.has(loc.id)) { + const key = `prvdr${i}${loc.id}${iter}`; + onSrchObj[ + key + ] = `duplicate location id: ${loc.id} in /bpp/providers[${i}]/locations[${iter}]`; + } else { + prvdrLocId.add(loc.id); + } + + console.log("Checking store days..."); + const days = loc.time.days.split(","); + days.forEach((day) => { + day = parseInt(day); + if (isNaN(day) || day < 1 || day > 7) { + const key = `prvdr${i}locdays${iter}`; + onSrchObj[ + key + ] = `store days (bpp/providers[${i}]/locations[${iter}]/time/days) should be in the format ("1,2,3,4,5,6,7") where 1- Monday and 7- Sunday`; + } + }); + + console.log("Checking fixed or split timings"); + //scenario 1: range =1 freq/times =1 + if ( + loc.time.range && + (loc.time.schedule.frequency || loc.time.schedule.times) + ) { + const key = `prvdr${i}loctime${iter}`; + onSrchObj[ + key + ] = `Either one of fixed (range) or split (frequency and times) timings should be provided in /bpp/providers[${i}]/locations[${iter}]/time`; + } + // scenario 2: range=0 freq || times =1 + if ( + !loc.time.range && + (!loc.time.schedule.frequency || !loc.time.schedule.times) + ) { + const key = `prvdr${i}loctime${iter}`; + onSrchObj[ + key + ] = `Either one of fixed timings (range) or split timings (both frequency and times) should be provided in /bpp/providers[${i}]/locations[${iter}]/time`; + } + + //scenario 3: range=1 (start and end not compliant) frequency=0; + if ("range" in loc.time) { + console.log("checking range (fixed timings) start and end"); + const startTime = + "start" in loc.time.range ? parseInt(loc.time.range.start) : ""; + const endTime = + "end" in loc.time.range ? parseInt(loc.time.range.end) : ""; + if ( + isNaN(startTime) || + isNaN(endTime) || + startTime > endTime || + endTime > 2359 + ) { + onSrchObj.startEndTime = `end time must be greater than start time in fixed timings /locations/time/range (fixed store timings)`; + } + } + }); + + try { + console.log( + `Checking items for provider (${prvdr.id}) in bpp/providers[${i}]` + ); + let j = 0; + const items = onSearch["bpp/providers"][i]["items"]; + const iLen = items.length; + while (j < iLen) { + console.log( + `Validating uniqueness for item id in bpp/providers[${i}].items[${j}]...` + ); + let item = items[j]; + + if (itemsId.has(item.id)) { + const key = `prvdr${i}item${j}`; + onSrchObj[ + key + ] = `duplicate item id: ${item.id} in bpp/providers[${i}]`; + } else { + itemsId.add(item.id); + } + + console.log( + `Checking available and maximum count for item id: ${item.id}` + ); + if ("available" in item.quantity && "maximum" in item.quantity) { + const avlblCnt = parseInt(item.quantity.available.count); + const mxCnt = parseInt(item.quantity.maximum.count); + + if (avlblCnt > mxCnt) { + const key = `prvdr${i}item${j}Cnt`; + onSrchObj[ + key + ] = `available count of item should be smaller or equal to the maximum count (/bpp/providers[${i}]/items[${j}]/quantity)`; + } + } + + console.log( + `Checking selling price and maximum price for item id: ${item.id}` + ); + + if ("price" in item) { + const sPrice = parseFloat(item.price.value); + const maxPrice = parseFloat(item.price.maximum_value); - // try { - // console.log("Checking available and max count in on_search catalog"); - // } catch (error) {} + if (sPrice > maxPrice) { + const key = `prvdr${i}item${j}Price`; + onSrchObj[ + key + ] = `selling price of item /price/value with id: (${item.id}) can't be greater than the maximum price /price/maximum_value in /bpp/providers[${i}]/items[${j}]/`; + } + } + + console.log(`Checking category_id for item id: ${item.id}`); + if ("category_id" in item) { + ctgryId.add(item.category_id); + } + + console.log(`Checking fulfillment_id for item id: ${item.id}`); + + if (!onSearchFFIds.has(item.fulfillment_id)) { + const key = `prvdr${i}item${j}ff`; + onSrchObj[ + key + ] = `fulfillment_id in /bpp/providers[${i}]/items[${j}] should map to one of the fulfillments id in bpp/fulfillments`; + } + + console.log(`Checking location_id for item id: ${item.id}`); + + if (!prvdrLocId.has(item.location_id)) { + const key = `prvdr${i}item${j}loc`; + onSrchObj[ + key + ] = `location_id in /bpp/providers[${i}]/items[${j}] should be one of the locations id in /bpp/providers[${i}]/locations`; + } + + console.log( + `Checking consumer care details for item id: ${item.id}` + ); + if ("@ondc/org/contact_details_consumer_care" in item) { + let consCare = item["@ondc/org/contact_details_consumer_care"]; + consCare = consCare.split(","); + checkEmail = utils.emailRegex(consCare[1].trim()); + if (isNaN(consCare[2].trim()) || !checkEmail) { + const key = `prvdr${i}consCare`; + onSrchObj[ + key + ] = `@ondc/org/contact_details_consumer_care should be in the format "name,email,contactno" in /bpp/providers[${i}]/items`; + } + } + j++; + } + } catch (error) { + console.log( + `!!Errors while checking items in bpp/providers[${i}]`, + error + ); + } + + try { + console.log( + `Checking serviceability construct for bpp/providers[${i}]` + ); + + const tags = onSearch["bpp/providers"][i]["tags"]; + //checking for each serviceability construct + tags.forEach((sc, t) => { + if ("list" in sc) { + if (sc.list.length != 5) { + const key = `prvdr${i}tags${t}`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract`; + } + + //checking location + const loc = + sc.list.find((elem) => elem.code === "location") || ""; + if (!loc) { + const key = `prvdr${i}tags${t}loc`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (location is missing)`; + } else { + if ("value" in loc) { + if (!prvdrLocId.has(loc.value)) { + const key = `prvdr${i}tags${t}loc`; + onSrchObj[ + key + ] = `location in serviceability construct should be one of the location ids bpp/providers[${i}]/locations`; + } + } else { + const key = `prvdr${i}tags${t}loc`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (location is missing)`; + } + } + + //checking category + const ctgry = + sc.list.find((elem) => elem.code === "category") || ""; + if (!ctgry) { + const key = `prvdr${i}tags${t}ctgry`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (category is missing)`; + } else { + if ("value" in ctgry) { + if (!ctgryId.has(ctgry.value)) { + const key = `prvdr${i}tags${t}ctgry`; + onSrchObj[ + key + ] = `category in serviceability construct should be one of the category ids bpp/providers[${i}]/items/category_id`; + } + } else { + const key = `prvdr${i}tags${t}ctgry`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (category is missing)`; + } + } + + //checking type (hyperlocal, intercity or PAN India) + const type = sc.list.find((elem) => elem.code === "type") || ""; + if (!type) { + const key = `prvdr${i}tags${t}type`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (type is missing)`; + } else { + if ("value" in type) { + switch (type.value) { + case "10": + { + //For hyperlocal + + //checking value + const val = + sc.list.find((elem) => elem.code === "val") || ""; + if ("value" in val) { + if (isNaN(val.value)) { + const key = `prvdr${i}tags${t}valvalue`; + onSrchObj[ + key + ] = `value should be a number (code:"val") for type 10 (hyperlocal) in /bpp/providers[${i}]/tags[${t}]`; + } + } else { + const key = `prvdr${i}tags${t}val`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (value is missing for code "val")`; + } + + //checking unit + const unit = + sc.list.find((elem) => elem.code === "unit") || ""; + if ("value" in unit) { + if (unit.value != "km") { + const key = `prvdr${i}tags${t}unitvalue`; + onSrchObj[ + key + ] = `value should be "km" (code:"unit") for type 10 (hyperlocal) in /bpp/providers[${i}]/tags[${t}]`; + } + } else { + const key = `prvdr${i}tags${t}unit`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (value is missing for code "unit")`; + } + } + + break; + case "11": + { + //intercity + + //checking value + const val = + sc.list.find((elem) => elem.code === "val") || ""; + if ("value" in val) { + const pincodes = val.value.split(/,|-/); + pincodes.forEach((pincode) => { + if (isNaN(pincode) || pincode.length != 6) { + const key = `prvdr${i}tags${t}valvalue`; + onSrchObj[ + key + ] = `value should be a valid range of pincodes (code:"val") for type 11 (intercity) in /bpp/providers[${i}]/tags[${t}]`; + } + }); + } else { + const key = `prvdr${i}tags${t}val`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (value is missing for code "val")`; + } + + //checking unit + const unit = + sc.list.find((elem) => elem.code === "unit") || ""; + if ("value" in unit) { + if (unit.value != "pincode") { + const key = `prvdr${i}tags${t}unitvalue`; + onSrchObj[ + key + ] = `value should be "pincode" (code:"unit") for type 11 (intercity) in /bpp/providers[${i}]/tags[${t}]`; + } + } else { + const key = `prvdr${i}tags${t}unit`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (value is missing for code "unit")`; + } + } + + break; + case "12": + { + //PAN India + + //checking value + const val = + sc.list.find((elem) => elem.code === "val") || ""; + if ("value" in val) { + if (val.value != "IND") { + const key = `prvdr${i}tags${t}valvalue`; + onSrchObj[ + key + ] = `value should be "IND" (code:"val") for type 12 (PAN India) in /bpp/providers[${i}]tags[${t}]`; + } + } else { + const key = `prvdr${i}tags${t}val`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (value is missing for code "val")`; + } + + //checking unit + const unit = + sc.list.find((elem) => elem.code === "unit") || ""; + if ("value" in unit) { + if (unit.value != "country") { + const key = `prvdr${i}tags${t}unitvalue`; + onSrchObj[ + key + ] = `value should be "country" (code:"unit") for type 12 (PAN India) in /bpp/providers[${i}]tags[${t}]`; + } + } else { + const key = `prvdr${i}tags${t}unit`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (value is missing for code "unit")`; + } + } + + break; + default: { + const key = `prvdr${i}tags${t}type`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (invalid type "${type.value}")`; + } + } + } else { + const key = `prvdr${i}tags${t}type`; + onSrchObj[ + key + ] = `serviceability construct /bpp/providers[${i}]/tags[${t}] should be defined as per the API contract (type is missing)`; + } + } + } + }); + } catch (error) { + console.log( + `!!Error while checking serviceability construct for bpp/providers[${i}]`, + error + ); + } + + i++; + } + } catch (error) { + console.log( + `!!Error while checking Providers info in /${constants.RET_ONSEARCH}`, + error + ); + } + + dao.setValue("onSearch", onSearch); + console.log(onSrchObj); dao.setValue("onSrchObj", onSrchObj); } catch (err) { if (err.code === "ENOENT") { diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index a081585..d5a6ee0 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -57,8 +57,15 @@ const checkOnSelect = (dirPath, msgIdSet) => { console.log( `Comparing timestamp of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` ); - if (_.gte(dao.getValue("tmpstmp"), on_select.context.timestamp)) { + const tmpstmp = dao.getValue("tmpstmp"); + if (_.gte(tmpstmp, on_select.context.timestamp)) { onSlctObj.tmpstmp = `Timestamp for /${constants.RET_SELECT} api cannot be greater than or equal to /${constants.RET_ONSELECT} api`; + } else { + const timeDiff = utils.timeDiff(on_select.context.timestamp, tmpstmp); + console.log(timeDiff); + if (timeDiff > 5000) { + onSlctObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONSELECT} and /${constants.RET_SELECT} should be smaller than 5 sec`; + } } dao.setValue("tmpstmp", on_select.context.timestamp); } catch (error) { diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index 1e8a743..7c2ef77 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -105,12 +105,12 @@ const checkSelect = (dirPath, msgIdSet) => { ); } - let order = select.message.order; + let select = select.message.order; let onSearch = dao.getValue("onSearch"); let provider = onSearch["bpp/providers"].filter( - (provider) => provider.id === order.provider.id + (provider) => provider.id === select.provider.id ); if (provider[0]) { @@ -122,7 +122,7 @@ const checkSelect = (dirPath, msgIdSet) => { console.log( `Comparing provider location in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` ); - if (provider.locations[0].id != order.provider.locations[0].id) { + if (provider.locations[0].id != select.provider.locations[0].id) { slctObj.prvdLoc = `provider.locations[0].id ${provider.locations[0].id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; } } catch (error) { @@ -136,7 +136,7 @@ const checkSelect = (dirPath, msgIdSet) => { `Mapping Item Ids with their counts, categories and prices /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` ); try { - order.items.forEach((item) => { + select.items.forEach((item) => { let itemOnSearch = provider.items.find((it) => it.id === item.id); if (!itemOnSearch) { @@ -177,11 +177,11 @@ const checkSelect = (dirPath, msgIdSet) => { console.log( `Provider Ids in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} mismatch` ); - slctObj.prvdrIdMatch = `Provider Id ${order.provider.id} in /${constants.RET_SELECT} does not exist in /${constants.RET_ONSEARCH}`; + slctObj.prvdrIdMatch = `Provider Id ${select.provider.id} in /${constants.RET_SELECT} does not exist in /${constants.RET_ONSEARCH}`; } try { - order.fulfillments.forEach((ff, indx) => { + select.fulfillments.forEach((ff, indx) => { console.log(`Checking GPS Precision in /${constants.RET_SELECT}`); if (ff.hasOwnProperty("end")) { diff --git a/utilities/log-validation-utility/utils/utils.js b/utilities/log-validation-utility/utils/utils.js index 1a17faf..62198ca 100644 --- a/utilities/log-validation-utility/utils/utils.js +++ b/utilities/log-validation-utility/utils/utils.js @@ -94,15 +94,6 @@ const logOrderState = [ ]; const bpp_fulfillments = ["Delivery", "Pickup", "Delivery and Pickup"]; //id =1,2,3 -const bpp_provider_days = [ - "1", - "1,2", - "1,2,3", - "1,2,3,4", - "1,2,3,4,5", - "1,2,3,4,5,6", - "1,2,3,4,5,6,7", -]; const grocery_categories_id = [ "Fruits and Vegetables", @@ -206,6 +197,48 @@ const countDecimalDigits = (num) => { return num.toString().split(".")[1].length; }; +const emailRegex = (email) => { + const emailRE = /^\S+@\S+\.\S+$/; + return emailRE.test(email); +}; + +const timeDiff = (time1, time2) => { + const dtime1 = new Date(time1); + const dtime2 = new Date(time2); + + if (isNaN(dtime1 - dtime2)) return 0; + else return dtime1 - dtime2; +}; + +const isoDurToSec = (duration) => { + let durRE = + /P((\d+)Y)?((\d+)M)?((\d+)W)?((\d+)D)?T?((\d+)H)?((\d+)M)?((\d+)S)?/; + + const splitTime = durRE.exec(duration); + if (!splitTime) { + return 0; + } + + const years = Number(splitTime?.[2]) || 0; + const months = Number(splitTime?.[4]) || 0; + const weeks = Number(splitTime?.[6]) || 0; + const days = Number(splitTime?.[8]) || 0; + const hours = Number(splitTime?.[10]) || 0; + const minutes = Number(splitTime?.[12]) || 0; + const seconds = Number(splitTime?.[14]) || 0; + + const result = + years * 31536000 + + months * 2628288 + + weeks * 604800 + + days * 86400 + + hours * 3600 + + minutes * 60 + + seconds; + + return result; +}; + module.exports = { timestampCheck, rootPath, @@ -215,7 +248,6 @@ module.exports = { logFulfillmentState, logOrderState, bpp_fulfillments, - bpp_provider_days, cancellation_rid, getObjValues, retailPaymentType, @@ -225,4 +257,7 @@ module.exports = { countDecimalDigits, grocery_categories_id, fnb_categories_id, + emailRegex, + isoDurToSec, + timeDiff, }; From 3bd5088a2d87cd730f803a1b0e6199b4757f9eea Mon Sep 17 00:00:00 2001 From: bluecypher Date: Wed, 26 Apr 2023 11:05:15 +0530 Subject: [PATCH 024/228] bug fixes --- .DS_Store | Bin 8196 -> 8196 bytes utilities/.DS_Store | Bin 8196 -> 8196 bytes .../utils/retail/retConfirm.js | 2 +- .../utils/retail/retSelect.js | 4 ++-- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.DS_Store b/.DS_Store index 110fa6c79bec6582f7a18cb356ed248cbdd93a15..cfdbbaa11ac429762756bd53e8d9b1d566b99133 100644 GIT binary patch delta 76 zcmZp1XmOa}&&azmU^hP_?_?eUZB7;jJ%)6KOoo!l7X*)s!g*!EMR_^-dFc!c42+vi Z1guy#7H?$Q%r5bbWwNM96;3d>O(RvKguvCNj)rSkJJV;RM57 zhW8AA8QB>H7?l{c8BG{%8SNQ87y}uD7?T-O7&94*AO$S?Oy&d&=dN-fJwEsw|q zvV$|LQYY^cR#V~-VL%0poFRFMxv8AW4gnB}$=o7}=8}v`jM|JQjJAySj2?`hj8Tly tj0ud15EV>}P$Oi}jLMoUBWSRBsz?#@#0Kuo>=NHtHgkynXPVf+0RU!JBv1eV diff --git a/utilities/log-validation-utility/utils/retail/retConfirm.js b/utilities/log-validation-utility/utils/retail/retConfirm.js index 3fa3251..4699a0a 100644 --- a/utilities/log-validation-utility/utils/retail/retConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retConfirm.js @@ -8,7 +8,7 @@ const validateSchema = require("../schemaValidation"); const checkConfirm = (dirPath, msgIdSet) => { let cnfrmObj = {}; try { - var confirm = fs.readFileSync(dirPath + `/${constants.RET_CONFIRM}.json`); + let confirm = fs.readFileSync(dirPath + `/${constants.RET_CONFIRM}.json`); confirm = JSON.parse(confirm); try { diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index 7c2ef77..2b262c7 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -16,7 +16,7 @@ const checkSelect = (dirPath, msgIdSet) => { let slctObj = {}; try { - select = fs.readFileSync(dirPath + `/${constants.RET_SELECT}.json`); //testing + let select = fs.readFileSync(dirPath + `/${constants.RET_SELECT}.json`); //testing select = JSON.parse(select); try { console.log(`Validating Schema for ${constants.RET_SELECT} API`); @@ -105,7 +105,7 @@ const checkSelect = (dirPath, msgIdSet) => { ); } - let select = select.message.order; + select = select.message.order; let onSearch = dao.getValue("onSearch"); From ba30e57e6adf4c7fc774d500e2b79a7bfae7b9db Mon Sep 17 00:00:00 2001 From: bluecypher Date: Thu, 27 Apr 2023 17:52:13 +0530 Subject: [PATCH 025/228] bug fixes --- .../onSearchItemValidations.js | 100 ++++++++---------- .../utils/retail/retOnSearch.js | 27 +++++ 2 files changed, 72 insertions(+), 55 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js index 50f730b..6b26d90 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js @@ -1,65 +1,55 @@ onSearchRules = [ // { - // if: { properties: { "@ondc/org/returnable": { const: false } } }, + // if: { + // properties: { + // category_id: { + // enum: [ + // "F&B", + // "Continental", + // "Middle Eastern", + // "North Indian", + // "Pan-Asian", + // "Regional Indian", + // "South Indian", + // "Tex-Mexican", + // "World Cuisines", + // "Healthy Food", + // "Fast Food", + // "Desserts", + // "Bakes & Cakes", + // "Beverages (MTO)", + // ], + // }, + // }, + // }, // then: { - // not: { - // required: ["@ondc/org/return_window"], - // errorMessage: "return window is available when returnable is false", + // required: ["@ondc/org/fssai_license_no"], + // }, + // }, + // { + // if: { + // properties: { + // category_id: { + // enum: [ + // "Gourmet & World Foods", + // "Beverages", + // "Bakery, Cakes & Dairy", + // "Snacks & Branded Foods", + // ], + // }, // }, // }, + // then: { + // required: ["@ondc/org/fssai_license_no"], + // }, // }, - { - if: { - properties: { - category_id: { - enum: [ - "F&B", - "Continental", - "Middle Eastern", - "North Indian", - "Pan-Asian", - "Regional Indian", - "South Indian", - "Tex-Mexican", - "World Cuisines", - "Healthy Food", - "Fast Food", - "Desserts", - "Bakes & Cakes", - "Beverages (MTO)", - ], - }, - }, - }, - then: { - required: ["@ondc/org/fssai_license_no"], - }, - }, - { - if: { - properties: { - category_id: { - enum: [ - "Gourmet & World Foods", - "Beverages", - "Bakery, Cakes & Dairy", - "Snacks & Branded Foods", - ], - }, - }, - }, - then: { - required: ["@ondc/org/fssai_license_no"], - }, - }, - - { - if: { properties: { "@ondc/org/returnable": { const: false } } }, - then: { - required: ["@ondc/org/return_window"], - }, - }, + // { + // if: { properties: { "@ondc/org/returnable": { const: false } } }, + // then: { + // required: ["@ondc/org/return_window"], + // }, + // }, { if: { diff --git a/utilities/log-validation-utility/utils/retail/retOnSearch.js b/utilities/log-validation-utility/utils/retail/retOnSearch.js index b21b8b8..97c1eda 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSearch.js +++ b/utilities/log-validation-utility/utils/retail/retOnSearch.js @@ -292,6 +292,33 @@ const checkOnSearch = (dirPath, msgIdSet) => { console.log(`Checking category_id for item id: ${item.id}`); if ("category_id" in item) { ctgryId.add(item.category_id); + const categoryList = [ + "F&B", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ]; + try { + if (categoryList.includes(item.category_id)) { + if (!prvdr["@ondc/org/fssai_license_no"]) { + onSrchObj.fssaiLiceNo = `@ondc/org/fssai_license_no is mandatory for category_id ${item.category_id}`; + } + } + } catch (error) {} } console.log(`Checking fulfillment_id for item id: ${item.id}`); From 1c315d7e6ea10c80af82ad52e51b2e76f2946036 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Tue, 13 Jun 2023 11:40:48 +0530 Subject: [PATCH 026/228] Log Validation Utility v1.1.0 --- .DS_Store | Bin 8196 -> 8196 bytes utilities/.DS_Store | Bin 8196 -> 8196 bytes utilities/log-validation-utility/.gitignore | 5 +- utilities/log-validation-utility/README.md | 62 +- utilities/log-validation-utility/dao/dao.js | 5 +- utilities/log-validation-utility/index.js | 16 +- utilities/log-validation-utility/package.json | 4 +- .../retail_api_json_schema/SchemaValidator.js | 28 +- .../retail_api_json_schema/confirmSchema.js | 46 +- .../retail_api_json_schema/initSchema.js | 10 +- .../retail_api_json_schema/onConfirmSchema.js | 68 +- .../retail_api_json_schema/onInitSchema.js | 54 +- .../onSearchItemValidations.js | 137 ++-- .../retail_api_json_schema/onSearchSchema.js | 80 +- .../retail_api_json_schema/onSelectSchema.js | 2 +- .../retail_api_json_schema/onStatusSchema.js | 219 +++-- .../onStatusValidations.js | 217 +++++ .../retail_api_json_schema/onSupportSchema.js | 5 +- .../retail_api_json_schema/onUpdateSchema.js | 287 ++++--- .../postConfirmValidations.js | 0 .../retail_api_json_schema/searchSchema.js | 2 +- .../retail_api_json_schema/updateSchema.js | 6 +- .../services/cbCheck.service.js | 27 +- .../services/service.js | 9 +- .../log-validation-utility/utils/constants.js | 11 + .../log-validation-utility/utils/logger.js | 35 + .../utils/retail/retCancel.js | 78 +- .../utils/retail/retConfirm.js | 175 ++-- .../utils/retail/retInit.js | 120 ++- .../utils/retail/retOnCancel.js | 121 +-- .../utils/retail/retOnConfirm.js | 207 ++--- .../utils/retail/retOnInit.js | 129 ++- .../utils/retail/retOnSearch.js | 152 ++-- .../utils/retail/retOnSelect.js | 224 ++--- .../utils/retail/retOnStatus.js | 369 +++++---- .../utils/retail/retOnStatusDelivered.js | 186 +++++ .../utils/retail/retOnStatusPending.js | 64 ++ .../utils/retail/retOnStatusPicked.js | 146 ++++ .../utils/retail/retOnSupport.js | 49 +- .../utils/retail/retOnTrack.js | 63 +- .../utils/retail/retOnUpdate.js | 770 ++++++++++++------ .../utils/retail/retOnUpdateApproved.js | 61 ++ .../utils/retail/retOnUpdateDelivered.js | 173 ++++ .../utils/retail/retOnUpdateInit.js | 52 ++ .../utils/retail/retOnUpdateLiquidated.js | 71 ++ .../utils/retail/retOnUpdateRejected.js | 61 ++ .../utils/retail/retPostConfirm.js | 12 - .../utils/retail/retSearch.js | 60 +- .../utils/retail/retSelect.js | 221 ++--- .../utils/retail/retStatus.js | 53 +- .../utils/retail/retSupport.js | 60 +- .../utils/retail/retTrack.js | 55 +- .../utils/retail/retUnsolicitedOnStatus.js | 20 + .../utils/retail/retUnsolicitedOnUpdate.js | 67 ++ .../utils/retail/retUpdate.js | 63 +- .../utils/retail/retUpdateBilling.js | 154 ++++ .../utils/retail/retonUpdatePicked.js | 137 ++++ .../utils/schemaValidation.js | 3 +- .../log-validation-utility/utils/utils.js | 260 +++++- .../utils/validateLogUtil.js | 151 ++-- 60 files changed, 4055 insertions(+), 1867 deletions(-) create mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/onStatusValidations.js delete mode 100644 utilities/log-validation-utility/schema/retail_api_json_schema/postConfirmValidations.js create mode 100644 utilities/log-validation-utility/utils/logger.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnStatusDelivered.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnStatusPending.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnStatusPicked.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnUpdateApproved.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnUpdateDelivered.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnUpdateInit.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnUpdateLiquidated.js create mode 100644 utilities/log-validation-utility/utils/retail/retOnUpdateRejected.js delete mode 100644 utilities/log-validation-utility/utils/retail/retPostConfirm.js create mode 100644 utilities/log-validation-utility/utils/retail/retUnsolicitedOnStatus.js create mode 100644 utilities/log-validation-utility/utils/retail/retUnsolicitedOnUpdate.js create mode 100644 utilities/log-validation-utility/utils/retail/retUpdateBilling.js create mode 100644 utilities/log-validation-utility/utils/retail/retonUpdatePicked.js diff --git a/.DS_Store b/.DS_Store index cfdbbaa11ac429762756bd53e8d9b1d566b99133..73041bce0f7b779fffdac2a0cc6a3e00e0d4d12f 100644 GIT binary patch delta 104 zcmZp1XmQwZSV(MpQbA5;afyM!HAW_87FITPc20I~_Q{C?VLF_g9Gvk2;?>ngmO2VX zCPuY73e}cI2099+rWUoeoE)Oc`qn}5**Up+`JIzvgyk8#CKm{aZJs1t%CebF;ycUc Iec0}BuU diff --git a/utilities/.DS_Store b/utilities/.DS_Store index 55da67a617d36bdee2aa4498e501c4e008c79f51..ca4da9957d2287edaa0c3aed180e9321f631d7f7 100644 GIT binary patch delta 261 zcmZp1XmQxESWs+xQbA5;afyM!HAW_87FITPc20I~_Q{C?VLF_g9Gvk2;?>ngmO2VX zCPuY73e}cI2099+rWUoeoE)Oc`qn}5**Up+`JIz(gyb2!CdUX_Gai~eLr95JR8&k{ zR6zVKWtpkv5t%@CaAsBNH zl~dUv03tD&TSU=Zl2M6Ko6&^PmeHQkgVB>QiZPlofiV%Hf{77ogbbQdS(9Z14K_~| XDPo@3z_XcM;ycS`F44bC6B{@I%|JLr delta 171 zcmZp1XmQxESa7npz@EwSg1VEtg}52dPM$8L#3?2!E+Hx@B`rDmkkB3Jh|J{tyx`2L z)OZ2@;*9)qParp-D77pzwS4kUVKruD2Z6~qh2^-E9Re7@fO9gVh@zzcqY|SwqY0xe zqdlVsV<2M?V=`k3V All the payloads should be named in the correct format as mentioned in the table below. -> The utility validates all the 18 payloads as documented in the [API Contract](https://drive.google.com/file/d/1Z0eT1PZ8_tthEyxli8bLs-B9oCYAZIS0/view). - -| Payloads (Correct Format) | -| ------------------------- | -| search.json | -| on_search.json | -| select.json | -| on_select.json | -| init.json | -| on_init.json | -| confirm.json | -| on_confirm.json | -| cancel.json | -| on_cancel.json | -| track.json | -| on_track.json | -| status.json | -| on_status.json | -| update.json | -| on_update.json | -| support.json | -| on_support.json | +> The utility validates all the payloads as documented in the [API Contract](https://drive.google.com/file/d/1Z0eT1PZ8_tthEyxli8bLs-B9oCYAZIS0/view). + +| Payloads (Correct Format) | +| ------------------------------------------- | +| search.json | +| on_search.json | +| select.json | +| on_select.json | +| init.json | +| on_init.json | +| confirm.json | +| on_confirm.json | +| cancel.json | +| on_cancel.json | +| track.json | +| on_track.json | +| on_status_pending.json (Pending) | +| on_status_picked.json (Order-picked-up) | +| on_status_delivered.json (Order-delivered) | +| update.json | +| update_billing.json (Refund) | +| on_update_initiated.json (Return_Initiated) | +| on_update_approved.json (Return_Approved) | +| on_update_picked.json (Return_Picked) | +| on_update_delivered.json (Return_Delivered) | +| on_update_liquidated.json (Liquidated) | +| on_update_rejected.json (Return_Rejected) | +| support.json | +| on_support.json | > Sample payload for search.json is demonstrated below: @@ -80,7 +87,7 @@ _Notes:_ "bap_uri": "https://buyer-app-preprod.ondc.org/protocol/v1", "transaction_id": "7fc3bf55-2efc-442d-fda3-465d27a35d26", "message_id": "89b0ffb1-5f49-4eb7-b319-ca02caecc059", - "timestamp": "2022-11-11T19:59:52.452Z", + "timestamp": "2023-05-20T12:15:00.000Z", "ttl": "PT30S" }, "message": { @@ -94,7 +101,7 @@ _Notes:_ "type": "Delivery", "end": { "location": { - "gps": "12.96774,77.58891" + "gps": "12.967794,77.588891" } } }, @@ -107,4 +114,9 @@ _Notes:_ } ``` -### FAQs for Retail API Contract and Log Validation Utility ([FAQs](https://docs.google.com/document/d/1K-kqoOQ8IB-ywl_4pEiQKttTDk5Co381J07GldEUmD4/edit?usp=sharing)) +### N.B. + +> - Please utilize the Log Validation Utility to validate logs for Flow 1, as outlined in the test case scenario document (accessible at: [link](https://docs.google.com/document/d/1ttixilM-I6dutEdHL10uzqRFd8RcJlEO_9wBUijtdDc/edit)). +> - Please be aware that for Flow 2 and subsequent flows, the Log Validation Utility may produce unnecessary outcomes. +> - For debugging purpose, please review the "./logs/validations.log" file that is generated after running the utility. It will consist of the error logs of the utility +> - Community contributions are welcomed to enhance this utility for future releases. diff --git a/utilities/log-validation-utility/dao/dao.js b/utilities/log-validation-utility/dao/dao.js index af6e9fd..76ccf9b 100644 --- a/utilities/log-validation-utility/dao/dao.js +++ b/utilities/log-validation-utility/dao/dao.js @@ -1,5 +1,6 @@ const { open } = require("lmdb"); const constants = require("../utils/constants"); +const logger = require("../utils/logger"); const getConnection = () => { let myDB = open({ @@ -30,10 +31,10 @@ const dropDB = () => { myDB .drop() .then((res) => { - console.log("DB Dropped Successfully!!", res); + logger.info("DB Dropped Successfully!!", res); }) .catch((err) => { - console.log("!!Error while removing LMDB"); + logger.error("!!Error while removing LMDB"); }); }); }; diff --git a/utilities/log-validation-utility/index.js b/utilities/log-validation-utility/index.js index 68d24cf..0b7bc74 100644 --- a/utilities/log-validation-utility/index.js +++ b/utilities/log-validation-utility/index.js @@ -1,9 +1,10 @@ const { validateLog } = require("./services/cbCheck.service"); const fs = require("fs"); - +require("dotenv").config(); +const logger = require("./utils/logger"); try { if (process.argv.length < 3) { - console.log( + logger.error( "Need arguments in the format: node index.js 'domain' '/path/to/logs/folder/'" ); return; @@ -15,16 +16,19 @@ try { fs.readdir(path, function (err, files) { try { if (err) { - console.log(`Some error occurred while reading files from ${path}`); + logger.error( + `Some error occurred while reading files from ${path}`, + err + ); } else if (!files.length) { - console.log(`${path} folder is empty!!`); + logger.error(`${path} folder is empty!!`); } else { validateLog(domain, path); } } catch (error) { - console.log(`Error while reading logs folder`, error); + logger.error(`Error while reading logs folder`, error); } }); } catch (error) { - console.log("!!Some Unexpected Error Occurred", error); + logger.error(`!!Some Unexpected Error Occurred, ${error.stack}`); } diff --git a/utilities/log-validation-utility/package.json b/utilities/log-validation-utility/package.json index fc84ba1..576683a 100644 --- a/utilities/log-validation-utility/package.json +++ b/utilities/log-validation-utility/package.json @@ -20,7 +20,9 @@ "ajv": "^8.12.0", "ajv-errors": "^3.0.0", "ajv-formats": "^2.1.1", + "dotenv": "^16.1.3", "lmdb": "^2.7.5", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "winston": "^3.8.2" } } diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js index 8981d71..9ed7280 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -28,17 +28,23 @@ const formatted_error = (errors) => { error_list = []; let status = ""; errors.forEach((error) => { - error_dict = { - message: `${error.message}${ - error.params.allowedValues ? ` (${error.params.allowedValues})` : "" - }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ - error.params.additionalProperty - ? ` (${error.params.additionalProperty})` - : "" - }`, - details: error.instancePath, - }; - error_list.push(error_dict); + if ( + !["not", "oneOf", "anyOf", "allOf", "if", "then", "else"].includes( + error.keyword + ) + ) { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + } }); if (error_list.length === 0) status = "pass"; else status = "fail"; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js index c4ef9ab..970b28d 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/confirmSchema.js @@ -149,7 +149,7 @@ module.exports = { ], }, email: { type: "string", format: "email" }, - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, created_at: { type: "string", format: "date-time", @@ -205,6 +205,8 @@ module.exports = { }, phone: { type: "string", + minLength: 10, + maxLength: 11, }, }, required: ["phone"], @@ -257,7 +259,7 @@ module.exports = { required: ["person", "contact", "location"], }, }, - required: ["id", "type", "tracking", "end"], + required: ["id", "type", "end"], }, }, quote: { @@ -387,11 +389,9 @@ module.exports = { upi_address: { type: "string" }, settlement_bank_account_no: { type: "string", - pattern: "^(?!s*$).+", }, settlement_ifsc_code: { type: "string", - pattern: "^(?!s*$).+", }, bank_name: { type: "string" }, beneficiary_name: { @@ -399,11 +399,6 @@ module.exports = { }, branch_name: { type: "string" }, }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], allOf: [ { if: { @@ -414,6 +409,11 @@ module.exports = { }, }, then: { + properties: { + upi_address: { + type: "string", + }, + }, required: ["upi_address"], }, }, @@ -421,28 +421,21 @@ module.exports = { if: { properties: { settlement_type: { - const: "rtgs", + enum: ["rtgs", "neft"], }, }, }, then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { properties: { - settlement_type: { - const: "neft", + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", }, + bank_name: { type: "string" }, + branch_name: { type: "string" }, }, - }, - then: { required: [ "settlement_ifsc_code", "settlement_bank_account_no", @@ -452,6 +445,11 @@ module.exports = { }, }, ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], }, }, }, diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js index b931365..c0e6de3 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/initSchema.js @@ -166,9 +166,8 @@ module.exports = { type: "string", format: "email", }, - phone: { - type: "string", - }, + phone: { type: "string", minLength: 10, maxLength: 11 }, + created_at: { type: "string", format: "date-time", @@ -212,12 +211,15 @@ module.exports = { properties: { name: { type: "string", + minLength: 3, }, building: { type: "string", + minLength: 3, }, locality: { type: "string", + minLength: 3, }, city: { type: "string", @@ -250,6 +252,8 @@ module.exports = { properties: { phone: { type: "string", + minLength: 10, + maxLength: 11, }, }, required: ["phone"], diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js index 27fbd31..bb964a5 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onConfirmSchema.js @@ -66,7 +66,8 @@ module.exports = { ], }, email: { type: "string", format: "email" }, - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, + created_at: { type: "string", format: "date-time", @@ -151,7 +152,8 @@ module.exports = { contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, + email: { type: "string" }, }, required: ["phone"], @@ -220,7 +222,7 @@ module.exports = { contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, }, required: ["phone"], }, @@ -233,7 +235,6 @@ module.exports = { "@ondc/org/provider_name", "state", "type", - "tracking", "start", "end", ], @@ -361,14 +362,12 @@ module.exports = { type: "string", enum: ["upi", "neft", "rtgs"], }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, + upi_address: { type: "string" }, settlement_bank_account_no: { type: "string", - pattern: "^(?!s*$).+", }, settlement_ifsc_code: { type: "string", - pattern: "^(?!s*$).+", }, bank_name: { type: "string" }, beneficiary_name: { @@ -376,11 +375,6 @@ module.exports = { }, branch_name: { type: "string" }, }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], allOf: [ { if: { @@ -391,6 +385,11 @@ module.exports = { }, }, then: { + properties: { + upi_address: { + type: "string", + }, + }, required: ["upi_address"], }, }, @@ -398,28 +397,21 @@ module.exports = { if: { properties: { settlement_type: { - const: "rtgs", + enum: ["rtgs", "neft"], }, }, }, then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { properties: { - settlement_type: { - const: "neft", + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", }, + bank_name: { type: "string" }, + branch_name: { type: "string" }, }, - }, - then: { required: [ "settlement_ifsc_code", "settlement_bank_account_no", @@ -428,6 +420,28 @@ module.exports = { ], }, }, + // { + // if: { + // properties: { + // settlement_type: { + // const: "neft", + // }, + // }, + // }, + // then: { + // required: [ + // "settlement_ifsc_code", + // "settlement_bank_account_no", + // "bank_name", + // "branch_name", + // ], + // }, + // }, + ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", ], }, }, diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js index 3c03116..76a5210 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onInitSchema.js @@ -59,7 +59,7 @@ module.exports = { ], }, email: { type: "string", format: "email" }, - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, created_at: { type: "string", format: "date-time" }, updated_at: { type: "string", format: "date-time" }, }, @@ -108,7 +108,7 @@ module.exports = { contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, email: { type: "string", format: "email" }, }, required: ["phone"], @@ -227,19 +227,18 @@ module.exports = { }, settlement_phase: { type: "string", + const: "sale-amount", }, settlement_type: { type: "string", enum: ["upi", "neft", "rtgs"], }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, + upi_address: { type: "string" }, settlement_bank_account_no: { type: "string", - pattern: "^(?!s*$).+", }, settlement_ifsc_code: { type: "string", - pattern: "^(?!s*$).+", }, bank_name: { type: "string" }, beneficiary_name: { @@ -257,6 +256,11 @@ module.exports = { }, }, then: { + properties: { + upi_address: { + type: "string", + }, + }, required: ["upi_address"], }, }, @@ -264,28 +268,21 @@ module.exports = { if: { properties: { settlement_type: { - const: "rtgs", + enum: ["rtgs", "neft"], }, }, }, then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { properties: { - settlement_type: { - const: "neft", + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", }, + bank_name: { type: "string" }, + branch_name: { type: "string" }, }, - }, - then: { required: [ "settlement_ifsc_code", "settlement_bank_account_no", @@ -294,6 +291,23 @@ module.exports = { ], }, }, + // { + // if: { + // properties: { + // settlement_type: { + // const: "neft", + // }, + // }, + // }, + // then: { + // required: [ + // "settlement_ifsc_code", + // "settlement_bank_account_no", + // "bank_name", + // "branch_name", + // ], + // }, + // }, ], required: [ "settlement_counterparty", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js index 6b26d90..b76bf42 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchItemValidations.js @@ -1,49 +1,4 @@ onSearchRules = [ - // { - // if: { - // properties: { - // category_id: { - // enum: [ - // "F&B", - // "Continental", - // "Middle Eastern", - // "North Indian", - // "Pan-Asian", - // "Regional Indian", - // "South Indian", - // "Tex-Mexican", - // "World Cuisines", - // "Healthy Food", - // "Fast Food", - // "Desserts", - // "Bakes & Cakes", - // "Beverages (MTO)", - // ], - // }, - // }, - // }, - // then: { - // required: ["@ondc/org/fssai_license_no"], - // }, - // }, - // { - // if: { - // properties: { - // category_id: { - // enum: [ - // "Gourmet & World Foods", - // "Beverages", - // "Bakery, Cakes & Dairy", - // "Snacks & Branded Foods", - // ], - // }, - // }, - // }, - // then: { - // required: ["@ondc/org/fssai_license_no"], - // }, - // }, - // { // if: { properties: { "@ondc/org/returnable": { const: false } } }, // then: { @@ -71,6 +26,11 @@ onSearchRules = [ }, }, then: { + properties: { + "@ondc/org/statutory_reqs_packaged_commodities": { + type: "object", + }, + }, required: ["@ondc/org/statutory_reqs_packaged_commodities"], }, }, @@ -89,6 +49,11 @@ onSearchRules = [ }, }, then: { + properties: { + "@ondc/org/statutory_reqs_prepackaged_food": { + type: "object", + }, + }, required: ["@ondc/org/statutory_reqs_prepackaged_food"], }, }, @@ -101,7 +66,13 @@ onSearchRules = [ }, }, then: { + properties: { + "@ondc/org/mandatory_reqs_veggies_fruits": { + type: "object", + }, + }, required: ["@ondc/org/mandatory_reqs_veggies_fruits"], + errorMessage: `"@ondc/org/mandatory_reqs_veggies_fruits" is mandatory for "Fruits and Vegetables" category`, }, }, @@ -124,19 +95,6 @@ onSearchRules = [ "Bakes & Cakes", "Beverages (MTO)", "F&B", - ], - }, - }, - }, - then: { - required: ["tags"], - }, - }, - { - if: { - properties: { - category_id: { - enum: [ "Gourmet & World Foods", "Beverages", "Bakery, Cakes & Dairy", @@ -146,9 +104,43 @@ onSearchRules = [ }, }, then: { + properties: { + tags: { + type: "object", + properties: { + veg: { + type: "string", + enum: ["yes", "no"], + }, + non_veg: { + type: "string", + enum: ["yes", "no"], + }, + }, + required: ["veg", "non_veg"], + }, + }, required: ["tags"], + errorMessage: `veg/non-veg categorization is mandatory for F&B categories or packaged foods in /tags`, }, }, + // { + // if: { + // properties: { + // category_id: { + // enum: [ + // "Gourmet & World Foods", + // "Beverages", + // "Bakery, Cakes & Dairy", + // "Snacks & Branded Foods", + // ], + // }, + // }, + // }, + // then: { + // required: ["tags"], + // }, + // }, { if: { properties: { @@ -175,6 +167,17 @@ onSearchRules = [ then: { properties: { descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, required: ["name", "symbol", "short_desc", "long_desc"], }, }, @@ -182,6 +185,24 @@ onSearchRules = [ else: { properties: { descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + minItems: 1, + items: { + type: "string", + }, + }, + }, required: ["name", "symbol", "short_desc", "long_desc", "images"], }, }, diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index fb54338..aba3ffd 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -1,16 +1,17 @@ const onSearchItemValidations = require("./onSearchItemValidations"); - +const utils = require("../../utils/utils"); +const constants = require("../../utils/constants"); module.exports = { type: "object", properties: { context: { type: "object", properties: { - domain: { type: "string" }, + domain: { type: "string", const: "nic2004:52110" }, country: { type: "string" }, city: { type: "string" }, - action: { type: "string" }, - core_version: { type: "string" }, + action: { type: "string", const: "on_search" }, + core_version: { type: "string", const: "1.1.0" }, bap_id: { type: "string" }, bap_uri: { type: "string" }, transaction_id: { type: "string" }, @@ -177,6 +178,7 @@ module.exports = { type: "array", items: { type: "string", + format: "date", }, }, frequency: { @@ -229,43 +231,8 @@ module.exports = { }, category_id: { type: "string", - enum: [ - "Fruits and Vegetables", - "Masala & Seasoning", - "Oil & Ghee", - "Gourmet & World Foods", - "Foodgrains", - "Eggs, Meat & Fish", - "Cleaning & Household", - "Beverages", - "Beauty & Hygiene", - "Bakery, Cakes & Dairy", - "Kitchen Accessories", - "Baby Care", - "Snacks & Branded Foods", - "Pet Care", - "Stationery", - "Continental", - "Middle Eastern", - "North Indian", - "Pan-Asian", - "Regional Indian", - "South Indian", - "Tex-Mexican", - "World Cuisines", - "Healthy Food", - "Fast Food", - "Desserts", - "Bakes & Cakes", - "Beverages (MTO)", - "Home Decor", - "Home Furnishings", - "Furniture", - "Garden and Outdoor Products", - "Home Improvement", - "Cookware and Dining", - "Storage and Organisation", - ], + enum: utils.allCategories, + errorMessage: `category_id should be one of the valid categories as defined in [enhanced sub-category list](${constants.ENHANCED_SUBCATEGORY_LIST})`, }, fulfillment_id: { type: "string" }, @@ -323,11 +290,11 @@ module.exports = { properties: { veg: { type: "string", - enum: ["yes", "no", "Yes", "No"], + enum: ["yes", "no"], }, non_veg: { type: "string", - enum: ["yes", "no", "Yes", "No"], + enum: ["yes", "no"], }, }, required: ["veg", "non_veg"], @@ -355,8 +322,19 @@ module.exports = { type: "string", pattern: "^(?!\\s*$).+", }, + imported_product_country_of_origin: { + type: "string", + pattern: + "/^A(BW|FG|GO|IA|L[AB]|ND|R[EGM]|SM|T[AFG]|U[ST]|ZE)|B(DI|E[LNS]|FA|G[DR]|H[RS]|IH|L[MRZ]|MU|OL|R[ABN]|TN|VT|WA)|C(A[FN]|CK|H[ELN]|IV|MR|O[DGKLM]|PV|RI|U[BW]|XR|Y[MP]|ZE)|D(EU|JI|MA|NK|OM|ZA)|E(CU|GY|RI|S[HPT]|TH)|F(IN|JI|LK|R[AO]|SM)|G(AB|BR|EO|GY|HA|I[BN]|LP|MB|N[BQ]|R[CDL]|TM|U[FMY])|H(KG|MD|ND|RV|TI|UN)|I(DN|MN|ND|OT|R[LNQ]|S[LR]|TA)|J(AM|EY|OR|PN)|K(AZ|EN|GZ|HM|IR|NA|OR|WT)|L(AO|B[NRY]|CA|IE|KA|SO|TU|UX|VA)|M(A[CFR]|CO|D[AGV]|EX|HL|KD|L[IT]|MR|N[EGP]|OZ|RT|SR|TQ|US|WI|Y[ST])|N(AM|CL|ER|FK|GA|I[CU]|LD|OR|PL|RU|ZL)|OMN|P(A[KN]|CN|ER|HL|LW|NG|OL|R[IKTY]|SE|YF)|QAT|R(EU|OU|US|WA)|S(AU|DN|EN|G[PS]|HN|JM|L[BEV]|MR|OM|PM|RB|SD|TP|UR|V[KN]|W[EZ]|XM|Y[CR])|T(C[AD]|GO|HA|JK|K[LM]|LS|ON|TO|U[NRV]|WN|ZA)|U(GA|KR|MI|RY|SA|ZB)|V(AT|CT|EN|GB|IR|NM|UT)|W(LF|SM)|YEM|Z(AF|MB|WE)$/ix".toString(), + errorMessage: + "country of origin must be in ISO 3166-1 alpha-3 code format", + }, }, - required: ["nutritional_info", "additives_info"], + required: [ + "nutritional_info", + "additives_info", + "imported_product_country_of_origin", + ], anyOf: [ { required: ["importer_FSSAI_license_no"], @@ -407,6 +385,13 @@ module.exports = { type: "string", pattern: "^(?!\\s*$).+", }, + imported_product_country_of_origin: { + type: "string", + pattern: + "/^A(BW|FG|GO|IA|L[AB]|ND|R[EGM]|SM|T[AFG]|U[ST]|ZE)|B(DI|E[LNS]|FA|G[DR]|H[RS]|IH|L[MRZ]|MU|OL|R[ABN]|TN|VT|WA)|C(A[FN]|CK|H[ELN]|IV|MR|O[DGKLM]|PV|RI|U[BW]|XR|Y[MP]|ZE)|D(EU|JI|MA|NK|OM|ZA)|E(CU|GY|RI|S[HPT]|TH)|F(IN|JI|LK|R[AO]|SM)|G(AB|BR|EO|GY|HA|I[BN]|LP|MB|N[BQ]|R[CDL]|TM|U[FMY])|H(KG|MD|ND|RV|TI|UN)|I(DN|MN|ND|OT|R[LNQ]|S[LR]|TA)|J(AM|EY|OR|PN)|K(AZ|EN|GZ|HM|IR|NA|OR|WT)|L(AO|B[NRY]|CA|IE|KA|SO|TU|UX|VA)|M(A[CFR]|CO|D[AGV]|EX|HL|KD|L[IT]|MR|N[EGP]|OZ|RT|SR|TQ|US|WI|Y[ST])|N(AM|CL|ER|FK|GA|I[CU]|LD|OR|PL|RU|ZL)|OMN|P(A[KN]|CN|ER|HL|LW|NG|OL|R[IKTY]|SE|YF)|QAT|R(EU|OU|US|WA)|S(AU|DN|EN|G[PS]|HN|JM|L[BEV]|MR|OM|PM|RB|SD|TP|UR|V[KN]|W[EZ]|XM|Y[CR])|T(C[AD]|GO|HA|JK|K[LM]|LS|ON|TO|U[NRV]|WN|ZA)|U(GA|KR|MI|RY|SA|ZB)|V(AT|CT|EN|GB|IR|NM|UT)|W(LF|SM)|YEM|Z(AF|MB|WE)$/ix".toString(), + errorMessage: + "country of origin must be in ISO 3166-1 alpha-3 code format", + }, }, required: [ "manufacturer_or_packer_name", @@ -414,6 +399,7 @@ module.exports = { "common_or_generic_name_of_commodity", "month_year_of_manufacture_packing_import", "net_quantity_or_measure_of_commodity_in_pkg", + "imported_product_country_of_origin", ], }, "@ondc/org/mandatory_reqs_veggies_fruits": { @@ -441,6 +427,7 @@ module.exports = { images: { type: "array", minItems: 1, + maxItems: 3, items: { type: "string", }, @@ -449,7 +436,6 @@ module.exports = { }, }, - allOf: onSearchItemValidations.onSearchRules, required: [ "id", "category_id", @@ -463,6 +449,7 @@ module.exports = { "@ondc/org/available_on_cod", "@ondc/org/time_to_ship", ], + allOf: onSearchItemValidations.onSearchRules, }, }, fulfillments: { @@ -489,12 +476,15 @@ module.exports = { tags: { type: "array", + minItems: 1, items: { type: "object", properties: { code: { type: "string", const: "serviceability" }, list: { type: "array", + minItems: 5, + maxItems: 5, items: { type: "object", properties: { diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js index 2dfa71a..1c1a160 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSelectSchema.js @@ -14,7 +14,7 @@ module.exports = { type: "object", properties: { id: { type: "string", minLength: 1 }, - fulfillment_id: { type: "string", pattern: "^(?!s*$).+" }, + fulfillment_id: { type: "string" }, }, required: ["id", "fulfillment_id"], }, diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js index dfe0fcb..18bef5d 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusSchema.js @@ -1,4 +1,4 @@ -const postConfirmRules = require("./postConfirmValidations"); +const onStatusRules = require("./onStatusValidations"); module.exports = { type: "object", @@ -22,7 +22,6 @@ module.exports = { required: ["id"], }, }, - rateable: { type: "boolean" }, }, required: ["id", "locations"], }, @@ -55,6 +54,7 @@ module.exports = { "Liquidated", "Cancelled", ], + errorMessage: `tags should only be used for part returned/cancelled items`, }, }, required: ["status"], @@ -90,16 +90,14 @@ module.exports = { ], }, email: { type: "string", format: "email" }, - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, created_at: { type: "string", format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", }, updated_at: { type: "string", format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", }, }, required: ["name", "address", "phone", "created_at", "updated_at"], @@ -149,7 +147,6 @@ module.exports = { location: { type: "object", properties: { - id: { type: "string" }, descriptor: { type: "object", properties: { @@ -165,7 +162,7 @@ module.exports = { }, gps: { type: "string" }, }, - required: ["id", "descriptor", "gps"], + required: ["descriptor", "gps"], }, time: { type: "object", @@ -201,7 +198,7 @@ module.exports = { contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, email: { type: "string" }, }, required: ["phone"], @@ -274,7 +271,7 @@ module.exports = { contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, }, required: ["phone"], }, @@ -287,10 +284,20 @@ module.exports = { "@ondc/org/provider_name", "state", "type", - "tracking", "start", "end", ], + if: { + properties: { + type: { + type: "string", + const: "Delivery", + }, + }, + }, + then: { + allOf: onStatusRules.timeRules, + }, }, }, @@ -403,83 +410,124 @@ module.exports = { "@ondc/org/settlement_details": { type: "array", items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - allOf: [ + anyOf: [ { - if: { - properties: { - settlement_type: { - const: "upi", - }, + type: "object", + properties: { + settlement_counterparty: { + type: "string", }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string" }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + properties: { + upi_address: { + type: "string", + }, + }, + required: ["upi_address"], }, }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, + { + if: { + properties: { + settlement_type: { + enum: ["rtgs", "neft"], + }, + }, + }, + then: { + properties: { + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { type: "string" }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + // { + // if: { + // properties: { + // settlement_type: { + // const: "neft", + // }, + // }, + // }, + // then: { + // required: [ + // "settlement_ifsc_code", + // "settlement_bank_account_no", + // "bank_name", + // "branch_name", + // ], + // }, + // }, + ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], }, { - if: { - properties: { - settlement_type: { - const: "neft", - }, + type: "object", + properties: { + settlement_counterparty: { + type: "string", + const: "buyer", + }, + settlement_phase: { + type: "string", + const: "refund", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + settlement_amount: { + type: "string", + }, + settlement_timestamp: { + type: "string", + format: "date-time", }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], }, }, ], @@ -509,16 +557,7 @@ module.exports = { // }, // ], }, - documents: { - type: "array", - items: { - type: "object", - properties: { - url: { type: "string" }, - label: { type: "string", const: "Invoice" }, - }, - }, - }, + tags: { type: "object", properties: { @@ -532,7 +571,7 @@ module.exports = { created_at: { type: "string", format: "date-time" }, updated_at: { type: "string", format: "date-time" }, }, - // allOf: postConfirmRules, + allOf: onStatusRules.invoiceRules, required: [ "payment", "fulfillments", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusValidations.js new file mode 100644 index 0000000..95f3623 --- /dev/null +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onStatusValidations.js @@ -0,0 +1,217 @@ +invoiceRules = [ + { + if: { + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + ], + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + then: { + properties: { + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { type: "string" }, + label: { type: "string", const: "Invoice" }, + }, + required: ["url", "label"], + }, + }, + }, + required: ["documents"], + }, + }, + { + if: { + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Pending", "Packed"], + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + then: { + not: { + required: ["documents"], + }, + errorMessage: `Invoice url must be present as part of documents objects (only in Order-picked-up state and thereafter)`, + }, + }, +]; + +timeRules = [ + { + if: { + properties: { + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + ], + }, + }, + }, + }, + }, + }, + }, + then: { + properties: { + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["timestamp"], + errorMessage: `pickup time is mandatory when order is picked and thereafter`, + }, + }, + }, + }, + }, + else: { + properties: { + start: { + type: "object", + properties: { + time: { + type: "object", + not: { + properties: { + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["timestamp"], + }, + errorMessage: `pickup time should not be present until order is picked`, + }, + }, + }, + }, + }, + }, + { + if: { + properties: { + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Order-delivered"], + }, + }, + }, + }, + }, + }, + }, + then: { + properties: { + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["timestamp"], + errorMessage: `delivery time is mandatory when order is delivered`, + }, + }, + }, + }, + }, + else: { + properties: { + end: { + type: "object", + properties: { + time: { + type: "object", + not: { + properties: { + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["timestamp"], + }, + errorMessage: `delivery time should not be present until order is delivered`, + }, + }, + }, + }, + }, + }, +]; + +module.exports = { invoiceRules, timeRules }; diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js index 73d2357..172c2c6 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSupportSchema.js @@ -1,9 +1,8 @@ module.exports = { type: "object", properties: { - phone: { - type: "string", - }, + phone: { type: "string", minLength: 10, maxLength: 11 }, + email: { type: "string", format: "email", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js index ea0ebd7..7914a81 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onUpdateSchema.js @@ -1,4 +1,4 @@ -const postConfirmRules = require("./postConfirmValidations"); +const onStatusRules = require("./onStatusValidations"); module.exports = { type: "object", @@ -36,6 +36,7 @@ module.exports = { "Liquidated", "Cancelled", ], + errorMessage: `tags should only be used for part returned/cancelled items`, }, }, required: ["status"], @@ -89,7 +90,6 @@ module.exports = { location: { type: "object", properties: { - id: { type: "string" }, descriptor: { type: "object", properties: { @@ -105,7 +105,7 @@ module.exports = { }, gps: { type: "string" }, }, - required: ["id", "descriptor", "gps"], + required: ["descriptor"], }, time: { type: "object", @@ -131,23 +131,16 @@ module.exports = { }, required: ["range"], }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, email: { type: "string" }, }, required: ["phone"], }, }, - required: ["location", "time", "contact"], + required: ["time"], }, end: { type: "object", @@ -178,7 +171,6 @@ module.exports = { }, gps: { type: "string" }, }, - required: ["address", "gps"], }, time: { type: "object", @@ -202,34 +194,66 @@ module.exports = { format: "date-time", }, }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, }, contact: { type: "object", properties: { - phone: { type: "string" }, + phone: { type: "string", minLength: 10, maxLength: 11 }, }, required: ["phone"], }, }, - required: ["location", "time", "contact"], + required: ["time"], }, }, - required: [ - "id", - "@ondc/org/provider_name", - "state", - "type", - "tracking", - "start", - "end", + required: ["id", "state", "type", "start"], + anyOf: [ + { + if: { + properties: { + type: { + type: "string", + const: "Delivery", + }, + }, + }, + then: { + properties: { + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range", "timestamp"], + }, + }, + }, + }, + required: ["end"], + }, + }, + { + if: { + properties: { + type: { + type: "string", + const: "Reverse QC", + }, + }, + }, + then: { + allOf: onStatusRules.timeRules, + }, + }, ], }, }, @@ -276,7 +300,7 @@ module.exports = { minLength: 1, pattern: "^(\\d*.?\\d{1,2})$", }, - currency: { type: "string", pattern: "^(?!s*$).+" }, + currency: { type: "string" }, }, required: ["value", "currency"], }, @@ -343,83 +367,124 @@ module.exports = { "@ondc/org/settlement_details": { type: "array", items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - allOf: [ + anyOf: [ { - if: { - properties: { - settlement_type: { - const: "upi", - }, + type: "object", + properties: { + settlement_counterparty: { + type: "string", }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string" }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + properties: { + upi_address: { + type: "string", + }, + }, + required: ["upi_address"], }, }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, + { + if: { + properties: { + settlement_type: { + enum: ["rtgs", "neft"], + }, + }, + }, + then: { + properties: { + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { type: "string" }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + // { + // if: { + // properties: { + // settlement_type: { + // const: "neft", + // }, + // }, + // }, + // then: { + // required: [ + // "settlement_ifsc_code", + // "settlement_bank_account_no", + // "bank_name", + // "branch_name", + // ], + // }, + // }, + ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], }, { - if: { - properties: { - settlement_type: { - const: "neft", - }, + type: "object", + properties: { + settlement_counterparty: { + type: "string", + const: "buyer", + }, + settlement_phase: { + type: "string", + const: "refund", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + settlement_amount: { + type: "string", + }, + settlement_timestamp: { + type: "string", + format: "date-time", }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], }, }, ], @@ -449,26 +514,6 @@ module.exports = { // }, // ], }, - documents: { - type: "array", - items: { - type: "object", - properties: { - url: { type: "string" }, - label: { type: "string", const: "Invoice" }, - }, - }, - }, - tags: { - type: "object", - properties: { - cancellation_reason_id: { - type: "string", - maxLength: 3, - minLength: 3, - }, - }, - }, created_at: { type: "string", format: "date-time" }, updated_at: { type: "string", format: "date-time" }, }, diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/postConfirmValidations.js b/utilities/log-validation-utility/schema/retail_api_json_schema/postConfirmValidations.js deleted file mode 100644 index e69de29..0000000 diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js index 8f0ea0d..5225b2d 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/searchSchema.js @@ -117,7 +117,7 @@ module.exports = { properties: { "@ondc/org/buyer_app_finder_fee_type": { type: "string", - enum: ["percent", "amount"], + const: "percent", }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js index dbf0a8d..f79f92a 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/updateSchema.js @@ -70,7 +70,7 @@ module.exports = { properties: { update_target: { type: "string", - enum: ["item", "payment"], + enum: ["item", "billing"], }, order: { type: "object", @@ -113,7 +113,7 @@ module.exports = { properties: { update_type: { type: "string", - enum: ["return", "cancel"], + const: "return", }, reason_code: { type: "string", @@ -162,9 +162,11 @@ module.exports = { properties: { settlement_counterparty: { type: "string", + const: "buyer", }, settlement_phase: { type: "string", + const: "refund", }, settlement_type: { type: "string", diff --git a/utilities/log-validation-utility/services/cbCheck.service.js b/utilities/log-validation-utility/services/cbCheck.service.js index cfe6d0a..dad46c4 100644 --- a/utilities/log-validation-utility/services/cbCheck.service.js +++ b/utilities/log-validation-utility/services/cbCheck.service.js @@ -1,40 +1,19 @@ const path = require("path"); -const utils = require("../utils/utils"); +const logger = require("../utils/logger"); const vl = require("../utils/validateLogUtil"); const fs = require("fs"); const validateLog = async (domain, dirPath) => { - console.log("Inside Log Validation Service..."); + logger.info("Inside Log Validation Service..."); const logsPath = path.join(__dirname, "..", dirPath); switch (domain) { case "retail": vl.validateLogs(logsPath); break; default: - console.log("Invalid Domain!!"); + logger.warn("Invalid Domain!!"); } }; -// const saveSchema = (domain) => { -// console.log( -// `Inside Callback Check Service....\n*** Saving Schemas on DB for ${domain} domain ***` -// ); -// const logDir = path.join(utils.rootPath, "public", "logs"); - -// fs.readdir(logDir, (err, filenames) => { -// if (err) throw err; -// filenames.forEach((filename) => { -// fs.readFile(path.join(logDir, filename), "utf-8", (err, content) => { -// console.log(`reading file ${filename}`); -// if (err) throw new Error(err); -// content = JSON.parse(content); - -// retCbCheckUtil.saveSchema(content, domain); -// }); -// }); -// }); -// // console.log(txnId); -// }; - module.exports = { validateLog }; diff --git a/utilities/log-validation-utility/services/service.js b/utilities/log-validation-utility/services/service.js index edf9add..40df3ce 100644 --- a/utilities/log-validation-utility/services/service.js +++ b/utilities/log-validation-utility/services/service.js @@ -2,10 +2,12 @@ const config = require("../config/config"); const constants = require("../utils/constants"); const validateSchema = require("../utils/schemaValidation"); const utils = require("../utils/utils"); +const logger = require("../utils/logger"); + const _ = require("lodash"); const checkContext = (data, path) => { - console.log( + logger.info( `Inside Context Validation Check....\n*** Validating context for ${path} ***` ); @@ -46,11 +48,12 @@ const checkContext = (data, path) => { if (_.isEmpty(errObj)) { const result = { valid: true, SUCCESS: "Context Valid" }; - console.log(result); + logger.info(JSON.stringify(result)); return result; } else { const result = { valid: false, ERRORS: errObj }; - console.error(result); + + logger.warn(JSON.stringify(result)); return result; } }; diff --git a/utilities/log-validation-utility/utils/constants.js b/utilities/log-validation-utility/utils/constants.js index aad46cc..28037fc 100644 --- a/utilities/log-validation-utility/utils/constants.js +++ b/utilities/log-validation-utility/utils/constants.js @@ -20,4 +20,15 @@ module.exports = Object.freeze({ RET_ONSTATUS: "on_status", RET_SUPPORT: "support", RET_ONSUPPORT: "on_support", + LOG_FILE_PATH: "./logs", + ORDER_DELIVERED: "Order-delivered", + ENHANCED_SUBCATEGORY_LIST: `https://docs.google.com/spreadsheets/d/1ayRbp-WmXwwbzp7z1MgRO0NuKZM1AQk4GGZ8SE4NTnw/edit#gid=0`, + ORDER_PICKED: "Order-picked-up", + DECIMAL_PRECISION: 6, + RETURN_INITIATED: "Return_Initiated", + RETURN_APPROVED: "Return_Initiated", + RETURN_PICKED: "Return_Picked", + RETURN_REJECTED: "Return_Rejected", + RETURN_DELIVERED: "Return_Delivered", + LIQUIDATED: "Liquidated", }); diff --git a/utilities/log-validation-utility/utils/logger.js b/utilities/log-validation-utility/utils/logger.js new file mode 100644 index 0000000..d8af9ec --- /dev/null +++ b/utilities/log-validation-utility/utils/logger.js @@ -0,0 +1,35 @@ +"use strict"; +const { createLogger, format, transports } = require("winston"); +const { combine, timestamp, printf, colorize } = format; +const constants = require("./constants"); + +const log_dir = constants.LOG_FILE_PATH; + +const loggerFormat = printf(({ level, message, timestamp }) => { + return `[${level}]: ${message}`; +}); + +const loggerOpts = { + console: { + format: combine(colorize(), timestamp(), loggerFormat), + }, + file: { + filename: log_dir + "/validations.log", + level: "error", + format: combine(timestamp(), loggerFormat), + options: { flags: "w" }, + }, +}; + +// instantiate a new Winston Logger with the settings defined above +const logger = createLogger({ + level: "info", + defaultMeta: { service: "user-service" }, + exitOnError: false, + transports: [ + new transports.Console(loggerOpts.console), + new transports.File(loggerOpts.file), + ], +}); + +module.exports = logger; diff --git a/utilities/log-validation-utility/utils/retail/retCancel.js b/utilities/log-validation-utility/utils/retail/retCancel.js index 9eb97ae..693db58 100644 --- a/utilities/log-validation-utility/utils/retail/retCancel.js +++ b/utilities/log-validation-utility/utils/retail/retCancel.js @@ -5,6 +5,7 @@ const { checkContext } = require("../../services/service"); const utils = require("../utils"); const constants = require("../constants"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkCancel = (dirPath, msgIdSet) => { let cnclObj = {}; @@ -13,48 +14,45 @@ const checkCancel = (dirPath, msgIdSet) => { cancel = JSON.parse(cancel); try { - console.log(`Validating Schema for ${constants.RET_CANCEL} API`); + logger.info(`Validating Schema for ${constants.RET_CANCEL} API`); const vs = validateSchema("retail", constants.RET_CANCEL, cancel); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(cnclObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_CANCEL}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_CANCEL}, ${error.stack}` ); } - console.log(`Checking context for /${constants.RET_CANCEL} API`); //checking context + logger.info(`Checking context for /${constants.RET_CANCEL} API`); //checking context try { res = checkContext(cancel.context, constants.RET_CANCEL); if (!res.valid) { Object.assign(cnclObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_CANCEL} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_CANCEL} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SELECT} and /${constants.RET_CANCEL}` ); if (!_.isEqual(dao.getValue("city"), cancel.context.city)) { cnclObj.city = `City code mismatch in /${constants.RET_SELECT} and /${constants.RET_CANCEL}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SELECT} and /${constants.RET_CANCEL}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SELECT} and /${constants.RET_CANCEL}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), cancel.context.timestamp)) { @@ -62,28 +60,26 @@ const checkCancel = (dirPath, msgIdSet) => { cnclObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_CANCEL} api`; } } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_CANCEL} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_CANCEL} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_CANCEL}` ); if (!_.isEqual(dao.getValue("txnId"), cancel.context.transaction_id)) { - cnclObj.txnId = `Transaction Id for /${constants.RET_SELECT} and /${constants.RET_CANCEL} api should be same`; + cnclObj.txnId = `Transaction Id for should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_CANCEL} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_CANCEL} api, ${error.stack}` ); } try { - console.log(`Checking Message Id of /${constants.RET_CANCEL}`); + logger.info(`Checking Message Id of /${constants.RET_CANCEL}`); // if (!_.isEqual(msgId, onSelect.context.message_id)) { // onSlctObj.msgId = // "Message Id for /select and /on_select api should be same"; @@ -95,56 +91,54 @@ const checkCancel = (dirPath, msgIdSet) => { dao.setValue("msgId", cancel.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_CANCEL}`, - error + logger.error( + `!!Error while checking message id for /${constants.RET_CANCEL}, ${error.stack}` ); } cancel = cancel.message; try { - console.log( + logger.info( `Comparing order Id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}` ); if (cancel.order_id != dao.getValue("cnfrmOrdrId")) { cnclObj.cancelOrdrId = `Order Id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM} do not match`; - console.log( + logger.info( `Order Id mismatch in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}` ); } } catch (error) { - console.log( - `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}`, - error + logger.info( + `Error while comparing order id in /${constants.RET_CANCEL} and /${constants.RET_CONFIRM}, ${error.stack}` ); // cnclObj.cancelOrdrId = // "Order Id in /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM} do not match"; } try { - console.log("Checking the validity of cancellation reason id"); - if (!(cancel.cancellation_reason_id in utils.cancellation_rid)) { - console.log( - `Cancellation Reason Id in /${constants.RET_CANCEL} is not a valid reason id` + logger.info("Checking the validity of cancellation reason id"); + if (!utils.buyerCancellationRid.has(cancel.cancellation_reason_id)) { + logger.info( + `cancellation_reason_id should be a valid cancellation id (buyer app initiated)` ); - cnclObj.cancelRid = `Cancellation reason id in /${constants.RET_CANCEL} is not a valid reason id`; + cnclObj.cancelRid = `Cancellation reason id is not a valid reason id (buyer app initiated)`; } else dao.setValue("cnclRid", cancel.cancellation_reason_id); } catch (error) { // cnclObj.cancelRid = // "Cancellation reason id in /${constants.RET_CANCEL} is not a valid reason id"; - console.log( - `Error while checking validity of cancellation reason id /${constants.RET_CANCEL}`, - error + logger.info( + `Error while checking validity of cancellation reason id /${constants.RET_CANCEL}, ${error.stack}` ); } - dao.setValue("cnclObj", cnclObj); + // dao.setValue("cnclObj", cnclObj); + return cnclObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_CANCEL} API!`); + logger.info(`!!File not found for /${constants.RET_CANCEL} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_CANCEL} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retConfirm.js b/utilities/log-validation-utility/utils/retail/retConfirm.js index 4699a0a..7c81387 100644 --- a/utilities/log-validation-utility/utils/retail/retConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retConfirm.js @@ -2,8 +2,10 @@ const fs = require("fs"); const _ = require("lodash"); const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); +const utils = require("../utils"); const constants = require("../constants"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkConfirm = (dirPath, msgIdSet) => { let cnfrmObj = {}; @@ -12,48 +14,45 @@ const checkConfirm = (dirPath, msgIdSet) => { confirm = JSON.parse(confirm); try { - console.log(`Validating Schema for ${constants.RET_CONFIRM} API`); + logger.info(`Validating Schema for ${constants.RET_CONFIRM} API`); const vs = validateSchema("retail", constants.RET_CONFIRM, confirm); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(cnfrmObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_CONFIRM} API`); //checking context + logger.info(`Checking context for /${constants.RET_CONFIRM} API`); //checking context res = checkContext(confirm.context, constants.RET_CONFIRM); if (!res.valid) { Object.assign(cnfrmObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_CONFIRM} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_CONFIRM} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}` ); if (!_.isEqual(dao.getValue("city"), confirm.context.city)) { cnfrmObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_ONINIT} and /${constants.RET_CONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), confirm.context.timestamp)) { @@ -61,28 +60,26 @@ const checkConfirm = (dirPath, msgIdSet) => { } dao.setValue("tmpstmp", confirm.context.timestamp); } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_ONINIT} and /${constants.RET_CONFIRM} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_ONINIT} and /${constants.RET_CONFIRM} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_CONFIRM}` ); if (!_.isEqual(dao.getValue("txnId"), confirm.context.transaction_id)) { cnfrmObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_CONFIRM} api`, - error + logger.info( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_CONFIRM} api, ${error.stack}` ); } try { - console.log(`Checking Message Id of /${constants.RET_CONFIRM}`); + logger.info(`Checking Message Id of /${constants.RET_CONFIRM}`); // if (!_.isEqual(msgId, on_init.context.message_id)) { // onInitObj.msgId = "Message Ids for /init and /on_init api should be same"; // } @@ -94,9 +91,8 @@ const checkConfirm = (dirPath, msgIdSet) => { dao.setValue("msgId", confirm.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while checking message id for /${constants.RET_CONFIRM}, ${error.stack}` ); } @@ -106,19 +102,18 @@ const checkConfirm = (dirPath, msgIdSet) => { dao.setValue("cnfrmOrdrId", cnfrmOrdrId); try { - console.log(`Checking order state in /${constants.RET_CONFIRM}`); - if (confirm.state.toLowerCase() != "created") { + logger.info(`Checking order state in /${constants.RET_CONFIRM}`); + if (confirm.state != "Created") { cnfrmObj.state = `Default order state should be used in /${constants.RET_CONFIRM}`; } } catch (error) { - console.log( - `!!Error while checking order state in /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while checking order state in /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Checking provider id and location in /${constants.RET_CONFIRM}` ); if (confirm.provider.id != dao.getValue("providerId")) { @@ -129,20 +124,20 @@ const checkConfirm = (dirPath, msgIdSet) => { cnfrmObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_CONFIRM}`; } } catch (error) { - console.log( - `!!Error while checking provider id and location in /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while checking provider id and location in /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing item Ids and fulfillment ids in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` ); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); - const itemsIdList = dao.getValue("itemsIdList"); + let itemsIdList = dao.getValue("itemsIdList"); let i = 0; const len = confirm.items.length; + let itemsCountChange = false; while (i < len) { let itemId = confirm.items[i].id; if (itemId in itemFlfllmnts) { @@ -161,34 +156,40 @@ const checkConfirm = (dirPath, msgIdSet) => { if (itemId in itemsIdList) { if (confirm.items[i].quantity.count != itemsIdList[itemId]) { + itemsIdList[itemId] = confirm.items[i].quantity.count; //changing the item quantity as per the order confirmation + itemsCountChange = true; cnfrmObj.cntErr = `Warning: items[${i}].quantity.count for item ${itemId} mismatches with the items quantity selected in /${constants.RET_SELECT}`; } } i++; } + if (itemsCountChange) { + dao.setValue("itemsIdList", itemsIdList); + } } catch (error) { - console.log( - `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing billing object in /${constants.RET_INIT} and /${constants.RET_CONFIRM}` ); const billing = dao.getValue("billing"); - if (!_.isEqual(billing, confirm.billing)) { - cnfrmObj.bill = `Billing object mismatches in /${constants.RET_INIT} and /${constants.RET_CONFIRM}`; + if (utils.isObjectEqual(billing, confirm.billing).length>0) { + const billingMismatch= utils.isObjectEqual(billing, confirm.billing); + cnfrmObj.bill = `${billingMismatch.join(", ")} mismatches in /billing in /${constants.RET_INIT} and /${constants.RET_CONFIRM}`; } + dao.setValue("billing", confirm.billing); } catch (error) { - console.log( + logger.error( `!!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_CONFIRM}` ); } try { - console.log(`Checking fulfillments objects in /${constants.RET_CONFIRM}`); + logger.info(`Checking fulfillments objects in /${constants.RET_CONFIRM}`); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); let i = 0; const len = confirm.fulfillments.length; @@ -235,31 +236,30 @@ const checkConfirm = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while checking fulfillments object in /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while checking fulfillments object in /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log(`Checking payment object in /${constants.RET_CONFIRM}`); + logger.info(`Checking payment object in /${constants.RET_CONFIRM}`); // if (dao.getValue("paymentType") === "ON-ORDER") { - if (confirm.payment.status != "PAID") { - cnfrmObj.pymntEr = `payment.status should be "PAID" in case of pre-paid order(ON-ORDER)`; - } else if ( - !confirm.payment.params || - !confirm.payment.params.transaction_id - ) { - cnfrmObj.pymntErrr = `payment.params.transaction_id is missing when status is PAID`; - } + // if (confirm.payment.status != "PAID") { + // cnfrmObj.pymntEr = `payment.status should be "PAID" in case of pre-paid order(ON-ORDER)`; + // } else if ( + // !confirm.payment.params || + // !confirm.payment.params.transaction_id + // ) { + // cnfrmObj.pymntErrr = `payment.params.transaction_id is missing when status is PAID`; + // } - if (confirm.payment.type != "ON-ORDER") { - cnfrmObj.pymnttype = `payment.type is expected to be ON-ORDER`; - } + // if (confirm.payment.type != "ON-ORDER") { + // cnfrmObj.pymnttype = `payment.type is expected to be ON-ORDER`; + // } - if (confirm.payment.collected_by != `BAP`) { - cnfrmObj.pymntcollected = `payment.collected_by is expected to be BAP`; - } + // if (confirm.payment.collected_by != `BAP`) { + // cnfrmObj.pymntcollected = `payment.collected_by is expected to be BAP`; + // } // if (!confirm.payment.uri) // cnfrmObj.uri = `payment.uri is mandatory in /confirm`; @@ -292,49 +292,43 @@ const checkConfirm = (dirPath, msgIdSet) => { } else { if (!_.isEqual(confirm.created_at, dao.getValue("tmpstmp"))) { cnfrmObj.orderCrtd = `order.created_at timestamp should match context.timestamp`; - } else { - dao.setValue("ordrcrtdtmpstmp", confirm.created_at); } if (!_.isEqual(confirm.created_at, confirm.updated_at)) { cnfrmObj.ordrupdtd = `order.updated_at timestamp should match order.created_at timestamp`; - } else { - dao.setValue("ordrupdtdtmpstmp", confirm.updated_at); } } } catch (error) { - console.log( - `!!Error while checking payment object in /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while checking payment object in /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log(`storing payment object in /${constants.RET_CONFIRM}`); + logger.info(`storing payment object in /${constants.RET_CONFIRM}`); dao.setValue("cnfrmpymnt", confirm.payment); } catch (error) { - console.log( - `!!Error while storing payment object in /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while storing payment object in /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` ); if (!_.isEqual(dao.getValue("quoteObj"), confirm.quote)) { cnfrmObj.quoteObj = `Discrepancies between the quote object in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`; } } catch (error) { - console.log( + logger.error( `!!Error while Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` ); // cnfrmObj.quoteObj = "Quote Object in /on_select and /confirm mismatch"; } try { - console.log( + logger.info( `Checking Buyer App finder fee amount in /${constants.RET_CONFIRM}` ); const buyerFF = dao.getValue("buyerFF"); @@ -344,66 +338,67 @@ const checkConfirm = (dirPath, msgIdSet) => { buyerFF ) { cnfrmObj.bapFinderFee = `Buyer App Finder fee can't change`; - console.log( + logger.info( `Buyer app finder fee ${confirm.payment["@ondc/org/buyer_app_finder_fee_amount"]} can't change in /${constants.RET_CONFIRM}` ); } } catch (error) { - console.log( - `!!Error while Checking Buyer App finder fee amount in /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while Checking Buyer App finder fee amount in /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log("storing order created and updated timestamps"); + logger.info("storing order created and updated timestamps"); if (confirm.created_at) dao.setValue("ordrCrtd", confirm.created_at); if (confirm.updated_at) dao.setValue("ordrUpdtd", confirm.updated_at); } catch (error) { - console.log( + logger.error( `!!Error while storing order created and updated timestamps in /${constants.RET_CONFIRM}` ); } try { - console.log( + logger.info( `Comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` ); const onSelectPrice = dao.getValue("onSelectPrice"); const confirmQuotePrice = parseFloat(confirm.quote.price.value); if (onSelectPrice != confirmQuotePrice) { - console.log( + logger.info( `order quote price in /${constants.RET_CONFIRM} is not equal to the quoted price in /${constants.RET_ONSELECT}` ); cnfrmObj.quoteErr = `Quoted Price in /${constants.RET_CONFIRM} INR ${confirmQuotePrice} does not match with the quoted price in /${constants.RET_ONSELECT} INR ${onSelectPrice}`; } + dao.setValue("quotePrice", confirmQuotePrice); } catch (error) { - console.log( + logger.error( `!!Error while comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}` ); } // try { - // console.log( + // logger.info( // `Checking and Storing buyer's T&C in /${constants.RET_CONFIRM}` // ); // if (confirm.hasOwnProperty("tags")) { // dao.setValue("buyerT&C", confirm.tags); // } // } catch (error) { - // console.log( + // logger.info( // `!!Error while checking and storing buyer's T&C in /${constants.RET_CONFIRM}`, // error // ); // } - dao.setValue("cnfrmObj", cnfrmObj); + // dao.setValue("cnfrmObj", cnfrmObj); + return cnfrmObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_CONFIRM} API!`); + logger.info(`!!File not found for /${constants.RET_CONFIRM} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_CONFIRM} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retInit.js b/utilities/log-validation-utility/utils/retail/retInit.js index c5b6ee1..4513851 100644 --- a/utilities/log-validation-utility/utils/retail/retInit.js +++ b/utilities/log-validation-utility/utils/retail/retInit.js @@ -4,6 +4,7 @@ const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const constants = require("../constants"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkInit = (dirPath, msgIdSet) => { let initObj = {}; @@ -12,34 +13,31 @@ const checkInit = (dirPath, msgIdSet) => { init = JSON.parse(init); try { - console.log(`Validating Schema for ${constants.RET_INIT} API`); + logger.info(`Validating Schema for ${constants.RET_INIT} API`); const vs = validateSchema("retail", constants.RET_INIT, init); - console.log("DEBUGGG", vs); if (vs != "error") { Object.assign(initObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_INIT}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_INIT}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_INIT} API`); //checking context + logger.info(`Checking context for /${constants.RET_INIT} API`); //checking context res = checkContext(init.context, constants.RET_INIT); if (!res.valid) { Object.assign(initObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_INIT} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_INIT} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_INIT}` ); @@ -47,14 +45,13 @@ const checkInit = (dirPath, msgIdSet) => { initObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_INIT}`; } } catch (error) { - console.log( - `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_INIT}`, - error + logger.info( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_INIT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_ONSELECT} and /${constants.RET_INIT}` ); if (_.gte(dao.getValue("tmpstmp"), init.context.timestamp)) { @@ -62,28 +59,26 @@ const checkInit = (dirPath, msgIdSet) => { } dao.setValue("tmpstmp", init.context.timestamp); } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_ONSELECT} and /${constants.RET_INIT} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_ONSELECT} and /${constants.RET_INIT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_INIT}` ); if (!_.isEqual(dao.getValue("txnId"), init.context.transaction_id)) { initObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_INIT} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_INIT} api, ${error.stack}` ); } try { - console.log(`Checking Message Ids of /${constants.RET_INIT}`); + logger.info(`Checking Message Ids of /${constants.RET_INIT}`); // if (!_.isEqual(msgId, onSelect.context.message_id)) { // onSlctObj.msgId = // "Message Id for /select and /on_select api should be same"; @@ -95,16 +90,15 @@ const checkInit = (dirPath, msgIdSet) => { dao.setValue("msgId", init.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( - `Error while checking message id for /${constants.RET_INIT}`, - error + logger.info( + `Error while checking message id for /${constants.RET_INIT}, ${error.stack}` ); } init = init.message.order; try { - console.log( + logger.info( `Comparing provider object in /${constants.RET_SELECT} and /${constants.RET_INIT}` ); @@ -116,14 +110,13 @@ const checkInit = (dirPath, msgIdSet) => { initObj.prvdfrLoc = `Provider.locations[0].id mismatches in /${constants.RET_SELECT} and /${constants.RET_INIT}`; } } catch (error) { - console.log( - `!!Error while checking provider object in /${constants.RET_SELECT} and /${constants.RET_INIT}`, - error + logger.error( + `!!Error while checking provider object in /${constants.RET_SELECT} and /${constants.RET_INIT}, ${error.stack}` ); } try { - console.log(`Checking billing object in /${constants.RET_INIT}`); + logger.info(`Checking billing object in /${constants.RET_INIT}`); if (!init["billing"]) { initObj.bill = `Billing object missing in /${constants.RET_INIT}`; } else { @@ -131,11 +124,11 @@ const checkInit = (dirPath, msgIdSet) => { const tmpstmp = dao.getValue("tmpstmp"); dao.setValue("billing", billing); if (!_.isEqual(billing.created_at, tmpstmp)) { - initObj.bllngCrtd = `billing.created_at should match context.timestamp`; + initObj.bllngCrtd = `billing/created_at should match context.timestamp`; } if (!_.isEqual(init.billing.updated_at, tmpstmp)) { - initObj.bllngUptd = `billing.updated_at should match context.timestamp`; + initObj.bllngUptd = `billing/updated_at should match context.timestamp`; } // if ( // !_.isEqual(init.billing.address.area_code, dao.getValue("buyerAddr")) @@ -144,14 +137,53 @@ const checkInit = (dirPath, msgIdSet) => { // } } } catch (error) { - console.log( - `!!Error while checking billing object in /${constants.RET_INIT}`, - error + logger.error( + `!!Error while checking billing object in /${constants.RET_INIT}, ${error.stack}` ); } try { - console.log( + //checking address components length + const noOfFulfillments = init.fulfillments.length; //will be 1 ideally + let i = 0; + while (i < noOfFulfillments) { + const address = init.fulfillments[i].end.location.address; + + const lenName = address.name.length; + const lenBuilding = address.building.length; + const lenLocality = address.locality.length; + + if (lenName + lenBuilding + lenLocality >= 190) { + initObj.addressLen = `address.name + address.building + address.locality should be less than 190 chars;`; + } + if (lenBuilding <= 3) { + initObj.lenBuilding = `address.building should be more than 3 chars`; + } + if (lenName <= 3) { + initObj.lenName = `address.name should be more than 3 chars`; + } + if (lenLocality <= 3) { + initObj.lenLocality = `address.locality should be more than 3 chars`; + } + + if ( + address.building === address.locality || + address.name === address.building || + address.name === address.locality + ) { + initObj.addressComponents = `value of address.name, address.building and address.locality should be unique`; + } + + i++; + } + } catch (error) { + logger.error( + `!!Error while checking address components in /${constants.RET_INIT}, ${error.stack}` + ); + } + + try { + logger.info( `Comparing item Ids and fulfillment ids in /${constants.RET_ONSELECT} and /${constants.RET_INIT}` ); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); @@ -180,13 +212,13 @@ const checkInit = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( + logger.error( `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_INIT}` ); } try { - console.log(`Checking fulfillments objects in /${constants.RET_INIT}`); + logger.info(`Checking fulfillments objects in /${constants.RET_INIT}`); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); let i = 0; const len = init.fulfillments.length; @@ -243,18 +275,18 @@ const checkInit = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while checking fulfillments object in /${constants.RET_INIT}`, - error + logger.error( + `!!Error while checking fulfillments object in /${constants.RET_INIT}, ${error.stack}` ); } - dao.setValue("initObj", initObj); + // dao.setValue("initObj", initObj); + return initObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_INIT} API!`); + logger.info(`!!File not found for /${constants.RET_INIT} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_INIT} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retOnCancel.js b/utilities/log-validation-utility/utils/retail/retOnCancel.js index 2b8cdd9..5ab28e5 100644 --- a/utilities/log-validation-utility/utils/retail/retOnCancel.js +++ b/utilities/log-validation-utility/utils/retail/retOnCancel.js @@ -4,158 +4,171 @@ const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const constants = require("../constants"); const validateSchema = require("../schemaValidation"); +const utils = require("../utils"); +const logger = require("../logger"); const checkOnCancel = (dirPath, msgIdSet) => { let onCnclObj = {}; try { - var on_cancel = fs.readFileSync( + let on_cancel = fs.readFileSync( dirPath + `/${constants.RET_ONCANCEL}.json` ); + const isSolicited = fs.existsSync( + dirPath + `/${constants.RET_CANCEL}.json` + ); on_cancel = JSON.parse(on_cancel); try { - console.log(`Validating Schema for /${constants.RET_ONCANCEL} API`); + logger.info(`Validating Schema for /${constants.RET_ONCANCEL} API`); const vs = validateSchema("retail", constants.RET_ONCANCEL, on_cancel); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onCnclObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONCANCEL}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONCANCEL}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_ONCANCEL} API`); //checking context + logger.info(`Checking context for /${constants.RET_ONCANCEL} API`); //checking context res = checkContext(on_cancel.context, constants.RET_ONCANCEL); if (!res.valid) { Object.assign(onCnclObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONCANCEL} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONCANCEL} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}` ); if (!_.isEqual(dao.getValue("city"), on_cancel.context.city)) { onCnclObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONCANCEL}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), on_cancel.context.timestamp)) { onCnclObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONCANCEL} api`; } } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONCANCEL} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONCANCEL} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL}` ); if (_.gte(dao.getValue("cnclTmpstmp"), on_cancel.context.timestamp)) { onCnclObj.tmpstmp = `Timestamp for /${constants.RET_CANCEL} api cannot be greater than or equal to /${constants.RET_ONCANCEL} api`; } } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONCANCEL}` ); if (!_.isEqual(dao.getValue("txnId"), on_cancel.context.transaction_id)) { - onCnclObj.txnId = `Transaction Id for /${constants.RET_SELECT} and /${constants.RET_ONCANCEL} api should be same`; + onCnclObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONCANCEL} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONCANCEL} api, ${error.stack}` ); } try { - console.log(`Checking Message Id of /${constants.RET_ONCANCEL}`); - if (!_.isEqual(dao.getValue("msgId"), on_cancel.context.message_id)) { - onCnclObj.msgId = `Message Id for /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} api should be same`; + if (isSolicited) { + logger.info(`Checking Message Id of /${constants.RET_ONCANCEL}`); + if (!_.isEqual(dao.getValue("msgId"), on_cancel.context.message_id)) { + onCnclObj.msgId = `Message Id for /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} api should be same`; + } + // if (msgIdSet.has(status.context.message_id)) { + // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; + // } + // msgId = status.context.message_id; + msgIdSet.add(on_cancel.context.message_id); } - // if (msgIdSet.has(status.context.message_id)) { - // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; - // } - // msgId = status.context.message_id; - msgIdSet.add(on_cancel.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_ONCANCEL}`, - error + logger.error( + `!!Error while checking message id for /${constants.RET_ONCANCEL}, ${error.stack}` ); } on_cancel = on_cancel.message.order; try { - console.log( + logger.info( `Comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM}` ); if (on_cancel.id != dao.getValue("cnfrmOrdrId")) { onCnclObj.onCancelId = `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM} do not match`; - console.log( + logger.info( `Order id in /${constants.RET_ONCANCEL} and /${constants.RET_CONFIRM} do not match` ); } } catch (error) { // onCnclObj.onCancelId = // "Order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM} do not match"; - console.log( - `!!Error while comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while comparing order id in /${constants.RET_ONCANCEL} and /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( - `Comparing cancellation reason id in /${constants.RET_ONCANCEL} and /${constants.RET_CANCEL}` - ); - if (dao.getValue("cnclRid") != on_cancel.tags.cancellation_reason_id) { - onCnclObj.onCancelRID = `Cancellation Reason Id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} should be same`; + if (isSolicited) { + logger.info( + `Comparing cancellation reason id in /${constants.RET_ONCANCEL} and /${constants.RET_CANCEL}` + ); + if (dao.getValue("cnclRid") != on_cancel.tags.cancellation_reason_id) { + onCnclObj.onCancelRID = `Cancellation Reason Id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} should be same`; + } + } else { + if ( + !utils.sellerCancellationRid.has( + on_cancel.tags.cancellation_reason_id + ) + ) { + logger.info( + `Cancellation Reason Id in /${constants.RET_ONCANCEL} is not a valid reason id` + ); + + onCnclObj.cancelRid = `cancellation_reason_id should be a valid cancellation id (unsolicited seller app initiated)`; + } } } catch (error) { - console.log( - `!!Error while comparing cancellation reason id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL}`, - error + logger.error( + `!!Error while checking cancellation reason id in /${constants.RET_ONCANCEL}, ${error.stack}` ); // onCnclObj.onCancelRID = // "Cancellation reason Id in /${constants.RET_CANCEL} and /${constants.RET_ONCANCEL} (inside tags) should be same"; } - dao.setValue("onCnclObj", onCnclObj); + // dao.setValue("onCnclObj", onCnclObj); + return onCnclObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONCANCEL} API!`); + logger.info(`!!File not found for /${constants.RET_ONCANCEL} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_ONCANCEL} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retOnConfirm.js b/utilities/log-validation-utility/utils/retail/retOnConfirm.js index 4c7e056..ce60ee9 100644 --- a/utilities/log-validation-utility/utils/retail/retOnConfirm.js +++ b/utilities/log-validation-utility/utils/retail/retOnConfirm.js @@ -5,6 +5,7 @@ const { checkContext } = require("../../services/service"); const validateSchema = require("../schemaValidation"); const utils = require("../utils"); const constants = require("../constants"); +const logger = require("../logger"); const checkOnConfirm = (dirPath, msgIdSet) => { let onCnfrmObj = {}; @@ -16,48 +17,45 @@ const checkOnConfirm = (dirPath, msgIdSet) => { on_confirm = JSON.parse(on_confirm); try { - console.log(`Validating Schema for /${constants.RET_ONCONFIRM} API`); + logger.info(`Validating Schema for /${constants.RET_ONCONFIRM} API`); const vs = validateSchema("retail", constants.RET_ONCONFIRM, on_confirm); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onCnfrmObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_ONCONFIRM} API`); //checking context + logger.info(`Checking context for /${constants.RET_ONCONFIRM} API`); //checking context res = checkContext(on_confirm.context, constants.RET_ONCONFIRM); if (!res.valid) { Object.assign(onCnfrmObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONCONFIRM} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONCONFIRM} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}` ); if (!_.isEqual(dao.getValue("city"), on_confirm.context.city)) { onCnfrmObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}`; } } catch (error) { - console.log( - `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}`, - error + logger.info( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` ); const tmpstmp = dao.getValue("tmpstmp"); @@ -65,7 +63,7 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.tmpstmp = `Timestamp for /${constants.RET_CONFIRM} api cannot be greater than or equal to /${constants.RET_ONCONFIRM} api`; } else { const timeDiff = utils.timeDiff(on_confirm.context.timestamp, tmpstmp); - console.log(timeDiff); + logger.info(timeDiff); if (timeDiff > 5000) { onCnfrmObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONCONFIRM} and /${constants.RET_CONFIRM} should be smaller than 5 sec`; } @@ -73,14 +71,13 @@ const checkOnConfirm = (dirPath, msgIdSet) => { dao.setValue("tmpstmp", on_confirm.context.timestamp); } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM} api`, - error + logger.info( + `Error while comparing timestamp for /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM}` ); if ( @@ -89,14 +86,13 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Message Ids of /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` ); if (!_.isEqual(dao.getValue("msgId"), on_confirm.context.message_id)) { @@ -108,37 +104,32 @@ const checkOnConfirm = (dirPath, msgIdSet) => { // msgId = confirm.context.message_id; msgIdSet.add(on_confirm.context.message_id); } catch (error) { - console.log( - `Error while checking message id for /${constants.RET_ONCONFIRM}`, - error + logger.info( + `Error while checking message id for /${constants.RET_ONCONFIRM}, ${error.stack}` ); } on_confirm = on_confirm.message.order; try { - console.log( + logger.info( `Comparing order ids in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` ); if (dao.getValue("cnfrmOrdrId") != on_confirm.id) { onCnfrmObj.orderID = `Order Id mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`; } } catch (error) { - console.log( - `!!Error while trying to fetch order ids in /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while trying to fetch order ids in /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `checking created_at and updated_at timestamp in /${constants.RET_ONCONFIRM}` ); const cnfrmOrdrCrtd = dao.getValue("ordrCrtd"); const cnfrmOrdrUpdtd = dao.getValue("ordrUpdtd"); - if ( - on_confirm.state.toLowerCase() === "created" || - on_confirm.state.toLowerCase() === "accepted" - ) { + if (on_confirm.state === "Created" || on_confirm.state === "Accepted") { if ( cnfrmOrdrCrtd && (!on_confirm.created_at || on_confirm.created_at != cnfrmOrdrCrtd) @@ -155,27 +146,16 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.updtdtmstmp = `order.updated_at timestamp should be updated as per the context.timestamp (since default fulfillment state is added)`; } } - - // if (on_confirm.state.toLowerCase() === "accepted") { - // if ( - // cnfrmOrdrUpdtd && - // (!on_confirm.updated_at || - // _.gt(cnfrmOrdrUpdtd, on_confirm.updated_at)) - // ) { - // onCnfrmObj.updtdtmstmp = `order.updated_at timestamp can't be same when order state changes`; - // } - // } } catch (error) { - console.log( - `!!Error while checking order timestamps in /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while checking order timestamps in /${constants.RET_ONCONFIRM}, ${error.stack}` ); } // dao.setValue("onCnfrmOrdrId", on_confirm.id); try { - console.log( + logger.info( `Checking provider id and location in /${constants.RET_ONCONFIRM}` ); if (on_confirm.provider.id != dao.getValue("providerId")) { @@ -186,14 +166,17 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONCONFIRM}`; } } catch (error) { - console.log( - `!!Error while checking provider id and location in /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while checking provider id and location in /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( + //checking provider location and name in /fulfillments/start + } catch (error) {} + + try { + logger.info( `Comparing item Ids and fulfillment ids in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` ); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); @@ -224,29 +207,29 @@ const checkOnConfirm = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}`, - error + logger.error( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_CONFIRM}, ${error.stack}` ); } try { - console.log( - `Comparing billing object in ${constants.RET_INIT} and /${constants.RET_ONCONFIRM}` + logger.info( + `Comparing billing object in ${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` ); const billing = dao.getValue("billing"); - if (!_.isEqual(billing, on_confirm.billing)) { - onCnfrmObj.bill = `Billing object mismatches in /${constants.RET_INIT} and /${constants.RET_ONCONFIRM}`; + if (utils.isObjectEqual(billing, on_confirm.billing).length>0) { + const billingMismatch= utils.isObjectEqual(billing, on_confirm.billing); + onCnfrmObj.bill = `${billingMismatch.join(", ")} mismatches in /billing in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`; } // dao.setValue("billing", on_confirm.billing); } catch (error) { - console.log( - `!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONCONFIRM}` + logger.info( + `!Error while comparing billing object in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` ); } // try { - // console.log("Comparing count of items in /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM}"); + // logger.info("Comparing count of items in /${constants.RET_SELECT} and /${constants.RET_ONCONFIRM}"); // const itemsIdList = dao.getValue("itemsIdList"); // on_confirm.items.forEach((item) => { // if (item["id"] in itemsIdList) { @@ -257,14 +240,14 @@ const checkOnConfirm = (dirPath, msgIdSet) => { // }); // } catch (error) { // // onCnfrmObj.countErr = `Count of item in /${constants.RET_ONCONFIRM} does not match with the count in /${constants.RET_SELECT}`; - // console.log( + // logger.info( // "!!Error while comparing count items in /${constants.RET_ONCONFIRM} and /${constants.RET_SELECT}", // error // ); // } try { - console.log( + logger.info( `Checking fulfillments objects in /${constants.RET_ONCONFIRM}` ); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); @@ -285,12 +268,12 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.ffId = `fulfillments[${i}].id is missing in /${constants.RET_ONCONFIRM}`; } - console.log("Checking the fulfillments state"); + logger.info("Checking the fulfillments state"); const ffDesc = on_confirm.fulfillments[i].state.descriptor; const ffStateCheck = ffDesc.hasOwnProperty("code") - ? ffDesc.code.toLowerCase() === "pending" + ? ffDesc.code === "Pending" : false; if (!ffStateCheck) { @@ -306,13 +289,43 @@ const checkOnConfirm = (dirPath, msgIdSet) => { ) { onCnfrmObj.ffstartend = `fulfillments[${i}] start and end locations are mandatory`; } + try { + if ( + !utils.compareCoordinates( + on_confirm.fulfillments[i].start.location.gps, + dao.getValue("providerGps") + ) + ) { + onCnfrmObj.sellerGpsErr = `store gps location /fulfillments[${i}]/start/location/gps can't change`; + } + } catch (error) { + logger.error( + `!!Error while checking store location in /${constants.RET_ONCONFIRM}` + ); + } + + try { + if ( + !_.isEqual( + on_confirm.fulfillments[i].start.location.descriptor.name, + dao.getValue("providerName") + ) + ) { + onCnfrmObj.sellerNameErr = `store name /fulfillments[${i}]/start/location/descriptor/name can't change`; + } + } catch (error) { + logger.error( + `!!Error while checking store name in /${constants.RET_ONCONFIRM}` + ); + } + if ( !_.isEqual( on_confirm.fulfillments[i].end.location.gps, dao.getValue("buyerGps") ) ) { - onCnfrmObj.gpsErr = `fulfillments[${i}].end.location gps is not matching with gps in /select`; + onCnfrmObj.buyerGpsErr = `fulfillments[${i}].end.location gps is not matching with gps in /select`; } if ( @@ -327,14 +340,13 @@ const checkOnConfirm = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while checking fulfillments object in /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while checking fulfillments object in /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing /${constants.RET_ONCONFIRM} quoted Price and Payment Params amount` ); if ( @@ -344,14 +356,13 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.onConfirmedAmount = `Quoted price (/${constants.RET_ONCONFIRM}) doesn't match with the amount in payment.params`; } } catch (error) { - console.log( - `!!Error while Comparing /${constants.RET_ONCONFIRM} quoted Price and Payment Params amount`, - error + logger.error( + `!!Error while Comparing /${constants.RET_ONCONFIRM} quoted Price and Payment Params amount, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Quote object for /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` ); if (!_.isEqual(dao.getValue("quoteObj"), on_confirm.quote)) { @@ -359,32 +370,31 @@ const checkOnConfirm = (dirPath, msgIdSet) => { } } catch (error) { // onCnfrmObj.onQuoteObj = `Quote Object in /on_init and /${constants.RET_ONCONFIRM} mismatch`; - console.log( + logger.error( `!!Error while comparing quote in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` ); } try { - console.log( + logger.info( `Comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}` ); const onSelectPrice = dao.getValue("onSelectPrice"); const onConfirmQuotePrice = parseFloat(on_confirm.quote.price.value); if (onSelectPrice != onConfirmQuotePrice) { - console.log( + logger.info( `order quote price in /${constants.RET_ONCONFIRM} is not equal to the quoted price in /${constants.RET_ONSELECT}` ); onCnfrmObj.quoteErr = `Quoted Price in /${constants.RET_ONCONFIRM} ${onConfirmQuotePrice} does not match with the quoted price in /${constants.RET_ONSELECT} ${onSelectPrice}`; } } catch (error) { - console.log( - `!!Error while comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while comparing order price value in /${constants.RET_ONSELECT} and /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing payment object in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}` ); @@ -392,14 +402,13 @@ const checkOnConfirm = (dirPath, msgIdSet) => { onCnfrmObj.pymntObj = `payment object mismatches in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`; } } catch (error) { - console.log( - `!!Error while comparing payment object in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}`, - error + logger.error( + `!!Error while comparing payment object in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}, ${error.stack}` ); } try { - console.log( + logger.info( `Checking Buyer App finder fee amount in /${constants.RET_ONCONFIRM}` ); const buyerFF = dao.getValue("buyerFF"); @@ -410,19 +419,18 @@ const checkOnConfirm = (dirPath, msgIdSet) => { ) != buyerFF ) { onCnfrmObj.buyerFF = `Buyer app finder fee can't change in /${constants.RET_ONCONFIRM}`; - console.log( + logger.info( `Buyer app finder fee can't change in /${constants.RET_ONCONFIRM}` ); } } catch (error) { - console.log( - `!Error while comparing buyer app finder fee in /${constants.RET_ONCONFIRM}`, - error + logger.info( + `!Error while comparing buyer app finder fee in /${constants.RET_ONCONFIRM}, ${error.stack}` ); } // try { - // console.log( + // logger.info( // `comparing created and updated order timestamps in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}` // ); @@ -448,13 +456,13 @@ const checkOnConfirm = (dirPath, msgIdSet) => { // } // } // } catch (error) { - // console.log( + // logger.info( // `!!Error while comparing created and updated timestamps in /${constants.RET_CONFIRM} & /${constants.RET_ONCONFIRM}` // ); // } //TNC ARRAY OF OBJECTS DEEP COMPARISON WITH LODASH // try { - // console.log( + // logger.info( // `Comparing buyer's T&C in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}` // ); // const buyerTnc = dao.getValue("buyerT&C"); @@ -463,22 +471,23 @@ const checkOnConfirm = (dirPath, msgIdSet) => { // buyerTnc && // (!on_confirm.tags || !utils.isArrayEqual(buyerTnc, on_confirm.tags)) // ) { - // // console.log(buyerTnc); + // // logger.info(buyerTnc); // onCnfrmObj.buyertnc = `Buyer's T&C in tags mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`; // } // } catch (error) { - // console.log( + // logger.info( // `!!Error while checking buyer's T&C in /${constants.RET_CONFIRM} and /${constants.RET_ONCONFIRM}`, // error // ); // } - dao.setValue("onCnfrmObj", onCnfrmObj); + // dao.setValue("onCnfrmObj", onCnfrmObj); + return onCnfrmObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONCONFIRM} API!`); + logger.info(`!!File not found for /${constants.RET_ONCONFIRM} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_ONCONFIRM} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retOnInit.js b/utilities/log-validation-utility/utils/retail/retOnInit.js index 32b22ab..ea346bd 100644 --- a/utilities/log-validation-utility/utils/retail/retOnInit.js +++ b/utilities/log-validation-utility/utils/retail/retOnInit.js @@ -5,6 +5,7 @@ const dao = require("../../dao/dao"); const utils = require("../utils"); const validateSchema = require("../schemaValidation"); const constants = require("../constants"); +const logger = require("../logger"); const checkOnInit = (dirPath, msgIdSet) => { let onInitObj = {}; @@ -15,48 +16,45 @@ const checkOnInit = (dirPath, msgIdSet) => { on_init = JSON.parse(on_init); try { - console.log(`Validating Schema for /${constants.RET_ONINIT} API`); + logger.info(`Validating Schema for /${constants.RET_ONINIT} API`); const vs = validateSchema("retail", constants.RET_ONINIT, on_init); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onInitObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONINIT}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONINIT}, ${error.stack}` ); } - console.log(`Checking context for /${constants.RET_ONINIT} API`); //checking context + logger.info(`Checking context for /${constants.RET_ONINIT} API`); //checking context try { res = checkContext(on_init.context, constants.RET_ONINIT); if (!res.valid) { Object.assign(onInitObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONINIT} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONINIT} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of ${constants.RET_SEARCH} & ${constants.RET_ONINIT}` ); if (!_.isEqual(dao.getValue("city"), on_init.context.city)) { onInitObj.city = `City code mismatch in ${constants.RET_SEARCH} & ${constants.RET_ONINIT}`; } } catch (error) { - console.log( - `Error while comparing city in ${constants.RET_SEARCH} & ${constants.RET_ONINIT}`, - error + logger.info( + `Error while comparing city in ${constants.RET_SEARCH} & ${constants.RET_ONINIT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of ${constants.RET_INIT} & ${constants.RET_ONINIT}` ); const tmpstmp = dao.getValue("tmpstmp"); @@ -64,7 +62,7 @@ const checkOnInit = (dirPath, msgIdSet) => { onInitObj.tmpstmp = `Timestamp for ${constants.RET_INIT} api cannot be greater than or equal to ${constants.RET_ONINIT} api`; } else { const timeDiff = utils.timeDiff(on_init.context.timestamp, tmpstmp); - console.log(timeDiff); + logger.info(timeDiff); if (timeDiff > 5000) { onInitObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONINIT} and /${constants.RET_INIT} should be smaller than 5 sec`; } @@ -72,28 +70,26 @@ const checkOnInit = (dirPath, msgIdSet) => { dao.setValue("tmpstmp", on_init.context.timestamp); } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_INIT} and /${constants.RET_ONINIT} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_INIT} and /${constants.RET_ONINIT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} & /${constants.RET_ONINIT}` ); if (!_.isEqual(dao.getValue("txnId"), on_init.context.transaction_id)) { onInitObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} & /${constants.RET_ONINIT} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} & /${constants.RET_ONINIT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Message Ids of /${constants.RET_INIT} and /${constants.RET_ONINIT}` ); if (!_.isEqual(dao.getValue("msgId"), on_init.context.message_id)) { @@ -106,16 +102,15 @@ const checkOnInit = (dirPath, msgIdSet) => { // msgId = select.context.message_id; msgIdSet.add(on_init.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_INIT}`, - error + logger.error( + `!!Error while checking message id for /${constants.RET_INIT}, ${error.stack}` ); } on_init = on_init.message.order; try { - console.log( + logger.info( `Checking provider Id and provider_location Id in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}` ); if ( @@ -135,14 +130,13 @@ const checkOnInit = (dirPath, msgIdSet) => { onInitObj.prvdrloc = `provider_location object is missing in /${constants.RET_ONINIT}`; } } catch (error) { - console.log( - `!!Error while comparing provider Id and location Id in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}`, - error + logger.error( + `!!Error while comparing provider Id and location Id in /${constants.RET_ONSEARCH} and /${constants.RET_ONINIT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing item Ids and fulfillment Ids in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` ); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); @@ -172,29 +166,29 @@ const checkOnInit = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`, - error + logger.error( + `!!Error while comparing Item and Fulfillment Id in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONINIT}` ); const billing = dao.getValue("billing"); - if (!_.isEqual(billing, on_init.billing)) { - onInitObj.bill = `Billing object mismatches in /${constants.RET_INIT} and /${constants.RET_ONINIT}`; + + if (utils.isObjectEqual(billing, on_init.billing).length>0) { + const billingMismatch= utils.isObjectEqual(billing, on_init.billing); + onInitObj.bill = `${billingMismatch.join(", ")} mismatches in /billing in /${constants.RET_INIT} and /${constants.RET_ONINIT}`; } } catch (error) { - console.log( - `!!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONINIT}`, - error + logger.error( + `!!Error while comparing billing object in /${constants.RET_INIT} and /${constants.RET_ONINIT}, ${error.stack}` ); } try { - console.log(`Checking fulfillments objects in /${constants.RET_ONINIT}`); + logger.info(`Checking fulfillments objects in /${constants.RET_ONINIT}`); const itemFlfllmnts = dao.getValue("itemFlfllmnts"); let i = 0; const len = on_init.fulfillments.length; @@ -251,53 +245,52 @@ const checkOnInit = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while checking fulfillments object in /${constants.RET_ONINIT}`, - error + logger.error( + `!!Error while checking fulfillments object in /${constants.RET_ONINIT}, ${error.stack}` ); } let initQuotePrice = 0; let initBreakupPrice = 0; // dao.setValue("onInitQuote", on_init.quote); - console.log(`Calculating Net /${constants.RET_ONINIT} Price breakup`); + logger.info(`Calculating Net /${constants.RET_ONINIT} Price breakup`); on_init.quote.breakup.forEach((element) => { initBreakupPrice += parseFloat(element.price.value); }); - console.log(`/${constants.RET_ONINIT} Price Breakup: ${initBreakupPrice}`); + logger.info(`/${constants.RET_ONINIT} Price Breakup: ${initBreakupPrice}`); initQuotePrice = parseFloat(on_init.quote.price.value); - console.log(`/${constants.RET_ONINIT} Quoted Price: ${initQuotePrice}`); + logger.info(`/${constants.RET_ONINIT} Quoted Price: ${initQuotePrice}`); - console.log( + logger.info( `Comparing /${constants.RET_ONINIT} Quoted Price and Net Price Breakup` ); if (initQuotePrice != initBreakupPrice) { - console.log( + logger.info( `Quoted Price in /${constants.RET_ONINIT} is not equal to the Net Breakup Price` ); onInitObj.onInitPriceErr = `Quoted Price ${initQuotePrice} does not match with Net Breakup Price ${initBreakupPrice} in /${constants.RET_ONINIT}`; } - console.log( + logger.info( `Comparing /${constants.RET_ONINIT} Quoted Price and /${constants.RET_ONSELECT} Quoted Price` ); const onSelectPrice = dao.getValue("onSelectPrice"); if (onSelectPrice != initQuotePrice) { - console.log( + logger.info( `Quoted Price in /${constants.RET_ONINIT} is not equal to the quoted price in /${constants.RET_ONSELECT}` ); onInitObj.onInitPriceErr2 = `Quoted Price in /${constants.RET_ONINIT} INR ${initQuotePrice} does not match with the quoted price in /${constants.RET_ONSELECT} INR ${onSelectPrice}`; } - console.log(`Checking Payment Object for /${constants.RET_ONINIT}`); + logger.info(`Checking Payment Object for /${constants.RET_ONINIT}`); if (!on_init.payment) { onInitObj.pymntOnInitObj = `Payment Object can't be null in /${constants.RET_ONINIT}`; } try { - console.log( + logger.info( `Checking Buyer App finder fee amount in /${constants.RET_ONINIT}` ); const buyerFF = dao.getValue("buyerFF"); @@ -308,31 +301,30 @@ const checkOnInit = (dirPath, msgIdSet) => { buyerFF ) { onInitObj.buyerFF = `Buyer app finder fee can't change in /${constants.RET_ONINIT}`; - // console.log(`Buyer app finder fee amount can't change in /on_init`); + // logger.info(`Buyer app finder fee amount can't change in /on_init`); } } catch (error) { - console.log( - `!!Error while checking buyer app finder fee in /${constants.RET_ONINIT}`, - error + logger.error( + `!!Error while checking buyer app finder fee in /${constants.RET_ONINIT}, ${error.stack}` ); } try { - console.log( + logger.info( `Checking Quote Object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` ); if (!_.isEqual(dao.getValue("quoteObj"), on_init.quote)) { onInitObj.quoteErr = `Discrepancies between the quote object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; } } catch (error) { - console.log( + logger.error( `!!Error while checking quote object in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}` ); } //CHECKING PAYMENT OBJECT IN /ON_INIT // try { - // console.log("checking payment object in /on_init"); + // logger.info("checking payment object in /on_init"); // if ( // on_init.payment.collected_by === "BAP" && // on_init.payment["@ondc/org/settlement_details"][0][ @@ -354,14 +346,14 @@ const checkOnInit = (dirPath, msgIdSet) => { // dao.setValue("paymentType", on_init.payment.type); // dao.setValue("pymntCollectedBy", on_init.payment.collected_by); // } catch (error) { - // console.log( + // logger.info( // `!!Error while checking payment object in /${constants.RET_ONINIT}`, // error // ); // } try { - console.log(`checking payment object in /${constants.RET_ONINIT}`); + logger.info(`checking payment object in /${constants.RET_ONINIT}`); if ( on_init.payment["@ondc/org/settlement_details"][0][ "settlement_counterparty" @@ -370,13 +362,13 @@ const checkOnInit = (dirPath, msgIdSet) => { onInitObj.sttlmntcntrparty = `settlement_counterparty is expected to be 'seller-app' in @ondc/org/settlement_details`; } } catch (error) { - console.log( + logger.error( `!!Error while checking payment object in /${constants.RET_ONINIT}` ); } try { - console.log( + logger.info( `storing payment settlement details in /${constants.RET_ONINIT}` ); if (on_init.payment.hasOwnProperty("@ondc/org/settlement_details")) @@ -388,17 +380,18 @@ const checkOnInit = (dirPath, msgIdSet) => { onInitObj.pymntSttlmntObj = `payment settlement_details missing in /${constants.RET_ONINIT}`; } } catch (error) { - console.log( + logger.error( `!!Error while storing payment settlement details in /${constants.RET_ONINIT}` ); } - dao.setValue("onInitObj", onInitObj); + // dao.setValue("onInitObj", onInitObj); + return onInitObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONINIT} API!`); + logger.info(`!!File not found for /${constants.RET_ONINIT} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_ONINIT} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retOnSearch.js b/utilities/log-validation-utility/utils/retail/retOnSearch.js index 97c1eda..4ccd874 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSearch.js +++ b/utilities/log-validation-utility/utils/retail/retOnSearch.js @@ -5,6 +5,8 @@ const constants = require("../constants"); const utils = require("../utils"); const { checkContext } = require("../../services/service"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); +// const address = require("../reverseGeocodeUtil"); const checkOnSearch = (dirPath, msgIdSet) => { let onSrchObj = {}; @@ -13,59 +15,55 @@ const checkOnSearch = (dirPath, msgIdSet) => { let onSearch = fs.readFileSync(dirPath + `/${constants.RET_ONSEARCH}.json`); onSearch = JSON.parse(onSearch); try { - console.log(`Validating Schema for ${constants.RET_ONSEARCH} API`); + logger.info(`Validating Schema for ${constants.RET_ONSEARCH} API`); const vs = validateSchema("retail", constants.RET_ONSEARCH, onSearch); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onSrchObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONSEARCH}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONSEARCH}, ${error.stack}` ); } try { - console.log(`Storing BAP_ID and BPP_ID in /${constants.RET_ONSEARCH}`); + logger.info(`Storing BAP_ID and BPP_ID in /${constants.RET_ONSEARCH}`); dao.setValue("bapId", onSearch.context.bap_id); dao.setValue("bppId", onSearch.context.bpp_id); } catch (error) { - console.log( - `!!Error while storing BAP and BPP Ids in /${constants.RET_ONSEARCH}`, - error + logger.error( + `!!Error while storing BAP and BPP Ids in /${constants.RET_ONSEARCH}, ${error.stack}` ); } try { - console.log(`Checking context for ${constants.RET_ONSEARCH} API`); + logger.info(`Checking context for ${constants.RET_ONSEARCH} API`); res = checkContext(onSearch.context, constants.RET_ONSEARCH); if (!res.valid) { Object.assign(onSrchObj, res.ERRORS); } } catch (error) { - console.log( - `Some error occurred while checking /${constants.RET_ONSEARCH} context`, - error + logger.info( + `Some error occurred while checking /${constants.RET_ONSEARCH} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` ); if (!_.isEqual(dao.getValue("city"), onSearch.context.city)) { onSrchObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}`; } } catch (error) { - console.log( - `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}`, - error + logger.info( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` ); const tmpstmp = dao.getValue("tmpstmp"); @@ -73,7 +71,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { onSrchObj.tmpstmp = `Context timestamp for /${constants.RET_SEARCH} api cannot be greater than or equal to /${constants.RET_ONSEARCH} api`; } else { const timeDiff = utils.timeDiff(onSearch.context.timestamp, tmpstmp); - console.log(timeDiff); + logger.info(timeDiff); if (timeDiff > 5000) { onSrchObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONSEARCH} and /${constants.RET_SEARCH} should be smaller than 5 sec`; } @@ -81,13 +79,13 @@ const checkOnSearch = (dirPath, msgIdSet) => { dao.setValue("tmpstmp", onSearch.context.timestamp); } catch (error) { - console.log( + logger.info( `Error while comparing timestamp for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` ); if (!_.isEqual(dao.getValue("txnId"), onSearch.context.transaction_id)) { @@ -95,14 +93,13 @@ const checkOnSearch = (dirPath, msgIdSet) => { } // dao.setValue("txnId", onSearch.context.transaction_id); } catch (error) { - console.log( - `Error while comparing transaction ids for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api`, - error + logger.info( + `Error while comparing transaction ids for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Message Ids of /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH}` ); if (!_.isEqual(dao.getValue("msgId"), onSearch.context.message_id)) { @@ -110,9 +107,8 @@ const checkOnSearch = (dirPath, msgIdSet) => { } msgIdSet.add(onSearch.context.message_id); } catch (error) { - console.log( - `Error while comparing message ids for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api`, - error + logger.info( + `Error while comparing message ids for /${constants.RET_SEARCH} and /${constants.RET_ONSEARCH} api, ${error.stack}` ); } @@ -121,7 +117,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { let prvdrsId = new Set(); try { - console.log( + logger.info( `Saving static fulfillment ids in /${constants.RET_ONSEARCH}` ); @@ -133,14 +129,13 @@ const checkOnSearch = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `Error while saving static fulfillment ids in /${constants.RET_ONSEARCH}`, - error + logger.info( + `Error while saving static fulfillment ids in /${constants.RET_ONSEARCH}, ${error.stack}` ); } try { - console.log( + logger.info( `Checking Providers info (bpp/providers) in /${constants.RET_ONSEARCH}` ); let i = 0; @@ -152,7 +147,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { let prvdrLocId = new Set(); let ctgryId = new Set(); - console.log( + logger.info( `Validating uniqueness for provider id in bpp/providers[${i}]...` ); let prvdr = bppPrvdrs[i]; @@ -166,15 +161,35 @@ const checkOnSearch = (dirPath, msgIdSet) => { prvdrsId.add(prvdr.id); } - console.log( + logger.info( `Checking store enable/disable timestamp in bpp/providers[${i}]` ); if (!_.isEqual(prvdr.time.timestamp, tmpstmp)) { onSrchObj.storeEnblDsbl = `store enable/disable timestamp (/bpp/providers/time/timestamp) must match context.timestamp`; } - console.log(`Checking store timings in bpp/providers[${i}]`); + logger.info(`Checking store timings in bpp/providers[${i}]`); prvdr.locations.forEach((loc, iter) => { + try { + logger.info( + `Checking gps precision of store location in /bpp/providers[${i}]/locations[${iter}]` + ); + const has = Object.prototype.hasOwnProperty; + if (has.call(loc, "gps")) { + if (!utils.checkGpsPrecision(loc.gps)) { + onSrchObj.gpsPrecision = `/bpp/providers[${i}]/locations[${iter}]/gps coordinates must be specified with at least six decimal places of precision.`; + } + } + + // const addr = address.getReverseGeocode(lat, long); + // console.log("DDRESS", addr); + } catch (error) { + logger.error( + `!!Error while checking gps precision of store location in /bpp/providers[${i}]/locations[${iter}]`, + error + ); + } + if (prvdrLocId.has(loc.id)) { const key = `prvdr${i}${loc.id}${iter}`; onSrchObj[ @@ -184,7 +199,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { prvdrLocId.add(loc.id); } - console.log("Checking store days..."); + logger.info("Checking store days..."); const days = loc.time.days.split(","); days.forEach((day) => { day = parseInt(day); @@ -196,7 +211,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { } }); - console.log("Checking fixed or split timings"); + logger.info("Checking fixed or split timings"); //scenario 1: range =1 freq/times =1 if ( loc.time.range && @@ -220,7 +235,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { //scenario 3: range=1 (start and end not compliant) frequency=0; if ("range" in loc.time) { - console.log("checking range (fixed timings) start and end"); + logger.info("checking range (fixed timings) start and end"); const startTime = "start" in loc.time.range ? parseInt(loc.time.range.start) : ""; const endTime = @@ -237,14 +252,14 @@ const checkOnSearch = (dirPath, msgIdSet) => { }); try { - console.log( + logger.info( `Checking items for provider (${prvdr.id}) in bpp/providers[${i}]` ); let j = 0; const items = onSearch["bpp/providers"][i]["items"]; const iLen = items.length; while (j < iLen) { - console.log( + logger.info( `Validating uniqueness for item id in bpp/providers[${i}].items[${j}]...` ); let item = items[j]; @@ -258,7 +273,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { itemsId.add(item.id); } - console.log( + logger.info( `Checking available and maximum count for item id: ${item.id}` ); if ("available" in item.quantity && "maximum" in item.quantity) { @@ -273,7 +288,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { } } - console.log( + logger.info( `Checking selling price and maximum price for item id: ${item.id}` ); @@ -289,7 +304,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { } } - console.log(`Checking category_id for item id: ${item.id}`); + logger.info(`Checking category_id for item id: ${item.id}`); if ("category_id" in item) { ctgryId.add(item.category_id); const categoryList = [ @@ -316,12 +331,22 @@ const checkOnSearch = (dirPath, msgIdSet) => { if (categoryList.includes(item.category_id)) { if (!prvdr["@ondc/org/fssai_license_no"]) { onSrchObj.fssaiLiceNo = `@ondc/org/fssai_license_no is mandatory for category_id ${item.category_id}`; + } else if ( + prvdr.hasOwnProperty("@ondc/org/fssai_license_no") + ) { + if (prvdr["@ondc/org/fssai_license_no"].length != 14) { + onSrchObj.fssaiLiceNo = `@ondc/org/fssai_license_no must contain a valid 14 digit FSSAI No.`; + } } } - } catch (error) {} + } catch (error) { + logger.info( + `!!Error occurred while checking fssai license no for provider ${prvdr.id}` + ); + } } - console.log(`Checking fulfillment_id for item id: ${item.id}`); + logger.info(`Checking fulfillment_id for item id: ${item.id}`); if (!onSearchFFIds.has(item.fulfillment_id)) { const key = `prvdr${i}item${j}ff`; @@ -330,7 +355,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { ] = `fulfillment_id in /bpp/providers[${i}]/items[${j}] should map to one of the fulfillments id in bpp/fulfillments`; } - console.log(`Checking location_id for item id: ${item.id}`); + logger.info(`Checking location_id for item id: ${item.id}`); if (!prvdrLocId.has(item.location_id)) { const key = `prvdr${i}item${j}loc`; @@ -339,31 +364,38 @@ const checkOnSearch = (dirPath, msgIdSet) => { ] = `location_id in /bpp/providers[${i}]/items[${j}] should be one of the locations id in /bpp/providers[${i}]/locations`; } - console.log( + logger.info( `Checking consumer care details for item id: ${item.id}` ); if ("@ondc/org/contact_details_consumer_care" in item) { let consCare = item["@ondc/org/contact_details_consumer_care"]; consCare = consCare.split(","); - checkEmail = utils.emailRegex(consCare[1].trim()); - if (isNaN(consCare[2].trim()) || !checkEmail) { + if (consCare.length < 3) { const key = `prvdr${i}consCare`; onSrchObj[ key ] = `@ondc/org/contact_details_consumer_care should be in the format "name,email,contactno" in /bpp/providers[${i}]/items`; + } else { + checkEmail = utils.emailRegex(consCare[1].trim()); + if (isNaN(consCare[2].trim()) || !checkEmail) { + const key = `prvdr${i}consCare`; + onSrchObj[ + key + ] = `@ondc/org/contact_details_consumer_care should be in the format "name,email,contactno" in /bpp/providers[${i}]/items`; + } } } j++; } } catch (error) { - console.log( + logger.error( `!!Errors while checking items in bpp/providers[${i}]`, error ); } try { - console.log( + logger.info( `Checking serviceability construct for bpp/providers[${i}]` ); @@ -576,7 +608,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { } }); } catch (error) { - console.log( + logger.error( `!!Error while checking serviceability construct for bpp/providers[${i}]`, error ); @@ -585,20 +617,20 @@ const checkOnSearch = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while checking Providers info in /${constants.RET_ONSEARCH}`, - error + logger.error( + `!!Error while checking Providers info in /${constants.RET_ONSEARCH}, ${error.stack}` ); } dao.setValue("onSearch", onSearch); - console.log(onSrchObj); - dao.setValue("onSrchObj", onSrchObj); + + // dao.setValue("onSrchObj", onSrchObj); + return onSrchObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for ${constants.RET_ONSEARCH} API!`); + logger.info(`!!File not found for ${constants.RET_ONSEARCH} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_ONSEARCH} API` ); } diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index d5a6ee0..da571d2 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -5,6 +5,7 @@ const dao = require("../../dao/dao"); const utils = require("../utils"); const validateSchema = require("../schemaValidation"); const constants = require("../constants"); +const logger = require("../logger"); const checkOnSelect = (dirPath, msgIdSet) => { let onSlctObj = {}; @@ -14,47 +15,44 @@ const checkOnSelect = (dirPath, msgIdSet) => { on_select = JSON.parse(on_select); try { - console.log(`Checking context for /${constants.RET_ONSELECT} API`); //checking context + logger.info(`Checking context for /${constants.RET_ONSELECT} API`); //checking context res = checkContext(on_select.context, constants.RET_ONSELECT); if (!res.valid) { Object.assign(onSlctObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONSELECT} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONSELECT} context, ${error.stack}` ); } try { - console.log(`Validating Schema for /${constants.RET_ONSELECT} API`); + logger.info(`Validating Schema for /${constants.RET_ONSELECT} API`); const vs = validateSchema("retail", constants.RET_ONSELECT, on_select); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onSlctObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONSELECT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}` ); if (!_.isEqual(dao.getValue("city"), on_select.context.city)) { onSlctObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSELECT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` ); const tmpstmp = dao.getValue("tmpstmp"); @@ -62,35 +60,33 @@ const checkOnSelect = (dirPath, msgIdSet) => { onSlctObj.tmpstmp = `Timestamp for /${constants.RET_SELECT} api cannot be greater than or equal to /${constants.RET_ONSELECT} api`; } else { const timeDiff = utils.timeDiff(on_select.context.timestamp, tmpstmp); - console.log(timeDiff); + logger.info(timeDiff); if (timeDiff > 5000) { onSlctObj.tmpstmp = `context/timestamp difference between /${constants.RET_ONSELECT} and /${constants.RET_SELECT} should be smaller than 5 sec`; } } dao.setValue("tmpstmp", on_select.context.timestamp); } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_SELECT} and /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_SELECT} and /${constants.RET_ONSELECT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` ); if (!_.isEqual(dao.getValue("txnId"), on_select.context.transaction_id)) { onSlctObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Message Ids of /${constants.RET_SELECT} and /${constants.RET_ONSELECT}` ); if (!_.isEqual(dao.getValue("msgId"), on_select.context.message_id)) { @@ -104,22 +100,20 @@ const checkOnSelect = (dirPath, msgIdSet) => { // msgId = select.context.message_id; msgIdSet.add(on_select.context.message_id); } catch (error) { - console.log( - `Error while comparing message ids for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api`, - error + logger.info( + `Error while comparing message ids for /${constants.RET_SELECT} and /${constants.RET_ONSELECT} api, ${error.stack}` ); } let on_select_error = {}; try { - console.log(`Checking domain-error in /${constants.RET_ONSELECT}`); + logger.info(`Checking domain-error in /${constants.RET_ONSELECT}`); if (on_select.hasOwnProperty("error")) { on_select_error = on_select.error; } } catch (error) { - console.log( - `Error while checking domain-error in /${constants.RET_ONSELECT}`, - error + logger.info( + `Error while checking domain-error in /${constants.RET_ONSELECT}, ${error.stack}` ); } @@ -127,21 +121,20 @@ const checkOnSelect = (dirPath, msgIdSet) => { let itemFlfllmnts = {}; try { - console.log( + logger.info( `Checking provider id in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}` ); if (dao.getValue("providerId") != on_select.provider.id) { onSlctObj.prvdrId = `provider.id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}`; } } catch (error) { - console.log( - `Error while comparing provider ids in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}`, - error + logger.info( + `Error while comparing provider ids in /${constants.RET_ONSEARCH} and /${constants.RET_ONSELECT}, ${error.stack}` ); } try { - console.log(`Item Id and Fulfillment Id Mapping in /on_select`); + logger.info(`Item Id and Fulfillment Id Mapping in /on_select`); let i = 0; const len = on_select.items.length; while (i < len) { @@ -157,14 +150,13 @@ const checkOnSelect = (dirPath, msgIdSet) => { i++; } } catch (error) { - console.log( - `!!Error while checking Item Id and Fulfillment Id Mapping in /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while checking Item Id and Fulfillment Id Mapping in /${constants.RET_ONSELECT}, ${error.stack}` ); } try { - console.log("Mapping and storing item Id and fulfillment Id"); + logger.info("Mapping and storing item Id and fulfillment Id"); let i = 0; const len = on_select.items.length; while (i < len) { @@ -174,23 +166,42 @@ const checkOnSelect = (dirPath, msgIdSet) => { } dao.setValue("itemFlfllmnts", itemFlfllmnts); } catch (error) { - console.log( - "!!Error occurred while mapping and storing item Id and fulfillment Id", - error + logger.error( + `!!Error occurred while mapping and storing item Id and fulfillment Id, ${error.stack}` ); } try { - console.log(`Checking fulfillments' state in ${constants.RET_ONSELECT}`); - let nonServiceableFlag = 0; + logger.info(`Checking TAT and TTS in /${constants.RET_ONSELECT}`); + const tts = dao.getValue("timeToShip"); + on_select.fulfillments.forEach((ff, indx) => { + const tat = utils.isoDurToSec(ff["@ondc/org/TAT"]); + + if (tat < tts) { + onSlctObj.ttstat = `/fulfillments[${indx}]/@ondc/org/TAT (O2D) in /${constants.RET_ONSELECT} can't be smaller than @ondc/org/time_ship (O2S) in /${constants.RET_ONSEARCH}`; + } + if (tat === tts) { + onSlctObj.ttstat = `/fulfillments[${indx}]/@ondc/org/TAT (O2D) in /${constants.RET_ONSELECT} can't be equal to @ondc/org/time_ship (O2S) in /${constants.RET_ONSEARCH}`; + } + + logger.info(tat, "asdfasdf", tts); + }); + } catch (error) { + logger.error( + `!!Error while checking TAT and TTS in /${constants.RET_ONSELECT}` + ); + } + + let nonServiceableFlag = 0; + try { + logger.info(`Checking fulfillments' state in ${constants.RET_ONSELECT}`); const ffState = on_select.fulfillments.every((ff) => { const ffDesc = ff.state.descriptor; - if (ffDesc.code.toLowerCase() === "non-serviceable") { + if (ffDesc.code === "Non-serviceable") { nonServiceableFlag = 1; } return ffDesc.hasOwnProperty("code") - ? ffDesc.code.toLowerCase() === "serviceable" || - ffDesc.code.toLowerCase() === "non-serviceable" + ? ffDesc.code === "Serviceable" || ffDesc.code === "Non-serviceable" : false; }); @@ -205,9 +216,8 @@ const checkOnSelect = (dirPath, msgIdSet) => { onSlctObj.notServiceable = `Non Serviceable Domain error should be provided when fulfillment is not serviceable`; } } catch (error) { - console.log( - `!!Error while checking fulfillments' state in /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while checking fulfillments' state in /${constants.RET_ONSELECT}, ${error.stack}` ); } @@ -215,35 +225,16 @@ const checkOnSelect = (dirPath, msgIdSet) => { let onSelectItemsPrice = 0; //Price of only items in /on_select try { - console.log( + logger.info( `Comparing count of items in ${constants.RET_SELECT} and ${constants.RET_ONSELECT}` ); let itemsIdList = dao.getValue("itemsIdList"); - console.log(itemsIdList); + logger.info(itemsIdList); on_select.quote.breakup.forEach((item) => { if ( item["@ondc/org/item_id"] in itemsIdList && item["@ondc/org/title_type"] === "item" ) { - // if ( - // itemsIdList[item["@ondc/org/item_id"]] === - // item["@ondc/org/item_quantity"].count || - // (itemsIdList[item["@ondc/org/item_id"]] > - // item["@ondc/org/item_quantity"].count && - // on_select_error && - // on_select_error.type === "DOMAIN-ERROR" && - // on_select_error.code === "400002") - // ) { - // console.log( - // `count of item with id: ${item["@ondc/org/item_id"]} is as per the API contract` - // ); - // } else { - // let cntkey = `cnt${item["@ondc/org/item_id"]}`; - // onSlctObj[ - // cntkey - // ] = `Warning: Count of item with id: ${item["@ondc/org/item_id"]} does not match in ${constants.RET_SELECT} & ${constants.RET_ONSELECT} (suitable domain error should be provided)`; - // } - if ( itemsIdList[item["@ondc/org/item_id"]] != item["@ondc/org/item_quantity"].count && @@ -265,23 +256,22 @@ const checkOnSelect = (dirPath, msgIdSet) => { }); } catch (error) { // onSlctObj.countErr = `Count of item does not match with the count in /select`; - console.log( - `!!Error while comparing count items in ${constants.RET_SELECT} and ${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while comparing count items in ${constants.RET_SELECT} and ${constants.RET_ONSELECT}, ${error.stack}` ); } try { - console.log( + logger.info( `-x-x-x-x-Quote Breakup ${constants.RET_ONSELECT} all checks-x-x-x-x` ); let itemsIdList = dao.getValue("itemsIdList"); let itemsCtgrs = dao.getValue("itemsCtgrs"); on_select.quote.breakup.forEach((element, i) => { let titleType = element["@ondc/org/title_type"]; - // console.log(element.price.value); + // logger.info(element.price.value); - console.log( + logger.info( `Calculating quoted Price Breakup for element ${element.title}` ); onSelectPrice += parseFloat(element.price.value); @@ -294,7 +284,7 @@ const checkOnSelect = (dirPath, msgIdSet) => { ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; } - console.log( + logger.info( `Comparing individual item's total price and unit price ` ); if (!element.hasOwnProperty("item")) { @@ -307,7 +297,7 @@ const checkOnSelect = (dirPath, msgIdSet) => { onSlctObj.priceBreakup = `Item's unit and total price mismatch for id: ${element["@ondc/org/item_id"]}`; } - console.log( + logger.info( `checking available and maximum count in ${constants.RET_ONSELECT}` ); @@ -326,7 +316,7 @@ const checkOnSelect = (dirPath, msgIdSet) => { } } - console.log(`Calculating Items' prices in /${constants.RET_ONSELECT}`); + logger.info(`Calculating Items' prices in /${constants.RET_ONSELECT}`); if (element["@ondc/org/item_id"] in itemsIdList) { if ( titleType === "item" || @@ -343,7 +333,15 @@ const checkOnSelect = (dirPath, msgIdSet) => { let brkupitemsid = `brkupitemstitles${i}`; onSlctObj[ brkupitemsid - ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[] (should be a valid item id)`; + } + } + if (["tax", "discount", "packing", "misc"].includes(titleType)) { + if (parseFloat(element.price.value) == 0) { + let key = `breakupItem${titletype}`; + onSlctObj[ + key + ] = `${titleType} line item should not be present if price=0`; } } @@ -358,14 +356,14 @@ const checkOnSelect = (dirPath, msgIdSet) => { let brkupffid = `brkupfftitles${i}`; onSlctObj[ brkupffid - ] = `${titleType} with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in fulfillments[]`; + ] = `invalid id: ${element["@ondc/org/item_id"]} in ${titleType} line item (should be a valid fulfillment_id)`; } } }); dao.setValue("onSelectPrice", on_select.quote.price.value); - console.log( + logger.info( `Matching quoted Price ${parseFloat( on_select.quote.price.value )} with Breakup Price ${onSelectPrice}` @@ -374,23 +372,38 @@ const checkOnSelect = (dirPath, msgIdSet) => { onSlctObj.quoteBrkup = `quote.price.value ${on_select.quote.price.value} does not match with the price breakup ${onSelectPrice}`; } let selectedPrice = dao.getValue("selectedPrice"); - console.log( + logger.info( `Matching price breakup of items ${onSelectItemsPrice} (/${constants.RET_ONSELECT}) with selected items price ${selectedPrice} (${constants.RET_SELECT})` ); if (onSelectItemsPrice != selectedPrice) { onSlctObj.priceErr = `Warning: Quoted Price in /${constants.RET_ONSELECT} INR ${onSelectItemsPrice} does not match with the total price of items in /${constants.RET_SELECT} INR ${selectedPrice}`; - console.log("Quoted Price and Selected Items price mismatch"); + logger.info("Quoted Price and Selected Items price mismatch"); + } + } catch (error) { + logger.error( + `!!Error while checking and comparing the quoted price in /${constants.RET_ONSELECT}, ${error.stack}` + ); + } + + try { + // checking if delivery line item present in case of Serviceable + const quoteBreakup = on_select.quote.breakup; + const deliveryItems = quoteBreakup.filter( + (item) => item["@ondc/org/title_type"] === "delivery" + ); + const noOfDeliveries = deliveryItems.length; + if (!noOfDeliveries && !nonServiceableFlag) { + onSlctObj.deliveryLineItem = `delivery line item must be present in quote/breakup (if location is serviceable)`; } } catch (error) { - console.log( - `!!Error while checking and comparing the quoted price in /${constants.RET_ONSELECT}`, - error + logger.info( + `!!Error occurred while checking delivery line item in /${constants.RET_ONSELECT}` ); } try { - console.log( + logger.info( `Checking payment breakup title & type in /${constants.RET_ONSELECT}` ); on_select.quote.breakup.forEach((item) => { @@ -421,42 +434,41 @@ const checkOnSelect = (dirPath, msgIdSet) => { } }); } catch (error) { - console.log( - `!!Error while checking payment breakup title & type in /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while checking payment breakup title & type in /${constants.RET_ONSELECT}, ${error.stack}` ); } try { //matching fulfillments TAT - console.log("Checking Fulfillment TAT..."); + logger.info("Checking Fulfillment TAT..."); on_select.fulfillments.forEach((ff) => { if (!ff["@ondc/org/TAT"]) { - console.log( + logger.info( `Fulfillment TAT must be present for Fulfillment ID: ${ff.id}` ); onSlctObj.ffTAT = `Fulfillment TAT must be present for fulfillment ID: ${ff.id}`; } }); } catch (error) { - console.log( + logger.info( `Error while checking fulfillments TAT in /${constants.RET_ONSELECT}` ); } try { - console.log("Checking quote validity quote.ttl"); + logger.info("Checking quote validity quote.ttl"); if (!on_select.quote.hasOwnProperty("ttl")) { onSlctObj.qtTtl = "quote.ttl: Validity of the quote is missing"; } } catch (error) { - console.log( + logger.error( `!!Error while checking quote.ttl in /${constants.RET_ONSELECT}` ); } try { - console.log(`Storing Quote object in /${constants.RET_ONSELECT}`); + logger.info(`Storing Quote object in /${constants.RET_ONSELECT}`); on_select.quote.breakup.forEach((element) => { if (element["@ondc/org/title_type"] === "item") { if (element.hasOwnProperty("item")) { @@ -467,20 +479,20 @@ const checkOnSelect = (dirPath, msgIdSet) => { //saving on select quote dao.setValue("quoteObj", on_select.quote); } catch (error) { - console.log( - `!!Error while storing quote object in /${constants.RET_ONSELECT}`, - error + logger.error( + `!!Error while storing quote object in /${constants.RET_ONSELECT}, ${error.stack}` ); } - dao.setValue("onSlctObj", onSlctObj); + // dao.setValue("onSlctObj", onSlctObj); + logger.info(onSlctObj); + return onSlctObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONSELECT} API`); + logger.info(`!!File not found for /${constants.RET_ONSELECT} API`); } else { - console.log( - `!!Some error occurred while checking /${constants.RET_ONSELECT} API`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONSELECT} API, ${error.stack}` ); } } diff --git a/utilities/log-validation-utility/utils/retail/retOnStatus.js b/utilities/log-validation-utility/utils/retail/retOnStatus.js index 8566510..cd6f740 100644 --- a/utilities/log-validation-utility/utils/retail/retOnStatus.js +++ b/utilities/log-validation-utility/utils/retail/retOnStatus.js @@ -5,196 +5,239 @@ const { checkContext } = require("../../services/service"); const utils = require("../utils"); const validateSchema = require("../schemaValidation"); const constants = require("../constants"); +const logger = require("../logger"); -const checkOnStatus = (dirPath, msgIdSet) => { +const checkOnStatus = (msgIdSet, on_status, state) => { let onStatObj = {}; + let cntxtTmpstmp = ""; + try { - let on_status = fs.readFileSync( - dirPath + `/${constants.RET_ONSTATUS}.json` - ); - - on_status = JSON.parse(on_status); - - try { - console.log(`Validating Schema for /${constants.RET_ONSTATUS} API`); - const vs = validateSchema("retail", constants.RET_ONSTATUS, on_status); - if (vs != "error") { - // console.log(vs); - Object.assign(onStatObj, vs); - } - } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONSTATUS}`, - error - ); + logger.info( + `Validating Schema for /${constants.RET_ONSTATUS}_${state} API` + ); + const vs = validateSchema("retail", constants.RET_ONSTATUS, on_status); + if (vs != "error") { + // logger.info(vs); + Object.assign(onStatObj, vs); } + } catch (error) { + logger.info( + `!!Error occurred while performing schema validation for /${constants.RET_ONSTATUS}_${state}`, + error + ); + } - try { - console.log("Checking context for /${constants.RET_ONSTATUS} API"); //checking context - res = checkContext(on_status.context, "on_status"); - if (!res.valid) { - Object.assign(onStatObj, res.ERRORS); - } - } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONSTATUS} context`, - error - ); + try { + logger.info(`Checking context for /${constants.RET_ONSTATUS}_${state} API`); //checking context + res = checkContext(on_status.context, "on_status"); + if (!res.valid) { + Object.assign(onStatObj, res.ERRORS); } + } catch (error) { + logger.info( + `!!Some error occurred while checking /${constants.RET_ONSTATUS}_${state} context`, + error + ); + } - try { - console.log( - `Comparing city of ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}` - ); - if (!_.isEqual(dao.getValue("city"), on_status.context.city)) { - onStatObj.city = `City code mismatch in ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}`; - } - } catch (error) { - console.log( - `!!Error while comparing city in ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}`, - error - ); + try { + logger.info( + `Comparing city of ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}_${state}` + ); + if (!_.isEqual(dao.getValue("city"), on_status.context.city)) { + onStatObj.city = `City code mismatch in ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}_${state}`; } + } catch (error) { + logger.info( + `!!Error while comparing city in ${constants.RET_SEARCH} and /${constants.RET_ONSTATUS}_${state}`, + error + ); + } - try { - console.log( - `Comparing timestamp of /${constants.RET_ONSTATUS} and /${constants.RET_ONCONFIRM}` - ); - if (_.gte(dao.getValue("tmpstmp"), on_status.context.timestamp)) { - onStatObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONSTATUS} api`; - } - } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS} api`, - error - ); + try { + logger.info( + `Comparing timestamp of /${constants.RET_ONSTATUS}_${state} and /${constants.RET_ONCONFIRM}` + ); + if (_.gte(dao.getValue("tmpstmp"), on_status.context.timestamp)) { + onStatObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONSTATUS}_${state} api`; } + cntxtTmpstmp = on_status.context.timestamp; + } catch (error) { + logger.info( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}_${state} api`, + error + ); + } - try { - console.log( - `Comparing timestamp of /${constants.RET_STATUS} and /${constants.RET_ONSTATUS}` - ); - if (_.gte(dao.getValue("statTmpstmp"), on_status.context.timestamp)) { - onStatObj.tmpstmp = `Timestamp for /${constants.RET_STATUS} api cannot be greater than or equal to /${constants.RET_ONSTATUS} api`; - } - } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_STATUS} and /${constants.RET_ONSTATUS} api`, - error - ); - } + // try { + // logger.info( + // `Comparing timestamp of /${constants.RET_STATUS} and /${constants.RET_ONSTATUS}_${state}` + // ); + // if (_.gte(dao.getValue("statTmpstmp"), on_status.context.timestamp)) { + // onStatObj.tmpstmp = `Timestamp for /${constants.RET_STATUS} api cannot be greater than or equal to /${constants.RET_ONSTATUS}_${state} api`; + // } + // } catch (error) { + // logger.info( + // `!!Error while comparing timestamp for /${constants.RET_STATUS} and /${constants.RET_ONSTATUS}_${state} api`, + // error + // ); + // } - try { - console.log( - `Comparing transaction Ids of /select and /${constants.RET_ONSTATUS}` - ); - if (!_.isEqual(dao.getValue("txnId"), on_status.context.transaction_id)) { - onStatObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; - } - } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSTATUS} api`, - error - ); + try { + logger.info( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONSTATUS}_${state}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_status.context.transaction_id)) { + onStatObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } + } catch (error) { + logger.info( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSTATUS}_${state} api`, + error + ); + } - try { - console.log(`Checking Message Id of /${constants.RET_ONSTATUS}`); - if (!_.isEqual(dao.getValue("msgId"), on_status.context.message_id)) { - onStatObj.msgId = `Message Id for /${constants.RET_STATUS} and /${constants.RET_ONSTATUS} api should be same`; - } - - // if (msgIdSet.has(status.context.message_id)) { - // statObj.msgId2 = "Message Id cannot be same for different sets of APIs"; - // } - // msgId = status.context.message_id; - msgIdSet.add(on_status.context.message_id); - } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_ONSTATUS}`, - error - ); + try { + logger.info(`Checking Message Id of /${constants.RET_ONSTATUS}_${state}`); + // if (!_.isEqual(dao.getValue("msgId"), on_status.context.message_id)) { + // onStatObj.msgId = `Message Id for /${constants.RET_STATUS} and /${constants.RET_ONSTATUS}_${state} api should be same`; + // } + + if (msgIdSet.has(on_status.context.message_id)) { + onStatObj.msgId2 = "Message Id cannot be same for different sets of APIs"; } + // msgId = status.context.message_id; + msgIdSet.add(on_status.context.message_id); + } catch (error) { + logger.info( + `!!Error while checking message id for /${constants.RET_ONSTATUS}_${state}`, + error + ); + } - on_status = on_status.message.order; + on_status = on_status.message.order; - try { - console.log( - `Comparing order Id in /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}` - ); - if (on_status.id != dao.getValue("cnfrmOrdrId")) { - console.log( - `Order id (/${constants.RET_ONSTATUS}) mismatches with /${constants.RET_CONFIRM})` - ); - onStatObj.onStatusOdrId = `Order id in /${constants.RET_CONFIRM} and /${constants.RET_ONSTATUS} do not match`; - } - } catch (error) { - console.log( - `!!Error while comparing order id in /${constants.RET_ONSTATUS} and /${constants.RET_CONFIRM}`, - error + try { + logger.info( + `Comparing order Id in /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}_${state}` + ); + if (on_status.id != dao.getValue("cnfrmOrdrId")) { + logger.info( + `Order id (/${constants.RET_ONSTATUS}_${state}) mismatches with /${constants.RET_CONFIRM})` ); - // onStatObj.onStatusOrdrId = - // "Order id mismatches in /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}"; + onStatObj.onStatusOdrId = `Order id in /${constants.RET_CONFIRM} and /${constants.RET_ONSTATUS}_${state} do not match`; } - try { - console.log(`Checking order state in /${constants.RET_ONSTATUS}`); - if (!utils.retailOrderState.includes(on_status.state)) { - onStatObj.ordrSt = `Order State in /${constants.RET_ONSTATUS} is not as per the API Contract`; - } - } catch (error) { - // onStatObj.ordrSt = `Order State (/${constants.RET_ONSTATUS}) should be as per the API Contract`; - console.log( - `!!Error while checking order state in /${constants.RET_ONSTATUS}`, - error - ); + } catch (error) { + logger.info( + `!!Error while comparing order id in /${constants.RET_ONSTATUS}_${state} and /${constants.RET_CONFIRM}`, + error + ); + } + // try { + // logger.info(`Checking order state in /${constants.RET_ONSTATUS}_${state}`); + // if (!utils.retailOrderState.includes(on_status.state)) { + // onStatObj.ordrSt = `Order State in /${constants.RET_ONSTATUS}_${state} is not as per the API Contract`; + // } + // } catch (error) { + // // onStatObj.ordrSt = `Order State (/${constants.RET_ONSTATUS}_${state}) should be as per the API Contract`; + // logger.info( + // `!!Error while checking order state in /${constants.RET_ONSTATUS}_${state}`, + // error + // ); + // } + + try { + logger.info( + `Comparing billing object in ${constants.RET_CONFIRM} and /${constants.RET_ONSTATUS}_${state}` + ); + const billing = dao.getValue("billing"); + if (utils.isObjectEqual(billing, on_status.billing).length>0) { + const billingMismatch= utils.isObjectEqual(billing, on_status.billing); + onStatObj.bill = `${billingMismatch.join(", ")} mismatches in /billing in /${constants.RET_CONFIRM} and /${constants.RET_ONSTATUS}_${state}`; } + // dao.setValue("billing", on_confirm.billing); + } catch (error) { + logger.info( + `!Error while comparing billing object in /${constants.RET_CONFIRM} and /${constants.RET_ONSTATUS}_${state}` + ); + } - try { - console.log( - `Checking provider id and location in /${constants.RET_ONSTATUS}` - ); - if (on_status.provider.id != dao.getValue("providerId")) { - onStatObj.prvdrId = `Provider Id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSTATUS}`; - } - - if (on_status.provider.locations[0].id != dao.getValue("providerLoc")) { - onStatObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSTATUS}`; - } - } catch (error) { - console.log( - `!!Error while checking provider id and location in /${constants.RET_ONSTATUS}`, - error - ); + try { + logger.info( + `Checking provider id and location in /${constants.RET_ONSTATUS}_${state}` + ); + if (!_.isEqual(on_status.provider.id, dao.getValue("providerId"))) { + onStatObj.prvdrId = `Provider Id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSTATUS}_${state}`; } - try { - console.log("Checking Fulfillments state"); - on_status.fulfillments.forEach((element) => { - console.log(`Checking fulfillment state for Id ${element.id}`); - if ( - !utils.retailFulfillmentState.includes(element.state.descriptor.code) - ) { - onStatObj.ffStatusState = `Fulfillment State Code in /${constants.RET_ONSTATUS} is not as per the API Contract`; - } - }); - } catch (error) { - console.log( - `Fulfillment state Code (/${constants.RET_ONSTATUS}) should be as per the API Contract.`, - error - ); + if ( + !_.isEqual( + on_status.provider.locations[0].id, + dao.getValue("providerLoc") + ) + ) { + onStatObj.prvdrLoc = `provider.locations[0].id mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_ONSTATUS}_${state}`; + } + } catch (error) { + logger.info( + `!!Error while checking provider id and location in /${constants.RET_ONSTATUS}_${state}`, + error + ); + } + + try { + //checking order timestamps in /on_status + if (!_.isEqual(on_status.created_at, dao.getValue("ordrCrtd"))) { + onStatObj.crtdTmstmp = `order/created_at timestamp can't change (should remain same as in /${constants.RET_CONFIRM})`; } - dao.setValue("onStatObj", onStatObj); - } catch (err) { - if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONSTATUS} API!`); - } else { - console.log( - `!!Some error occurred while checking /${constants.RET_ONSTATUS} API`, - err - ); + if (_.gte(on_status.created_at, on_status.updated_at)) { + onStatObj.ordrTmstmp = `order created_at timestamp must always be earlier than the updated_at timestamp`; } + } catch (error) { + logger.info( + `!!Error while checking order timestamps in /${constants.RET_ONSTATUS}_${state}` + ); } + + // try { + // logger.info(`Checking Fulfillments state in /${constants.RET_ONSTATUS}_${state}`); + // on_status.fulfillments.forEach((element, indx) => { + // logger.info(`Checking fulfillment state for Id ${element.id}`); + // if ( + // !utils.retailFulfillmentState.includes(element.state.descriptor.code) + // ) { + // onStatObj.ffStatusState = `Fulfillment State Code in /${constants.RET_ONSTATUS}_${state} is not as per the API Contract`; + // } else { + // const ffState = element.state.descriptor.code; + // if (ffState === "Order-picked-up") { + // const pickupTime = element.start.time.timestamp; + // if (pickupTime != cntxtTmpstmp) { + // onStatObj.ffTmpstmps = `pickup time /fulfillments[${indx}]/start/time/timestamp must match context/timestamp when fulfillment state is ${ffState} `; + // } + // if (pickupTime != on_status.updated_at) { + // onStatObj.updtdTmpstmps = `order/updated_at timestamp must match context/timestamp when fulfillment state is ${ffState} `; + // } + // } else if (ffState === "Order-delivered") { + // const deliveryTime = element.end.time.timestamp; + // if (deliveryTime != cntxtTmpstmp) { + // onStatObj.ffTmpstmps = `delivery time /fulfillments[${indx}]/end/time/timestamp must match context/timestamp when fulfillment state is ${ffState} `; + // } + // if (deliveryTime != on_status.updated_at) { + // onStatObj.updtdTmpstmps = `order/updated_at timestamp must match context/timestamp when fulfillment state is ${ffState} `; + // } + // } + // } + // }); + // } catch (error) { + // logger.info( + // `Fulfillment state Code (/${constants.RET_ONSTATUS}_${state}) should be as per the API Contract.`, + // error + // ); + // } + + return onStatObj; + // dao.setValue("onStatObj", onStatObj); }; module.exports = checkOnStatus; diff --git a/utilities/log-validation-utility/utils/retail/retOnStatusDelivered.js b/utilities/log-validation-utility/utils/retail/retOnStatusDelivered.js new file mode 100644 index 0000000..8fe3aca --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnStatusDelivered.js @@ -0,0 +1,186 @@ +const checkOnStatus = require("./retOnStatus"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); +const constants = require("../constants"); + +const checkOnStatusDelivered = (dirPath, msgIdSet, state) => { + try { + let on_status = fs.readFileSync( + dirPath + `/${constants.RET_ONSTATUS}_${state}.json` + ); + let compareApi = `/${constants.RET_ONCONFIRM}`; + let isPickedApi = false; + + const pickedOnStatus = fs.existsSync( + dirPath + `/${constants.RET_ONSTATUS}_picked.json` + ); + //setting comparison API to the previous recentmost API + if (pickedOnStatus) { + isPickedApi = true; + compareApi = `/${constants.RET_ONSTATUS}_picked`; + } else { + const pendingOnStatus = fs.existsSync( + dirPath + `/${constants.RET_ONSTATUS}_pending.json` + ); + if (pendingOnStatus) compareApi = `/${constants.RET_ONSTATUS}_pending`; + } + //parsing the on_status call + on_status = JSON.parse(on_status); + + let deliveredObj = {}; + deliveredObj = checkOnStatus(msgIdSet, on_status, state); + const contextTime = on_status.context.timestamp; + on_status = on_status.message.order; + + try { + logger.info( + `comparing context/timestamp of /${constants.RET_ONSTATUS}_${state} and ${compareApi}` + ); + const tmpstmp = dao.getValue("tmpstmp"); + if (_.gte(tmpstmp, contextTime)) { + deliveredObj.tmpstmp = `context/timestamp of ${compareApi} api cannot be greater than or equal to /${constants.RET_ONSTATUS}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error while comparing context/timestamp of /${constants.RET_ONSTATUS}_${state} and ${compareApi}` + ); + } + + try { + logger.info( + `Checking order state in /${constants.RET_ONSTATUS}_${state}` + ); + if (on_status.state != "Completed") { + deliveredObj.ordrState = `order/state should be "Completed" for /${constants.RET_ONSTATUS}_${state}`; + } + } catch (error) { + logger.error( + `!!Error while checking order state in /${constants.RET_ONSTATUS}_${state}` + ); + } + + try { + logger.info( + `Checking delivery timestamp in /${constants.RET_ONSTATUS}_${state}` + ); + const noOfFulfillments = on_status.fulfillments.length; + let orderDelivered = false; + let i = 0; + let deliveryTimestamps = {}; + let pickupTimestamps = {}; + + while (i < noOfFulfillments) { + const fulfillment = on_status.fulfillments[i]; + const ffState = fulfillment.state.descriptor.code; + + //type should be Delivery + if (fulfillment.type != "Delivery") { + i++; + continue; + } + + if (ffState === constants.ORDER_DELIVERED) { + orderDelivered = true; + const pickUpTime = fulfillment.start.time.timestamp; + const deliveryTime = fulfillment.end.time.timestamp; + deliveryTimestamps[fulfillment.id] = deliveryTime; + + // dao.setValue("deliveredTime",deliveryTime); + + try { + //checking delivery time matching with context timestamp + if (!_.lte(deliveryTime, contextTime)) { + deliveredObj.deliveryTime = `delivery timestamp should match context/timestamp and can't be future dated`; + } + } catch (error) { + logger.error( + `!!Error while checking delivery time matching with context timestamp in /${constants.RET_ONSTATUS}_${state}`, + error + ); + } + + try { + //checking delivery time and pickup time + if (_.gte(pickUpTime, deliveryTime)) { + deliveredObj.delPickTime = `delivery timestamp (/end/time/timestamp) can't be less than or equal to the pickup timestamp (start/time/timestamp)`; + } + } catch (error) { + logger.error( + `!!Error while checking delivery time and pickup time in /${constants.RET_ONSTATUS}_${state}`, + error + ); + } + + try { + if (isPickedApi) { + pickupTimestamps = dao.getValue("pickupTimestamps"); + const orderPickedTime = pickupTimestamps[fulfillment.id]; + + if (orderPickedTime && !_.isEqual(pickUpTime, orderPickedTime)) { + deliveredObj.orderPickTime = `pickup time (/start/time/timestamp) can't change (should remain same as in "Order-picked-up" state) `; + } + } else { + pickupTimestamps[fulfillment.id] = pickUpTime; + } + } catch (error) { + logger.error( + `!!Error while comparing pickup time with pickup time in Order-picked-up state`, + error + ); + } + + try { + //checking order/updated_at timestamp + if (!_.gte(on_status.updated_at, deliveryTime)) { + deliveredObj.updatedAt = `order/updated_at timestamp can't be less than the delivery time`; + } + if (!_.gte(contextTime, on_status.updated_at)) { + deliveredObj.updatedAtTime = `order/updated_at timestamp can't be future dated (should match context/timestamp)`; + } + } catch (error) { + logger.info( + `!!Error while checking order/updated_at timestamp in /${constants.RET_ONSTATUS}_${state}`, + error + ); + } + } + + i++; + } + + if (!isPickedApi) { + dao.setValue("pickupTimestamps", pickupTimestamps); + } + + dao.setValue("deliveryTimestamps", deliveryTimestamps); + + if (!orderDelivered) { + deliveredObj.noOrdrDelivered = `fulfillments/state should be Order-delivered for /${constants.RET_ONSTATUS}_${state}`; + } + } catch (error) { + logger.info( + `Error while checking delivery timestamp in /${constants.RET_ONSTATUS}_${state}.json` + ); + } + + return deliveredObj; + + //timestamp validations + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONSTATUS}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONSTATUS}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnStatusDelivered; diff --git a/utilities/log-validation-utility/utils/retail/retOnStatusPending.js b/utilities/log-validation-utility/utils/retail/retOnStatusPending.js new file mode 100644 index 0000000..d866ab2 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnStatusPending.js @@ -0,0 +1,64 @@ +const checkOnStatus = require("./retOnStatus"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const logger = require("../logger"); + +const checkOnStatusPending = (dirPath, msgIdSet, state) => { + try { + let on_status = fs.readFileSync( + dirPath + `/${constants.RET_ONSTATUS}_${state}.json` + ); + on_status = JSON.parse(on_status); + + let pendingObj = {}; + pendingObj = checkOnStatus(msgIdSet, on_status, state); + + //timestamp validation + + try { + logger.info( + `Comparing timestamp of /${constants.RET_ONCONFIRM} and /${constants.RET_ONSTATUS}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), on_status.context.timestamp)) { + pendingObj.tmpstmp1 = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONSTATUS}_${state} api`; + } + dao.setValue("tmpstmp", on_status.context.timestamp); + } catch (error) { + logger.error( + `!!Error occurred while comparing timestamp for /${constants.RET_ONSTATUS}_${state}, ${error.stack}` + ); + } + + const contextTime = on_status.context.timestamp; + on_status = on_status.message.order; + try { + logger.info( + `Comparing order.updated_at and context timestamp for /${constants.RET_ONSTATUS}_${state} API` + ); + + if (!_.isEqual(on_status.updated_at, contextTime)) { + pendingObj.tmpstmp2 = ` order.updated_at timestamp should match context timestamp for /${constants.RET_ONSTATUS}_${state} api`; + } + } catch (error) { + logger.error( + `!!Error occurred while comparing order updated at for /${constants.RET_ONSTATUS}_${state}, ${error.stack}` + ); + } + return pendingObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONSTATUS}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONSTATUS}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnStatusPending; diff --git a/utilities/log-validation-utility/utils/retail/retOnStatusPicked.js b/utilities/log-validation-utility/utils/retail/retOnStatusPicked.js new file mode 100644 index 0000000..42914e5 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnStatusPicked.js @@ -0,0 +1,146 @@ +// Order picked on status + +const checkOnStatus = require("./retOnStatus"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const logger = require("../logger"); + +const checkOnStatusPicked = (dirPath, msgIdSet, state) => { + try { + let on_status = fs.readFileSync( + dirPath + `/${constants.RET_ONSTATUS}_${state}.json` + ); + let compareApi = `/${constants.RET_ONCONFIRM}`; + let isPendingApi = false; + + const pendingOnstatus = fs.existsSync( + dirPath + `/${constants.RET_ONSTATUS}_pending.json` + ); + + //setting comparison API to the previous recentmost API + if (pendingOnstatus) { + isPendingApi = true; + compareApi = `/${constants.RET_ONSTATUS}_pending`; + } + + //parsing the on_status call + on_status = JSON.parse(on_status); + + let pickedupObj = {}; + pickedupObj = checkOnStatus(msgIdSet, on_status, state); + + const contextTime = on_status.context.timestamp; + on_status = on_status.message.order; + //timestamp validations + + try { + logger.info( + `Comparing timestamp of ${compareApi} and /${constants.RET_ONSTATUS}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + pickedupObj.tmpstmp1 = `Timestamp for ${compareApi} api cannot be greater than or equal to /${constants.RET_ONSTATUS}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONSTATUS}_${state}, ${error.stack}` + ); + } + + try { + logger.info( + `Checking order state in /${constants.RET_ONSTATUS}_${state}` + ); + if (on_status.state != "In-progress") { + pickedupObj.ordrState = `order/state should be "In-progress" for /${constants.RET_ONSTATUS}_${state}`; + } + } catch (error) { + logger.error( + `!!Error while checking order state in /${constants.RET_ONSTATUS}_${state}` + ); + } + + try { + logger.info( + `Checking pickup timestamp in /${constants.RET_ONSTATUS}_${state}` + ); + const noOfFulfillments = on_status.fulfillments.length; + let orderPicked = false; + let i = 0; + let pickupTimestamps = {}; + + while (i < noOfFulfillments) { + const fulfillment = on_status.fulfillments[i]; + const ffState = fulfillment.state.descriptor.code; + + //type should be Delivery + if (fulfillment.type != "Delivery") { + i++; + continue; + } + + if (ffState === constants.ORDER_PICKED) { + orderPicked = true; + const pickUpTime = fulfillment.start.time.timestamp; + pickupTimestamps[fulfillment.id] = pickUpTime; + + try { + //checking pickup time matching with context timestamp + if (!_.lte(pickUpTime, contextTime)) { + pickedupObj.pickupTime = `pickup timestamp should match context/timestamp and can't be future dated`; + } + } catch (error) { + logger.error( + `!!Error while checking pickup time matching with context timestamp in /${constants.RET_ONSTATUS}_${state}`, + error + ); + } + + try { + //checking order/updated_at timestamp + if (!_.gte(on_status.updated_at, pickUpTime)) { + pickedupObj.updatedAt = `order/updated_at timestamp can't be less than the pickup time`; + } + if (!_.gte(contextTime, on_status.updated_at)) { + pickedupObj.updatedAtTime = `order/updated_at timestamp can't be future dated (should match context/timestamp)`; + } + } catch (error) { + logger.error( + `!!Error while checking order/updated_at timestamp in /${constants.RET_ONSTATUS}_${state}`, + error + ); + } + } + + i++; + } + + dao.setValue("pickupTimestamps", pickupTimestamps); + + if (!orderPicked) { + pickedupObj.noOrdrPicked = `fulfillments/state should be Order-picked-up for /${constants.RET_ONSTATUS}_${state}`; + } + } catch (error) { + logger.info( + `Error while checking pickup timestamp in /${constants.RET_ONSTATUS}_${state}.json` + ); + } + + return pickedupObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONSTATUS}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONSTATUS}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnStatusPicked; diff --git a/utilities/log-validation-utility/utils/retail/retOnSupport.js b/utilities/log-validation-utility/utils/retail/retOnSupport.js index 37bd6cf..aa9aac4 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSupport.js +++ b/utilities/log-validation-utility/utils/retail/retOnSupport.js @@ -5,6 +5,7 @@ const { checkContext } = require("../../services/service"); const utils = require("../utils"); const validateSchema = require("../schemaValidation"); const constants = require("../constants"); +const logger = require("../logger"); const checkOnSupport = (dirPath, msgIdSet) => { let onSprtObj = {}; @@ -16,61 +17,58 @@ const checkOnSupport = (dirPath, msgIdSet) => { on_support = JSON.parse(on_support); try { - console.log(`Validating Schema for /${constants.RET_ONSUPPORT} API`); + logger.info(`Validating Schema for /${constants.RET_ONSUPPORT} API`); const vs = validateSchema("retail", constants.RET_ONSUPPORT, on_support); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onSprtObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONSUPPORT}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONSUPPORT}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_ONSUPPORT} API`); //checking context + logger.info(`Checking context for /${constants.RET_ONSUPPORT} API`); //checking context res = checkContext(on_support.context, constants.RET_ONSUPPORT); if (!res.valid) { Object.assign(onSprtObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONSUPPORT} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONSUPPORT} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}` ); if (!_.isEqual(dao.getValue("city"), on_support.context.city)) { onSprtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONSUPPORT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_SUPPORT} and /${constants.RET_ONSUPPORT}` ); if (_.gte(dao.getValue("sprtTmpstmp"), on_support.context.timestamp)) { onSprtObj.tmpstmp = `Timestamp for /${constants.RET_SUPPORT} api cannot be greater than or equal to /${constants.RET_ONSUPPORT} api`; } } catch (error) { - console.log( + logger.info( `Error while comparing timestamp for /${constants.RET_SUPPORT} and /${constants.RET_ONSUPPORT} api` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONSUPPORT}` ); if ( @@ -79,14 +77,13 @@ const checkOnSupport = (dirPath, msgIdSet) => { onSprtObj.txnId = `transaction_id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSUPPORT} api`, - error + logger.info( + `Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONSUPPORT} api, ${error.stack}` ); } try { - console.log("Checking Message Id of /on_support"); + logger.info("Checking Message Id of /on_support"); if (!_.isEqual(dao.getValue("msgId"), on_support.context.message_id)) { onSprtObj.msgId = `Message Id for /${constants.RET_SUPPORT} and /${constants.RET_ONSUPPORT} api should be same`; } @@ -97,20 +94,20 @@ const checkOnSupport = (dirPath, msgIdSet) => { // msgId = status.context.message_id; msgIdSet.add(on_support.context.message_id); } catch (error) { - console.log( - `Error while checking message id for /${constants.RET_ONSUPPORT}`, - error + logger.info( + `Error while checking message id for /${constants.RET_ONSUPPORT}, ${error.stack}` ); } on_support = on_support.message; - dao.setValue("onSprtObj", onSprtObj); + // dao.setValue("onSprtObj", onSprtObj); + return onSprtObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONSUPPORT} API!`); + logger.info(`!!File not found for /${constants.RET_ONSUPPORT} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_ONSUPPORT} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retOnTrack.js b/utilities/log-validation-utility/utils/retail/retOnTrack.js index edfe0ca..ca677c3 100644 --- a/utilities/log-validation-utility/utils/retail/retOnTrack.js +++ b/utilities/log-validation-utility/utils/retail/retOnTrack.js @@ -4,6 +4,7 @@ const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const validateSchema = require("../schemaValidation"); const constants = require("../constants"); +const logger = require("../logger"); const checkOnTrack = (dirPath, msgIdSet) => { let onTrckObj = {}; @@ -11,89 +12,84 @@ const checkOnTrack = (dirPath, msgIdSet) => { let on_track = fs.readFileSync(dirPath + `/${constants.RET_ONTRACK}.json`); on_track = JSON.parse(on_track); try { - console.log(`Validating Schema for /${constants.RET_ONTRACK} API`); + logger.info(`Validating Schema for /${constants.RET_ONTRACK} API`); const vs = validateSchema("retail", constants.RET_ONTRACK, on_track); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(onTrckObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONTRACK}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONTRACK}, ${error.stack}` ); } - console.log(`Checking context for /${constants.RET_ONTRACK} API`); //checking context + logger.info(`Checking context for /${constants.RET_ONTRACK} API`); //checking context try { res = checkContext(on_track.context, "on_track"); if (!res.valid) { Object.assign(onTrckObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONTRACK} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_ONTRACK} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}` ); if (!_.isEqual(dao.getValue("city"), on_track.context.city)) { onTrckObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONTRACK}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_ONTRACK} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), on_track.context.timestamp)) { onTrckObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_ONTRACK} api`; } } catch (error) { - console.log( + logger.error( `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONTRACK} api` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_TRACK} and /${constants.RET_ONTRACK}` ); if (_.gte(dao.getValue("trckTmpstmp"), on_track.context.timestamp)) { onTrckObj.tmpstmp = `Timestamp for /${constants.RET_TRACK} api cannot be greater than or equal to /${constants.RET_ONTRACK} api`; } } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_TRACK} and /${constants.RET_ONTRACK} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_TRACK} and /${constants.RET_ONTRACK} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONTRACK}` ); if (!_.isEqual(dao.getValue("txnId"), on_track.context.transaction_id)) { onTrckObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONTRACK} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONTRACK} api, ${error.stack}` ); } try { - console.log(`Checking Message Id of /${constants.RET_ONTRACK}`); + logger.info(`Checking Message Id of /${constants.RET_ONTRACK}`); if (!_.isEqual(dao.getValue("msgId"), on_track.context.message_id)) { onTrckObj.msgId = `Message Id for /${constants.RET_TRACK} and /${constants.RET_ONTRACK} api should be same`; } @@ -104,16 +100,15 @@ const checkOnTrack = (dirPath, msgIdSet) => { // msgId = status.context.message_id; msgIdSet.add(on_track.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_ONTRACK}`, - error + logger.error( + `!!Error while checking message id for /${constants.RET_ONTRACK}, ${error.stack}` ); } on_track = on_track.message.tracking; try { - console.log( + logger.info( `Checking tracking URL when status is active (/${constants.RET_ONTRACK})` ); if (on_track.status === "active" && !on_track.url) { @@ -121,20 +116,20 @@ const checkOnTrack = (dirPath, msgIdSet) => { "Tracking url can't be null when status is active"; } } catch (error) { - console.log( - `!!Error while checking tracking url in /${constants.RET_ONTRACK}`, - error + logger.error( + `!!Error while checking tracking url in /${constants.RET_ONTRACK}, ${error.stack}` ); // onTrckObj.onTrackUrl = // "Tracking url can't be null in case status is active"; } - dao.setValue("onTrckObj", onTrckObj); + // dao.setValue("onTrckObj", onTrckObj); + return onTrckObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONTRACK} API!`); + logger.info(`!!File not found for /${constants.RET_ONTRACK} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_ONTRACK} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdate.js b/utilities/log-validation-utility/utils/retail/retOnUpdate.js index e8365d4..1bc1d22 100644 --- a/utilities/log-validation-utility/utils/retail/retOnUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retOnUpdate.js @@ -5,296 +5,594 @@ const { checkContext } = require("../../services/service"); const validateSchema = require("../schemaValidation"); const utils = require("../utils"); const constants = require("../constants"); -const { RET_ONUPDATE } = require("../constants"); - -const checkOnUpdate = (dirPath, msgIdSet) => { +const logger = require("../logger"); +//updatedQuotePrice +//refundTriggering (state:time) +//quotePrice +const checkOnUpdate = (msgIdSet, on_update, state) => { let onUpdtObj = {}; try { - let on_update = fs.readFileSync( - dirPath + `/${constants.RET_ONUPDATE}.json` + logger.info( + `Validating Schema for /${constants.RET_ONUPDATE}_${state} API` ); - on_update = JSON.parse(on_update); - - try { - console.log(`Validating Schema for /${constants.RET_ONUPDATE} API`); - const vs = validateSchema("retail", constants.RET_ONUPDATE, on_update); - if (vs != "error") { - // console.log(vs); - Object.assign(onUpdtObj, vs); - } - } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_ONUPDATE}`, - error - ); + const vs = validateSchema("retail", constants.RET_ONUPDATE, on_update); + if (vs != "error") { + // logger.info(vs); + Object.assign(onUpdtObj, vs); } + } catch (error) { + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_ONUPDATE}_${state}`, + error + ); + } - try { - console.log(`Checking context for /${constants.RET_ONUPDATE} API`); //checking context - res = checkContext(on_update.context, constants.RET_ONUPDATE); - if (!res.valid) { - Object.assign(onUpdtObj, res.ERRORS); - } - } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_ONUPDATE} context`, - error - ); + try { + logger.info(`Checking context for /${constants.RET_ONUPDATE}_${state} API`); //checking context + res = checkContext(on_update.context, constants.RET_ONUPDATE); + if (!res.valid) { + Object.assign(onUpdtObj, res.ERRORS); } + } catch (error) { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} context`, + error + ); + } - try { - console.log( - `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}` - ); - if (!_.isEqual(dao.getValue("city"), on_update.context.city)) { - onUpdtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}`; - } - } catch (error) { - console.log( - `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}`, - error - ); + try { + logger.info( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}_${state}` + ); + if (!_.isEqual(dao.getValue("city"), on_update.context.city)) { + onUpdtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}_${state}`; } + } catch (error) { + logger.info( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_ONUPDATE}_${state}`, + error + ); + } - try { - console.log( - `Comparing timestamp of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}` - ); - if (_.gte(dao.getValue("updtTmpstmp"), on_update.context.timestamp)) { - onUpdtObj.tmpstmp = `Timestamp for /${constants.RET_UPDATE} api cannot be greater than or equal to /${constants.RET_ONUPDATE} api`; - } - } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE} api`, - error - ); + try { + logger.info( + `Comparing timestamp of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}_${state}` + ); + if (_.gte(dao.getValue("updtTmpstmp"), on_update.context.timestamp)) { + onUpdtObj.tmpstmp = `Timestamp for /${constants.RET_UPDATE} api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; } + } catch (error) { + logger.info( + `Error while comparing timestamp for /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}_${state} api`, + error + ); + } - try { - console.log( - `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONUPDATE}` - ); - if (!_.isEqual(dao.getValue("txnId"), on_update.context.transaction_id)) { - onUpdtObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; - } - } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONUPDATE} API`, - error - ); + try { + logger.info( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_ONUPDATE}_${state}` + ); + if (!_.isEqual(dao.getValue("txnId"), on_update.context.transaction_id)) { + onUpdtObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } + } catch (error) { + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_ONUPDATE}_${state} API`, + error + ); + } - try { - console.log( - `Comparing Message Ids of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}` - ); - if (!_.isEqual(dao.getValue("msgId"), on_update.context.message_id)) { - onUpdtObj.msgId = `Message Ids for /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE} apis should be same`; - } - // if (msgIdSet.has(confirm.context.message_id)) { - // cnfrmObj.msgId2 = "Message Id cannot be same for different sets of APIs"; - // } - // msgId = confirm.context.message_id; - msgIdSet.add(on_update.context.message_id); - } catch (error) { - console.log( - `Error while checking message id for /${constants.RET_ONUPDATE}`, - error - ); + try { + logger.info( + `Comparing Message Ids of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}_${state}` + ); + if (!_.isEqual(dao.getValue("msgId"), on_update.context.message_id)) { + onUpdtObj.msgId = `message_id of all unsolicited /on_update calls should be same for a particular /update request`; + } + } catch (error) { + logger.info( + `Error while checking message id for /${constants.RET_ONUPDATE}_${state}`, + error + ); + } + + on_update = on_update.message.order; + + try { + logger.info( + `Comparing order ids in /${constants.RET_CONFIRM} and /${constants.RET_ONUPDATE}_${state}` + ); + if (!_.isEqual(dao.getValue("cnfrmOrdrId"), on_update.id)) { + onUpdtObj.orderID = `Order Id mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONUPDATE}_${state}`; } + } catch (error) { + logger.error( + `!!Error while trying to fetch order ids in /${constants.RET_ONUPDATE}_${state}`, + error + ); + } + + try { + let i = 0; + //checking count of returned item in //onupdate_picked - on_update = on_update.message.order; + const quoteBreakup = on_update.quote.breakup; + const returnedItemsCount = dao.getValue("itemsUpdt"); + const itemsActualCount = dao.getValue("itemsIdList"); - try { - console.log( - `Comparing order ids in /${constants.RET_CONFIRM} and /${constants.RET_ONUPDATE}` + for (itemId in returnedItemsCount) { + let remainingCount = _.subtract( + itemsActualCount[itemId], + returnedItemsCount[itemId] ); - if (dao.getValue("cnfrmOrdrId") != on_update.id) { - onUpdtObj.orderID = `Order Id mismatches in /${constants.RET_CONFIRM} and /${constants.RET_ONUPDATE}`; - } - } catch (error) { - console.log( - `!!Error while trying to fetch order ids in /${constants.RET_ONUPDATE}`, - error + + let quoteItem = quoteBreakup.filter( + (itm) => + itm["@ondc/org/item_id"] === itemId && + itm["@ondc/org/title_type"] === "item" ); - } - try { - console.log(`Checking items update status`); - itemsUpdt = dao.getValue("itemsUpdt"); - for (item in itemsUpdt) { - let updatedItem = on_update.items.find((it) => it.id === item); - //Checking if item can be updated? (if update_type is return, fulfillment state should be Order-delivered and in case of cancel, fulfillment state should be cancelled) - if (itemsUpdt[item][1] === "return") { - let itemff = on_update.fulfillments.find( - (ff) => ff.id === updatedItem.fulfillment_id - ); - if (itemff.state.descriptor.code != "Order-delivered") { - onUpdtObj.updtTypFF = `item with id: ${item} can't be returned when order is not delivered (fulfillment state should be Order-delivered)`; + const noOfQuoteItems = quoteItem.length; + //There should be only one object present for that returned item in quote/breakup + if (noOfQuoteItems > 1) { + let key = `quoteItemErr${itemId}`; + onUpdtObj[ + key + ] = `Invalid quote/breakup item: ${itemId} can't have multiple objects`; + } else { + //In below states quote is not updated + + try { + if ( + ["Return_Initiated", "Return_Approved", "Return_Rejected"].includes( + state + ) + ) { + //item should not be removed from the quote + if (!noOfQuoteItems) { + let key = `quoteItemUpdt${itemId}`; + onUpdtObj[ + key + ] = `returned item: ${itemId} should not be removed from quote when return state is ${state}`; + } else if ( + //count of returned item should not change + !_.isEqual( + quoteItem[0]["@ondc/org/item_quantity"]["count"], + itemsActualCount[itemId] + ) + ) { + let key = `quoteItemUpdt${itemId}`; + onUpdtObj[ + key + ] = `item quantity should not change in quote/breakup for item: ${itemId} when state is ${state}`; + } } - } else if (itemsUpdt[item][1] === "cancel") { - let itemff = on_update.fulfillments.find( - (ff) => ff.id === updatedItem.fulfillment_id + } catch (error) { + logger.error( + `Error while checking quote/breakup in ${constants.RET_ONUPDATE}_${state}, ${error.stack}` ); + } + + //For below states,the quote is updated + + try { if ( - itemff.state.descriptor.code != "Pending" || - itemff.state.descriptor.code != "Packed" + ["Return_Picked", "Return_Delivered", "Liquidated"].includes(state) ) { - onUpdtObj.updtTypFF = `item with id: ${item} can't be cancelled when fulfillment state is not Pending/Packed`; + //count of returned item should not change + if ( + noOfQuoteItems && + !_.isEqual( + quoteItem[0]["@ondc/org/item_quantity"]["count"], + remainingCount + ) + ) { + let key = `quoteItemUpdt${itemId}`; + onUpdtObj[ + key + ] = `item quantity should be updated in quote/breakup for item: ${itemId} when state is ${state}`; + } + + dao.setValue("updatedQuotePrice", on_update.quote.price.value); } + } catch (error) { + logger.error( + `Error while checking quote/breakup in ${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); } - } - } catch (error) { - console.log( - `!!Error while checking items update status in /${constants.RET_ONUPDATE}`, - error - ); - } - try { - console.log( - `Checking start/end time.timestamp in case of triggering fulfillment states` - ); - on_update.fulfillments.forEach((ff) => { - state = ff.state.descriptor.code; - if (state === "Order-picked-up" || state === "Out-for-delivery") { - if (!ff.start.time.timestamp) { - onUpdtObj.ffstrttimetmpstmp = `fulfillment start timestamp is mandatory when fulfillment state is ${state}`; - } - } else if (state === "Order-delivered") { - if (!ff.start.time.timestamp) { - onUpdtObj.ffstrttimetmpstmp = `fulfillment start timestamp is mandatory when fulfillment state is ${state}`; - } - if (!ff.end.time.timestamp) { - onUpdtObj.ffendtimetmpstmp = `fulfillment end timestamp is mandatory when fulfillment state is ${state}`; + try { + if (_.isEqual(state, "Liquidated")) { + if (!noOfQuoteItems) { + onUpdtObj.quoteLineItem = `liquidated item must be present in quote/breakup with count=${remainingCount}`; + } } + } catch (error) { + logger.error( + `Error while checking quote/breakup in ${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); } - }); - } catch (error) { - console.log( - `Error while checking timestamp in case of triggering fulfillment states in /${RET_ONUPDATE}`, - error - ); + } } + } catch (error) { + logger.error( + `!!Error while checking count of returned item in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } - try { - console.log(`Quote Breakup ${constants.RET_ONUPDATE} all checks`); - // let itemsIdList = dao.getValue("itemsIdList"); - // let itemsCtgrs = dao.getValue("itemsCtgrs"); - let itemFlfllmnts = dao.getValue("itemFlfllmnts"); - let onUpdatePrice = 0; + try { + logger.info(`checking quote price in ${constants.RET_ONUPDATE}_${state}`); + const quoteNotUpdates = [ + "Return_Initiated", + "Return_Rejected", + "Return_Approved", + "Cancelled", + ].includes(state); - on_update.quote.breakup.forEach((element, i) => { - let titleType = element["@ondc/org/title_type"]; - // console.log(element.price.value); + const quoteUpdates = [ + "Return_Picked", + "Return_Delivered", + "Liquidated", + ].includes(state); - console.log( - `Calculating quoted Price Breakup for element ${element.title}` - ); - onUpdatePrice += parseFloat(element.price.value); - if (titleType === "item") { - if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { - let brkupitemid = `brkupitemid${i}`; - onUpdtObj[ - brkupitemid - ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; - } + const quotePrice = parseFloat(dao.getValue("quotePrice")); + if ( + quoteNotUpdates && + quotePrice && + !_.isEqual(quotePrice, parseFloat(on_update.quote.price.value)) + ) { + onUpdtObj.quoteNotUpdateState = `quote price should not change for return state ${state}`; + } else if ( + quoteUpdates && + quotePrice && + _.isEqual(quotePrice, on_update.quote.price.value) + ) { + onUpdtObj.quoteUpdateState = `quote price should be updated for return state ${state}`; + } + } catch (error) { + logger.error( + `!!Error while checking quote price in ${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } - console.log( - `Comparing individual item's total price and unit price ` - ); - if (!element.hasOwnProperty("item")) { - onUpdtObj.priceBreakup = `Item's unit price missing in quote.breakup for item id ${element["@ondc/org/item_id"]}`; + const checkReturnItem = ( + returnedItem, + item, + itemsUpdt, + itemFulfillmentId + ) => { + if (!_.isEqual(returnedItem.tags.status, state)) { + let key = `returnedItem${item}state`; + onUpdtObj[ + key + ] = `return state should be ${state} in /items/tags/status for item: ${item}`; + } + + if (!_.isEqual(returnedItem.quantity.count, itemsUpdt[item])) { + let key = `returnedItemCount${item}`; + onUpdtObj[ + key + ] = `quantity of returned item: ${item} mismatches in /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}`; + // } + } + + if ( + [ + "Return_Initiated", + "Return_Rejected", + "Liquidated", + "Cancelled", + ].includes(state) + ) { + if (!_.isEqual(returnedItem.fulfillment_id, itemFulfillmentId)) { + onUpdtObj.ffStateCreation = `new fulfillment id should not be created for item: ${item} when return state is ${state}`; + } + } else if ( + ["Return_Approved", "Return_Picked", "Return_Delivered"].includes(state) + ) { + if (_.isEqual(returnedItem.fulfillment_id, itemFulfillmentId)) { + onUpdtObj.ffStateCreation = `new fulfillment id should be created for item: ${item} when return state is ${state}`; + } + } + }; + + const checkReturnTags = (obj) => { + const has = Object.prototype.hasOwnProperty; + if (!has.call(obj, "tags")) { + const key = `tags${obj.id}`; + onUpdtObj[ + key + ] = `return state must be present in /items/tags for item: ${obj.id}`; + + return 0; + } else return 1; + }; + + try { + logger.info(`Checking items update status`); + const itemsUpdt = dao.getValue("itemsUpdt"); + const itemFlfllmnts = dao.getValue("itemFlfllmnts"); + const itemsIdList = dao.getValue("itemsIdList"); + //verifying the returned items + for (item in itemsUpdt) { + let updatedItem = on_update.items.filter((it) => it.id === item); + totalItemsBreakup = updatedItem.length; + + const itemFulfillmentId = itemFlfllmnts[item]; + //checking if tags (return status) is present for returned item + // let returnedItem = updatedItem.filter((item) => + // item.hasOwnProperty("tags") + // ); + // if (!returnedItem.length) { + // onUpdtObj.updatedItem = `return state must be present in /items/tags for item: ${item}`; + // } + + // console.log("TESTING", returnedItem); + + //either all the purchased quantity is returned (totalItemsBreakup=1) or part returned (totalItemsBreakup>1) + if (!totalItemsBreakup) { + onUpdtObj.updatedItemNotPresent = `item for which return was initiated is not present in /items`; + } else if (totalItemsBreakup === 1) { + if (checkReturnTags(updatedItem[0])) { + checkReturnItem(updatedItem[0], item, itemsUpdt, itemFulfillmentId); + } + } else if (totalItemsBreakup > 1) { + let i = 0; + let isTags = false; + let noOfItemsBreakup = updatedItem.length; + let totalItemCount = 0; + while (i < noOfItemsBreakup) { + let itemBreakup = updatedItem[i]; + totalItemCount += parseInt(itemBreakup.quantity.count); + + const has = Object.prototype.hasOwnProperty; + + if (has.call(itemBreakup, "tags")) { + isTags = true; + checkReturnItem(itemBreakup, item, itemsUpdt, itemFulfillmentId); } else if ( - parseFloat(element.item.price.value) * - element["@ondc/org/item_quantity"].count != - element.price.value + !_.isEqual(itemBreakup.fulfillment_id, itemFulfillmentId) ) { - onUpdtObj.priceBreakup = `Item's unit and total price mismatch for id: ${element["@ondc/org/item_id"]}`; + onUpdtObj.nonReturnedItem = `fulfillment_id should not change for item: ${item} which is not returned`; } - console.log( - `checking available and maximum count in ${constants.RET_ONUPDATE}` - ); + i++; + } + if (!isTags) { + const key = `tags${item}`; + onUpdtObj[ + key + ] = `return state must be present in /items/tags for item: ${item}`; + } - if (element.item.hasOwnProperty("quantity")) { - if ( - _.gt( - element.item.quantity.available.count, - element.item.quantity.maximum.count - ) - ) { - onUpdtObj.qntCnt = `available count can't be greater than maximum count for item id: ${element["@ondc/org/item_id"]}`; - } - } + //checking fulfillment id for returned item in various states + + if (totalItemCount != itemsIdList[item]) { + onUpdtObj.itemCntErr = `Invalid quantity of items present in /order/items (returned & non-returned) for item: ${item}`; } + } - // console.log(`Calculating Items' prices in /${constants.RET_ONUPDATE}`); - // if (element["@ondc/org/item_id"] in itemsIdList) { - // if ( - // titleType === "item" || - // (titleType === "tax" && - // !utils.taxNotInlcusive.includes( - // itemsCtgrs[element["@ondc/org/item_id"]] - // )) - // ) - // onUpdateItemsPrice += parseFloat(element.price.value); - // } - - if (titleType === "tax" || titleType === "discount") { - if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { - let brkupitemsid = `brkupitemstitles${i}`; - onUpdtObj[ - brkupitemsid - ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; - } + //Checking if item can be updated? (if update_type is return, fulfillment state should be Order-delivered ) + + let itemff = on_update.fulfillments.find( + (ff) => ff.id === itemFulfillmentId + ); + if ( + itemff.type === "Delivery" && + itemff.state.descriptor.code != "Order-delivered" + ) { + onUpdtObj.updtTypFF = `item with id: ${item} can't be returned when order is not delivered (fulfillment state should be Order-delivered)`; + } + + // else if (itemsUpdt[item][1] === "cancel") { + // let itemff = on_update.fulfillments.find( + // (ff) => ff.id === updatedItem.fulfillment_id + // ); + // if ( + // itemff.state.descriptor.code != "Pending" || + // itemff.state.descriptor.code != "Packed" + // ) { + // onUpdtObj.updtTypFF = `item with id: ${item} can't be cancelled when fulfillment state is not Pending/Packed`; + // } + // } + } + } catch (error) { + logger.error( + `!!Error while checking items update status in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + try { + //checking fulfillment states as per the return state + + const reverseQCFulfillment = on_update.fulfillments.filter( + (fulfillment) => { + return fulfillment.type === "Reverse QC"; + } + ); + const noOfReverseQC = reverseQCFulfillment.length; + if ( + [ + "Return_Initiated", + "Return_Rejected", + "Liquidated", + "Cancelled", + ].includes(state) && + noOfReverseQC + ) { + onUpdtObj.reverseQcFulfillment = `Reverse QC fulfillment should not be created for return state ${state}`; + } else if ( + ["Return_Approved", "Return_Picked", "Return_Delivered"].includes( + state + ) && + !noOfReverseQC + ) { + onUpdtObj.reverseQcFulfillment = `Reverse QC fulfillment should be created for return state ${state}`; + } + } catch (error) { + logger.error( + `!!Error while checking reverse QC fulfillment in /${constants.RET_ONUPDATE}_${state}` + ); + } + + try { + const pickupTimestamps = dao.getValue("pickupTimestamps"); + const deliveryTimestamps = dao.getValue("deliveryTimestamps"); + const deliveryFulfillment = on_update.fulfillments.filter((fulfillment) => { + return fulfillment.type === "Delivery"; + }); + + const noOfDeliveries = deliveryFulfillment.length; + let i = 0; + while (i < noOfDeliveries) { + let fulfillment = deliveryFulfillment[i]; + + const pickupTime = fulfillment.start.time.timestamp; + const deliveryTime = fulfillment.end.time.timestamp; + //checking if pickup and delivery timestamps are same as in /on_status delivered + if (!_.isEqual(pickupTime, pickupTimestamps[fulfillment.id])) { + let key = `pickupTime${i}`; + onUpdtObj[ + key + ] = `pickup timestamp (/start/time/timestamp) can't change for fulfillment id ${fulfillment.id}`; + } + if (!_.isEqual(deliveryTime, deliveryTimestamps[fulfillment.id])) { + let key = `deliveryTime${i}`; + onUpdtObj[ + key + ] = `delivery timestamp (/end/time/timestamp) can't change for fulfillment id ${fulfillment.id}`; + } + + i++; + } + } catch (error) { + logger.error( + `Error while checking pickup and delivery timestamp in ${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + try { + //checking order timestamps in /on_status + if (!_.isEqual(on_update.created_at, dao.getValue("ordrCrtd"))) { + onUpdtObj.crtdTmstmp = `order/created_at timestamp can't change (should remain same as in /${constants.RET_CONFIRM})`; + } + + if (_.gte(on_update.created_at, on_update.updated_at)) { + onStatObj.ordrTmstmp = `order created_at timestamp must always be earlier than the updated_at timestamp`; + } + } catch (error) { + logger.error( + `!!Error while checking order timestamps in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + try { + logger.info(`Quote Breakup ${constants.RET_ONUPDATE}_${state} all checks`); + // let itemsIdList = dao.getValue("itemsIdList"); + // let itemsCtgrs = dao.getValue("itemsCtgrs"); + let itemFlfllmnts = dao.getValue("itemFlfllmnts"); + let onUpdatePrice = 0; + + on_update.quote.breakup.forEach((element, i) => { + let titleType = element["@ondc/org/title_type"]; + // logger.info(element.price.value); + + logger.info( + `Calculating quoted Price Breakup for element ${element.title}` + ); + onUpdatePrice += parseFloat(element.price.value); + if (titleType === "item") { + if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { + let brkupitemid = `brkupitemid${i}`; + onUpdtObj[ + brkupitemid + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[]`; } - if ( - titleType === "packing" || - titleType === "delivery" || - titleType === "misc" + logger.info(`Comparing individual item's total price and unit price `); + if (!element.hasOwnProperty("item")) { + onUpdtObj.priceBreakup = `Item's unit price missing in quote.breakup for item id ${element["@ondc/org/item_id"]}`; + } else if ( + parseFloat(element.item.price.value) * + element["@ondc/org/item_quantity"].count != + element.price.value ) { + onUpdtObj.priceBreakup = `Item's unit and total price mismatch for id: ${element["@ondc/org/item_id"]}`; + } + + logger.info( + `checking available and maximum count in ${constants.RET_ONUPDATE}_${state}` + ); + + if (element.item.hasOwnProperty("quantity")) { if ( - !Object.values(itemFlfllmnts).includes(element["@ondc/org/item_id"]) + _.gt( + element.item.quantity.available.count, + element.item.quantity.maximum.count + ) ) { - let brkupffid = `brkupfftitles${i}`; - onUpdtObj[ - brkupffid - ] = `${titleType} with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in fulfillments[]`; + onUpdtObj.qntCnt = `available count can't be greater than maximum count for item id: ${element["@ondc/org/item_id"]}`; } } - }); + } - dao.setValue("onUpdatePrice", onUpdatePrice); + // logger.info(`Calculating Items' prices in /${constants.RET_ONUPDATE}_${state}`); + // if (element["@ondc/org/item_id"] in itemsIdList) { + // if ( + // titleType === "item" || + // (titleType === "tax" && + // !utils.taxNotInlcusive.includes( + // itemsCtgrs[element["@ondc/org/item_id"]] + // )) + // ) + // onUpdateItemsPrice += parseFloat(element.price.value); + // } - console.log( - `Matching quoted Price ${parseFloat( - on_update.quote.price.value - )} with Breakup Price ${onUpdatePrice}` - ); - if (onUpdatePrice != parseFloat(on_update.quote.price.value)) { - onUpdtObj.quoteBrkup = `quote.price.value ${on_update.quote.price.value} does not match with the price breakup ${onUpdatePrice}`; + if (titleType === "tax" || titleType === "discount") { + if (!(element["@ondc/org/item_id"] in itemFlfllmnts)) { + let brkupitemsid = `brkupitemstitles${i}`; + onUpdtObj[ + brkupitemsid + ] = `item with id: ${element["@ondc/org/item_id"]} in quote.breakup[${i}] does not exist in items[] (should be valid item id)`; + } } - } catch (error) { - console.log( - `!!Error while checking and comparing the quoted price in /${constants.RET_ONUPDATE}`, - error - ); - } - dao.setValue("onUpdtObj", onUpdtObj); - } catch (err) { - if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_ONUPDATE} API!`); - } else { - console.log( - `!!Some error occurred while checking /${constants.RET_ONUPDATE} API`, - err - ); + if ( + titleType === "packing" || + titleType === "delivery" || + titleType === "misc" + ) { + if ( + !Object.values(itemFlfllmnts).includes(element["@ondc/org/item_id"]) + ) { + let brkupffid = `brkupfftitles${i}`; + onUpdtObj[ + brkupffid + ] = `invalid id: ${element["@ondc/org/item_id"]} in ${titleType} line item (should be a valid fulfillment_id)`; + } + } + }); + + dao.setValue("onUpdatePrice", onUpdatePrice); + + logger.info( + `Matching quoted Price ${parseFloat( + on_update.quote.price.value + )} with Breakup Price ${onUpdatePrice}` + ); + if (onUpdatePrice != parseFloat(on_update.quote.price.value)) { + onUpdtObj.quoteBrkup = `quote.price.value ${on_update.quote.price.value} does not match with the price breakup ${onUpdatePrice}`; } + } catch (error) { + logger.error( + `!!Error while checking and comparing the quoted price in /${constants.RET_ONUPDATE}_${state}`, + error + ); } + + // dao.setValue("onUpdtObj", onUpdtObj); + return onUpdtObj; }; module.exports = checkOnUpdate; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdateApproved.js b/utilities/log-validation-utility/utils/retail/retOnUpdateApproved.js new file mode 100644 index 0000000..ff27a90 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnUpdateApproved.js @@ -0,0 +1,61 @@ +const constants = require("../constants"); +const checkOnUpdate = require("./retOnUpdate"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); + +const checkOnUpdateApproved = (dirPath, msgIdSet, state) => { + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}_approved.json` + ); + let compareApi = `/${constants.RET_ONSTATUS}_delivered`; + + const initiatedOnUpdate = fs.existsSync( + dirPath + `/${constants.RET_ONUPDATE}_initiated.json` + ); + //setting comparison API to the previous recentmost API + if (initiatedOnUpdate) { + compareApi = `/${constants.RET_ONUPDATE}_initiated`; + } + + //parsing the on_update call + on_update = JSON.parse(on_update); + + let approvedObj = {}; + approvedObj = checkOnUpdate(msgIdSet, on_update, state); + + const contextTime = on_update.context.timestamp; + on_update = on_update.message.order; + //timestamp validations + + try { + logger.info( + `Comparing timestamp of ${compareApi} and /${constants.RET_ONUPDATE}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + approvedObj.tmpstmp1 = `Timestamp for ${compareApi} api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + return approvedObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONUPDATE}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnUpdateApproved; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdateDelivered.js b/utilities/log-validation-utility/utils/retail/retOnUpdateDelivered.js new file mode 100644 index 0000000..c03c5c9 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnUpdateDelivered.js @@ -0,0 +1,173 @@ +const constants = require("../constants"); +const checkOnUpdate = require("./retOnUpdate"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); + +const checkOnUpdateDelivered = (dirPath, msgIdSet, state) => { + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}_delivered.json` + ); + let compareApi = `/${constants.RET_ONUPDATE}_delivered`; + let isPickedApi = false; + + const initiatedOnUpdate = fs.existsSync( + dirPath + `/${constants.RET_ONUPDATE}_initiated.json` + ); + //setting comparison API to the previous recentmost API + if (initiatedOnUpdate) { + compareApi = `/${constants.RET_ONUPDATE}_initiated`; + } + + const pickedOnUpdate = fs.existsSync( + dirPath + `/${constants.RET_ONUPDATE}_picked.json` + ); + + if (pickedOnUpdate) { + isPickedApi = true; + compareApi = `/${constants.RET_ONUPDATE}_picked`; + } + + //parsing the on_update call + on_update = JSON.parse(on_update); + + let deliveredObj = {}; + deliveredObj = checkOnUpdate(msgIdSet, on_update, state); + + const contextTime = on_update.context.timestamp; + on_update = on_update.message.order; + //timestamp validations + + try { + logger.info( + `Comparing timestamp of ${compareApi} and /${constants.RET_ONUPDATE}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + deliveredObj.tmpstmp1 = `Timestamp for ${compareApi} api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + try { + logger.info( + `Checking delivery timestamp in /${constants.RET_ONUPDATE}_${state}` + ); + const noOfFulfillments = on_update.fulfillments.length; + let orderDelivered = false; + let i = 0; + let returnDeliveryTimestamps = {}; + let returnPickupTimestamps = {}; + + while (i < noOfFulfillments) { + const fulfillment = on_update.fulfillments[i]; + const ffState = fulfillment.state.descriptor.code; + + //type should be Delivery + if (fulfillment.type != "Reverse QC") { + i++; + continue; + } + + if (ffState === constants.ORDER_DELIVERED) { + orderDelivered = true; + const pickUpTime = fulfillment.start.time.timestamp; + const deliveryTime = fulfillment.end.time.timestamp; + returnDeliveryTimestamps[fulfillment.id] = deliveryTime; + + try { + //checking delivery time matching with context timestamp + if (!_.lte(deliveryTime, contextTime)) { + deliveredObj.deliveryTime = `delivery timestamp should match context/timestamp and can't be future dated`; + } + } catch (error) { + logger.error( + `!!Error while checking delivery time matching with context timestamp in /${constants.RET_ONUPDATE}_${state}`, + error + ); + } + + try { + //checking delivery time and pickup time + if (_.gte(pickUpTime, deliveryTime)) { + deliveredObj.delPickTime = `delivery timestamp (/end/time/timestamp) can't be less than or equal to the pickup timestamp (start/time/timestamp)`; + } + } catch (error) { + logger.error( + `!!Error while checking delivery time and pickup time in /${constants.RET_ONUPDATE}_${state}`, + error + ); + } + + try { + if (isPickedApi) { + returnPickupTimestamps = dao.getValue("returnPickupTimestamps"); + const orderPickedTime = returnPickupTimestamps[fulfillment.id]; + + if (orderPickedTime && !_.isEqual(pickUpTime, orderPickedTime)) { + deliveredObj.orderPickTime = `pickup time (/start/time/timestamp) can't change (should remain same as in "Return_Picked" state) `; + } + } else { + returnPickupTimestamps[fulfillment.id] = pickUpTime; + } + } catch (error) { + logger.error( + `!!Error while comparing pickup time with pickup time in ${state} state`, + error + ); + } + + try { + //checking order/updated_at timestamp + if (!_.gte(on_update.updated_at, deliveryTime)) { + deliveredObj.updatedAt = `order/updated_at timestamp can't be less than the delivery time`; + } + if (!_.gte(contextTime, on_update.updated_at)) { + deliveredObj.updatedAtTime = `order/updated_at timestamp can't be future dated (should match context/timestamp)`; + } + } catch (error) { + logger.error( + `!!Error while checking order/updated_at timestamp in /${constants.RET_ONUPDATE}_${state}`, + error + ); + } + } + + i++; + } + + if (!isPickedApi) { + dao.setValue("returnPickupTimestamps", returnPickupTimestamps); + } + + dao.setValue("returnDeliveryTimestamps", returnDeliveryTimestamps); + + if (!orderDelivered) { + deliveredObj.noOrdrDelivered = `fulfillments/state should be "${constants.ORDER_DELIVERED}" for /${constants.RET_ONUPDATE}_${state}`; + } + } catch (error) { + logger.error( + `!! Error while checking delivery timestamp in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + return deliveredObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONUPDATE}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} API ${err.stack}` + ); + } + } +}; + +module.exports = checkOnUpdateDelivered; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdateInit.js b/utilities/log-validation-utility/utils/retail/retOnUpdateInit.js new file mode 100644 index 0000000..f763d0a --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnUpdateInit.js @@ -0,0 +1,52 @@ +const constants = require("../constants"); +const checkOnUpdate = require("./retOnUpdate"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); + +const checkOnUpdateInitiated = (dirPath, msgIdSet, state) => { + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}_initiated.json` + ); + + //parsing the on_update call + on_update = JSON.parse(on_update); + + let initdObj = {}; + initdObj = checkOnUpdate(msgIdSet, on_update, state); + + const contextTime = on_update.context.timestamp; + on_update = on_update.message.order; + //timestamp validations + + try { + logger.info( + `Comparing timestamp of ${constants.RET_ONSTATUS}_delivered and /${constants.RET_ONUPDATE}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + initdObj.tmpstmp1 = `Timestamp for ${constants.RET_ONSTATUS}_delivered api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + return initdObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONUPDATE}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnUpdateInitiated; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdateLiquidated.js b/utilities/log-validation-utility/utils/retail/retOnUpdateLiquidated.js new file mode 100644 index 0000000..bd1a262 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnUpdateLiquidated.js @@ -0,0 +1,71 @@ +const constants = require("../constants"); +const checkOnUpdate = require("./retOnUpdate"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); + +const checkOnUpdateLiquidated = (dirPath, msgIdSet, state) => { + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}_liquidated.json` + ); + let compareApi = `/${constants.RET_ONSTATUS}_delivered`; + + const initiatedOnUpdate = fs.existsSync( + dirPath + `/${constants.RET_ONUPDATE}_initiated.json` + ); + //setting comparison API to the previous recentmost API + if (initiatedOnUpdate) { + compareApi = `/${constants.RET_ONUPDATE}_initiated`; + } + + //parsing the on_update call + on_update = JSON.parse(on_update); + + let liquidatedObj = {}; + liquidatedObj = checkOnUpdate(msgIdSet, on_update, state); + + const contextTime = on_update.context.timestamp; + on_update = on_update.message.order; + //timestamp validations + try { + let refundTriggering = {}; + refundTriggering[state] = contextTime; + dao.setValue("refundTriggering", refundTriggering); + } catch (error) { + logger.error( + `Error while saving timestmap for refund triggering state ${state} ` + ); + } + + try { + logger.info( + `Comparing timestamp of ${compareApi} and /${constants.RET_ONUPDATE}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + liquidatedObj.tmpstmp1 = `Timestamp for ${compareApi} api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + return liquidatedObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONUPDATE}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnUpdateLiquidated; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdateRejected.js b/utilities/log-validation-utility/utils/retail/retOnUpdateRejected.js new file mode 100644 index 0000000..ba96a14 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retOnUpdateRejected.js @@ -0,0 +1,61 @@ +const constants = require("../constants"); +const checkOnUpdate = require("./retOnUpdate"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); + +const checkOnUpdateRejected = (dirPath, msgIdSet, state) => { + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}_rejected.json` + ); + let compareApi = `/${constants.RET_ONSTATUS}_delivered`; + + const initiatedOnUpdate = fs.existsSync( + dirPath + `/${constants.RET_ONUPDATE}_initiated.json` + ); + //setting comparison API to the previous recentmost API + if (initiatedOnUpdate) { + compareApi = `/${constants.RET_ONUPDATE}_initiated`; + } + + //parsing the on_update call + on_update = JSON.parse(on_update); + + let rejectedObj = {}; + rejectedObj = checkOnUpdate(msgIdSet, on_update, state); + + const contextTime = on_update.context.timestamp; + on_update = on_update.message.order; + //timestamp validations + + try { + logger.info( + `Comparing timestamp of ${compareApi} and /${constants.RET_ONUPDATE}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + rejectedObj.tmpstmp1 = `Timestamp for ${compareApi} api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + return rejectedObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONUPDATE}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnUpdateRejected; diff --git a/utilities/log-validation-utility/utils/retail/retPostConfirm.js b/utilities/log-validation-utility/utils/retail/retPostConfirm.js deleted file mode 100644 index 5046dc2..0000000 --- a/utilities/log-validation-utility/utils/retail/retPostConfirm.js +++ /dev/null @@ -1,12 +0,0 @@ -const fs = require("fs"); -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const { checkContext } = require("../../services/service"); -const utils = require("../utils"); -const validateSchema = require("../schemaValidation"); -const constants = require("../constants"); - -//helper function to check /on_status and /on_update -checkPostConfirm = (msgPyld) => {}; - -module.exports = checkPostConfirm; diff --git a/utilities/log-validation-utility/utils/retail/retSearch.js b/utilities/log-validation-utility/utils/retail/retSearch.js index a5f6854..6d937b4 100644 --- a/utilities/log-validation-utility/utils/retail/retSearch.js +++ b/utilities/log-validation-utility/utils/retail/retSearch.js @@ -4,6 +4,7 @@ const utils = require("../utils"); const constants = require("../constants"); const { checkContext } = require("../../services/service"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkSearch = (dirPath, msgIdSet) => { let srchObj = {}; @@ -12,7 +13,7 @@ const checkSearch = (dirPath, msgIdSet) => { search = JSON.parse(search); try { - console.log(`Checking context for ${constants.RET_SEARCH} API`); //context checking + logger.info(`Checking context for ${constants.RET_SEARCH} API`); //context checking res = checkContext(search.context, constants.RET_SEARCH); dao.setValue("tmpstmp", search.context.timestamp); dao.setValue("txnId", search.context.transaction_id); @@ -23,73 +24,60 @@ const checkSearch = (dirPath, msgIdSet) => { Object.assign(srchObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_SEARCH} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_SEARCH} context, ${error.stack}` ); } try { - console.log(`Validating Schema for ${constants.RET_SEARCH} API`); + logger.info(`Validating Schema for ${constants.RET_SEARCH} API`); const vs = validateSchema("retail", constants.RET_SEARCH, search); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(srchObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_SEARCH}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_SEARCH}, ${error.stack}` ); } search = search.message.intent; try { - console.log("Getting Buyer App finder fee amount"); - if (search.payment["@ondc/org/buyer_app_finder_fee_type"] != "percent") { - srchObj.bffTyp = `Buyer app finder fee type should be "percent"`; - } + logger.info("Getting Buyer App finder fee amount"); + // if (search.payment["@ondc/org/buyer_app_finder_fee_type"] != "percent") { + // srchObj.bffTyp = `Buyer app finder fee type should be "percent"`; + // } var buyerFF = parseFloat( search.payment["@ondc/org/buyer_app_finder_fee_amount"] ); dao.setValue("buyerFF", buyerFF); } catch (error) { - console.log("!!Error while fetching buyer app finder fee amount", error); + logger.error("!!Error while fetching buyer app finder fee amount", error); } try { - console.log("Checking GPS Precision in /search"); - if (search.hasOwnProperty("item")) { - if (search.hasOwnProperty("fulfillment")) { - const gps = search.fulfillment.end.location.gps.split(","); - const gpsLat = gps[0]; - const gpsLong = gps[1]; + logger.info("Checking GPS Precision in /search"); + const has = Object.prototype.hasOwnProperty; + if (has.call(search, "item")) { + if (has.call(search, "fulfillment")) { + const gps = search.fulfillment.end.location.gps; - if (!gpsLat || !gpsLong) { - srchObj.gpsErr = `location.gps is not as per the API contract`; + if (!utils.checkGpsPrecision(gps)) { + srchObj.gpsPrecision = `fulfillment/end/location/gps coordinates must be specified with at least six decimal places of precision.`; } - // else { - // if ( - // utils.countDecimalDigits(gpsLat) != - // utils.countDecimalDigits(gpsLong) - // ) { - // srchObj.gpsErr = `GPS Lat/Long Precision should be same `; - // } - // } - } else { - srchObj.flfllmntObj = `Fulfillment object missing in /${constants.RET_SEARCH} API`; } } } catch (error) { - console.log("!!Error while checking GPS Precision", error); + logger.error("!!Error while checking GPS Precision", error); } - dao.setValue("srchObj", srchObj); + return srchObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_SEARCH} API!`); + logger.info(`!!File not found for /${constants.RET_SEARCH} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_SEARCH} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index 2b262c7..be69274 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -5,6 +5,7 @@ const utils = require("../utils"); const { checkContext } = require("../../services/service"); const constants = require("../constants"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkSelect = (dirPath, msgIdSet) => { //list to store selected items @@ -12,55 +13,54 @@ const checkSelect = (dirPath, msgIdSet) => { let selectedPrice = 0; let itemsIdList = {}; let itemsCtgrs = {}; - let itemsTat = {}; + let itemsTat = []; let slctObj = {}; try { let select = fs.readFileSync(dirPath + `/${constants.RET_SELECT}.json`); //testing select = JSON.parse(select); try { - console.log(`Validating Schema for ${constants.RET_SELECT} API`); + logger.info(`Validating Schema for ${constants.RET_SELECT} API`); const vs = validateSchema("retail", constants.RET_SELECT, select); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(slctObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_SELECT}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_SELECT}, ${error.stack}` + .stack ); } - console.log(`Checking context for ${constants.RET_SELECT} API`); //checking context + logger.info(`Checking context for ${constants.RET_SELECT} API`); //checking context try { res = checkContext(select.context, constants.RET_SELECT); if (!res.valid) { Object.assign(slctObj, res.ERRORS); } } catch (error) { - console.log( - `Some error occurred while checking /${constants.RET_SELECT} context`, - error + logger.info( + `Some error occurred while checking /${constants.RET_SELECT} context, ${error.stack}` + .stack ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_SELECT}` ); if (!_.isEqual(dao.getValue("city"), select.context.city)) { slctObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_SELECT}`; } } catch (error) { - console.log( - `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_SELECT}`, - error + logger.info( + `Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_SELECT}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` ); if (_.gte(dao.getValue("tmpstmp"), select.context.timestamp)) { @@ -68,14 +68,13 @@ const checkSelect = (dirPath, msgIdSet) => { } dao.setValue("tmpstmp", select.context.timestamp); } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api`, - error + logger.info( + `Error while comparing timestamp for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` ); // if (_.isEqual(dao.getValue("txnId"), select.context.transaction_id)) { @@ -83,14 +82,13 @@ const checkSelect = (dirPath, msgIdSet) => { // } dao.setValue("txnId", select.context.transaction_id); } catch (error) { - console.log( - `Error while comparing transaction ids for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api`, - error + logger.info( + `Error while comparing transaction ids for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing Message Ids of /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` ); if (_.isEqual(dao.getValue("msgId"), select.context.message_id)) { @@ -99,90 +97,116 @@ const checkSelect = (dirPath, msgIdSet) => { dao.setValue("msgId", select.context.message_id); // msgIdSet.add(select.context.message_id); } catch (error) { - console.log( - `Error while comparing message ids for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api`, - error + logger.info( + `Error while comparing message ids for /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} api, ${error.stack}` ); } select = select.message.order; - let onSearch = dao.getValue("onSearch"); - - let provider = onSearch["bpp/providers"].filter( - (provider) => provider.id === select.provider.id - ); + try { + let onSearch = dao.getValue("onSearch"); - if (provider[0]) { - provider = provider[0]; - dao.setValue("providerId", provider.id); - dao.setValue("providerLoc", provider.locations[0].id); + let provider = onSearch["bpp/providers"].filter( + (provider) => provider.id === select.provider.id + ); - try { - console.log( - `Comparing provider location in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` - ); - if (provider.locations[0].id != select.provider.locations[0].id) { - slctObj.prvdLoc = `provider.locations[0].id ${provider.locations[0].id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; + if (provider[0]) { + provider = provider[0]; + dao.setValue("providerId", provider.id); + dao.setValue("providerLoc", provider.locations[0].id); + dao.setValue("providerGps", provider.locations[0].gps); + dao.setValue("providerName", provider.descriptor.name); + + try { + logger.info( + `Comparing provider location in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + if (provider.locations[0].id != select.provider.locations[0].id) { + slctObj.prvdLoc = `provider.locations[0].id ${provider.locations[0].id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; + } + } catch (error) { + logger.error( + `!!Error while comparing provider's location id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, + error + ); } - } catch (error) { - console.log( - `!!Error while comparing provider.location id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, - error - ); - } - console.log( - `Mapping Item Ids with their counts, categories and prices /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` - ); - try { - select.items.forEach((item) => { - let itemOnSearch = provider.items.find((it) => it.id === item.id); - - if (!itemOnSearch) { - key = `id${item.id}`; - slctObj[ - key - ] = `Item Id ${item.id} does not exist in /${constants.RET_ONSEARCH}`; - } else { - console.log( - `ITEM ID: ${item.id}, Price: ${itemOnSearch.price.value}, Count: ${item.quantity.count}` - ); - if ( - item.location_id && - itemOnSearch.location_id != item.location_id - ) { - slctObj.itemLocErr = `Location id for Item ${item.id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; + logger.info( + `Mapping Item Ids with their counts, categories and prices /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}` + ); + try { + select.items.forEach((item) => { + let itemOnSearch = provider.items.find((it) => it.id === item.id); + + if (!itemOnSearch) { + key = `id${item.id}`; + slctObj[ + key + ] = `Item Id ${item.id} does not exist in /${constants.RET_ONSEARCH}`; + } else { + logger.info( + `ITEM ID: ${item.id}, Price: ${itemOnSearch.price.value}, Count: ${item.quantity.count}` + ); + if ( + item.location_id && + itemOnSearch.location_id != item.location_id + ) { + slctObj.itemLocErr = `Location id for Item ${item.id} mismatches in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`; + } + itemsIdList[item.id] = item.quantity.count; + itemsCtgrs[item.id] = itemOnSearch.category_id; + itemsTat.push(itemOnSearch["@ondc/org/time_to_ship"]); + selectedPrice += itemOnSearch.price.value * item.quantity.count; } - itemsIdList[item.id] = item.quantity.count; - itemsCtgrs[item.id] = itemOnSearch.category_id; - itemsTat[item.id] = itemOnSearch["@ondc/org/time_to_ship"]; - selectedPrice += itemOnSearch.price.value * item.quantity.count; + }); + + try { + logger.info(`Saving time_to_ship in /${constants.RET_ONSEARCH}`); + let timeToShip = 0; + logger.info("ITEMSDKJDKLSJF", itemsTat); + itemsTat.forEach((tts) => { + const ttship = utils.isoDurToSec(tts); + logger.info(ttship); + timeToShip = Math.max(timeToShip, ttship); + }); + logger.info("timeTOSHIP", timeToShip); + dao.setValue("timeToShip", timeToShip); + } catch (error) { + logger.error( + `!!Error while saving time_to_ship in ${constants.RET_ONSEARCH}`, + error + ); } - }); - dao.setValue("itemsIdList", itemsIdList); - dao.setValue("itemsCtgrs", itemsCtgrs); - dao.setValue("selectedPrice", selectedPrice); - dao.setValue("itemsTat", itemsTat); - console.log( - `Provider Id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} matched` - ); - } catch (error) { - console.log( - `!!Error while Comparing and Mapping Items in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, - error + + dao.setValue("itemsIdList", itemsIdList); + dao.setValue("itemsCtgrs", itemsCtgrs); + dao.setValue("selectedPrice", selectedPrice); + + logger.info( + `Provider Id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} matched` + ); + } catch (error) { + logger.error( + `!!Error while Comparing and Mapping Items in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, + error + ); + } + } else { + logger.info( + `Provider Ids in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} mismatch` ); + slctObj.prvdrIdMatch = `Provider Id ${select.provider.id} in /${constants.RET_SELECT} does not exist in /${constants.RET_ONSEARCH}`; } - } else { - console.log( - `Provider Ids in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT} mismatch` + } catch (error) { + logger.error( + `!!Error occcurred while checking providers info in /${constants.RET_SELECT}` ); - slctObj.prvdrIdMatch = `Provider Id ${select.provider.id} in /${constants.RET_SELECT} does not exist in /${constants.RET_ONSEARCH}`; } try { select.fulfillments.forEach((ff, indx) => { - console.log(`Checking GPS Precision in /${constants.RET_SELECT}`); + logger.info(`Checking GPS Precision in /${constants.RET_SELECT}`); if (ff.hasOwnProperty("end")) { dao.setValue("buyerGps", ff.end.location.gps); @@ -190,7 +214,7 @@ const checkSelect = (dirPath, msgIdSet) => { const gps = ff.end.location.gps.split(","); const gpsLat = gps[0]; const gpsLong = gps[1]; - // console.log(gpsLat, " sfsfdsf ", gpsLong); + // logger.info(gpsLat, " sfsfdsf ", gpsLong); if (!gpsLat || !gpsLong) { slctObj.gpsErr = `fulfillments location.gps is not as per the API contract`; } @@ -198,24 +222,23 @@ const checkSelect = (dirPath, msgIdSet) => { if (!ff.end.location.address.hasOwnProperty("area_code")) { slctObj.areaCode = `address.area_code is required property in /${constants.RET_SELECT}`; } - } else { - srchObj.endflfllmntObj = `fulfillments[${indx}].end object missing in /${constants.RET_SELECT} API`; } }); } catch (error) { - console.log( - `!!Error while checking GPS Precision in /${constants.RET_SELECT}`, - error + logger.error( + `!!Error while checking GPS Precision in /${constants.RET_SELECT}, ${error.stack}` + .stack ); } - console.log("Total Price of Selected Items:", selectedPrice); - dao.setValue("slctObj", slctObj); + logger.info("Total Price of Selected Items:", selectedPrice); + // dao.setValue("slctObj", slctObj); + return slctObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_SELECT} API!`); + logger.info(`!!File not found for /${constants.RET_SELECT} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_SELECT} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retStatus.js b/utilities/log-validation-utility/utils/retail/retStatus.js index cbf4014..184c8c3 100644 --- a/utilities/log-validation-utility/utils/retail/retStatus.js +++ b/utilities/log-validation-utility/utils/retail/retStatus.js @@ -4,6 +4,7 @@ const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const constants = require("../constants"); const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkStatus = (dirPath, msgIdSet) => { let statObj = {}; @@ -12,48 +13,45 @@ const checkStatus = (dirPath, msgIdSet) => { status = JSON.parse(status); try { - console.log(`Validating Schema for ${constants.RET_STATUS} API`); + logger.info(`Validating Schema for ${constants.RET_STATUS} API`); const vs = validateSchema("retail", constants.RET_STATUS, status); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(statObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_STATUS}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_STATUS}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_STATUS} API`); //checking context + logger.info(`Checking context for /${constants.RET_STATUS} API`); //checking context res = checkContext(status.context, constants.RET_STATUS); if (!res.valid) { Object.assign(statObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_STATUS} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_STATUS} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_STATUS}` ); if (!_.isEqual(dao.getValue("city"), status.context.city)) { statObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_STATUS}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_STATUS}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_STATUS}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_STATUS} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), status.context.timestamp)) { @@ -61,27 +59,26 @@ const checkStatus = (dirPath, msgIdSet) => { statObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_STATUS} api`; } } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_STATUS} api`, - error + logger.info( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_STATUS} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_STATUS}` ); if (!_.isEqual(dao.getValue("txnId"), status.context.transaction_id)) { statObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( + logger.error( `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_STATUS} api` ); } try { - console.log(`Checking Message Id of /${constants.RET_STATUS}`); + logger.info(`Checking Message Id of /${constants.RET_STATUS}`); // if (!_.isEqual(msgId, onSelect.context.message_id)) { // onSlctObj.msgId = // "Message Id for ${constants.RET_SELECT} and /on_select api should be same"; @@ -93,7 +90,7 @@ const checkStatus = (dirPath, msgIdSet) => { dao.setValue("msgId", status.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( + logger.error( `!!Error while checking message id for /${constants.RET_STATUS}` ); } @@ -101,25 +98,25 @@ const checkStatus = (dirPath, msgIdSet) => { status = status.message; try { - console.log( + logger.info( `Comparing order id for /${constants.RET_CONFIRM} and /${constants.RET_STATUS}` ); if (dao.getValue("cnfrmOrdrId") != status.order_id) { statObj.orderId = `Order ids in /${constants.RET_CONFIRM} and /${constants.RET_STATUS} do not match`; } } catch (error) { - console.log( - `!!Error occurred while comparing order ids /confirm and /${constants.RET_STATUS}`, - error + logger.error( + `!!Error occurred while comparing order ids /confirm and /${constants.RET_STATUS}, ${error.stack}` ); } - dao.setValue("statObj", statObj); + // dao.setValue("statObj", statObj); + return statObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_STATUS} API!`); + logger.info(`!!File not found for /${constants.RET_STATUS} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_STATUS} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retSupport.js b/utilities/log-validation-utility/utils/retail/retSupport.js index 5ebfd92..240af91 100644 --- a/utilities/log-validation-utility/utils/retail/retSupport.js +++ b/utilities/log-validation-utility/utils/retail/retSupport.js @@ -3,6 +3,8 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const constants = require("../constants"); +const validateSchema = require("../schemaValidation"); +const logger = require("../logger"); const checkSupport = (dirPath, msgIdSet) => { let sprtObj = {}; @@ -11,45 +13,42 @@ const checkSupport = (dirPath, msgIdSet) => { support = JSON.parse(support); try { - console.log(`Validating Schema for ${constants.RET_SUPPORT} API`); + logger.info(`Validating Schema for ${constants.RET_SUPPORT} API`); const vs = validateSchema("retail", constants.RET_SUPPORT, support); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(sprtObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_SUPPORT}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_SUPPORT}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_SUPPORT} API`); //checking context + logger.info(`Checking context for /${constants.RET_SUPPORT} API`); //checking context res = checkContext(support.context, constants.RET_SUPPORT); if (!res.valid) { Object.assign(sprtObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_SUPPORT} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_SUPPORT} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}` ); if (!_.isEqual(dao.getValue("city"), support.context.city)) { sprtObj.city = `City code mismatch in ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}`; } } catch (error) { - console.log( - `Error while comparing city in ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}`, - error + logger.info( + `Error while comparing city in ${constants.RET_SEARCH} and /${constants.RET_SUPPORT}, ${error.stack}` ); } - console.log( + logger.info( `Comparing timestamp of /${constants.RET_SUPPORT} and /${constants.RET_ONCONFIRM}` ); @@ -59,26 +58,24 @@ const checkSupport = (dirPath, msgIdSet) => { sprtObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_SUPPORT} api`; } } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_SUPPORT} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_SUPPORT} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_SUPPORT}` ); if (!_.isEqual(dao.getValue("txnId"), support.context.transaction_id)) { sprtObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_SUPPORT} api`, - error + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_SUPPORT} api, ${error.stack}` ); } try { - console.log(`Checking Message Id of /${constants.RET_SUPPORT}`); + logger.info(`Checking Message Id of /${constants.RET_SUPPORT}`); // if (!_.isEqual(msgId, onSelect.context.message_id)) { // onSlctObj.msgId = // "Message Id for /${constants.RET_SELECT} and /on_select api should be same"; @@ -89,32 +86,31 @@ const checkSupport = (dirPath, msgIdSet) => { dao.setValue("msgId", support.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_SUPPORT}`, - error + logger.error( + `!!Error while checking message id for /${constants.RET_SUPPORT}, ${error.stack}` ); } support = support.message; try { - console.log(`Checking ref_id in /${constants.RET_SUPPORT}`); + logger.info(`Checking ref_id in /${constants.RET_SUPPORT}`); if (!_.isEqual(dao.getValue("txnId"), support.ref_id)) { sprtObj.refId = `Transaction Id should be provided as ref_id`; } } catch (error) { sprtObj.refId = `Transaction Id should be provided as ref_id`; - console.log( - `!!Error while checking ref_id in /${constants.RET_SUPPORT}`, - error + logger.error( + `!!Error while checking ref_id in /${constants.RET_SUPPORT}, ${error.stack}` ); } - dao.setValue("sprtObj", sprtObj); + // dao.setValue("sprtObj", sprtObj); + return sprtObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_SUPPORT} API!`); + logger.info(`!!File not found for /${constants.RET_SUPPORT} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_SUPPORT} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retTrack.js b/utilities/log-validation-utility/utils/retail/retTrack.js index 856224f..0b9d771 100644 --- a/utilities/log-validation-utility/utils/retail/retTrack.js +++ b/utilities/log-validation-utility/utils/retail/retTrack.js @@ -3,6 +3,7 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const constants = require("../constants"); +const logger = require("../logger"); const checkTrack = (dirPath, msgIdSet) => { let trckObj = {}; @@ -11,47 +12,45 @@ const checkTrack = (dirPath, msgIdSet) => { track = JSON.parse(track); try { - console.log(`Validating Schema for ${constants.RET_TRACK} API`); + logger.info(`Validating Schema for ${constants.RET_TRACK} API`); const vs = validateSchema("retail", constants.RET_TRACK, track); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(trckObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_TRACK}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_TRACK}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_TRACK}rack API`); //checking context + logger.info(`Checking context for /${constants.RET_TRACK}rack API`); //checking context res = checkContext(track.context, constants.RET_TRACK); if (!res.valid) { Object.assign(trckObj, res.ERRORS); } } catch (error) { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_TRACK} context` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_TRACK}` ); if (!_.isEqual(dao.getValue("city"), track.context.city)) { trckObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_TRACK}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_TRACK}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_TRACK}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), track.context.timestamp)) { @@ -59,28 +58,26 @@ const checkTrack = (dirPath, msgIdSet) => { trckObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_TRACK} api`; } } catch (error) { - console.log( - `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_TRACK} api`, - error + logger.error( + `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_TRACK} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /select and /${constants.RET_TRACK}` ); if (!_.isEqual(dao.getValue("txnId"), track.context.transaction_id)) { trckObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( - `!!Error while comparing transaction ids for /select and /${constants.RET_TRACK} api`, - error + logger.error( + `!!Error while comparing transaction ids for /select and /${constants.RET_TRACK} api, ${error.stack}` ); } try { - console.log(`Checking Message Id of /${constants.RET_TRACK}`); + logger.info(`Checking Message Id of /${constants.RET_TRACK}`); // if (!_.isEqual(msgId, onSelect.context.message_id)) { // onSlctObj.msgId = // "Message Id for /select and /on_select api should be same"; @@ -92,7 +89,7 @@ const checkTrack = (dirPath, msgIdSet) => { dao.setValue("msgId", track.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( + logger.error( `!!Error while checking message id for /${constants.RET_TRACK}` ); } @@ -100,28 +97,28 @@ const checkTrack = (dirPath, msgIdSet) => { track = track.message; try { - console.log( + logger.info( `Checking Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}` ); if (track.order_id != dao.getValue("cnfrmOrdrId")) { - console.log( + logger.info( `Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM} do not match` ); trckObj.trackOrdrId = `Order Id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM} do not match`; } } catch (error) { - console.log( - `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}`, - error + logger.info( + `Error while comparing order id in /${constants.RET_TRACK} and /${constants.RET_CONFIRM}, ${error.stack}` ); // trckObj.trackOrdrId = "Order Id in /${constants.RET_TRACK} and /${constants.RET_ONCONFIRM} do not match"; } - dao.setValue("trckObj", trckObj); + // dao.setValue("trckObj", trckObj); + return trckObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_TRACK} API!`); + logger.info(`!!File not found for /${constants.RET_TRACK} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_TRACK} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retUnsolicitedOnStatus.js b/utilities/log-validation-utility/utils/retail/retUnsolicitedOnStatus.js new file mode 100644 index 0000000..98b45e8 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retUnsolicitedOnStatus.js @@ -0,0 +1,20 @@ +const checkOnStatusDelivered = require("./retOnStatusDelivered"); +const checkOnStatusPending = require("./retOnStatusPending"); +const checkOnStatusPicked = require("./retOnStatusPicked"); + +const logger = require("../logger"); + +const checkUnsolicitedStatus = (dirPath, msgIdSet) => { + let onStatObj = {}; + + onStatObj.pending = checkOnStatusPending(dirPath, msgIdSet, "pending"); + + onStatObj.picked = checkOnStatusPicked(dirPath, msgIdSet, "picked"); + + onStatObj.delivered = checkOnStatusDelivered(dirPath, msgIdSet, "delivered"); + + // dao.setValue("onStatObj", onStatObj); + return onStatObj; +}; + +module.exports = checkUnsolicitedStatus; diff --git a/utilities/log-validation-utility/utils/retail/retUnsolicitedOnUpdate.js b/utilities/log-validation-utility/utils/retail/retUnsolicitedOnUpdate.js new file mode 100644 index 0000000..e5f34cc --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retUnsolicitedOnUpdate.js @@ -0,0 +1,67 @@ +const logger = require("../logger"); + + +const checkOnUpdateInitiated = require("./retOnUpdateInit"); +const checkOnUpdateLiquidated = require("./retOnUpdateLiquidated"); +const checkOnUpdateRejected = require("./retOnUpdateRejected"); +const checkOnUpdateApproved = require("./retOnUpdateApproved"); +const checkOnUpdatePicked = require("./retonUpdatePicked"); +const checkOnUpdateDelivered = require("./retOnUpdateDelivered"); +//itemsIdList +//temsUpdt +// quotePrice +const checkUnsolicitedOnUpdate = (dirPath, msgIdSet) => { + let onUpdateObj = {}; + + onUpdateObj.initiated = checkOnUpdateInitiated( + dirPath, + msgIdSet, + "Return_Initiated" + ); + + onUpdateObj.liquidated = checkOnUpdateLiquidated( + dirPath, + msgIdSet, + "Liquidated" + ); + + onUpdateObj.rejected = checkOnUpdateRejected( + dirPath, + msgIdSet, + "Return_Rejected" + ); + onUpdateObj.return_approved = checkOnUpdateApproved( + dirPath, + msgIdSet, + "Return_Approved" + ); + onUpdateObj.return_picked = checkOnUpdatePicked( + dirPath, + msgIdSet, + "Return_Picked" + ); + onUpdateObj.return_delivered = checkOnUpdateDelivered( + dirPath, + msgIdSet, + "Return_Delivered" + ); + + return onUpdateObj; + + //on_update_initiated + + //liquidate + // on_update liquidated + + //update_billing (refund) + + // reject + //rejected + + // reverseQC + // return approved + // return picked + // return delivered; +}; + +module.exports = checkUnsolicitedOnUpdate; diff --git a/utilities/log-validation-utility/utils/retail/retUpdate.js b/utilities/log-validation-utility/utils/retail/retUpdate.js index 3a47516..d7adf44 100644 --- a/utilities/log-validation-utility/utils/retail/retUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retUpdate.js @@ -3,6 +3,8 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const { checkContext } = require("../../services/service"); const utils = require("../utils"); +const logger = require("../logger"); + const validateSchema = require("../schemaValidation"); const constants = require("../constants"); @@ -15,48 +17,45 @@ const checkUpdate = (dirPath, msgIdSet) => { update = JSON.parse(update); try { - console.log(`Validating Schema for ${constants.RET_UPDATE} API`); + logger.info(`Validating Schema for ${constants.RET_UPDATE} API`); const vs = validateSchema("retail", constants.RET_UPDATE, update); if (vs != "error") { - // console.log(vs); + // logger.info(vs); Object.assign(updtObj, vs); } } catch (error) { - console.log( - `!!Error occurred while performing schema validation for /${constants.RET_UPDATE}`, - error + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_UPDATE}, ${error.stack}` ); } try { - console.log(`Checking context for /${constants.RET_UPDATE} API`); //checking context + logger.info(`Checking context for /${constants.RET_UPDATE} API`); //checking context res = checkContext(update.context, constants.RET_UPDATE); if (!res.valid) { Object.assign(updtObj, res.ERRORS); } } catch (error) { - console.log( - `!!Some error occurred while checking /${constants.RET_UPDATE} context`, - error + logger.error( + `!!Some error occurred while checking /${constants.RET_UPDATE} context, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_UPDATE}` ); if (!_.isEqual(dao.getValue("city"), update.context.city)) { updtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}`; } } catch (error) { - console.log( - `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}`, - error + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing timestamp of /${constants.RET_UPDATE} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), update.context.timestamp)) { @@ -64,26 +63,25 @@ const checkUpdate = (dirPath, msgIdSet) => { updtObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_UPDATE} api`; } } catch (error) { - console.log( - `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_UPDATE} api`, - error + logger.info( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_UPDATE} api, ${error.stack}` ); } try { - console.log( + logger.info( `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_UPDATE}` ); if (!_.isEqual(dao.getValue("txnId"), update.context.transaction_id)) { statObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { - console.log( + logger.error( `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_UPDATE} api` ); } try { - console.log(`Checking Message Id of /${constants.RET_UPDATE}`); + logger.info(`Checking Message Id of /${constants.RET_UPDATE}`); // if (!_.isEqual(msgId, onSelect.context.message_id)) { // onSlctObj.msgId = // "Message Id for ${constants.RET_SELECT} and /on_select api should be same"; @@ -95,22 +93,19 @@ const checkUpdate = (dirPath, msgIdSet) => { dao.setValue("msgId", update.context.message_id); // msgIdSet.add(onSelect.context.message_id); } catch (error) { - console.log( - `!!Error while checking message id for /${constants.RET_UPDATE}` + logger.error( + `!!Error while checking message id for /${constants.RET_UPDATE}, ${error.stack}` ); } update = update.message.order; try { - console.log(`Saving items update_type in /${constants.RET_UPDATE}`); + logger.info(`Saving items update_type in /${constants.RET_UPDATE}`); update.items.forEach((item, i) => { if (item.hasOwnProperty("tags")) { - if ( - item.tags.update_type === "return" || - item.tags.update_type === "cancel" - ) { - itemsUpdt[item.id] = [item.quantity.count, item.tags.update_type]; + if (item.tags.update_type === "return") { + itemsUpdt[item.id] = item.quantity.count; } else { updtObj.updtTypeErr = `items[${i}].tags.update_type can't be ${item.tags.update_type}`; } @@ -118,18 +113,18 @@ const checkUpdate = (dirPath, msgIdSet) => { }); dao.setValue("itemsUpdt", itemsUpdt); } catch (error) { - console.log( - `!!Error while saving items update_type in /${constants.RET_UPDATE}`, - error + logger.error( + `!!Error while saving items update_type in /${constants.RET_UPDATE}, ${error.stack}` ); } - dao.setValue("updtObj", updtObj); + // dao.setValue("updtObj", updtObj); + return updtObj; } catch (err) { if (err.code === "ENOENT") { - console.log(`!!File not found for /${constants.RET_UPDATE} API!`); + logger.info(`!!File not found for /${constants.RET_UPDATE} API!`); } else { - console.log( + logger.error( `!!Some error occurred while checking /${constants.RET_UPDATE} API`, err ); diff --git a/utilities/log-validation-utility/utils/retail/retUpdateBilling.js b/utilities/log-validation-utility/utils/retail/retUpdateBilling.js new file mode 100644 index 0000000..a769445 --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retUpdateBilling.js @@ -0,0 +1,154 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const { checkContext } = require("../../services/service"); +const validateSchema = require("../schemaValidation"); +const utils = require("../utils"); +const constants = require("../constants"); +const logger = require("../logger"); + +const checkUpdateBilling = (dirPath, msgIdSet) => { + let updtObj = {}; + + try { + let update = fs.readFileSync( + dirPath + `/${constants.RET_UPDATE}_billing.json` + ); + update = JSON.parse(update); + + try { + logger.info(`Validating Schema for ${constants.RET_UPDATE} API`); + const vs = validateSchema("retail", constants.RET_UPDATE, update); + if (vs != "error") { + // logger.info(vs); + Object.assign(updtObj, vs); + } + } catch (error) { + logger.error( + `!!Error occurred while performing schema validation for /${constants.RET_UPDATE}, ${error.stack}` + ); + } + + try { + logger.info(`Checking context for /${constants.RET_UPDATE} API`); //checking context + res = checkContext(update.context, constants.RET_UPDATE); + if (!res.valid) { + Object.assign(updtObj, res.ERRORS); + } + } catch (error) { + logger.error( + `!!Some error occurred while checking /${constants.RET_UPDATE} context, ${error.stack}` + ); + } + + try { + logger.info( + `Comparing city of /${constants.RET_SEARCH} and /${constants.RET_UPDATE}` + ); + if (!_.isEqual(dao.getValue("city"), update.context.city)) { + updtObj.city = `City code mismatch in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}`; + } + } catch (error) { + logger.error( + `!!Error while comparing city in /${constants.RET_SEARCH} and /${constants.RET_UPDATE}, ${error.stack}` + ); + } + + try { + const refundTriggering = dao.getValue("refundTriggering"); + const refundState = Object.keys(refundTriggering)[0]; + const refundTime = refundTriggering[refundState]; + logger.info( + `Comparing timestamp of /${constants.RET_UPDATE} and /${constants.RET_ONUPDATE}_${refundState}` + ); + if (_.lte(update.context.timestamp, refundTime)) { + updtObj.tmpstmp = `/update for refund should only be triggered after the triggering state ${refundState} `; + } + } catch (error) { + logger.info( + `Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_ONUPDATE}_${refundState} api, ${error.stack}` + ); + } + + try { + logger.info( + `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_UPDATE}` + ); + if (!_.isEqual(dao.getValue("txnId"), update.context.transaction_id)) { + statObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + } + } catch (error) { + logger.error( + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_UPDATE} api, ${error.stack}` + ); + } + try { + logger.info(`Checking Message Id of /${constants.RET_UPDATE}`); + // if (!_.isEqual(msgId, onSelect.context.message_id)) { + // onSlctObj.msgId = + // "Message Id for ${constants.RET_SELECT} and /on_select api should be same"; + // } + + if (msgIdSet.has(update.context.message_id)) { + updtObj.msgId2 = `Message Id cannot be same for different sets of APIs`; + } + dao.setValue("msgId", update.context.message_id); + // msgIdSet.add(onSelect.context.message_id); + } catch (error) { + logger.error( + `!!Error while checking message id for /${constants.RET_UPDATE}, ${error.stack}` + ); + } + + update = update.message.order; + + // dao.setValue("updtObj", updtObj); + + try { + logger.info( + `Checking refund settlement amount in /${constants.RET_UPDATE}_billing` + ); + + const updatedPrice = parseFloat(dao.getValue("updatedQuotePrice")); + const actualQuotePrice = parseFloat(dao.getValue("quotePrice")); + + const refundAmount = _.subtract(actualQuotePrice, updatedPrice); + + const has = Object.prototype.hasOwnProperty; + if (!has.call(update, "payment")) { + updtObj.pymnt = `/payment object is mandatory for settlement of refund`; + } else { + if (!has.call(update.payment, "@ondc/org/settlement_details")) { + updtObj.pymnt = `@ondc/org/settlement_details in /payment is mandatory for settlement of refund`; + } else { + const settlementAmount = parseFloat( + update.payment["@ondc/org/settlement_details"][0][ + "settlement_amount" + ] + ); + + if (!_.isEqual(settlementAmount, refundAmount)) { + updtObj.refundAmountMismatch = `Inaccurate calculation of refund amount (pls check the quote price in refund triggering state)`; + } + } + } + } catch (error) { + logger.error( + `!!Error while checking refund settlement amount in /${constants.RET_UPDATE}_billing, ${error.stack}` + ); + } + + return updtObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.info(`!!File not found for /${constants.RET_UPDATE}_billing API!`); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_UPDATE}_billing API`, + err + ); + } + } +}; + +module.exports = checkUpdateBilling; diff --git a/utilities/log-validation-utility/utils/retail/retonUpdatePicked.js b/utilities/log-validation-utility/utils/retail/retonUpdatePicked.js new file mode 100644 index 0000000..dd10dbe --- /dev/null +++ b/utilities/log-validation-utility/utils/retail/retonUpdatePicked.js @@ -0,0 +1,137 @@ +const constants = require("../constants"); +const checkOnUpdate = require("./retOnUpdate"); +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const logger = require("../logger"); + +const checkOnUpdatePicked = (dirPath, msgIdSet, state) => { + try { + let on_update = fs.readFileSync( + dirPath + `/${constants.RET_ONUPDATE}_picked.json` + ); + let compareApi = `/${constants.RET_ONSTATUS}_delivered`; + + const initiatedOnUpdate = fs.existsSync( + dirPath + `/${constants.RET_ONUPDATE}_initiated.json` + ); + //setting comparison API to the previous recentmost API + if (initiatedOnUpdate) { + compareApi = `/${constants.RET_ONUPDATE}_initiated`; + } + + //parsing the on_update call + on_update = JSON.parse(on_update); + + let pickedObj = {}; + pickedObj = checkOnUpdate(msgIdSet, on_update, state); + + const contextTime = on_update.context.timestamp; + on_update = on_update.message.order; + //timestamp validations + + try { + let refundTriggering = {}; + refundTriggering[state] = contextTime; + dao.setValue("refundTriggering", refundTriggering); + } catch (error) { + logger.error( + `Error while saving timestmap for refund triggering state ${state} ` + ); + } + + try { + logger.info( + `Comparing timestamp of ${compareApi} and /${constants.RET_ONUPDATE}_${state} API` + ); + if (_.gte(dao.getValue("tmstmp"), contextTime)) { + pickedObj.tmpstmp1 = `Timestamp for ${compareApi} api cannot be greater than or equal to /${constants.RET_ONUPDATE}_${state} api`; + } + dao.setValue("tmpstmp", contextTime); + } catch (error) { + logger.error( + `!!Error occurred while comparing context/timestamp for /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + try { + logger.info( + `Checking pickup timestamp in /${constants.RET_ONUPDATE}_${state}` + ); + const noOfFulfillments = on_update.fulfillments.length; + let orderPicked = false; + let i = 0; + let returnPickupTimestamps = {}; + + while (i < noOfFulfillments) { + const fulfillment = on_update.fulfillments[i]; + const ffState = fulfillment.state.descriptor.code; + + //type should be Delivery + if (fulfillment.type != "Reverse QC") { + i++; + continue; + } + + if (ffState === constants.ORDER_PICKED) { + orderPicked = true; + const pickUpTime = fulfillment.start.time.timestamp; + returnPickupTimestamps[fulfillment.id] = pickUpTime; + + try { + //checking pickup time matching with context timestamp + if (!_.lte(pickUpTime, contextTime)) { + pickedObj.pickupTime = `pickup timestamp should match context/timestamp and can't be future dated`; + } + } catch (error) { + logger.error( + `!!Error while checking pickup time matching with context timestamp in /${constants.RET_ONUPDATE}_${state}`, + error + ); + } + + try { + //checking order/updated_at timestamp + if (!_.gte(on_update.updated_at, pickUpTime)) { + pickedObj.updatedAt = `order/updated_at timestamp can't be less than the pickup time`; + } + if (!_.gte(contextTime, on_update.updated_at)) { + pickedObj.updatedAtTime = `order/updated_at timestamp can't be future dated (should match context/timestamp)`; + } + } catch (error) { + logger.error( + `!!Error while checking order/updated_at timestamp in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + } + + i++; + } + + dao.setValue("returnPickupTimestamps", returnPickupTimestamps); + + if (!orderPicked) { + pickedObj.noOrdrPicked = `fulfillments/state should be "${constants.ORDER_PICKED}" for /${constants.RET_ONSTATUS}_${state}`; + } + } catch (error) { + logger.error( + `!!Error while checking pickup timestamp in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + + return pickedObj; + } catch (err) { + if (err.code === "ENOENT") { + logger.error( + `!!File not found for /${constants.RET_ONUPDATE}_${state} API!` + ); + } else { + logger.error( + `!!Some error occurred while checking /${constants.RET_ONUPDATE}_${state} API`, + err + ); + } + } +}; + +module.exports = checkOnUpdatePicked; diff --git a/utilities/log-validation-utility/utils/schemaValidation.js b/utilities/log-validation-utility/utils/schemaValidation.js index 8cfe7a2..00ce07b 100644 --- a/utilities/log-validation-utility/utils/schemaValidation.js +++ b/utilities/log-validation-utility/utils/schemaValidation.js @@ -1,9 +1,10 @@ const schemaValidator = require("../schema/main"); const path = require("path"); const fs = require("fs"); +const logger = require("./logger"); const validateSchema = (domain, api, data) => { - console.log(`Inside Schema Validation for domain: ${domain}, api: ${api}`); + logger.info(`Inside Schema Validation for domain: ${domain}, api: ${api}`); let errObj = {}; const schmaVldtr = schemaValidator(domain, api, data); diff --git a/utilities/log-validation-utility/utils/utils.js b/utilities/log-validation-utility/utils/utils.js index 62198ca..f65017d 100644 --- a/utilities/log-validation-utility/utils/utils.js +++ b/utilities/log-validation-utility/utils/utils.js @@ -1,6 +1,7 @@ const path = require("path"); const _ = require("lodash"); const rootPath = path.dirname(process.mainModule.filename); +const constants = require("./constants"); const retailAPI = [ "search", @@ -23,8 +24,6 @@ const retailAPI = [ "on_support", ]; -const taxNotInlcusive = ["F&B"]; - const retailSttlmntPhase = ["sale-amount", "withholding-amount", "refund"]; const retailSttlmntCntrprty = [ @@ -34,6 +33,26 @@ const retailSttlmntCntrprty = [ "logistics-provider", ]; +const getDecimalPrecision = (numberString) => { + const parts = numberString.trim().split("."); + if (parts.length === 2) { + return parts[1].length; + } else { + return 0; + } +}; + +const checkGpsPrecision = (coordinates) => { + const [lat, long] = coordinates.split(","); + const latPrecision = getDecimalPrecision(lat); + const longPrecision = getDecimalPrecision(long); + const decimalPrecision = constants.DECIMAL_PRECISION; + + if (latPrecision >= decimalPrecision && longPrecision >= decimalPrecision) { + return 1; + } else return 0; +}; + const retailPymntTtl = { "delivery charges": "delivery", "packing charges": "packing", @@ -93,9 +112,7 @@ const logOrderState = [ "Cancelled", ]; -const bpp_fulfillments = ["Delivery", "Pickup", "Delivery and Pickup"]; //id =1,2,3 - -const grocery_categories_id = [ +const groceryCategories = [ "Fruits and Vegetables", "Masala & Seasoning", "Oil & Ghee", @@ -115,7 +132,7 @@ const grocery_categories_id = [ "Packaged Foods", ]; -const fnb_categories_id = [ +const fnbCategories = [ "Continental", "Middle Eastern", "North Indian", @@ -129,44 +146,133 @@ const fnb_categories_id = [ "Desserts", "Bakes & Cakes", "Beverages (MTO)", - "F&B", ]; -const fssai_nos = [ - "brand_owner_FSSAI_license_no", - "other_FSSAI_license_no", - "importer_FSSAI_license_no", +const homeDecorCategories = [ + "Home Decor", + "Home Furnishings", + "Furniture", + "Garden and Outdoor Products", + "Home Improvement", + "Cookware and Dining", + "Storage and Organisation", ]; -const cancellation_rid = { - "001": 0, - "002": 0, - "003": 0, - "004": 0, - "005": 0, - "006": 0, - "009": 1, - "010": 1, - "011": 1, - "012": 1, - "013": 1, - "014": 1, - "015": 1, - "016": 0, - "017": 0, - "018": 0, -}; +const pharmaCategories = [ + "Pain Relieving Ointments", + "Nutrition and Supplements", + "Personal and Baby Care", + "Sexual Wellness", + "Gastric and Other Concerns", + "Covid Essentials", + "Diabetes Control", + "Health Devices", +]; -// const uuidCheck = (data) => { -// console.log("***UUID Validation Utils***"); -// let uuid = -// /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; -// if (!uuid.test(data)) return false; -// return true; -// }; +const elctronicsCategories = [ + "Audio", + "Camera and Camcorder", + "Computer Peripheral", + "Desktop and Laptop", + "Earphone", + "Gaming", + "Headphone", + "Mobile Phone", + "Mobile Accessories", + "Safety Security", + "Smart Watches", + "Speaker", + "Television", + "Video", + "Air Conditioning and Air Cleaners", + "Health, Home and Personal Care", + "Heaters", + "Kitchen Appliances", + "Lighting & Electric Fans", + "Refrigerators and Freezers", + "Vacuum Cleaners", + "Washing Machines and Accessories", + "Water Purifiers and Coolers", + "Inverter & Stabilizer", +]; + +const bpcCategories = [ + "Bath & Body", + "Feminine Care", + "Fragrance", + "Hair Care", + "Make Up", + "Men's Grooming", + "Oral Care", + "Skin Care", + "Maternity Care", + "Nursing & Feeding", + "Sexual Wellness & Sensuality", + "Tools & Accessories", +]; + +const fashionCategories = [ + "Men's Fashion Accessories,Fashion", + "Men's Footwear Accessories", + "Men's Topwear", + "Men's Bottomwear", + "Men's Innerwear & Sleepwear", + "Men's Bags & Luggage", + "Men's Eyewear", + "Men's Footwear", + "Men's Jewellery", + "Women's Fashion Accessories", + "Women's Footwear Accessories", + "Women's Indian & Fusion Wear", + "Women's Western Wear", + "Women's Lingerie & Sleepwear", + "Women's Bags & Luggage", + "Women's Eyewear", + "Women's Footwear", + "Women's Jewellery", + "Boy's Clothing", + "Boy's Footwear", + "Girl's Clothing", + "Girl's Footwear", + "Infant's Wear", + "Infant Care & Accessories", + "Infant Feeding & Nursing Essentials", + "Infant Bath Accessories", + "Infant Health & Safety", + "Infant Diapers & Toilet Training", + "Kid's Towels & Wrappers", + "Kid's Fashion Accessories", + "Kid's Jewellery", + "Kid's Eyewear", + "Kid's Bags & Luggage", +]; + +const allCategories = [ + ...fnbCategories, + ...groceryCategories, + ...homeDecorCategories, + ...pharmaCategories, + ...elctronicsCategories, + ...bpcCategories, + ...fashionCategories, +]; + +const taxNotInlcusive = [...fnbCategories]; + +const buyerCancellationRid = new Set(["001", "003", "006", "009", "010"]); +const sellerCancellationRid = new Set([ + "002", + "005", + "011", + "012", + "013", + "014", + "015", + "018", + "019", +]); const timestampCheck = (date) => { - console.log("***Timestamp Check Utils***"); let dateParsed = new Date(Date.parse(date)); if (!isNaN(dateParsed)) { if (dateParsed.toISOString() != date) { @@ -182,14 +288,13 @@ const timestampCheck = (date) => { const getObjValues = (obj) => { let values = ""; Object.values(obj).forEach((value) => { - values += value + "\n"; + values += `- ${value}\n`; }); return values; }; const isArrayEqual = (x, y) => { flag = _(x).xorWith(y, _.isEqual).isEmpty(); - console.log("FLAG*********", _(x).xorWith(y, _.isEqual).isEmpty()); return flag; }; @@ -210,6 +315,64 @@ const timeDiff = (time1, time2) => { else return dtime1 - dtime2; }; + +const isObjectEqual = (obj1, obj2, parentKey = "") => { + const typeOfObj1 = typeof obj1; + const typeOfObj2 = typeof obj2; + + if (typeOfObj1 !== typeOfObj2) { + return [parentKey]; + } + + if (typeOfObj1 !== "object" || obj1 === null || obj2 === null) { + return obj1 === obj2 ? [] : [parentKey]; + } + + if (Array.isArray(obj1) && Array.isArray(obj2)) { + if (obj1.length !== obj2.length) { + return [parentKey]; + } + + const sortedObj1 = [...obj1].sort(); + const sortedObj2 = [...obj2].sort(); + + for (let i = 0; i < sortedObj1.length; i++) { + const nestedKeys = isObjectEqual(sortedObj1[i], sortedObj2[i], `${parentKey}[${i}]`); + if (nestedKeys.length > 0) { + return nestedKeys; + } + } + + return []; + } + + const obj1Keys = Object.keys(obj1); + const obj2Keys = Object.keys(obj2); + + const allKeys = [...new Set([...obj1Keys, ...obj2Keys])]; + + const notEqualKeys = []; + + for (let key of allKeys) { + if (!obj2.hasOwnProperty(key) || !obj1.hasOwnProperty(key)) { + notEqualKeys.push(parentKey ? `${parentKey}/${key}` : key); + continue; + } + + const nestedKeys = isObjectEqual( + obj1[key], + obj2[key], + parentKey ? `${parentKey}/${key}` : key + ); + + if (nestedKeys.length > 0) { + notEqualKeys.push(...nestedKeys); + } + } + + return notEqualKeys; +}; + const isoDurToSec = (duration) => { let durRE = /P((\d+)Y)?((\d+)M)?((\d+)W)?((\d+)D)?T?((\d+)H)?((\d+)M)?((\d+)S)?/; @@ -239,6 +402,15 @@ const isoDurToSec = (duration) => { return result; }; +const compareCoordinates = (coord1, coord2) => { + // Remove all spaces from the coordinates + const cleanCoord1 = coord1.replace(/\s/g, ""); + const cleanCoord2 = coord2.replace(/\s/g, ""); + + // Compare the cleaned coordinates + return cleanCoord1 === cleanCoord2; +}; + module.exports = { timestampCheck, rootPath, @@ -247,17 +419,19 @@ module.exports = { retailOrderState, logFulfillmentState, logOrderState, - bpp_fulfillments, - cancellation_rid, + buyerCancellationRid, + sellerCancellationRid, getObjValues, retailPaymentType, retailPymntTtl, taxNotInlcusive, + allCategories, isArrayEqual, countDecimalDigits, - grocery_categories_id, - fnb_categories_id, emailRegex, isoDurToSec, timeDiff, + isObjectEqual, + checkGpsPrecision, + compareCoordinates, }; diff --git a/utilities/log-validation-utility/utils/validateLogUtil.js b/utilities/log-validation-utility/utils/validateLogUtil.js index 1cad472..42c50e0 100644 --- a/utilities/log-validation-utility/utils/validateLogUtil.js +++ b/utilities/log-validation-utility/utils/validateLogUtil.js @@ -12,7 +12,7 @@ const checkOnInit = require("./retail/retOnInit"); const checkConfirm = require("./retail/retConfirm"); const checkOnConfirm = require("./retail/retOnConfirm"); const checkStatus = require("./retail/retStatus"); -const checkOnStatus = require("./retail/retOnStatus"); +// const checkOnStatus = require("./retail/retOnStatus"); const checkTrack = require("./retail/retTrack"); const checkOnTrack = require("./retail/retOnTrack"); const checkCancel = require("./retail/retCancel"); @@ -20,8 +20,10 @@ const checkOnCancel = require("./retail/retOnCancel"); const checkSupport = require("./retail/retSupport"); const checkOnSupport = require("./retail/retOnSupport"); const checkUpdate = require("./retail/retUpdate"); -const checkOnUpdate = require("./retail/retOnUpdate"); - +const checkUnsolicitedStatus = require("./retail/retUnsolicitedOnStatus"); +const logger = require("./logger"); +const checkUnsolicitedOnUpdate = require("./retail/retUnsolicitedOnUpdate"); +const checkUpdateBilling = require("./retail/retUpdateBilling"); //TAT in on_select = sumof(time to ship in /on_search and TAT by LSP in logistics /on_search) // If non-serviceable in /on_select, there should be domain-error @@ -67,7 +69,8 @@ const validateLogs = (dirPath) => { // //ON_STATUS API - let onStatResp = checkOnStatus(dirPath, msgIdSet); + // let onStatResp = checkOnStatus(dirPath, msgIdSet); + let onStatResp = checkUnsolicitedStatus(dirPath, msgIdSet); // //UPDATE API @@ -75,7 +78,10 @@ const validateLogs = (dirPath) => { // //ON_UPDATE API - let onUpdtResp = checkOnUpdate(dirPath, msgIdSet); + let onUpdtResp = checkUnsolicitedOnUpdate(dirPath, msgIdSet); + + // //UPDATE REFUND API + let updtRfndResp = checkUpdateBilling(dirPath, msgIdSet); // //TRACK API @@ -101,105 +107,124 @@ const validateLogs = (dirPath) => { let logReport = ""; - let srchObj = dao.getValue("srchObj"); - let onSrchObj = dao.getValue("onSrchObj"); - let slctObj = dao.getValue("slctObj"); - let onSlctObj = dao.getValue("onSlctObj"); - let initObj = dao.getValue("initObj"); - let onInitObj = dao.getValue("onInitObj"); - let cnfrmObj = dao.getValue("cnfrmObj"); - let onCnfrmObj = dao.getValue("onCnfrmObj"); - let cnclObj = dao.getValue("cnclObj"); - let onCnclObj = dao.getValue("onCnclObj"); - let trckObj = dao.getValue("trckObj"); - let onTrckObj = dao.getValue("onTrckObj"); - let sprtObj = dao.getValue("sprtObj"); - let onSprtObj = dao.getValue("onSprtObj"); - let updtObj = dao.getValue("updtObj"); - let onUpdtObj = dao.getValue("onUpdtObj"); - let statObj = dao.getValue("statObj"); - let onStatObj = dao.getValue("onStatObj"); - try { - console.log("Flushing DB Data"); + logger.info("Flushing DB Data"); dao.dropDB(); } catch (error) { - console.log("Error while removing LMDB"); + logger.error("!!Error while removing LMDB", error); } - if (!_.isEmpty(srchObj)) { - logReport += `**/search**\n${getObjValues(srchObj)}\n`; + if (!_.isEmpty(srchResp)) { + logReport += `**/search**\n${getObjValues(srchResp)}\n`; } - if (!_.isEmpty(onSrchObj)) { - logReport += `**/on_search**\n${getObjValues(onSrchObj)}\n`; + if (!_.isEmpty(onSrchResp)) { + logReport += `**/on_search**\n${getObjValues(onSrchResp)}\n`; } - if (!_.isEmpty(slctObj)) { - logReport += `**/select**\n${getObjValues(slctObj)}\n`; + if (!_.isEmpty(slctResp)) { + logReport += `**/select**\n${getObjValues(slctResp)}\n`; } - if (!_.isEmpty(onSlctObj)) { - logReport += `**/on_select**\n${getObjValues(onSlctObj)}\n`; + if (!_.isEmpty(onSlctResp)) { + logReport += `**/on_select**\n${getObjValues(onSlctResp)}\n`; } - if (!_.isEmpty(initObj)) { - logReport += `**/init**\n${getObjValues(initObj)}\n`; + if (!_.isEmpty(initResp)) { + logReport += `**/init**\n${getObjValues(initResp)}\n`; } - if (!_.isEmpty(onInitObj)) { - logReport += `**/on_init**\n${getObjValues(onInitObj)}\n`; + if (!_.isEmpty(onInitResp)) { + logReport += `**/on_init**\n${getObjValues(onInitResp)}\n`; } - if (!_.isEmpty(cnfrmObj)) { - logReport += `**/confirm**\n${getObjValues(cnfrmObj)}\n`; + if (!_.isEmpty(cnfrmResp)) { + logReport += `**/confirm**\n${getObjValues(cnfrmResp)}\n`; } - if (!_.isEmpty(onCnfrmObj)) { - logReport += `**/on_confirm**\n${getObjValues(onCnfrmObj)}\n`; + if (!_.isEmpty(onCnfrmResp)) { + logReport += `**/on_confirm**\n${getObjValues(onCnfrmResp)}\n`; } - if (!_.isEmpty(cnclObj)) { - logReport += `**/cancel**\n${getObjValues(cnclObj)}\n`; + if (!_.isEmpty(cnclResp)) { + logReport += `**/cancel**\n${getObjValues(cnclResp)}\n`; } - if (!_.isEmpty(onCnclObj)) { - logReport += `**/on_cancel**\n${getObjValues(onCnclObj)}\n`; + if (!_.isEmpty(onCnclResp)) { + logReport += `**/on_cancel**\n${getObjValues(onCnclResp)}\n`; } - if (!_.isEmpty(trckObj)) { - logReport += `**/track**\n${getObjValues(trckObj)}\n`; + if (!_.isEmpty(trckResp)) { + logReport += `**/track**\n${getObjValues(trckResp)}\n`; } - if (!_.isEmpty(onTrckObj)) { - logReport += `**/on_track**\n${getObjValues(onTrckObj)}\n`; + if (!_.isEmpty(onTrckResp)) { + logReport += `**/on_track**\n${getObjValues(onTrckResp)}\n`; } - if (!_.isEmpty(statObj)) { - logReport += `**/status**\n${getObjValues(statObj)}\n`; + if (!_.isEmpty(statResp)) { + logReport += `**/status**\n${getObjValues(statResp)}\n`; } - if (!_.isEmpty(onStatObj)) { - logReport += `**/on_status**\n${getObjValues(onStatObj)}\n`; + if (!_.isEmpty(onStatResp.pending)) { + logReport += `**/on_status (Pending)**\n${getObjValues( + onStatResp.pending + )}\n`; + } + if (!_.isEmpty(onStatResp.picked)) { + logReport += `**/on_status (Order-picked-up)**\n${getObjValues( + onStatResp.picked + )}\n`; + } + if (!_.isEmpty(onStatResp.delivered)) { + logReport += `**/on_status (Order-Delivered)**\n${getObjValues( + onStatResp.delivered + )}\n`; } - if (!_.isEmpty(updtObj)) { - logReport += `**/update**\n${getObjValues(updtObj)}\n`; + if (!_.isEmpty(updtResp)) { + logReport += `**/update**\n${getObjValues(updtResp)}\n`; + } + if (!_.isEmpty(onUpdtResp.initiated)) { + logReport += `**/on_update (Initiated)**\n${getObjValues( + onUpdtResp.initiated + )}\n`; } - if (!_.isEmpty(onUpdtObj)) { - logReport += `**/on_update**\n${getObjValues(onUpdtObj)}\n`; + if (!_.isEmpty(onUpdtResp.liquidated)) { + logReport += `**/on_update (Liquidated)**\n${getObjValues( + onUpdtResp.liquidated + )}\n`; + } + if (!_.isEmpty(onUpdtResp.rejected)) { + logReport += `**/on_update (Rejected)**\n${getObjValues( + onUpdtResp.rejected + )}\n`; + } + if (!_.isEmpty(onUpdtResp.return_approved)) { + logReport += `**/on_update (Return_Approved)**\n${getObjValues( + onUpdtResp.return_approved + )}\n`; + } + if (!_.isEmpty(onUpdtResp.return_delivered)) { + logReport += `**/on_update (Return_Delivered)**\n${getObjValues( + onUpdtResp.return_delivered + )}\n`; + } + + if (!_.isEmpty(updtRfndResp)) { + logReport += `**/update (Refund)**\n${getObjValues(updtRfndResp)}\n`; } - if (!_.isEmpty(sprtObj)) { - logReport += `**/support**\n${getObjValues(sprtObj)}\n`; + if (!_.isEmpty(sprtResp)) { + logReport += `**/support**\n${getObjValues(sprtResp)}\n`; } - if (!_.isEmpty(onSprtObj)) { - logReport += `**/on_support** \n${getObjValues(onSprtObj)}\n`; + if (!_.isEmpty(onSprtResp)) { + logReport += `**/on_support** \n${getObjValues(onSprtResp)}\n`; } fs.writeFileSync("log_report.md", logReport); - console.log("Report Generated Successfully!!"); + logger.info("Report Generated Successfully!!"); }; module.exports = { validateLogs }; From 1a3c3aa3f45db6e7ee4491d69df3c1c46ad0bae4 Mon Sep 17 00:00:00 2001 From: bluecypher Date: Tue, 13 Jun 2023 11:59:48 +0530 Subject: [PATCH 027/228] logger implementation --- utilities/log-validation-utility/utils/logger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/log-validation-utility/utils/logger.js b/utilities/log-validation-utility/utils/logger.js index d8af9ec..db01031 100644 --- a/utilities/log-validation-utility/utils/logger.js +++ b/utilities/log-validation-utility/utils/logger.js @@ -15,7 +15,7 @@ const loggerOpts = { }, file: { filename: log_dir + "/validations.log", - level: "error", + level: "info", format: combine(timestamp(), loggerFormat), options: { flags: "w" }, }, From 2406448d5a5a9346e6507b49b4513964630da0af Mon Sep 17 00:00:00 2001 From: ShubhneetChawla1805 <136677859+ShubhneetChawla1805@users.noreply.github.com> Date: Thu, 15 Jun 2023 12:59:00 +0530 Subject: [PATCH 028/228] Update README.md Added few instructions while proof testing & Implementing utility for signing and verification. --- utilities/signing_and_verification/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index 84d7fad..9bbca9a 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -11,9 +11,9 @@ pip3 install -r requirements.txt 2. Export request body json path: this file should be a valid json file ``` -export REQUEST_BODY_PATH= +export REQUEST_BODY_PATH= ``` - eg for json file provided, export REQUEST_BODY_PATH=request_body.json + eg if you rename the file ie request_body_raw_text.txt -> request_body.json , export REQUEST_BODY_PATH=request_body.json 3. Generate key-pairs ``` @@ -31,7 +31,7 @@ python cryptic_utils.py generate_key_pairs ``` export PRIVATE_KEY= export PUBLIC_KEY= -export CRYPTO_PRIVATE_KEY= +export CRYPTO_PRIVATE_KEY=. export CRYPTO_PUBLIC_KEY= ``` @@ -39,7 +39,7 @@ export CRYPTO_PUBLIC_KEY= ``` python cryptic_utils.py create_authorisation_header ``` -output will be like +output will be 'auth_header' like ```shell Signature keyId="buyer-app.ondc.org|207|ed25519",algorithm="ed25519",created="1641287875",expires="1641291475",headers="(created) (expires) digest",signature="fKQWvXhln4UdyZdL87ViXQObdBme0dHnsclD2LvvnHoNxIgcvAwUZOmwAnH5QKi9Upg5tRaxpoGhCFGHD+d+Bw==" ``` @@ -75,4 +75,4 @@ eg usage python cryptic_utils.py decrypt "MC4CAQAwBQYDK2VuBCIEIOgl3rf3arbk1PvIe0C9TZp7ImR71NSQdvuSu+zzY6xo" "MCowBQYDK2VuAyEAi801MjVpgFOXHjliyT6Nb14HkS5dj1p41qbeyU6/SC8=" "CrwN248HS4CIYsUvxtrK0pWCBaoyZh4LnWtGqeH7Mpc=" ``` -Output will be a Plain Text decoded string "ONDC is a Great Initiative!" \ No newline at end of file +Output will be a Plain Text decoded string "ONDC is a Great Initiative!" From a082280a766461ba99f1a82b40ba3488cacfcd91 Mon Sep 17 00:00:00 2001 From: ShubhneetChawla1805 <136677859+ShubhneetChawla1805@users.noreply.github.com> Date: Thu, 15 Jun 2023 13:03:49 +0530 Subject: [PATCH 029/228] Update README.md --- utilities/signing_and_verification/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index 9bbca9a..73a0136 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -31,7 +31,7 @@ python cryptic_utils.py generate_key_pairs ``` export PRIVATE_KEY= export PUBLIC_KEY= -export CRYPTO_PRIVATE_KEY=. +export CRYPTO_PRIVATE_KEY= export CRYPTO_PUBLIC_KEY= ``` From f10f9e2adcf5cdb0d84e42bd5041c5ecece5e3c2 Mon Sep 17 00:00:00 2001 From: ShubhneetChawla1805 <136677859+ShubhneetChawla1805@users.noreply.github.com> Date: Mon, 19 Jun 2023 13:45:57 +0530 Subject: [PATCH 030/228] Create auth_header_signing_and_verification.md --- .../auth_header_signing_and_verification.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 utilities/signing_and_verification/auth_header_signing_and_verification.md diff --git a/utilities/signing_and_verification/auth_header_signing_and_verification.md b/utilities/signing_and_verification/auth_header_signing_and_verification.md new file mode 100644 index 0000000..7708545 --- /dev/null +++ b/utilities/signing_and_verification/auth_header_signing_and_verification.md @@ -0,0 +1,28 @@ +**Pre-requisites** + +* Key pairs, for signing & encryption, can be generated using using [libsodium](https://libsodium.gitbook.io/doc/bindings_for_other_languages). + +**Creating Key Pairs** + +* Create key pairs, for signing (ed25519) & encryption (X25519); +* Update base64 encoded public keys in registry; + +* Utility to generate signing key pairs and test signing & verification is [here](https://github.com/ONDC-Official/reference-implementations/tree/main/utilities/signing_and_verification) + +**Auth Header Signing** + +* Generate UTF-8 byte array from json payload; +* Generate Blake2b hash from UTF-8 byte array; + +* Create base64 encoding of Blake2b hash. This becomes the digest for signing; +* Sign the request, using your private signing key, and add the signature to the request authorization header, following steps documented [here](https://docs.google.com/document/d/1Iw_x-6mtfoMh0KJwL4sqQYM0kD17MLxiMCUOZDBerBo/edit#heading=h.zs1tt1ewtdt) + +**Auth Header Verification** + +* Extract the digest from the encoded signature in the request; +* Get the signing_public_key from registry using lookup (by using the ukId in the authorization header); + +* Create (UTF-8) byte array from the raw payload and generate Blake2b hash; +* Compare generated Blake2b hash with the decoded digest from the signature in the request; + +* In case of failure to verify, HTTP error 401 should be thrown; From bb773475dcc8abac1f345ad160d94897ea1d7cf2 Mon Sep 17 00:00:00 2001 From: Sandeep Shahi <40382144+bluecypher@users.noreply.github.com> Date: Mon, 19 Jun 2023 20:52:53 +0530 Subject: [PATCH 031/228] patch/fixes (#34) --- .../log-validation-utility/utils/retail/retOnInit.js | 12 ++++++++---- .../utils/retail/retOnSelect.js | 2 +- .../utils/retail/retOnUpdate.js | 6 ++++-- .../log-validation-utility/utils/retail/retUpdate.js | 4 ++-- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/utilities/log-validation-utility/utils/retail/retOnInit.js b/utilities/log-validation-utility/utils/retail/retOnInit.js index ea346bd..8e67fdf 100644 --- a/utilities/log-validation-utility/utils/retail/retOnInit.js +++ b/utilities/log-validation-utility/utils/retail/retOnInit.js @@ -150,7 +150,7 @@ const checkOnInit = (dirPath, msgIdSet) => { let itemkey = `item_FFErr${i}`; onInitObj[ itemkey - ] = `items[${i}].fulfillment_id mismatches for Item ${itemId}} in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; + ] = `items[${i}].fulfillment_id mismatches for Item ${itemId} in /${constants.RET_ONSELECT} and /${constants.RET_ONINIT}`; } } else { let itemkey = `item_FFErr${i}`; @@ -177,9 +177,13 @@ const checkOnInit = (dirPath, msgIdSet) => { ); const billing = dao.getValue("billing"); - if (utils.isObjectEqual(billing, on_init.billing).length>0) { - const billingMismatch= utils.isObjectEqual(billing, on_init.billing); - onInitObj.bill = `${billingMismatch.join(", ")} mismatches in /billing in /${constants.RET_INIT} and /${constants.RET_ONINIT}`; + if (utils.isObjectEqual(billing, on_init.billing).length > 0) { + const billingMismatch = utils.isObjectEqual(billing, on_init.billing); + onInitObj.bill = `${billingMismatch.join( + ", " + )} mismatches in /billing in /${constants.RET_INIT} and /${ + constants.RET_ONINIT + }`; } } catch (error) { logger.error( diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index da571d2..3cada93 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -338,7 +338,7 @@ const checkOnSelect = (dirPath, msgIdSet) => { } if (["tax", "discount", "packing", "misc"].includes(titleType)) { if (parseFloat(element.price.value) == 0) { - let key = `breakupItem${titletype}`; + let key = `breakupItem${titleType}`; onSlctObj[ key ] = `${titleType} line item should not be present if price=0`; diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdate.js b/utilities/log-validation-utility/utils/retail/retOnUpdate.js index 1bc1d22..0e56d51 100644 --- a/utilities/log-validation-utility/utils/retail/retOnUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retOnUpdate.js @@ -376,9 +376,11 @@ const checkOnUpdate = (msgIdSet, on_update, state) => { //Checking if item can be updated? (if update_type is return, fulfillment state should be Order-delivered ) let itemff = on_update.fulfillments.find( - (ff) => ff.id === itemFulfillmentId + (ff) => ff.id === itemFulfillmentId && ff.type === "Delivery" ); + if ( + itemff && itemff.type === "Delivery" && itemff.state.descriptor.code != "Order-delivered" ) { @@ -479,7 +481,7 @@ const checkOnUpdate = (msgIdSet, on_update, state) => { } if (_.gte(on_update.created_at, on_update.updated_at)) { - onStatObj.ordrTmstmp = `order created_at timestamp must always be earlier than the updated_at timestamp`; + onUpdtObj.ordrTmstmp = `order created_at timestamp must always be earlier than the updated_at timestamp`; } } catch (error) { logger.error( diff --git a/utilities/log-validation-utility/utils/retail/retUpdate.js b/utilities/log-validation-utility/utils/retail/retUpdate.js index d7adf44..58ceac3 100644 --- a/utilities/log-validation-utility/utils/retail/retUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retUpdate.js @@ -73,11 +73,11 @@ const checkUpdate = (dirPath, msgIdSet) => { `Comparing transaction Ids of /${constants.RET_SELECT} and /${constants.RET_UPDATE}` ); if (!_.isEqual(dao.getValue("txnId"), update.context.transaction_id)) { - statObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; + updtObj.txnId = `Transaction Id should be same from /${constants.RET_SELECT} onwards`; } } catch (error) { logger.error( - `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_UPDATE} api` + `!!Error while comparing transaction ids for /${constants.RET_SELECT} and /${constants.RET_UPDATE} api, ${error.stack}` ); } try { From b07054488c559ab5ef0aea5f95ba3e833c902f7c Mon Sep 17 00:00:00 2001 From: Yash Bansal <67835516+yashb042@users.noreply.github.com> Date: Tue, 27 Jun 2023 14:20:20 +0530 Subject: [PATCH 032/228] Update README.md The sample output for encrypt function is wrong --- utilities/signing_and_verification/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index 73a0136..dc9777d 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -64,7 +64,7 @@ eg usage python cryptic_utils.py encrypt "MC4CAQAwBQYDK2VuBCIEIOgl3rf3arbk1PvIe0C9TZp7ImR71NSQdvuSu+zzY6xo" "MCowBQYDK2VuAyEAi801MjVpgFOXHjliyT6Nb14HkS5dj1p41qbeyU6/SC8=" ``` -Output will be base64 encoded string like "MCowBQYDK2VuAyEAi801MjVpgFOXHjliyT6Nb14HkS5dj1p41qbeyU6/SC8=" +Output will be base64 encoded string like "CrwN248HS4CIYsUvxtrK0pWCBaoyZh4LnWtGqeH7Mpc=" 8. Decrypt Payload ``` From 025e6cedb49a32cbcd88b599255f787a271287e3 Mon Sep 17 00:00:00 2001 From: Sandeep Shahi <40382144+bluecypher@users.noreply.github.com> Date: Thu, 29 Jun 2023 19:31:42 +0530 Subject: [PATCH 033/228] patch/on_update/order/updated_at (#36) --- .../retail_api_json_schema/onSearchSchema.js | 2 ++ .../utils/retail/retCancel.js | 2 +- .../utils/retail/retOnSearch.js | 6 ++---- .../utils/retail/retOnSelect.js | 1 + .../utils/retail/retOnUpdate.js | 16 +++++++++++++++- .../utils/retail/retSelect.js | 6 ++---- .../utils/validateLogUtil.js | 6 ++++++ 7 files changed, 29 insertions(+), 10 deletions(-) diff --git a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js index aba3ffd..5394117 100644 --- a/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js +++ b/utilities/log-validation-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -228,6 +228,7 @@ module.exports = { }, }, }, + required: ["available", "maximum"], }, category_id: { type: "string", @@ -438,6 +439,7 @@ module.exports = { required: [ "id", + "quantity", "category_id", "@ondc/org/contact_details_consumer_care", "price", diff --git a/utilities/log-validation-utility/utils/retail/retCancel.js b/utilities/log-validation-utility/utils/retail/retCancel.js index 693db58..b71ecad 100644 --- a/utilities/log-validation-utility/utils/retail/retCancel.js +++ b/utilities/log-validation-utility/utils/retail/retCancel.js @@ -56,9 +56,9 @@ const checkCancel = (dirPath, msgIdSet) => { `Comparing timestamp of /${constants.RET_CANCEL} and /${constants.RET_ONCONFIRM}` ); if (_.gte(dao.getValue("tmpstmp"), cancel.context.timestamp)) { - dao.setValue("cnclTmpstmp", cancel.context.timestamp); cnclObj.tmpstmp = `Timestamp for /${constants.RET_ONCONFIRM} api cannot be greater than or equal to /${constants.RET_CANCEL} api`; } + dao.setValue("cnclTmpstmp", cancel.context.timestamp); } catch (error) { logger.error( `!!Error while comparing timestamp for /${constants.RET_ONCONFIRM} and /${constants.RET_CANCEL} api, ${error.stack}` diff --git a/utilities/log-validation-utility/utils/retail/retOnSearch.js b/utilities/log-validation-utility/utils/retail/retOnSearch.js index 4ccd874..2d66966 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSearch.js +++ b/utilities/log-validation-utility/utils/retail/retOnSearch.js @@ -389,8 +389,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { } } catch (error) { logger.error( - `!!Errors while checking items in bpp/providers[${i}]`, - error + `!!Errors while checking items in bpp/providers[${i}], ${error.stack}` ); } @@ -609,8 +608,7 @@ const checkOnSearch = (dirPath, msgIdSet) => { }); } catch (error) { logger.error( - `!!Error while checking serviceability construct for bpp/providers[${i}]`, - error + `!!Error while checking serviceability construct for bpp/providers[${i}], ${error.stack}` ); } diff --git a/utilities/log-validation-utility/utils/retail/retOnSelect.js b/utilities/log-validation-utility/utils/retail/retOnSelect.js index 3cada93..a105c6f 100644 --- a/utilities/log-validation-utility/utils/retail/retOnSelect.js +++ b/utilities/log-validation-utility/utils/retail/retOnSelect.js @@ -362,6 +362,7 @@ const checkOnSelect = (dirPath, msgIdSet) => { }); dao.setValue("onSelectPrice", on_select.quote.price.value); + onSelectPrice = onSelectPrice.toFixed(2); logger.info( `Matching quoted Price ${parseFloat( diff --git a/utilities/log-validation-utility/utils/retail/retOnUpdate.js b/utilities/log-validation-utility/utils/retail/retOnUpdate.js index 0e56d51..cfd7b9d 100644 --- a/utilities/log-validation-utility/utils/retail/retOnUpdate.js +++ b/utilities/log-validation-utility/utils/retail/retOnUpdate.js @@ -96,7 +96,7 @@ const checkOnUpdate = (msgIdSet, on_update, state) => { error ); } - + const contextTime = on_update.context.timestamp; on_update = on_update.message.order; try { @@ -474,6 +474,20 @@ const checkOnUpdate = (msgIdSet, on_update, state) => { ); } + try { + logger.info( + `Checking order/updated_at timestamp in /${constants.RET_ONUPDATE}_${state}` + ); + + if (!_.gte(contextTime, on_update.updated_at)) { + onUpdtObj.updatedAtTmpstmp = `order/updated_at timestamp can't be future dated (should match context/timestamp)`; + } + } catch (error) { + logger.error( + `!! Error while checking order/updated_at timestamp in /${constants.RET_ONUPDATE}_${state}, ${error.stack}` + ); + } + try { //checking order timestamps in /on_status if (!_.isEqual(on_update.created_at, dao.getValue("ordrCrtd"))) { diff --git a/utilities/log-validation-utility/utils/retail/retSelect.js b/utilities/log-validation-utility/utils/retail/retSelect.js index be69274..a7f72da 100644 --- a/utilities/log-validation-utility/utils/retail/retSelect.js +++ b/utilities/log-validation-utility/utils/retail/retSelect.js @@ -127,8 +127,7 @@ const checkSelect = (dirPath, msgIdSet) => { } } catch (error) { logger.error( - `!!Error while comparing provider's location id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, - error + `!!Error while comparing provider's location id in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}, ${error.stack}` ); } @@ -188,8 +187,7 @@ const checkSelect = (dirPath, msgIdSet) => { ); } catch (error) { logger.error( - `!!Error while Comparing and Mapping Items in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}`, - error + `!!Error while Comparing and Mapping Items in /${constants.RET_ONSEARCH} and /${constants.RET_SELECT}, ${error.stack}` ); } } else { diff --git a/utilities/log-validation-utility/utils/validateLogUtil.js b/utilities/log-validation-utility/utils/validateLogUtil.js index 42c50e0..607cf70 100644 --- a/utilities/log-validation-utility/utils/validateLogUtil.js +++ b/utilities/log-validation-utility/utils/validateLogUtil.js @@ -204,6 +204,12 @@ const validateLogs = (dirPath) => { onUpdtResp.return_approved )}\n`; } + if (!_.isEmpty(onUpdtResp.return_picked)) { + logReport += `**/on_update (Return_Picked)**\n${getObjValues( + onUpdtResp.return_picked + )}\n`; + } + if (!_.isEmpty(onUpdtResp.return_delivered)) { logReport += `**/on_update (Return_Delivered)**\n${getObjValues( onUpdtResp.return_delivered From cf6541ba29780cae2103ca7b254f45cb9e123449 Mon Sep 17 00:00:00 2001 From: khuzema786 Date: Fri, 25 Aug 2023 00:43:53 +0530 Subject: [PATCH 034/228] ONDC Registry Subscribe --- utilities/on_subscibe-service/Readme.md | 41 +++ .../on_subscibe-service/requirements.txt | 24 ++ utilities/on_subscibe-service/server.py | 254 ++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 utilities/on_subscibe-service/Readme.md create mode 100644 utilities/on_subscibe-service/requirements.txt create mode 100644 utilities/on_subscibe-service/server.py diff --git a/utilities/on_subscibe-service/Readme.md b/utilities/on_subscibe-service/Readme.md new file mode 100644 index 0000000..a2f27c9 --- /dev/null +++ b/utilities/on_subscibe-service/Readme.md @@ -0,0 +1,41 @@ +# Subscribing to ONDC Registry + +1. Add following environment variables like below. +``` +- name: BAP_BASE_URL + value: "" +- name: BPP_BASE_URL + value: "" +- name: APP_PORT + value: "5000" +- name: STATIC_FILE_PORT + value: "9000" +- name: REGISTRY_URL + value: https://prod.registry.ondc.org/subscribe +``` +2. In **server.py** code and the below request_body please replace the `...` with the required details reffering from [ONDC Onboarding Guide](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) to get the server up and running properly. +3. To subscribe the BAP and BPP to ONDC registry after whitelisting of subscriber_id. You need to call your server with the below request body. +``` +curl --location 'https:///subscribe' \ +--header 'Content-Type: application/json' \ +--data '{ + "/bap/beckn/v1/4b17bd06-ae7e-48e9-85bf-282fb310209c | 60": { + "signingPublicKey": "...", + "signingPrivateKey": "...", + "ondcPublicKey": "MCowBQYDK2VuAyEAvVEyZY91O2yV8w8/CAwVDAnqIZDJJUPdLUUKwLo3K0M=", + "encPublicKey": "...", + "encPrivateKey": "...", + "type": "BAP", + "city": "std:080" + }, + "/dobpp/beckn/7f7896dd-787e-4a0b-8675-e9e6fe93bb8f | 50": { + "signingPublicKey": "HUVYp98+DBp/LIbs7LoeSec3NwQcojLZhsa/tQdqbP4=", + "signingPrivateKey": "...", + "ondcPublicKey": "MCowBQYDK2VuAyEAvVEyZY91O2yV8w8/CAwVDAnqIZDJJUPdLUUKwLo3K0M=", + "encPublicKey": "...", + "encPrivateKey": "...", + "type": "BPP", + "city": "std:080" + } +}' +``` \ No newline at end of file diff --git a/utilities/on_subscibe-service/requirements.txt b/utilities/on_subscibe-service/requirements.txt new file mode 100644 index 0000000..507720c --- /dev/null +++ b/utilities/on_subscibe-service/requirements.txt @@ -0,0 +1,24 @@ +autopep8==2.0.2 +blinker==1.6.2 +certifi==2023.5.7 +cffi==1.15.1 +charset-normalizer==3.1.0 +click==8.1.3 +cryptography==39.0.1 +fire==0.5.0 +Flask==2.3.2 +idna==3.4 +itsdangerous==2.1.2 +Jinja2==3.1.2 +MarkupSafe==2.1.3 +prometheus-client==0.17.0 +pycodestyle==2.10.0 +pycparser==2.21 +pycryptodomex==3.17 +PyNaCl==1.5.0 +pytz==2023.3 +requests==2.31.0 +six==1.16.0 +termcolor==2.3.0 +urllib3==2.0.3 +Werkzeug==2.3.6 diff --git a/utilities/on_subscibe-service/server.py b/utilities/on_subscibe-service/server.py new file mode 100644 index 0000000..feec8e2 --- /dev/null +++ b/utilities/on_subscibe-service/server.py @@ -0,0 +1,254 @@ +import json +import time +import os +import base64 +import datetime +import json +import nacl.encoding +import nacl.hash +from nacl.signing import SigningKey +from cryptography.hazmat.primitives import serialization +from Cryptodome.Cipher import AES +from Cryptodome.Util.Padding import unpad +from flask import Flask, request +import requests +import uuid +import multiprocessing +import threading +import pytz + +bapBaseUrl = os.getenv("BAP_BASE_URL") +bppBaseUrl = os.getenv("BPP_BASE_URL") +registry_url = os.getenv("REGISTRY_URL") +app_port = os.getenv("APP_PORT") +static_file_port = os.getenv("STATIC_FILE_PORT") +subscribers = None +subscribers_uniquekey_store = {} + +bapSubscribeBody = { + "context": { + "operation": { + "ops_no": 1 + }, + }, + "message": { + "request_id": "", + "timestamp": "", + "entity": { + "gst": { + "legal_entity_name": "...", + "business_address": "...", + "city_code": [ + "std:080" + ], + "gst_no": "..." + }, + "pan": { + "name_as_per_pan": "...", + "pan_no": "...", + "date_of_incorporation": "..." + }, + "name_of_authorised_signatory": "...", + "email_id": "email@domain.in", + "mobile_no": ..., + "country": "IND", + "subscriber_id": "", + "unique_key_id": "", + "callback_url": "/", + "key_pair": { + "signing_public_key": "", + "encryption_public_key": "", + "valid_from": "", + "valid_until": "2030-06-19T11:57:54.101Z" + } + }, + "network_participant": [ + { + "subscriber_url": "/", + "domain": "ONDC:TRV10", + "type": "buyerApp", + "msn": False, + "city_code": [] + } + ] + } +} + +bppSubscribeBody = { + "context": { + "operation": { + "ops_no": 2 + } + }, + "message": { + "request_id": "", + "timestamp": "", + "entity": { + "gst": { + "legal_entity_name": "...", + "business_address": "...", + "city_code": [ + "std:080" + ], + "gst_no": "..." + }, + "pan": { + "name_as_per_pan": "...", + "pan_no": "...", + "date_of_incorporation": "..." + }, + "name_of_authorised_signatory": "...", + "email_id": "email@domain.in", + "mobile_no": ..., + "country": "IND", + "subscriber_id": "", + "unique_key_id": "", + "callback_url": "/", + "key_pair": { + "signing_public_key": "", + "encryption_public_key": "", + "valid_from": "", + "valid_until": "2030-06-19T11:57:54.101Z" + } + }, + "network_participant": [ + { + "subscriber_url": "/", + "domain": "ONDC:TRV10", + "type": "sellerApp", + "msn": False, + "city_code": [] + } + ] + } +} + +def sign(signing_key, signing_private_key): + signing_private_key64 = base64.b64decode(signing_private_key) + signer = SigningKey(signing_private_key64, encoder=nacl.encoding.RawEncoder) + signed = signer.sign(bytes(signing_key, encoding='utf8')) + signature = base64.b64encode(signed.signature).decode() + return signature + +def decrypt(enc_public_key, enc_private_key, cipherstring): + private_key = serialization.load_der_private_key( + base64.b64decode(enc_private_key), + password=None + ) + public_key = serialization.load_der_public_key( + base64.b64decode(enc_public_key) + ) + shared_key = private_key.exchange(public_key) + cipher = AES.new(shared_key, AES.MODE_ECB) + ciphertxt = base64.b64decode(cipherstring) + return unpad(cipher.decrypt(ciphertxt), AES.block_size).decode('utf-8') + +def createHtml(request_id, subscriber, subscriber_id): + signature = sign(request_id, subscriber['signingPrivateKey']) + htmlFile = f''' + + + + + + ONDC Site Verification Page + + + ''' + if subscriber['type'] == "BAP": + if not os.path.exists(f'ondc-verification/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}'): + os.makedirs(f'ondc-verification/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}') + with open(f"ondc-verification/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}/ondc-site-verification.html", "w+") as file: + file.write(htmlFile) + elif subscriber['type'] == "BPP": + if not os.path.exists(f'ondc-verification/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}'): + os.makedirs(f'ondc-verification/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}') + with open(f"ondc-verification/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}/ondc-site-verification.html", "w+") as file: + file.write(htmlFile) + +app = Flask(__name__) + +@app.route('/subscribe/on_subscribe', methods=['POST']) +def onsubscribe(): + data = request.get_json() + print(f"/subscribe/on_subscribe called :: Request -> {data}") + subscriber_id = data['subscriber_id'] + unique_key_id = subscribers_uniquekey_store[subscriber_id] + subscriber = subscribers[f"{subscriber_id} | {unique_key_id}"] + return { + "answer" : decrypt(subscriber['ondcPublicKey'], subscriber['encPrivateKey'], data['challenge']) + } + +def serve_file(): + os.system(f'python -m http.server {static_file_port} --directory ondc-verification') + +def subscribe_helper(): + if subscribers != None: + global subscribers_uniquekey_store + for subscriber_uk_id, subscriber in subscribers.items(): + [subscriber_id, unique_key_id] = subscriber_uk_id.split(' | ') + subscribers_uniquekey_store[subscriber_id] = unique_key_id + request_id = str(uuid.uuid4()) + subscribers[subscriber_uk_id]['requestId'] = request_id + createHtml(request_id, subscriber, subscriber_id) + process = multiprocessing.Process(target=serve_file) + process.start() + time.sleep(5) + for subscriber_uk_id, subscriber in subscribers.items(): + [subscriber_id, unique_key_id] = subscriber_uk_id.split(' | ') + request_id = subscriber['requestId'] + current_datetime = datetime.datetime.now().astimezone(pytz.timezone('Asia/Kolkata')) + current_datetime_iso8601 = current_datetime.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z" + + if subscriber['type'] == 'BAP': + bapSubscribeBody['message']['request_id'] = request_id + bapSubscribeBody['message']['timestamp'] = current_datetime_iso8601 + bapSubscribeBody['message']['entity']['subscriber_id'] = subscriber_id + bapSubscribeBody['message']['entity']['unique_key_id'] = unique_key_id + bapSubscribeBody['message']['entity']['key_pair']['signing_public_key'] = subscriber['signingPublicKey'] + bapSubscribeBody['message']['entity']['key_pair']['encryption_public_key'] = subscriber['encPublicKey'] + bapSubscribeBody['message']['entity']['key_pair']['valid_from'] = current_datetime_iso8601 + bapSubscribeBody['message']['network_participant'][0]['city_code'] = [subscriber['city']] + + print(json.dumps(bapSubscribeBody)) + + response = requests.post(registry_url, json=bapSubscribeBody) + if response.status_code == 200: + print(f"/subscribe for {subscriber_uk_id} request successful :: {response.json()}") + else: + print(f"/subscribe for {subscriber_uk_id} request failed :: {response.json()}") + elif subscriber['type'] == 'BPP': + bppSubscribeBody['message']['request_id'] = request_id + bppSubscribeBody['message']['timestamp'] = current_datetime_iso8601 + bppSubscribeBody['message']['entity']['subscriber_id'] = subscriber_id + bppSubscribeBody['message']['entity']['unique_key_id'] = unique_key_id + bppSubscribeBody['message']['entity']['key_pair']['signing_public_key'] = subscriber['signingPublicKey'] + bppSubscribeBody['message']['entity']['key_pair']['encryption_public_key'] = subscriber['encPublicKey'] + bppSubscribeBody['message']['entity']['key_pair']['valid_from'] = current_datetime_iso8601 + bppSubscribeBody['message']['network_participant'][0]['city_code'] = [subscriber['city']] + + print(json.dumps(bppSubscribeBody)) + + response = requests.post(registry_url, json=bppSubscribeBody) + if response.status_code == 200: + print(f"/subscribe for {subscriber_uk_id} request successful :: {response.json()}") + else: + print(f"/subscribe for {subscriber_uk_id} request failed :: {response.json()}") + time.sleep(300) + process.terminate() + process.join() + +@app.route('/subscribe', methods=['POST']) +def subscribe(): + global subscribers + subscribers = request.get_json() + print(f"/subscribe called :: Request -> {subscribers}") + thread1 = threading.Thread(target=subscribe_helper) + thread1.start() + return { "success" : "ACK" } + +def start_flask_app(): + app.run(port=app_port, host="0.0.0.0") + +if __name__ == '__main__': + start_flask_app(); \ No newline at end of file From cb704632c8ea958e9071f22eb989be893354750b Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Mon, 18 Sep 2023 21:31:10 +0530 Subject: [PATCH 035/228] Log Verification utility for B2B and Logistics --- .../log-verification-utility/.gitignore | 16 + .../log-verification-utility/README.md | 136 +++ .../log-verification-utility/config/config.js | 3 + .../log-verification-utility/dao/dao.js | 41 + .../log-verification-utility/index.js | 33 + .../log-verification-utility/package.json | 27 + .../log-verification-utility/routes/routes.js | 25 + .../schema/B2B_json_schema/confirm.js | 767 ++++++++++++++ .../schema/B2B_json_schema/init.js | 526 ++++++++++ .../schema/B2B_json_schema/master.js | 78 ++ .../schema/B2B_json_schema/on_confirm.js | 832 +++++++++++++++ .../schema/B2B_json_schema/on_init.js | 692 +++++++++++++ .../schema/B2B_json_schema/on_search.js | 968 ++++++++++++++++++ .../schema/B2B_json_schema/on_select.js | 333 ++++++ .../schema/B2B_json_schema/on_status.js | 808 +++++++++++++++ .../schema/B2B_json_schema/on_update.js | 527 ++++++++++ .../schema/B2B_json_schema/schemaValidator.js | 93 ++ .../schema/B2B_json_schema/search.js | 263 +++++ .../schema/B2B_json_schema/select.js | 427 ++++++++ .../schema/B2B_json_schema/status.js | 108 ++ .../schema/B2B_json_schema/update.js | 334 ++++++ .../SchemaValidator.js | 102 ++ .../logistics_api_json_schema/cancelSchema.js | 95 ++ .../confirmSchema.js | 928 +++++++++++++++++ .../logistics_api_json_schema/initSchema.js | 469 +++++++++ .../logistics_api_json_schema/masterSchema.js | 103 ++ .../masterSchemacopy.js | 12 + .../onCancelSchema.js | 175 ++++ .../onConfirmSchema.js | 546 ++++++++++ .../logistics_api_json_schema/onInitSchema.js | 288 ++++++ .../onSearchSchema.js | 376 +++++++ .../onStatusSchema.js | 683 ++++++++++++ .../onSupportSchema.js | 111 ++ .../onTrackSchema.js | 115 +++ .../onUpdateSchema.js | 347 +++++++ .../logistics_api_json_schema/searchSchema.js | 361 +++++++ .../logistics_api_json_schema/statusSchema.js | 93 ++ .../supportSchema.js | 86 ++ .../logistics_api_json_schema/trackSchema.js | 95 ++ .../logistics_api_json_schema/updateSchema.js | 417 ++++++++ .../log-verification-utility/schema/main.js | 20 + .../retail_api_json_schema/SchemaValidator.js | 174 ++++ .../retail_api_json_schema/cancelSchema.js | 85 ++ .../retail_api_json_schema/confirmSchema.js | 490 +++++++++ .../retail_api_json_schema/initSchema.js | 273 +++++ .../retail_api_json_schema/onCancelSchema.js | 19 + .../retail_api_json_schema/onConfirmSchema.js | 473 +++++++++ .../retail_api_json_schema/onInitSchema.js | 322 ++++++ .../onSearchBPCSchema.js | 610 +++++++++++ .../onSearchGrocerySchema.js | 490 +++++++++ .../onSearchItemValidations.js | 201 ++++ .../retail_api_json_schema/onSearchSchema.js | 583 +++++++++++ .../onSearchfashionSchema.js | 490 +++++++++ .../retail_api_json_schema/onSelectSchema.js | 175 ++++ .../retail_api_json_schema/onStatusSchema.js | 548 ++++++++++ .../retail_api_json_schema/onSupportSchema.js | 14 + .../retail_api_json_schema/onTrackSchema.js | 13 + .../retail_api_json_schema/onUpdateSchema.js | 486 +++++++++ .../postConfirmValidations.js | 0 .../retail_api_json_schema/searchSchema.js | 140 +++ .../retail_api_json_schema/selectSchema.js | 170 +++ .../retail_api_json_schema/statusSchema.js | 80 ++ .../retail_api_json_schema/updateSchema.js | 201 ++++ .../services/cbCheck.service.js | 12 + .../services/service.js | 15 + .../utils/ContextVal.js | 93 ++ .../utils/ServicabilityCheck.js | 68 ++ .../utils/b2b/b2bInit.js | 91 ++ .../utils/b2b/b2bOnSearch.js | 33 + .../utils/b2b/b2bOnStatus.js | 194 ++++ .../utils/b2b/b2bSearch.js | 18 + .../utils/b2b/msgValidator.js | 20 + .../log-verification-utility/utils/clean.js | 19 + .../utils/constants.js | 48 + .../utils/logistics/logConfirm.js | 31 + .../utils/logistics/logInit.js | 124 +++ .../utils/logistics/logOnConfirm.js | 37 + .../utils/logistics/logOnInit.js | 64 ++ .../utils/logistics/logOnSearch.js | 112 ++ .../utils/logistics/logOnStatus.js | 198 ++++ .../utils/logistics/logOnUpdate.js | 47 + .../utils/logistics/logSearch.js | 32 + .../utils/logistics/logUpdate.js | 46 + .../utils/logistics/msgValidator.js | 44 + .../utils/mergeSort.js | 95 ++ .../utils/ret.cbCheck.util.js | 7 + .../utils/schemaVal.js | 76 ++ .../utils/schemaValidation.js | 26 + .../log-verification-utility/utils/utils.js | 350 +++++++ .../utils/validateLogUtil.js | 46 + 90 files changed, 20442 insertions(+) create mode 100755 utilities/logistics-b2b/log-verification-utility/.gitignore create mode 100644 utilities/logistics-b2b/log-verification-utility/README.md create mode 100755 utilities/logistics-b2b/log-verification-utility/config/config.js create mode 100755 utilities/logistics-b2b/log-verification-utility/dao/dao.js create mode 100755 utilities/logistics-b2b/log-verification-utility/index.js create mode 100755 utilities/logistics-b2b/log-verification-utility/package.json create mode 100755 utilities/logistics-b2b/log-verification-utility/routes/routes.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/cancelSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onCancelSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onTrackSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/statusSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/supportSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/trackSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/main.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/postConfirmValidations.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js create mode 100755 utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js create mode 100755 utilities/logistics-b2b/log-verification-utility/services/service.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/ServicabilityCheck.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/clean.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/constants.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/utils.js create mode 100755 utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore new file mode 100755 index 0000000..18113cb --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/.gitignore @@ -0,0 +1,16 @@ +node_modules +package-lock.json +*.env +.vscode +/public/logs/*.json +/public/* +verification-logs +/utils/*.json +/utils/*.txt +test_logs +dbfiles +test.js +!LICENSE.md +logFlow*.json +.DS_Store +log_report.json \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/README.md b/utilities/logistics-b2b/log-verification-utility/README.md new file mode 100644 index 0000000..3ec03df --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/README.md @@ -0,0 +1,136 @@ +# ONDC-LOG-VALIDATION + +### APIs Log Validation tool for Pre-Prod participants + +The tool is a NODE.js based utility to check the conformance and compliance of the API logs for [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) based on the examples in the API Contract. + +### Tech + +- [[node.js](https://nodejs.org/en/)] +- [[lmdb](https://www.npmjs.com/package/lmdb)] +- [[lodash](https://www.npmjs.com/package/lodash)] +- [[ajv](https://ajv.js.org/)] + +## Steps to run the utility + +Log Validation Tool requires [Node.js](https://nodejs.org/) to run. + +1. Clone the repository, navigate to log-validation-utility and install the dependencies. + +```sh + +cd log-validation-utility + +npm i +``` + +2. Move all the API payloads inside "/public/logs" folder or mention the path to the logs folder as demonstrated in the next step. + +3. Run the utility in the following format + + > node index.js "domain" "/path/to/logs/folder/" + +```sh +node index.js logistics ./public/logs/ +node index.js b2b ./public/logs/ +``` + +4. A text report (**log_report.json**) will be generated upon successful execution of the utility. + + +_Notes:_ + +> There must be a separate payload for every API. + +> The utility validates all the payloads as documented in the examples for respective domains: +* [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) + +* [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) + +> Test cases to be referred here -> [logsitics](https://docs.google.com/document/d/1ttixilM-I6dutEdHL10uzqRFd8RcJlEO_9wBUijtdDc/edit) and [B2B](https://docs.google.com/document/d/10ouiTKLY4dm1KnXCuhFwK38cYd9_aDQ30bklkqnPRkM/edit) + +> Sample payload for search.json is demonstrated below: + +```json +{ + "context": + { + "domain":"ONDC:RET10", + "location": { + "city": { + "code": "std:080" + }, + "country": { + "code": "IND" + } + }, + "action":"search", + "version":"2.0.1", + "bap_id":"buyerapp.com", + "bap_uri":"https://buyerapp.com/grocery", + "transaction_id":"T1", + "message_id":"M1", + "timestamp":"2023-01-08T22:00:00.000Z", + "ttl":"PT30S" + }, + "message": + { + "intent": + { + "item": + { + "descriptor": + { + "name":"oil" + } + }, + "fulfillment": + { + "type":"Delivery", + "stops": + [ + { + "type":"end", + "location": + { + "gps":"1.3806217468119772, 103.74636438437074", + "area_code":"680230" + } + } + ] + }, + "payment": + { + "type":"ON-FULFILLMENT" + }, + "tags": + [ + { + "descriptor": { + "code":"bap_terms" + }, + "list": + [ + { + "descriptor": { + "code":"finder_fee_type" + }, + "value":"percent" + }, + { + "descriptor": { + "code":"finder_fee_amount" + }, + "value":"0" + } + ] + } + ] + } + } +} +``` + +### N.B. + +> - Community contributions are welcomed to enhance this utility for future releases. diff --git a/utilities/logistics-b2b/log-verification-utility/config/config.js b/utilities/logistics-b2b/log-verification-utility/config/config.js new file mode 100755 index 0000000..2f23305 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/config/config.js @@ -0,0 +1,3 @@ +const config = {}; + +module.exports = config; diff --git a/utilities/logistics-b2b/log-verification-utility/dao/dao.js b/utilities/logistics-b2b/log-verification-utility/dao/dao.js new file mode 100755 index 0000000..5c8655c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/dao/dao.js @@ -0,0 +1,41 @@ +const { open } = require("lmdb"); +const constants = require("../utils/constants"); + +const getConnection = () => { + let myDB = open({ + path: constants.DB_PATH, + // maxReaders:200, //maxReaders limit + compression: true, + }); + + return myDB; +}; + +const setValue = (key, value) => { + let myDB = getConnection(); + + myDB.putSync(key, value); + myDB.close(); +}; +const getValue = (key) => { + let myDB = getConnection(); + let value = myDB.get(key); + myDB.close(); + return value; +}; + +const dropDB = () => { + let myDB = getConnection(); + return new Promise((resolve, reject) => { + myDB + .drop() + .then((res) => { + console.log("DB Dropped Successfully!!", res); + }) + .catch((err) => { + console.log("!!Error while removing LMDB"); + }); + }); +}; + +module.exports = { getValue, setValue, dropDB }; diff --git a/utilities/logistics-b2b/log-verification-utility/index.js b/utilities/logistics-b2b/log-verification-utility/index.js new file mode 100755 index 0000000..7db2481 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/index.js @@ -0,0 +1,33 @@ +const { validateLog } = require("./services/cbCheck.service"); +const fs = require("fs"); +const path = require("path"); + +try { + if (process.argv.length < 3) { + console.log( + "Need arguments in the format: node index.js 'domain' '/path/to/logs/folder/'" + ); + return; + } + + // Setting default values in case arguments not passed + const domain = process.argv[2].toLowerCase() || "logistics"; + const logpath = process.argv[3] || "./public/logs/"; + + //Read Log directory + fs.readdir(logpath, (err, files) =>{ + try { + if (err) { + console.log(`Some error occurred while reading files from ${path}`); + } else if (!files.length) { + console.log(`${path} folder is empty!!`); + } else { + validateLog(domain, logpath); + } + } catch (error) { + console.log(`Error while reading logs folder`, error); + } + }); +} catch (error) { + console.log("!!Some Unexpected Error Occurred", error); +} diff --git a/utilities/logistics-b2b/log-verification-utility/package.json b/utilities/logistics-b2b/log-verification-utility/package.json new file mode 100755 index 0000000..4dd4e33 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/package.json @@ -0,0 +1,27 @@ +{ + "name": "log-verification-ondc", + "version": "1.0.0", + "description": "Log Verification ONDC", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/bluecypher/ONDC-Log-Verification.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/bluecypher/ONDC-Log-Verification/issues" + }, + "homepage": "https://github.com/bluecypher/ONDC-Log-Verification#readme", + "dependencies": { + "ajv": "^8.12.0", + "ajv-errors": "^3.0.0", + "ajv-formats": "^2.1.1", + "lmdb": "^2.7.5", + "lodash": "^4.17.21" + }, + "keywords": [] +} diff --git a/utilities/logistics-b2b/log-verification-utility/routes/routes.js b/utilities/logistics-b2b/log-verification-utility/routes/routes.js new file mode 100755 index 0000000..741eb7b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/routes/routes.js @@ -0,0 +1,25 @@ +const express = require("express"); +const router = express.Router(); +const service = require("../services/service"); +const { validateLog } = require("../services/cbCheck.service"); + +router.post("/validateSchema/:path", (req, res) => { + const path = req.params.path; + const data = req.body; + const result = service.schemaValidation(domain, data, path); + res.json(result); +}); + +router.post("/CheckContext/:path", (req, res) => { + const path = req.params.path; + const data = req.body.context; + const result = service.checkContext(data, path); + res.json(result); +}); + +router.post("/ValidateLog/:domain", (req, res) => { + const domain = req.params.domain; + validateLog(domain); +}); + +module.exports = router; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js new file mode 100644 index 0000000..935ca04 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js @@ -0,0 +1,767 @@ +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "confirm", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + enum: ["Created"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + locations: { + type: "array", + const: { $data: "/init/0/message/order/provider/locations" }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["person"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "Discount", "Packing charges", "delivery ", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + created_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "created_at does not match context timestamp - ${3/context/timestamp}", + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "updated_at does not match context timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties:false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js new file mode 100644 index 0000000..9e0fb0e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js @@ -0,0 +1,526 @@ +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "init", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: { $data: "2/message/order/provider/ttl" }, + errorMessage:"should match provider ttl - ${2/message/order/provider/ttl}" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/locations/0/id"} + }, + }, + required: ["id"], + }, + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: ["id", "locations", "ttl"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["BUYER_TERMS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_REQ","PACKAGING_REQ"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + }, + address: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + }, + email: { + type: "string", + }, + phone: { + type: "string", + }, + }, + additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "License", + "Badge", + "Permit", + "Certificate", + ], + }, + desc: { + type: "string", + }, + icon: { + type: "string", + }, + url: { + type: "string", + pattern: + "^https://[\\w.-]+(\\.[a-zA-Z]{2,})?(:[0-9]+)?(/\\S*)?$", + }, + }, + required: ["id", "type", "desc", "icon", "url"], + }, + }, + }, + required: ["creds"], + }, + }, + required: ["person"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["INCOTERMS", "DELIVERY_DUTY"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + payments: { + type: "array", + items: + { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties:false, + required: [ + "provider", + "items", + "billing", + "fulfillments", + "payments", + "tags", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js new file mode 100644 index 0000000..d01fe98 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js @@ -0,0 +1,78 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + } + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js new file mode 100644 index 0000000..88a1c73 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js @@ -0,0 +1,832 @@ +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_confirm", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/provider/id" }, + }, + locations: { + type: "array", + const: { $data: "/confirm/0/message/order/provider/locations" }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + rateable: { + type: "boolean", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "stops", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + const: { $data: "3/context/timestamp" }, + errorMessage: + " should be updated as per context/timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "tags", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js new file mode 100644 index 0000000..4f9117a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js @@ -0,0 +1,692 @@ +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_init", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/locations/0/id"} + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["BUYER_TERMS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_REQ","PACKAGING_REQ"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "tracking", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "Discount", "Packing charges", "delivery ", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties:false, + required: [ + "provider", + "provider_location", + "items", + "billing", + "fulfillments", + "quote", + "payments", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js new file mode 100644 index 0000000..c9b2f76 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js @@ -0,0 +1,968 @@ +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_search", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup"] + }, + }, + required: ["id", "type"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["id", "type"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "short_desc", "long_desc", "images"], + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + additional_desc: { + type: "object", + properties: { + url: { + type: "string", + }, + content_type: { + type: "string", + }, + }, + required: ["url", "content_type"], + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "code"], + }, + rating: { + type: "string", + }, + ttl: { + type: "string", + format: "duration" + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + code: { + type: "string", + pattern: "^(std:?[0-9]{2,3})$" + }, + name: { + type: "string", + }, + }, + required: ["code", "name"], + }, + state: { + type: "object", + properties: { + code: { + type: "string", + pattern: "^(std:?[0-9]{2,3})$" + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + }, + additionalProperties:false, + required: [ + "id", + "gps", + "address", + "city", + "state", + "country", + "area_code", + ], + }, + }, + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["License", "Badge", "Permit", "Certificate"], + }, + desc: { + type: "string", + }, + url: { + type: "string", + format: "uri", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["mimetype", "url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + creator: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + required: ["full"], + }, + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["address", "phone"], + }, + }, + required: ["name", "contact"], + }, + }, + required: ["descriptor"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: ["currency", "value", "maximum_value"], + }, + quantity: { + type: "object", + properties: { + unitized: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["measure"], + }, + available: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, + maximum: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, + }, + required: ["unitized", "available", "maximum"], + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + }, + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: [ + "currency", + "value", + "offered_value", + "maximum_value", + ], + }, + }, + required: ["id", "descriptor", "price"], + }, + }, + cancellation_terms: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + refund_eligible: { + type: "string", + }, + return_policy: { + type: "object", + properties: { + return_eligible: { + type: "string", + }, + return_within: { + type: "string", + }, + fulfillment_managed_by: { + type: "string", + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + required: ["address", "gps"], + }, + }, + required: [ + "return_eligible", + "return_within", + "fulfillment_managed_by", + "return_location", + ], + }, + }, + if: { + properties: { + fulfillment_state: { + properties: { + descriptor: { + properties: { + code: { + const: "Order-delivered", + }, + }, + }, + }, + }, + }, + }, + then: { + required: ["fulfillment_state", "return_policy"], + }, + else: { + required: [ + "fulfillment_state", + "refund_eligible", + ], + }, + }, + }, + replacement_terms: { + type: "array", + items: { + type: "object", + properties: { + replace_within: { + type: "string", + }, + }, + required: ["replace_within"], + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + matched: { + type: "string", + }, + recommended: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + + "descriptor", + "creator", + "price", + "quantity", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "replacement_terms", + + "matched", + "recommended", + ], + }, + }, + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + location_ids: { + type: "array", + items: {}, + }, + category_ids: { + type: "array", + items: {}, + }, + item_ids: { + type: "array", + items: {}, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + }, + required: [ + "id", + "descriptor", + "location_ids", + "category_ids", + "item_ids", + "time", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["contact"], + }, + }, + }, + required: [ + "id", + "descriptor", + "ttl", + "locations", + "tags", + "items", + "fulfillments", + ], + }, + }, + }, + additionalProperties:false, + required: ["fulfillments", "payments", "descriptor", "providers"], + }, + }, + required: ["catalog"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js new file mode 100644 index 0000000..bc7da76 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js @@ -0,0 +1,333 @@ +module.exports = { + $id: "http://example.com/schema/onSelectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_select", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/select/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + tracking: { + type: "boolean", + }, + "@ondc/org/category": { + type: "string", + }, + "@ondc/org/TAT": { + type: "string", + format: "duration" + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Serviceable", "Non-Serviceable"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "tracking", + "@ondc/org/category", + "@ondc/org/TAT", + "state", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "Discount", "Packing charges", "delivery ", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + quantity: { + type: "object", + properties: { + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + }, + required: ["available", "maximum"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["quantity", "price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: ["price", "breakup", "ttl"], + }, + }, + required: ["provider", "items", "quote"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js new file mode 100644 index 0000000..d9a732c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js @@ -0,0 +1,808 @@ +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_status", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress", + "Cancelled", + "Completed", + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + required: ["name"], + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Agent-assigned", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + agent: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["person", "contact"], + }, + }, + if: { properties: { type: { const: "start" } } }, + then: { + properties: { + location: { required: ["id", "descriptor", "gps"] }, + }, + }, + else: { + properties: { + location: { required: ["address", "gps"] }, + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "type", + "tracking", + "state", + "stops", + ], + anyof: [ + { + properties: { + state: { + const: "Order-picked-up" + }, + stops: { + type: "array", + items: { + properties: { + type: { + const: "start" + }, + time: { + required: ["range", "timestamp"] + } + } + } + } + } + } + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + + documents: { + type: "array", + items: + { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", + }, + }, + required: ["url", "label"], + }, + + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "order/created_at should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "documents", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js new file mode 100644 index 0000000..ed5e80a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js @@ -0,0 +1,527 @@ +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "ONDC:RET10", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_update", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + }, + message_id: { + type: "string", + const: { $data: "/update/0/context/message_id" }, + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress" + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["id", "quantity", "fulfillment_ids"], + }, + }, + payment: { + type: "object", + properties: { + uri: { + type: "string", + }, + tl_method: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum:["BAP","BPP"] + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["Pending","Agent-assigned","Order-picked-up","Out-for-delivery","Delivered"] + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: [ + "type", + "location", + "time", + "instructions", + "contact", + ], + }, + }, + rateable: { + type: "boolean", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_DETAILS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_ID","COUNT","MEASURE_UNIT","MEASURE_VALUE"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "stops" + ], + }, + }, + }, + + required: ["id", "state", "provider", "items"], + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js new file mode 100644 index 0000000..aa79eae --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -0,0 +1,93 @@ +const onConfirmSchema = require("./on_confirm"); +const onInitSchema = require("./on_init"); +const onSearchSchema = require("./on_search"); +const selectSchema = require("./select"); +const onSelectSchema = require("./on_select"); +const onUpdateSchema = require("./on_update"); +const searchSchema = require("./search"); +const initSchema = require("./init"); +const masterSchema = require("./master"); +const confirmSchema = require("./confirm"); +const statusSchema = require("./status"); +const updateSchema = require("./update"); +const onStatusSchema = require("./on_status"); + +const fs = require("fs"); +//const async = require("async"); +const path = require("path"); + +const Ajv = require("ajv"); +const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + $data: true, +}); +const addFormats = require("ajv-formats"); + +addFormats(ajv); +require("ajv-errors")(ajv); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + +const validate_schema = (data, schema) => { + let error_list = []; + try { + validate = ajv + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(selectSchema) + .addSchema(onSelectSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema) + + + + validate = validate.compile(schema); + + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + } catch (error) { + console.log("ERROR!! validating schema"); + console.trace(error); + } + return error_list; +}; + +const validate_schema_b2b_master = (data) => { + error_list = validate_schema(data, masterSchema); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_b2b_master +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js new file mode 100644 index 0000000..9c8f6af --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js @@ -0,0 +1,263 @@ +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "ONDC:RET10", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "search", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + category: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Delivery and Self-Pickup"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + }, + required: ["type", "location"], + }, + }, + }, + required: ["type", "stops"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + tags: { + type: "array", + minItems: 2, + uniqueItems: true, + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["bap_terms", "buyer_id"], + }, + }, + required:["code"] + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + required:["code"] + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + minItems: 2, + }, + }, + required: ["descriptor", "list"], + if: { + properties: { + descriptor: { + properties: { code: { const: "bap_terms" } }, + }, + }, + }, + then: { + properties: { + list: { + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + enum: ["finder_fee_type", "finder_fee_amount"], + }, + }, + }, + }, + required: ["descriptor"], + }, + }, + }, + errorMessage: + "For 'bap_terms', the 'list' must contain either 'finder_fee_type' or 'finder_fee_amount'.", + }, + else: { + if: { + properties: { + descriptor: { + properties: { code: { const: "buyer_id" } }, + }, + }, + }, + then: { + properties: { + list: { + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + }, + required: ["descriptor"], + }, + }, + }, + errorMessage: + "For 'buyer_id', the 'list' must contain either 'buyer_id_code' or 'buyer_id_no'.", + }, + }, + }, + }, + }, + additionalProperties:false, + required: ["item", "fulfillment", "payment", "tags"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js new file mode 100644 index 0000000..9a4649c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js @@ -0,0 +1,427 @@ +module.exports = { + $id: "http://example.com/schema/selectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "select", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string" + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string" + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "location_ids", "quantity"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + }, + required: ["type", "location"], + }, + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "License", + "Badge", + "Permit", + "Certificate", + ], + }, + desc: { + type: "string", + }, + icon: { + type: "string", + }, + url: { + type: "string", + pattern: + "^https://[\\w.-]+(\\.[a-zA-Z]{2,})?(:[0-9]+)?(/\\S*)?$", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + }, + required: ["creds"], + }, + }, + required: ["person"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id", "COMM_CHANNEL"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: [ + "buyer_id_code", + "buyer_id_no", + "chat_url", + ], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties:false, + required: ["provider", "items", "fulfillments", "payments", "tags"], + }, + }, + required: ["order"], + additionalProperties:false, + }, + }, + required: ["context", "message"], + additionalProperties:false, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js new file mode 100644 index 0000000..45afe99 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js @@ -0,0 +1,108 @@ +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "ONDC:RET10", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "status", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/on_confirm/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/on_confirm/0/message/order/id" }, + }, + }, + additionalProperties:false, + required: ["order_id"], + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js new file mode 100644 index 0000000..62e1bd1 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js @@ -0,0 +1,334 @@ +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "ONDC:RET10", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "update", + }, + version: { + type: "string", + const: "2.0.1", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum:["fulfillment","item"] + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: + { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + }, + required: ["id", "quantity"], + }, + + }, + payments: { + type: "array", + items: + { + type: "object", + properties: { + uri: { + type: "string", + }, + tl_method: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: + { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: [ + "settlement_counterparty", + "settlement_type", + ], + }, + + }, + }, + required: [ + "uri", + "tl_method", + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + + }, + }, + additionalProperties:false, + required: ["id", "state", "provider", "items", "payments"], + }, + }, + required: ["update_target", "order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js new file mode 100644 index 0000000..df9a194 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js @@ -0,0 +1,102 @@ +const onConfirmSchema = require("./onConfirmSchema"); +const onInitSchema = require("./onInitSchema"); +const onSearchSchema = require("./onSearchSchema"); +const onTrackSchema = require("./onTrackSchema"); +const onSupportSchema = require("./onSupportSchema"); +const onStatusSchema = require("./onStatusSchema"); +const onCancelSchema = require("./onCancelSchema"); +const onUpdateSchema = require("./onUpdateSchema"); +const searchSchema = require("./searchSchema"); +const initSchema = require("./initSchema"); +const masterSchema = require("./masterSchema"); +const confirmSchema = require("./confirmSchema"); +const statusSchema = require("./statusSchema"); +const updateSchema = require("./updateSchema"); +const cancelSchema = require("./cancelSchema"); +const supportSchema = require("./supportSchema"); +const trackSchema = require("./trackSchema"); +const fs = require("fs"); +//const async = require("async"); +const path = require("path"); + +const Ajv = require("ajv"); +const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + verbose: true, + $data: true, +}); + +const addFormats = require("ajv-formats"); +//const masterSchemacopy = require("./masterSchemacopy"); + +addFormats(ajv); +require("ajv-errors")(ajv); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + +const validate_schema = (data, schema) => { + let error_list = []; + try { + validate = ajv + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema) + .addSchema(supportSchema) + .addSchema(onSupportSchema) + .addSchema(trackSchema) + .addSchema(onTrackSchema) + .addSchema(cancelSchema) + .addSchema(onCancelSchema); + + validate = validate.compile(schema); + + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + } catch (error) { + console.log("ERROR!! validating schema"); + console.trace(error); + } + + return error_list; +}; + +const validate_schema_master = (data) => { + error_list = validate_schema(data, masterSchema); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_master, +}; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/cancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/cancelSchema.js new file mode 100644 index 0000000..46f9146 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/cancelSchema.js @@ -0,0 +1,95 @@ +module.exports = { + $id: "http://example.com/schema/cancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "cancel", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + cancellation_reason_id: { + type: "string", + }, + }, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js new file mode 100644 index 0000000..8c025fb --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js @@ -0,0 +1,928 @@ +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/on_search/0/context/city" }, + }, + action: { + type: "string", + const: "confirm", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + const: "Created", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + }, + }, + }, + required: ["id"], + oneOf: [ + { + required: [ + "/on_search/0/message/catalog/bpp~1providers/0/locations", + "locations", + ], + }, + { + not: { + required: [ + "/on_search/0/message/catalog/bpp~1providers/0/locations", + ], + }, + }, + ], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, + }, + category_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + anyOf: [ + { + allOf: [ + { + properties: { + id: { + const: { + $data: + "/on_search/0/message/catalog/bpp~1providers/0/items/0/id", + }, + }, + }, + }, + { + properties: { + category_id: { + const: { + $data: + "/on_search/0/message/catalog/bpp~1providers/0/items/0/category_id", + }, + }, + }, + }, + ], + }, + { + allOf: [ + { + properties: { + id: { + const: { + $data: + "/on_search/0/message/catalog/bpp~1providers/1/items/0/id", + }, + }, + }, + }, + { + properties: { + category_id: { + const: { + $data: + "/on_search/0/message/catalog/bpp~1providers/1/items/0/category_id", + }, + }, + }, + }, + ], + }, + ], + }, + }, + quote: { + type: "object", + const: { $data: "/on_init/0/message/order/quote" }, + errorMessage: "object mismatches in /on_init and /confirm.", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + errorMessage: "mismatches in /on_init and /confirm.", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["Delivery Charge", "Tax"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + const: "INR", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + "@ondc/org/awb_no": { + type: "string", + }, + start: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + //required: ["long_desc", "images"], + }, + }, + required: ["person", "location", "contact"], + }, + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: + "name + building + locality < 190 chars & each of name / building / locality > 3 chars; name != locality", + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + additional_desc: { + type: "object", + properties: { + content_type: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["content_type", "url"], + }, + }, + // required: [ + // "long_desc", + // "additional_desc", + // ], + }, + }, + required: ["person", "location", "contact"], + }, + + "@ondc/org/ewaybillno": { + type: "string", + }, + "@ondc/org/ebnexpirydate": { + type: "string", + format: "date-time", + }, + tags: { + type: "object", + properties: { + "@ondc/org/order_ready_to_ship": { + type: "string", + enum: ["yes", "no"], + }, + }, + // if: { + // properties: { + // "@ondc/org/order_ready_to_ship": { const: "yes" }, + // }, + // }, + // then: { + // required: ["1/start/instructions"], + // errorMessage: + // "Pickup code (fulfillments/start/instructions), mandatory if order_ready_to_ship = yes in /confirm", + // }, + + required: ["@ondc/org/order_ready_to_ship"], + }, + }, + required: ["id", "type", "start", "end", "tags"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + const: { + $data: "/init/0/message/order/billing/address/name", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + building: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/building", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + locality: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/locality", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + city: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/city", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + state: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/state", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + country: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/country", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + area_code: { + type: "string", + const: { + $data: + "/init/0/message/order/billing/address/area code", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + const: { + $data: "/init/0/message/order/billing/tax_number", + }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + created_at: { + type: "string", + const: { + $data: "/init/0/message/order/billing/created_at", + }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + updated_at: { + type: "string", + const: { + $data: "/init/0/message/order/billing/updated_at", + }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "address", + "phone", + "tax_number", + "created_at", + "updated_at", + ], + }, + payment: { + type: "object", + properties: { + "@ondc/org/collection_amount": { + type: "string", + }, + collected_by: { + type: "string", + const: { + $data: "/on_init/0/message/order/payment/collected_by", + }, + errorMessage: "mismatches in /payment in /on_init and /confirm", + }, + type: { + type: "string", + enum: ["ON-FULFILLMENT", "POST-FULFILLMENT", "ON-ORDER"], + const: { + $data: "/on_init/0/message/order/payment/type", + }, + errorMessage: "mismatches in /payment in /on_init and /confirm", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "collected_by", + "type", + "@ondc/org/settlement_details", + ], + }, + "@ondc/org/linked_order": { + type: "object", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + category_id: { + type: "string", + enum: [ + "Grocery", + "F&B", + "Fashion", + "BPC", + "Electronics", + "Home & Decor", + "Pharma", + "Agriculture", + "Mobility", + ], + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["count", "measure"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "category_id", + "descriptor", + "quantity", + "price", + ], + }, + }, + provider: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + street: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + + required: [ + "name", + "locality", + "city", + "state", + "area_code", + ], + }, + }, + required: ["descriptor", "address"], + }, + order: { + type: "object", + properties: { + id: { + type: "string", + }, + weight: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "number", + const: { + $data: + "/search/0/message/intent/@ondc~1org~1payload_details/weight/value", + }, + errorMessage: + "Payload weight mismatches in /search and /confirm", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["id", "weight"], + }, + }, + required: ["items", "provider", "order"], + }, + created_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "created_at does not match context timestamp - ${3/context/timestamp}", + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "updated_at does not match context timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "billing", + "payment", + "@ondc/org/linked_order", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js new file mode 100644 index 0000000..336bc64 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js @@ -0,0 +1,469 @@ +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "init", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + category_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["CoD", "Prepaid"], + }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/start/location/gps", + }, + errorMessage: + "does not match start location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email" + }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/end/location/gps", + }, + errorMessage: + "does not match end location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage:"cannot be equal to locality" + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage:"cannot be equal to locality" + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email" + }, + }, + required: ["phone", "email"], + }, + }, + required: ["location", "contact"], + }, + }, + additionalProperties:false, + required: ["id", "type", "start", "end"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage:"cannot be equal to locality" + + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage:"cannot be equal to locality" + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + }, + phone: { + type: "string", + }, + email: { + type: "string", + format:"email" + }, + created_at: { + type: "string", + const: { $data: "4/context/timestamp" }, + errorMessage: + "does not match context timestamp - ${4/context/timestamp} ", + }, + updated_at: { + type: "string", + const: { $data: "4/context/timestamp" }, + errorMessage: + "does not match context timestamp - ${4/context/timestamp} ", + }, + }, + required: [ + "name", + "address", + "phone", + "created_at", + "updated_at", + ], + }, + payment: { + type: "object", + properties: { + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: [ + "settlement_counterparty", + "settlement_type", + ], + }, + }, + }, + required: ["@ondc/org/settlement_details"], + }, + }, + additionalProperties:false, + required: ["provider", "items", "fulfillments", "billing"] + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchema.js new file mode 100644 index 0000000..40b0880 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchema.js @@ -0,0 +1,103 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + }, + support: { + type: "array", + items: { + $ref: "supportSchema#", + }, + }, + on_support: { + type: "array", + items: { + $ref: "onSupportSchema#", + }, + }, + track: { + type: "array", + items: { + $ref: "trackSchema#", + }, + }, + on_track: { + type: "array", + items: { + $ref: "onTrackSchema#", + }, + }, + cancel: { + type: "array", + items: { + $ref: "cancelSchema#", + }, + }, + on_cancel: { + type: "array", + items: { + $ref: "onCancelSchema#", + }, + }, + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js new file mode 100644 index 0000000..0c8265f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js @@ -0,0 +1,12 @@ +module.exports = { + $id: "http://example.com/schema/masterSchemaCopy", + type: "object", + properties: { + search: { + $ref: "searchSchema1#", + }, + on_search: { + $ref: "onSearchSchema1#", + }, + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onCancelSchema.js new file mode 100644 index 0000000..a28db07 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onCancelSchema.js @@ -0,0 +1,175 @@ +module.exports = { + $id: "http://example.com/schema/onCancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "on_cancel", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + { + const: { $data: "/cancel/0/context/message_id" }, + errorMessage: + "Message ID should be same as /cancel: ${/cancel/0/context/message_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + + properties: { + id: { + type: "string", + const: { $data: "/on_confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum:["Cancelled"] + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + $data: "/on_confirm/0/message/order/fulfillments/0/id", + }, + type: { + type: "string", + $data: "/on_confirm/0/message/order/fulfillments/0/type", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["Cancelled"] + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + }, + "AWB no": { + type: "string", + }, + }, + required: ["cancellation_reason_id"], + }, + }, + additionalProperties: false, + required: ["id", "type", "state", "tags"], + }, + }, + }, + additionalProperties: false, + required: ["id", "state", "fulfillments"], + }, + }, + required: ["order"], + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js new file mode 100644 index 0000000..5be9e68 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js @@ -0,0 +1,546 @@ +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/on_search/0/context/city" }, + }, + action: { + type: "string", + const: "on_confirm", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/confirm/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/confirm/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + { + not: { + const: { $data: "/init/0/context/message_id" }, + }, + errorMessage: "Message ID should be unique", + }, + { + not: { + const: { $data: "/search/0/context/message_id" }, + }, + errorMessage: "Message ID should be unique", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/locations/0/id" }, + }, + }, + required: ["id"], + }, + }, + }, + required: ["id"], + // oneOf: [ + // { + // required: [ + // "/confirm/0/message/order/provider/locations", + // "locations", + // ], + // }, + // { + // not: { + // required: [ + // "/confirm/0/message/order/provider/locations", + // "locations", + // ], + // }, + // }, + // ], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, + }, + category_id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/category_id" }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/init/0/message/order/items/0/descriptor/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + quote: { + type: "object", + const: { $data: "/confirm/0/message/order/quote" }, + errorMessage: "object mismatches in /confirm and /on_confirm.", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/confirm/0/message/order/quote/price/value", + }, + errorMessage: "mismatches in /on_confirm and /confirm.", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["Delivery Charge", "Tax"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + const: "INR", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/confirm/0/message/order/fulfillments/0/id", + }, + }, + type: { + type: "string", + const: { + $data: "/confirm/0/message/order/fulfillments/0/type", + }, + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: "Pending", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + "@ondc/org/awb_no": { + type: "string", + + }, + tracking: { + type: "boolean", + }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + }, + required: ["time"], + }, + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + }, + required: ["time"], + }, + agent: { + type: "object", + properties: { + name: { + type: "string", + }, + phone: { + type: "string", + }, + }, + required: ["name", "phone"], + }, + vehicle: { + type: "object", + properties: { + category: { + type: "string", + }, + size: { + type: "string", + }, + registration: { + type: "string", + }, + }, + required: ["category", "size", "registration"], + }, + "@ondc/org/ewaybillno": { + type: "string", + const: { $data: "/confirm/0/message/order/fulfillments/0/@ondc~1org~1ewaybillno" }, + + + }, + "@ondc/org/ebnexpirydate": { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/fulfillments/0/@ondc~1org~1ebnexpirydate"}, + + }, + }, + required: ["id", "type", "state", "tracking"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/name" }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + const: { + $data: "/confirm/0/message/order/billing/address/name", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + building: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/building", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + locality: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/locality", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + city: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/city", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + state: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/state", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + country: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/country", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + area_code: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/area code", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/tax_number" }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + phone: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/phone" }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + email: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/email" }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + created_at: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/created_at" }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + updated_at: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/updated_at" }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "address", + "phone", + "tax_number", + "created_at", + "updated_at", + ], + }, + created_at: { + type: "string", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "mismatches in /confirm and /on_confirm", + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "does not match context/timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties:false, + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "billing", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js new file mode 100644 index 0000000..fee04d1 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js @@ -0,0 +1,288 @@ +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_init", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + { + not: { + const: { $data: "/search/0/context/message_id" }, + }, + errorMessage: "Message ID should be unique", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/locations/0/id" }, + }, + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, + }, + }, + required: ["id"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["Delivery Charge", "Tax"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: ["ON-FULFILLMENT", "POST-FULFILLMENT", "ON-ORDER"], + }, + collected_by: { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: ["type", "collected_by"], + }, + }, + additionalProperties:false, + required: ["provider", "items", "quote", "payment"], + // anyOf: [ + // { + // required: [ + // "/on_search/0/message/catalog/bpp~1providers/0/locations", + // "provider_location", + // ], + // errorMessage:"provider/location is required in /init if it was returned in /on_search" + // }, + // { + // not: { + // required: [ + // "/on_search/0/message/catalog/bpp~1providers/0/locations", + // ], + // }, + // }, + // ], + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js new file mode 100644 index 0000000..eda6346 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js @@ -0,0 +1,376 @@ +const { error } = require("ajv/dist/vocabularies/applicator/dependencies"); + +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_search", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + "bpp/fulfillments": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["Prepaid", "CoD", "RTO", "Reverse QC"], + }, + }, + required: ["id", "type"], + }, + }, + "bpp/descriptor": { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + "bpp/providers": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + required: ["name", "short_desc", "long_desc"], + }, + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + time: { + type: "object", + properties: { + label: { + type: "string", + const: "TAT", + }, + duration: { + type: "string", + format: "duration", + }, + }, + required: ["label", "duration"], + }, + }, + required: ["id"], + anyOf: [ + { + properties: { + id: { const: "Immediate Delivery" }, + time: { + type: "object", + properties: { + duration: { + type: "string", + pattern: "^PT([1-5][1-9]|60)?M$", + errorMessage: + "Duration is not correct as per Immediate Delivery", + }, + }, + required: ["label", "duration"], + }, + }, + required: ["id", "time"], + }, + { + not: { + properties: { + id: { const: "Immediate Delivery" }, + time: { + type: "object", + properties: { + duration: { + type: "string", + pattern: "^PT([1-5][1-9]|60)?M$", + }, + }, + required: ["label", "duration"], + }, + }, + required: ["id", "time"], + }, + }, + ], + }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + street: { + type: "string", + }, + city: { + type: "string", + }, + area_code: { + type: "string", + }, + state: { + type: "string", + }, + }, + required: ["street", "city", "area_code", "state"], + }, + }, + required: [], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + category_id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["P2P", "P2H2P"], + }, + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + required: ["code", "name", "short_desc", "long_desc"], + // if: { properties: { code: { const: "P2H2P" } } }, + // then: { + // required: [ + // "/search/0/message/intent/@ondc~1org~1payload_details/dimensions", + // ], + // errorMessage: + // "dimensions are required in /search for P2H2P shipments ${/search/0/message/intent/@ondc~1org~1payload_details/dimensions}", + // }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + const: "TAT", + }, + duration: { + type: "string", + format: "duration", + errorMessage: "${2/time/duration}", + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["label", "duration", "timestamp"], + }, + }, + required: [ + "id", + "category_id", + "fulfillment_id", + "descriptor", + "price", + ], + }, + }, + }, + if: + { + properties: { + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { const: "Immediate Delivery" }, + }, + }, + }, + }, + not: { + required: ["locations"], + }, + }, + // { + // not: { + // properties: { + // categories: { + // type: "array", + // items: { + // type: "object", + // properties: { + // id: { const: "Immediate Delivery" }, + // }, + // }, + // }, + // }, + // }, + // }, + else:{ + required: ["id", "descriptor", "categories", "items"], + } + }, + }, + }, + additionalProperties:false, + required: ["bpp/fulfillments", "bpp/descriptor", "bpp/providers"], + }, + }, + required: ["catalog"], + }, + }, + + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js new file mode 100644 index 0000000..06b5e20 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js @@ -0,0 +1,683 @@ +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_status", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress", + "Completed", + "Cancelled", + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + errorMessage:"mismatches between /init and /on_status" + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/init/0/message/order/provider/locations/0/id", + }, + }, + }, + }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, + }, + category_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + "@ondc/org/awb_no": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Searching-for-Agent", + "Agent-assigned", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + tracking: { + type: "boolean", + }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + required: ["time"], + }, + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + required: ["time"], + }, + agent: { + type: "object", + properties: { + name: { + type: "string", + }, + phone: { + type: "string", + }, + }, + required: ["name", "phone"], + }, + vehicle: { + type: "object", + properties: { + category: { + type: "string", + }, + size: { + type: "string", + }, + registration: { + type: "string", + }, + }, + required: ["category", "size", "registration"], + }, + "@ondc/org/ewaybillno": { + type: "string", + }, + "@ondc/org/ebnexpirydate": { + type: "string", + }, + }, + if: { properties: { type: { const: "Prepaid" } } }, + then: { required: ["type", "state", "tracking"] }, + else: { + required: ["type", "state"], + }, + }, + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + const: { $data: "/on_init/0/message/order/payment/type" }, + }, + collected_by: { + type: "string", + const: { + $data: "/on_init/0/message/order/payment/collected_by", + }, + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + settlement_status: { + type: "string", + }, + settlement_reference: { + type: "string", + }, + settlement_timestamp: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: ["type", "collected_by"], + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/name" }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + const: { + $data: "/confirm/0/message/order/billing/address/name", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + building: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/building", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + locality: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/locality", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + city: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/city", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + state: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/state", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + country: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/country", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + area_code: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/area code", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + }, + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/tax_number", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + phone: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/phone" }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + email: { + type: "string", + const: { $data: "/confirm/0/message/order/billing/email" }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + created_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/created_at", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + updated_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/updated_at", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + }, + additionalProperties: false, + required: ["name", "address", "phone", "tax_number"], + }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + }, + "AWB no": { + type: "string", + }, + }, + }, + created_at: { + type: "string", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "mismatches in /confirm and /on_status", + }, + updated_at: { + type: "string" + }, + }, + additionalProperties:false, + if: { properties: { state: { const: "Cancelled" } } }, + then: { + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "payment", + "billing", + "tags" + ], + }, + else: { + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "payment", + "billing", + ], + }, + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js new file mode 100644 index 0000000..17b891f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js @@ -0,0 +1,111 @@ +module.exports = { + $id: "http://example.com/schema/onSupportSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_support", + }, + core_version: { + type: "string", + const:"1.1.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/support/0/context/message_id" }, + errorMessage: + "Message ID should be same as /support: ${/support/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + uri: { + type: "string", + }, + }, + required: ["phone", "email", "uri"], + }, + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onTrackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onTrackSchema.js new file mode 100644 index 0000000..4072fc3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onTrackSchema.js @@ -0,0 +1,115 @@ +module.exports = { + $id: "http://example.com/schema/onTrackSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_track", + }, + core_version: { + type: "string", + const:"1.1.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/track/0/context/message_id" }, + errorMessage: + "Message ID should be same as /track: ${/track/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + tracking: { + type: "object", + properties: { + url: { + type: "string", + }, + status: { + type: "string", + enum:["active","inactive"] + }, + }, + required: ["url", "status"], + }, + }, + required: ["tracking"], + }, + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js new file mode 100644 index 0000000..73b0146 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js @@ -0,0 +1,347 @@ +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_update", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/update/0/context/message_id" }, + errorMessage: + "Message ID should be same as /update: ${/update/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "Cancelled", "In-progress"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + category_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + "@ondc/org/awb_no": { + type: "string", + }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + minimum: { $data: "7/context/timestamp" }, + errorMessage: "${7/context/timestamp}", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + }, + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + }, + agent: { + type: "object", + properties: { + name: { + type: "string", + }, + phone: { + type: "string", + }, + }, + required: ["name", "phone"], + }, + "@ondc/org/ewaybillno": { + type: "string", + const: { $data: "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ewaybillno" }, + }, + "@ondc/org/ebnexpirydate": { + type: "string", + format: "date-time", + const: { $data: "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ebnexpirydate"}, + }, + }, + additionalProperties:false, + required: ["id", "type", "start"], + }, + }, + created_at: { + type: "string", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "mismatches in /confirm and /on_update", + }, + updated_at: { + type: "string", + }, + }, + additionalProperties:false, + required: ["id", "state", "items", "fulfillments", "updated_at"], + + // oneOf: [ + // { + // allOf: [ + // { + // properties: { + // items: { + // type: "array", + // items: { + // type: "object", + // properties: { + // descriptor: { + // properties: { + // code: { const: "P2H2P" }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // { + // properties: { + // fulfillments: { + // required: [ + // "@ondc/org/awb_no", + // "start/instructions/images", + // ], + // }, + // }, + // } + // ], + // }, + // { + // properties: { + // items: { + // type: "array", + // items: { + // type: "object", + // properties: { + // descriptor: { + // properties: { + // code: { const: "P2P" }, + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // ], + }, + }, + required: ["order"], + }, + + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js new file mode 100644 index 0000000..987b1e3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js @@ -0,0 +1,361 @@ +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "search", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + category: { + type: "object", + properties: { + id: { + type: "string", + enum: [ + "Express Delivery", + "Standard Delivery", + "Immediate Delivery", + "Same Day Delivery", + "Next Day Delivery", + ], + }, + }, + required: ["id"], + }, + provider: { + type: "object", + properties: { + time: { + type: "object", + properties: { + days: { + type: "string", + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + format: "date", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + }, + }, + oneOf: [ + { + properties: { + schedule: { + type: "object", + required: ["times", "frequency"], + }, + }, + required: ["schedule"], + }, + { + type: "object", + required: ["range"], + }, + ], + errorMessage: + "Both range and schedule cannot be present in time", + }, + }, + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: ["CoD", "Prepaid", "Reverse QC"], + }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{1,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{1,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{1,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{1,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + }, + required: ["type", "start", "end"], + }, + payment: { + type: "object", + properties: { + "@ondc/org/collection_amount": { + type: "string", + }, + }, + required: ["@ondc/org/collection_amount"], + }, + "@ondc/org/payload_details": { + type: "object", + properties: { + weight: { + type: "object", + properties: { + unit: { + type: "string", + enum: ["Kilogram", "Gram"], + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + dimensions: { + type: "object", + properties: { + length: { + type: "object", + properties: { + unit: { + type: "string", + enum: ["centimeter", "meter"], + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + breadth: { + type: "object", + properties: { + unit: { + type: "string", + enum: ["centimeter", "meter"], + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + height: { + type: "object", + properties: { + unit: { + type: "string", + enum: ["centimeter", "meter"], + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["length", "breadth", "height"], + }, + category: { + type: "string", + enum: [ + "Grocery", + "F&B", + "Fashion", + "BPC", + "Electronics", + "Home & Decor", + "Pharma", + "Agriculture", + "Mobility", + ], + }, + dangerous_goods: { + type: "boolean" + // const: "true", + // errorMessage: + // "is an optional property and should be set when payload includes hazardous goods", + }, + value: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["weight", "category", "value"], + }, + }, + required: [ + "category", + "provider", + "fulfillment", + "@ondc/org/payload_details", + ], + // if: { + // properties: { + // code: { const: "P2H2P" }, + // }, + // }, + // then: { + // required: [ + // "/search/0/message/intent/@ondc~1org~1payload_details/dimensions", + // ], + // errorMessage: + // "dimensions are required for inter-city shipments in /search", + // }, + if: { + properties: { + fulfillment: { properties: { type: { const: "CoD" } } }, + }, + }, + then: { + required: ["payment"], + errorMessage: + "Payment object is required for fulfillment type 'CoD'", + }, + }, + }, + required: ["intent"], + }, + }, + + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/statusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/statusSchema.js new file mode 100644 index 0000000..8390017 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/statusSchema.js @@ -0,0 +1,93 @@ +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "status", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/supportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/supportSchema.js new file mode 100644 index 0000000..9fdf203 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/supportSchema.js @@ -0,0 +1,86 @@ +module.exports = { + $id: "http://example.com/schema/supportSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "support", + }, + core_version: { + type: "string", + const:"1.1.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + const: { $data: "/support/0/context/message_id" }, + errorMessage: + "Message ID should be same as /init: ${/support/0/context/message_id}", + }, + timestamp: { + type: "string", + format:"date-time" + }, + ttl: { + type: "string", + const :"PT30S" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + ref_id: { + type: "string", + }, + }, + required: ["ref_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/trackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/trackSchema.js new file mode 100644 index 0000000..3c38a07 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/trackSchema.js @@ -0,0 +1,95 @@ +module.exports = { + $id: "http://example.com/schema/trackSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "track", + }, + core_version: { + type: "string", + const:"1.1.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + callback_url: { + type: "string", + }, + }, + required: ["order_id", "callback_url"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js new file mode 100644 index 0000000..6c7d8e7 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js @@ -0,0 +1,417 @@ +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/on_search/0/context/city" }, + }, + action: { + type: "string", + const: "update", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/message/order/id" }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/message/order/items/0/id" }, + }, + category_id: { + type: "string", + const: { + $data: "/confirm/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/confirm/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + "@ondc/org/awb_no": { + type: "string", + }, + tags: { + type: "object", + properties: { + "@ondc/org/order_ready_to_ship": { + type: "string", + enum: ["yes", "no"], + }, + }, + required: ["@ondc/org/order_ready_to_ship"], + }, + start: { + type: "object", + properties: { + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + additional_desc: { + type: "object", + properties: { + content_type: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["content_type", "url"], + }, + }, + }, + }, + additionalProperties:false, + // required: ["instructions"], + }, + end: { + type: "object", + properties: { + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + additional_desc: { + type: "object", + properties: { + content_type: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["content_type", "url"], + }, + }, + required: ["short_desc", "long_desc"], + }, + }, + additionalProperties:false, + // required: ["instructions"], + }, + "@ondc/org/ewaybillno": { + type: "string", + const: { $data: "/confirm/0/message/order/fulfillments/0/@ondc~1org~1ewaybillno" }, + }, + "@ondc/org/ebnexpirydate": { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/fulfillments/0/@ondc~1org~1ebnexpirydate"}, + }, + }, + additionalProperties:false, + required: ["id", "type", "tags"], + + // if: { + // properties: { + // tags: { + // properties: { + // "@ondc/org/order_ready_to_ship": { const: "yes" }, + // }, + // }, + // }, + // }, + // then: { + // required: ["0/start/instructions"], + // errorMessage: + // "start/instructions are required when ready_to_ship = yes", + // }, + + // if: { + // properties: { + // tags: { + // properties: { + // "@ondc/org/order_ready_to_ship": { const: "yes" }, + // }, + // }, + // }, + // }, + // then: { + // required: [ + // "/on_update/message/order/fulfillments/0/start/time/range", + // "/on_update/message/order/fulfillments/0/end/time/range", + // ], + // errorMessage: + // "start and end time range is required when ready_to_ship=yes", + // }, + + // anyOf: [ + // { + // properties: { + // start: { + // properties: { + // instructions: { + // required: ["short_desc"], + // }, + // }, + // }, + // tags: { + // properties: { + // "@ondc/org/order_ready_to_ship": { + // enum: ["yes"], + // }, + // }, + // }, + // }, + // required: ["start"], + // }, + // { + // properties: { + // tags: { + // properties: { + // "@ondc/org/order_ready_to_ship": { + // enum: ["no"], + // }, + // }, + // }, + // }, + // }, + // ], + }, + }, + "@ondc/org/linked_order": { + type: "object", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + category_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "number", + + }, + }, + required: ["unit", "value"], + }, + }, + required: ["count", "measure"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "category_id", + "descriptor", + "quantity", + "price", + ], + }, + }, + order: { + type: "object", + properties: { + id: { + type: "string", + }, + weight: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "number", + const: { $data: "/search/0/message/intent/@ondc~1org~1payload_details/weight/value" }, + errorMessage:"Payload weight mismatches in /search and /update" + }, + }, + required: ["unit", "value"], + }, + }, + required: ["id", "weight"], + }, + }, + required: ["items", "order"], + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "does not match context timestamp - ${3/context/timestamp}", + }, + }, + required: ["id", "state", "items", "fulfillments", "updated_at"], + }, + }, + required: ["update_target", "order"], + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/main.js b/utilities/logistics-b2b/log-verification-utility/schema/main.js new file mode 100755 index 0000000..1959fa9 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/main.js @@ -0,0 +1,20 @@ +const retailSchemaValidator = require("./retail_api_json_schema/SchemaValidator"); +const {validate_schema_master} = require("./logistics_api_json_schema/SchemaValidator"); +const {validate_schema_b2b_master} = require("./B2B_json_schema/schemaValidator"); + +const fs = require("fs"); + +const validate_schema_for_domain_json = (vertical, data) => { + switch (vertical) { + case "logistics": + res = validate_schema_master(data); + return res; + case "b2b": + res = validate_schema_b2b_master(data); + return res; + default: + console.log("Invalid Domain!!"); + } +}; + +module.exports = validate_schema_for_domain_json; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js new file mode 100755 index 0000000..6283a62 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js @@ -0,0 +1,174 @@ +const onConfirmSchema = require("./onConfirmSchema"); +const onInitSchema = require("./onInitSchema"); +const onSearchSchema = require("./onSearchSchema"); +const onSelectSchema = require("./onSelectSchema"); +const onTrackSchema = require("./onTrackSchema"); +const onSupportSchema = require("./onSupportSchema"); +const onStatusSchema = require("./onStatusSchema"); +const onCancelSchema = require("./onCancelSchema"); +const onUpdateSchema = require("./onUpdateSchema"); +const searchSchema = require("./searchSchema"); +const selectSchema = require("./selectSchema"); +const initSchema = require("./initSchema"); +const confirmSchema = require("./confirmSchema"); +const statusSchema = require("./statusSchema"); +const updateSchema = require("./updateSchema"); +const cancelSchema = require("./cancelSchema"); + +const Ajv = require("ajv"); +const ajv = new Ajv({allErrors: true,strict: "log",}); +const addFormats = require("ajv-formats"); +addFormats(ajv); +require("ajv-errors")(ajv); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + +const validate_schema = (data, schema) => { + let error_list = []; + validate = ajv.compile(schema); + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + return error_list; +}; + +const validate_schema_search_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = searchSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_search_retail_for_json = (data) => { + // transformed_item_data = transform_on_search_schema(data); + error_list = validate_schema(data, (schema = onSearchSchema)); + return formatted_error(error_list); +}; + +const validate_schema_select_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = selectSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_select_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onSelectSchema)); + return formatted_error(error_list); +}; + +const validate_schema_init_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = initSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_init_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onInitSchema)); + return formatted_error(error_list); +}; + +const validate_schema_confirm_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = confirmSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_confirm_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onConfirmSchema)); + return formatted_error(error_list); +}; + +const validate_schema_status_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = statusSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_status_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onStatusSchema)); + return formatted_error(error_list); +}; + +const validate_schema_cancel_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = cancelSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_cancel_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onCancelSchema)); + return formatted_error(error_list); +}; + +const validate_schema_update_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = updateSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_update_retail_for_json = (data) => { + item_data = data["message"]["order"]; + error_list = validate_schema(item_data, (schema = onUpdateSchema)); + return formatted_error(error_list); +}; + +const validate_schema_track_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = trackSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_track_retail_for_json = (data) => { + item_data = data["message"]; + error_list = validate_schema(item_data, (schema = onTrackSchema)); + return formatted_error(error_list); +}; + +const validate_schema_support_retail_for_json = (data) => { + error_list = validate_schema(data, (schema = supportSchema)); + return formatted_error(error_list); +}; + +const validate_schema_on_support_retail_for_json = (data) => { + item_data = data["message"]; + error_list = validate_schema(item_data, (schema = onSupportSchema)); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_search_retail_for_json, + validate_schema_select_retail_for_json, + validate_schema_init_retail_for_json, + validate_schema_confirm_retail_for_json, + validate_schema_update_retail_for_json, + validate_schema_status_retail_for_json, + validate_schema_track_retail_for_json, + validate_schema_cancel_retail_for_json, + validate_schema_support_retail_for_json, + validate_schema_on_cancel_retail_for_json, + validate_schema_on_confirm_retail_for_json, + validate_schema_on_init_retail_for_json, + validate_schema_on_search_retail_for_json, + validate_schema_on_select_retail_for_json, + validate_schema_on_status_retail_for_json, + validate_schema_on_support_retail_for_json, + validate_schema_on_track_retail_for_json, + validate_schema_on_update_retail_for_json, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js new file mode 100755 index 0000000..74e1260 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js @@ -0,0 +1,85 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "cancel", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + cancellation_reason_id: { + type: "string", + minLength: 3, + maxLength: 3, + }, + }, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js new file mode 100755 index 0000000..4c6212f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js @@ -0,0 +1,490 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "confirm", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + const: "Created", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["id", "fulfillment_id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + updated_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + required: [ + "name", + "address", + "phone", + "created_at", + "updated_at", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + const: "Delivery", + }, + tracking: { + type: "boolean", + }, + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + email: { + type: "string", + format: "email", + }, + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["person", "contact", "location"], + }, + }, + required: ["id", "type", "tracking", "end"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payment", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js new file mode 100755 index 0000000..8b7019c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js @@ -0,0 +1,273 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "init", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + minLength: 1, + }, + fulfillment_id: { + type: "string", + minLength: 1, + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["id", "fulfillment_id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + phone: { + type: "string", + }, + created_at: { + type: "string", + format: "date-time", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + required: [ + "name", + "address", + "phone", + "created_at", + "updated_at", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + const: "Delivery", + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + }, + required: ["id", "type", "end"], + }, + }, + }, + required: ["provider", "items", "billing", "fulfillments"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js new file mode 100755 index 0000000..53fb7d0 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js @@ -0,0 +1,19 @@ +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { type: "string", pattern: "^(?!s*$).+" }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + minLength: 3, + maxLength: 3, + }, + }, + required: ["cancellation_reason_id"], + }, + }, + required: ["id", "state", "tags"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js new file mode 100755 index 0000000..0eead46 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js @@ -0,0 +1,473 @@ +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { type: "string", enum: ["Created", "Accepted", "Cancelled"] }, + provider: { + type: "object", + properties: { + id: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + }, + rateable: { type: "boolean" }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + }, + required: ["id", "quantity", "fulfillment_id"], + }, + }, + + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + updated_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + required: ["name", "address", "phone", "created_at", "updated_at"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + "@ondc/org/provider_name": { type: "string" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { type: "string", const: "Pending" }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { type: "string", const: "Delivery" }, + tracking: { type: "boolean" }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + }, + required: ["name"], + }, + gps: { type: "string" }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + gps: { type: "string" }, + }, + required: ["address", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "tracking", + "start", + "end", + ], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + // allOf: [ + // { + // if: { + // properties: { + // status: { + // const: "PAID", + // }, + // }, + // atPath: "1", + // }, + // then: { properties: { type: { const: "ON-ORDER" } } }, + // }, + // ], + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + required: [ + "payment", + "fulfillments", + "quote", + "items", + "id", + "state", + "provider", + "billing", + "created_at", + "updated_at", + ], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js new file mode 100755 index 0000000..2c883d7 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js @@ -0,0 +1,322 @@ +module.exports = { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + }, + required: ["id", "fulfillment_id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + required: ["name", "address", "phone", "created_at", "updated_at"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { type: "string", const: "Delivery" }, + tracking: { type: "boolean" }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string", format: "email" }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + }, + + required: ["id", "type", "end"], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + + payment: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + }, + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + }, + }, + required: [ + "payment", + "fulfillments", + "billing", + "quote", + "items", + "provider", + "provider_location", + ], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js new file mode 100755 index 0000000..8162718 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js @@ -0,0 +1,610 @@ +module.exports = { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { type: "string" }, + }, + required: ["id"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { type: "string" }, + }, + required: ["id"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + }, + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + code: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + }, + }, + rating: { type: "string" }, + ttl: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + gps: { type: "string" }, + address: { type: "string" }, + city: { + type: "object", + properties: { + code: { type: "string" }, + name: { type: "string" }, + }, + }, + state: { + type: "object", + properties: { + code: { type: "string" }, + }, + }, + country: { + type: "object", + properties: { + code: { type: "string" }, + }, + }, + area_code: { type: "string" }, + }, + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string" }, + value: { type: "string" }, + }, + }, + }, + }, + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + parent_item_id: { type: "string", pattern: "^(?!s*$).+" }, + descriptor: { + type: "object", + properties: { + name: { type: "string", pattern: "^(?!s*$).+" }, + code: { type: "string", pattern: "^(?!s*$).+" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + pattern: "^(?!s*$).+", + }, + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + }, + }, + }, + }, + manufacturer: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + }, + }, + }, + phone: { + type: "string", + pattern: + "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", + }, + }, + }, + price: { + type: "object", + properties: { + currency: { type: "string", pattern: "^(?!s*$).+" }, + value: { type: "string", pattern: "^d*.?d*$" }, + offered_value: { type: "string", pattern: "^d*.?d*$" }, + maximum_value: { type: "string", pattern: "^d*.?d*$" }, + }, + require: ["currency", "value"], + }, + + quantity: { + type: "object", + properties: { + unitized: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + pattern: "^d*$", + }, + }, + }, + maximum: { + type: "object", + properties: { + count: { type: "string", pattern: "^d*$" }, + }, + }, + }, + }, + category_ids: { + type: "array", + items: { + type: "string", + minItems: 1, + pattern: "^(?!s*$).+", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + minItems: 1, + pattern: "^(?!s*$).+", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + enum: ["1", "2"], + }, + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + pattern: "^(?!s*$).+", + }, + value: { + type: "string", + pattern: "^d*.?d*$", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + }, + }, + }, + }, + cancellation_terms: { + type: "array", + items: { + anyOf: [ + { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + }, + }, + }, + refund_eligible: { + type: "string", + }, + }, + required: ["fulfillment_state", "refund_eligible"], + }, + { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + }, + }, + }, + return_policy: { + type: "object", + properties: { + return_eligible: { + type: "string", + }, + return_within: { + type: "string", + }, + fulfillment_managed_by: { + type: "string", + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + }, + }, + required: [ + "return_eligible", + "return_within", + "return_location", + ], + }, + }, + required: ["fulfillment_state", "return_policy"], + }, + ], + }, + minLength: 2, + }, + + replacement_terms: { + type: "array", + items: { + type: "object", + properties: { + replace_within: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["replace_within"], + }, + }, + rating: { type: "string" }, + matched: { type: "string" }, + time: { + type: "object", + properties: { + label: { type: "string" }, + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + end: { + type: "string", + pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + }, + }, + }, + recommended: { type: "string" }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + }, + }, + }, + required: [ + "id", + "parent_item_id", + "descriptor", + "manufacturer", + "price", + "quantity", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "replacement_terms", + "matched", + "recommended", + "tags", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + pattern: + "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", + }, + email: { + type: "string", + pattern: + "^([a-zA-Z0-9_-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$", + }, + }, + }, + }, + }, + }, + + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + code: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + pattern: "^(?!s*$).+", + }, + url: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + }, + }, + }, + }, + time: { + type: "object", + properties: { + label: { type: "string" }, + range: { + type: "object", + properties: { + start: { type: "string" }, + end: { type: "string" }, + }, + }, + }, + }, + item_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + category_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + pattern: "^(?!s*$).+", + }, + }, + }, + }, + }, + }, + }, + }, + }, + required: ["fulfillments", "payments", "descriptor", "providers"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js new file mode 100755 index 0000000..a161f69 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js @@ -0,0 +1,490 @@ +onSearchGrocerySchema = { + "type": "object", + "properties": { + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "payments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "providers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "rating": {"type": "string"}, + "ttl": {"type": "string"}, + "locations": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "gps": {"type": "string"}, + "address": {"type": "string"}, + "city": {"type": "object", + "properties": { + "code": {"type": "string"}, + "name": {"type": "string"}, + } + }, + "state": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "country": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "area_code": {"type": "string"}, + } + } + }, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "value": {"type": "string"}, + } + }} + } + } + }, + "items": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "parent_item_id": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "code": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + }, + }, + "manufacturer": {"type": "object", + "properties": { + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + } + }, + "contact": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "address": { + "type": "object", + "properties": { + "full": { + "type": "string"}, + } + }, + } + }, + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} + } + }, + "price": {"type": "object", + "properties": { + "currency": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "maximum_value": {"type": "string", + "pattern": "^\d*\.?\d*$"} + }, + "require": ["currency", "value"], + }, + + "quantity": {"type": "object", + "properties": { + "unitized": {"type": "object", + "properties": { + "measure": { + "type": "object", + "properties": { + "unit": { + "type": "string"}, + "value": { + "type": "string"} + + } + }, + } + }, + "available": {"type": "object", + "properties": { + "count": { + "type": "string", + "pattern": "^\d*$"} + + } + }, + "maximum": {"type": "object", + "properties": { + "count": {"type": "string", + "pattern": "^\d*$"} + } + }, + } + }, + "category_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "fulfillment_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "payment_ids": {"type": "array", + "items": { + "type": "string", + "enum": ["1", "2"]}}, + "add-ons": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "code": { + "type": "string"}, + "short_desc": { + "type": "string"}, + "long_desc": { + "type": "string"}, + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "url"] + + } + } + } + }, + "price": {"type": "object", + "properties": { + "currency": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "value": { + "type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": { + "type": "string"}, + "maximum_value": { + "type": "string"} + } + }, + } + } + }, + "cancellation_terms": {"type": "array", + "items": {"anyOf": [ + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "refund_eligible": { + "type": "string"}, + }, + "required": [ + "fulfillment_state", + "refund_eligible"] + }, + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "return_policy": { + "type": "object", + "properties": { + "return_eligible": { + "type": "string"}, + "return_within": { + "type": "string"}, + "fulfillment_managed_by": { + "type": "string"}, + "return_location": { + "type": "object", + "properties": { + "address": { + "type": "string"}, + "gps": { + "type": "string"} + } + } + }, + "required": [ + "return_eligible", + "return_within", + "return_location", + ] + } + }, + "required": [ + "fulfillment_state", + "return_policy"] + } + ]}, + "minLength": 2 + }, + + "replacement_terms": {"type": "array", + "items": {"type": "object", + "properties": { + "replace_within": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "replace_within"] + } + }, + "rating": {"type": "string"}, + "matched": {"type": "string"}, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, + "end": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} + } + }, + } + }, + "recommended": {"type": "string"}, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": { + "type": "string"}, + "value": { + "type": "string"}, + }, + "required": [ + "code", + "value"] + } + }, + } + } + } + }, + "required": ["id", "parent_item_id", "descriptor", + "manufacturer", "price", "quantity", + "category_ids", "fulfillment_ids", "location_ids", + "payment_ids", + "cancellation_terms", "replacement_terms", + "matched", "recommended", "tags"], + } + }, + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "contact": {"type": "object", + "properties": { + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, + "email": {"type": "string", + "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} + } + } + }, + } + }, + + "offers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + } + }, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string"}, + "end": {"type": "string"} + } + }, + } + }, + "item_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "category_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + } + } + }, + + }, + + } + }, + + }, + "required": ["fulfillments", "payments", "descriptor", "providers"] + +} diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js new file mode 100755 index 0000000..bce2ac3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js @@ -0,0 +1,201 @@ +onSearchRules = [ + { + if: { properties: { "@ondc/org/returnable": { const: false } } }, + then: { + not: { + required: ["@ondc/org/return_window"], + error_message: "return window is available when returnable is false", + }, + }, + }, + + { + if: { + properties: { + category_id: { + enum: [ + "F&B", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + ], + }, + }, + }, + then: { + required: ["@ondc/org/fssai_license_no"], + }, + }, + { + if: { + properties: { + category_id: { + enum: [ + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ], + }, + }, + }, + then: { + required: ["@ondc/org/fssai_license_no"], + }, + }, + + { + if: { properties: { "@ondc/org/returnable": { const: false } } }, + then: { + required: ["@ondc/org/return_window"], + }, + }, + + { + if: { + properties: { + category_id: { + enum: [ + "Masala & Seasoning", + "Oil & Ghee", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beauty & Hygiene", + "Kitchen Accessories", + "Baby Care", + "Pet Care", + "Stationery", + ], + }, + }, + }, + then: { + required: ["@ondc/org/statutory_reqs_packaged_commodities"], + }, + }, + + { + if: { + properties: { + category_id: { + enum: [ + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ], + }, + }, + }, + then: { + required: ["@ondc/org/statutory_reqs_prepackaged_food"], + }, + }, + { + if: { + properties: { + category_id: { + const: "Fruits and Vegetables", + }, + }, + }, + then: { + required: ["@ondc/org/mandatory_reqs_veggies_fruits"], + }, + }, + + { + if: { + properties: { + category_id: { + enum: [ + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "F&B", + ], + }, + }, + }, + then: { + required: ["tags"], + }, + }, + { + if: { + properties: { + category_id: { + enum: [ + "Gourmet & World Foods", + "Beverages", + "Bakery, Cakes & Dairy", + "Snacks & Branded Foods", + ], + }, + }, + }, + then: { + required: ["tags"], + }, + }, + { + if: { + properties: { + category_id: { + enum: [ + "F&B", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + ], + }, + }, + }, + then: { + properties: { + descriptor: { + required: ["name", "symbol", "short_desc", "long_desc"], + }, + }, + }, + else: { + properties: { + descriptor: { + required: ["name", "symbol", "short_desc", "long_desc", "images"], + }, + }, + }, + }, +]; +module.exports = { onSearchRules }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js new file mode 100755 index 0000000..4b08957 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js @@ -0,0 +1,583 @@ +const onSearchItemValidations = require("./onSearchItemValidations"); + +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { type: "string" }, + country: { type: "string" }, + city: { type: "string" }, + action: { type: "string" }, + core_version: { type: "string" }, + bap_id: { type: "string" }, + bap_uri: { type: "string" }, + transaction_id: { type: "string", format: "uuid" }, + message_id: { type: "string" }, + timestamp: { type: "string", format: "date-time" }, + ttl: { type: "string", format: "duration" }, + bpp_uri: { type: "string" }, + bpp_id: { type: "string" }, + }, + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + "bpp/fulfillments": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { + type: "string", + enum: [ + "Delivery", + "Self-Pickup", + "Delivery and Self-Pickup", + ], + }, + }, + }, + }, + "bpp/descriptor": { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name", "symbol", "long_desc", "short_desc", "images"], + }, + "bpp/providers": { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + time: { + type: "object", + properties: { + label: { type: "string", enum: ["enable", "disable"] }, + timestamp: { type: "string", format: "date-time" }, + }, + required: ["label", "timestamp"], + }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { type: "string" }, + long_desc: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "name", + "symbol", + "long_desc", + "short_desc", + "images", + ], + }, + ttl: { type: "string", format: "duration" }, + "@ondc/org/fssai_license_no": { + type: "string", + minLength: 14, + maxLength: 14, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + gps: { type: "string" }, + address: { + type: "object", + properties: { + street: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["street", "city", "area_code", "state"], + }, + + circle: { + type: "object", + properties: { + gps: { + type: "string", + }, + radius: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + }, + }, + }, + time: { + type: "object", + oneOf: [ + { + $ref: "#/components/schemas/fixedTimings", + }, + { + $ref: "#/components/schemas/splitTimings", + }, + ], + }, + }, + required: ["id", "address", "gps", "time"], + }, + }, + items: { + type: "array", + minItems: 1, + items: { + type: "object", + properties: { + id: { type: "string" }, + quantity: { + type: "object", + properties: { + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + }, + }, + category_id: { + type: "string", + enum: [ + "Fruits and Vegetables", + "Masala & Seasoning", + "Oil & Ghee", + "Gourmet & World Foods", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beverages", + "Beauty & Hygiene", + "Bakery, Cakes & Dairy", + "Kitchen Accessories", + "Baby Care", + "Snacks & Branded Foods", + "Pet Care", + "Stationery", + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "Home Decor", + "Home Furnishings", + "Furniture", + "Garden and Outdoor Products", + "Home Improvement", + "Cookware and Dining", + "Storage and Organisation", + ], + }, + + // "@ondc/org/fssai_license_no": { + // type: "string", + // pattern: "^[a-zA-Z0-9]+$", + // }, + fulfillment_id: { type: "string" }, + location_id: { type: "string" }, + recommended: { type: "boolean" }, + "@ondc/org/returnable": { + type: "boolean", + }, + "@ondc/org/seller_pickup_return": { + type: "boolean", + }, + "@ondc/org/return_window": { + type: "string", + }, + "@ondc/org/cancellable": { + type: "boolean", + }, + "@ondc/org/time_to_ship": { + type: "string", + format: "duration", + }, + "@ondc/org/available_on_cod": { + type: "boolean", + }, + "@ondc/org/contact_details_consumer_care": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + not: { + type: "string", + pattern: "^0$", + }, + }, + + maximum_value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + not: { type: "string", pattern: "^0$" }, + }, + }, + required: ["value", "maximum_value", "currency"], + }, + tags: { + type: "object", + properties: { + veg: { + type: "string", + enum: ["yes", "no", "Yes", "No"], + }, + non_veg: { + type: "string", + enum: ["yes", "no", "Yes", "No"], + }, + }, + required: ["veg", "non_veg"], + }, + "@ondc/org/statutory_reqs_prepackaged_food": { + type: "object", + properties: { + nutritional_info: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + importer_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + brand_owner_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + other_FSSAI_license_no: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + additives_info: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + }, + required: ["nutritional_info", "additives_info"], + oneOf: [ + { + required: ["importer_FSSAI_license_no"], + properties: { + importer_FSSAI_license_no: { + type: "string", + }, + }, + }, + { + required: ["brand_owner_FSSAI_license_no"], + properties: { + brand_owner_FSSAI_license_no: { + type: "string", + }, + }, + }, + { + required: ["other_FSSAI_license_no"], + properties: { + other_FSSAI_license_no: { + type: "string", + }, + }, + }, + ], + }, + "@ondc/org/statutory_reqs_packaged_commodities": { + type: "object", + properties: { + manufacturer_or_packer_name: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + manufacturer_or_packer_address: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + common_or_generic_name_of_commodity: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + net_quantity_or_measure_of_commodity_in_pkg: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + month_year_of_manufacture_packing_import: { + type: "string", + pattern: "^(?!\\s*$).+", + }, + }, + required: [ + "manufacturer_or_packer_name", + "manufacturer_or_packer_address", + "common_or_generic_name_of_commodity", + "month_year_of_manufacture_packing_import", + "net_quantity_or_measure_of_commodity_in_pkg", + ], + }, + "@ondc/org/mandatory_reqs_veggies_fruits": { + type: "object", + properties: { + net_quantity: { + type: "string", + minLength: 1, + }, + }, + required: ["net_quantity"], + }, + + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + symbol: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + minItems: 1, + items: { + type: "string", + }, + }, + }, + }, + }, + + allOf: onSearchItemValidations.on_search_rules, + required: [ + "id", + "category_id", + "@ondc/org/contact_details_consumer_care", + "price", + "descriptor", + "@ondc/org/returnable", + "location_id", + "fulfillment_id", + "@ondc/org/cancellable", + "@ondc/org/available_on_cod", + "@ondc/org/time_to_ship", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + minLength: 10, + maxLength: 11, + }, + email: { type: "string", format: "email" }, + }, + required: ["phone"], + }, + }, + required: ["contact"], + }, + }, + + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { type: "string", const: "serviceability" }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "location", + "category", + "type", + "val", + "unit", + ], + }, + value: { type: "string" }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + }, + }, + required: [ + "items", + "id", + "time", + "descriptor", + "locations", + "fulfillments", + "tags", + "ttl", + ], + }, + }, + }, + required: ["bpp/fulfillments", "bpp/descriptor", "bpp/providers"], + }, + }, + required: ["catalog"], + }, + }, + required: ["context", "message"], + components: { + schemas: { + fixedTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + minLength: 4, + maxLength: 4, + }, + end: { + type: "string", + minLength: 4, + maxLength: 4, + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + additionalProperties: false, + }, + }, + required: ["days", "range", "schedule"], + }, + splitTimings: { + type: "object", + properties: { + days: { + type: "string", + }, + + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + }, + }, + frequency: { + type: "string", + format: "duration", + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays", "frequency", "times"], + }, + }, + required: ["days", "schedule"], + additionalProperties: false, + }, + }, + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js new file mode 100755 index 0000000..0068133 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js @@ -0,0 +1,490 @@ +onSearchFashionSchema = { + "type": "object", + "properties": { + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "payments": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "type": {"type": "string"} + }, + "required": ["id"] + } + }, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "providers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + } + }, + "rating": {"type": "string"}, + "ttl": {"type": "string"}, + "locations": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "gps": {"type": "string"}, + "address": {"type": "string"}, + "city": {"type": "object", + "properties": { + "code": {"type": "string"}, + "name": {"type": "string"}, + } + }, + "state": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "country": {"type": "object", + "properties": { + "code": {"type": "string"}, + } + }, + "area_code": {"type": "string"}, + } + } + }, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "value": {"type": "string"}, + } + }} + } + } + }, + "items": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string", "pattern": "^(?!\s*$).+"}, + "parent_item_id": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "code": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + }, + }, + "manufacturer": {"type": "object", + "properties": { + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + } + }, + "contact": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "address": { + "type": "object", + "properties": { + "full": { + "type": "string"}, + } + }, + } + }, + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} + } + }, + "price": {"type": "object", + "properties": { + "currency": {"type": "string", + "pattern": "^(?!\s*$).+"}, + "value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": {"type": "string", + "pattern": "^\d*\.?\d*$"}, + "maximum_value": {"type": "string", + "pattern": "^\d*\.?\d*$"} + }, + "require": ["currency", "value"], + }, + + "quantity": {"type": "object", + "properties": { + "unitized": {"type": "object", + "properties": { + "measure": { + "type": "object", + "properties": { + "unit": { + "type": "string"}, + "value": { + "type": "string"} + + } + }, + } + }, + "available": {"type": "object", + "properties": { + "count": { + "type": "string", + "pattern": "^\d*$"} + + } + }, + "maximum": {"type": "object", + "properties": { + "count": {"type": "string", + "pattern": "^\d*$"} + } + }, + } + }, + "category_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "fulfillment_ids": {"type": "array", + "items": { + "type": "string", "minItems": 1, + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "payment_ids": {"type": "array", + "items": { + "type": "string", + "enum": ["1", "2"]}}, + "add-ons": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": { + "type": "string"}, + "code": { + "type": "string"}, + "short_desc": { + "type": "string"}, + "long_desc": { + "type": "string"}, + "images": { + "type": "array", + "items": { + "type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "url"] + + } + } + } + }, + "price": {"type": "object", + "properties": { + "currency": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "value": { + "type": "string", + "pattern": "^\d*\.?\d*$"}, + "offered_value": { + "type": "string"}, + "maximum_value": { + "type": "string"} + } + }, + } + } + }, + "cancellation_terms": {"type": "array", + "items": {"anyOf": [ + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "refund_eligible": { + "type": "string"}, + }, + "required": [ + "fulfillment_state", + "refund_eligible"] + }, + {"type": "object", + "properties": { + "fulfillment_state": { + "type": "object", + "properties": { + "descriptor": { + "type": "object", + "properties": { + "code": { + "type": "string"} + } + }, + } + }, + "return_policy": { + "type": "object", + "properties": { + "return_eligible": { + "type": "string"}, + "return_within": { + "type": "string"}, + "fulfillment_managed_by": { + "type": "string"}, + "return_location": { + "type": "object", + "properties": { + "address": { + "type": "string"}, + "gps": { + "type": "string"} + } + } + }, + "required": [ + "return_eligible", + "return_within", + "return_location", + ] + } + }, + "required": [ + "fulfillment_state", + "return_policy"] + } + ]}, + "minLength": 2 + }, + + "replacement_terms": {"type": "array", + "items": {"type": "object", + "properties": { + "replace_within": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": [ + "replace_within"] + } + }, + "rating": {"type": "string"}, + "matched": {"type": "string"}, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, + "end": {"type": "string", + "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} + } + }, + } + }, + "recommended": {"type": "string"}, + "tags": {"type": "array", + "items": {"type": "object", + "properties": { + "code": {"type": "string"}, + "list": {"type": "array", + "items": {"type": "object", + "properties": { + "code": { + "type": "string"}, + "value": { + "type": "string"}, + }, + "required": [ + "code", + "value"] + } + }, + } + } + } + }, + "required": ["id", "parent_item_id", "descriptor", + "manufacturer", "price", "quantity", + "category_ids", "fulfillment_ids", "location_ids", + "payment_ids", + "cancellation_terms", "replacement_terms", + "matched", "recommended", "tags"], + } + }, + "fulfillments": {"type": "array", + "items": {"type": "object", + "properties": { + "contact": {"type": "object", + "properties": { + "phone": {"type": "string", + "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, + "email": {"type": "string", + "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} + } + } + }, + } + }, + + "offers": {"type": "array", + "items": {"type": "object", + "properties": { + "id": {"type": "string"}, + "descriptor": {"type": "object", + "properties": { + "name": {"type": "string"}, + "code": {"type": "string"}, + "short_desc": {"type": "string"}, + "long_desc": {"type": "string"}, + "images": {"type": "array", + "items": {"type": "object", + "properties": { + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + }, + "required": ["url"] + + } + }, + "media": {"type": "array", + "items": {"type": "object", + "properties": { + "mimetype": { + "type": "string", + "pattern": "^(?!\s*$).+"}, + "url": { + "type": "string", + "pattern": "^(?!\s*$).+"} + } + } + }, + } + }, + "time": {"type": "object", + "properties": { + "label": {"type": "string"}, + "range": {"type": "object", + "properties": { + "start": {"type": "string"}, + "end": {"type": "string"} + } + }, + } + }, + "item_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "category_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + "location_ids": {"type": "array", + "items": { + "type": "string", + "pattern": "^(?!\s*$).+"}}, + } + } + }, + + }, + + } + }, + + }, + "required": ["fulfillments", "payments", "descriptor", "providers"] + +} diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js new file mode 100755 index 0000000..4450640 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js @@ -0,0 +1,175 @@ +module.exports = { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", minLength: 1 }, + fulfillment_id: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["id", "fulfillment_id"], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + quantity: { + type: "object", + properties: { + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + }, + }, + }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + }, + }, + required: ["price", "quantity"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string", pattern: "^(?!s*$).+" }, + "@ondc/org/provider_name": { type: "string" }, + tracking: { type: "boolean" }, + "@ondc/org/category": { + type: "string", + enum: [ + "Express Delivery", + "Standard Delivery", + "Immediate Delivery", + "Same Day Delivery", + "Next Day Delivery", + ], + }, + "@ondc/org/TAT": { type: "string", format: "duration" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Serviceable", "Non-serviceable"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + }, + + required: [ + "id", + "@ondc/org/provider_name", + "state", + "@ondc/org/category", + "@ondc/org/TAT", + ], + }, + }, + }, + required: ["provider", "items", "fulfillments", "quote"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js new file mode 100755 index 0000000..faae4e4 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js @@ -0,0 +1,548 @@ +const postConfirmRules = require("./postConfirmValidations"); + +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress", "Completed", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + }, + required: ["id"], + }, + }, + rateable: { type: "boolean" }, + }, + required: ["id", "locations"], + }, + + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + status: { + type: "string", + enum: [ + "Return_Initiated", + "Return_Approved", + "Return_Rejected", + "Return_Picked", + "Return_Delivered", + "Liquidated", + "Cancelled", + ], + }, + }, + required: ["status"], + }, + }, + required: ["id", "quantity", "fulfillment_id"], + }, + }, + + billing: { + type: "object", + properties: { + name: { type: "string" }, + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + email: { type: "string", format: "email" }, + phone: { type: "string" }, + created_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + updated_at: { + type: "string", + format: "date-time", + // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", + }, + }, + required: ["name", "address", "phone", "created_at", "updated_at"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + "@ondc/org/provider_name": { type: "string" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Reverse QC"], + }, + tracking: { type: "boolean" }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { type: "string" }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + gps: { type: "string" }, + }, + required: ["address", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "tracking", + "start", + "end", + ], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + // allOf: [ + // { + // if: { + // properties: { + // status: { + // const: "PAID", + // }, + // }, + // atPath: "1", + // }, + // then: { properties: { type: { const: "ON-ORDER" } } }, + // }, + // ], + }, + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { type: "string" }, + label: { type: "string", const: "Invoice" }, + }, + }, + }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + maxLength: 3, + minLength: 3, + }, + }, + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + // allOf: postConfirmRules, + required: [ + "payment", + "fulfillments", + "quote", + "items", + "id", + "state", + "provider", + "billing", + "created_at", + "updated_at", + ], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js new file mode 100755 index 0000000..96dacab --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js @@ -0,0 +1,14 @@ +module.exports = { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + uri: { type: "string" }, + }, + required: ["phone"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js new file mode 100755 index 0000000..e232a05 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js @@ -0,0 +1,13 @@ +module.exports = { + type: "object", + properties: { + tracking: { + type: "object", + properties: { + url: { type: "string" }, + status: { type: "string", enum: ["active", "inactive"] }, + }, + required: ["status"], + }, + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js new file mode 100755 index 0000000..2a979f4 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js @@ -0,0 +1,486 @@ +const postConfirmRules = require("./postConfirmValidations"); + +module.exports = { + type: "object", + properties: { + id: { type: "string" }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress", "Completed", "Cancelled"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + fulfillment_id: { type: "string" }, + quantity: { + type: "object", + properties: { + count: { type: "integer" }, + }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + status: { + type: "string", + enum: [ + "Return_Initiated", + "Return_Approved", + "Return_Rejected", + "Return_Picked", + "Return_Delivered", + "Liquidated", + "Cancelled", + ], + }, + }, + required: ["status"], + }, + }, + required: ["id", "quantity", "fulfillment_id"], + }, + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + "@ondc/org/provider_name": { type: "string" }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Reverse QC"], + }, + tracking: { type: "boolean" }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + id: { type: "string" }, + descriptor: { + type: "object", + properties: { + name: { type: "string" }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { type: "string" }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + email: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + address: { + type: "object", + properties: { + name: { type: "string" }, + building: { type: "string" }, + locality: { type: "string" }, + city: { type: "string" }, + state: { type: "string" }, + country: { type: "string" }, + area_code: { type: "string" }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + gps: { type: "string" }, + }, + required: ["address", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { type: "string" }, + short_desc: { type: "string" }, + }, + }, + contact: { + type: "object", + properties: { + phone: { type: "string" }, + }, + required: ["phone"], + }, + }, + required: ["location", "time", "contact"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "tracking", + "start", + "end", + ], + }, + }, + + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { type: "string", minLength: 1 }, + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string" }, + }, + required: ["value", "currency"], + }, + "@ondc/org/item_id": { type: "string" }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + value: { + type: "string", + minLength: 1, + pattern: "^(\\d*.?\\d{1,2})$", + }, + currency: { type: "string", pattern: "^(?!s*$).+" }, + }, + required: ["value", "currency"], + }, + }, + required: ["price"], + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "delivery", + "packing", + "tax", + "misc", + "discount", + ], + }, + }, + required: [ + "price", + "title", + "@ondc/org/title_type", + "@ondc/org/item_id", + ], + }, + }, + + ttl: { type: "string", format: "duration" }, + }, + required: ["ttl", "price", "breakup"], + }, + payment: { + type: "object", + properties: { + status: { type: "string", const: "PAID" }, + type: { type: "string", const: "ON-ORDER" }, + collected_by: { type: "string", const: "BAP" }, + params: { + type: "object", + properties: { + amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, + transaction_id: { type: "string" }, + currency: { type: "string" }, + }, + required: ["amount", "currency", "transaction_id"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + pattern: "^(\\d*.?\\d{1,2})$", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { type: "string", pattern: "^(?!s*$).+" }, + settlement_bank_account_no: { + type: "string", + pattern: "^(?!s*$).+", + }, + settlement_ifsc_code: { + type: "string", + pattern: "^(?!s*$).+", + }, + bank_name: { type: "string" }, + beneficiary_name: { + type: "string", + }, + branch_name: { type: "string" }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + ], + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "rtgs", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + { + if: { + properties: { + settlement_type: { + const: "neft", + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + }, + }, + }, + required: [ + "status", + "type", + "params", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_details", + ], + // allOf: [ + // { + // if: { + // properties: { + // status: { + // const: "PAID", + // }, + // }, + // atPath: "1", + // }, + // then: { properties: { type: { const: "ON-ORDER" } } }, + // }, + // ], + }, + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { type: "string" }, + label: { type: "string", const: "Invoice" }, + }, + }, + }, + tags: { + type: "object", + properties: { + cancellation_reason_id: { + type: "string", + maxLength: 3, + minLength: 3, + }, + }, + }, + created_at: { type: "string", format: "date-time" }, + updated_at: { type: "string", format: "date-time" }, + }, + // allOf: postConfirmRules, + required: [ + "payment", + "fulfillments", + "quote", + "items", + "id", + "state", + "created_at", + "updated_at", + ], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/postConfirmValidations.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/postConfirmValidations.js new file mode 100755 index 0000000..e69de29 diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js new file mode 100755 index 0000000..9eb1efd --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js @@ -0,0 +1,140 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "search", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["descriptor"], + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + const: "Delivery", + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps"], + }, + }, + required: ["location"], + }, + }, + required: ["type", "end"], + }, + payment: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + enum: ["percent", "amount"], + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + required: ["item", "fulfillment", "payment"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js new file mode 100755 index 0000000..dfd110d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js @@ -0,0 +1,170 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "select", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + location_id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["id", "location_id", "quantity"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + }, + required: ["end"], + }, + }, + billing: { + type: "object", + properties: { + tax_number: { + type: "string", + }, + }, + required: ["tax_number"], + }, + }, + required: ["provider", "items", "fulfillments"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js new file mode 100755 index 0000000..c12164f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js @@ -0,0 +1,80 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "status", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js new file mode 100755 index 0000000..2bf87e6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js @@ -0,0 +1,201 @@ +module.exports = { + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:52110", + }, + action: { + type: "string", + const: "update", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + core_version: { + type: "string", + const: "1.1.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + format: "uuid", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "action", + "country", + "city", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum: ["item", "payment"], + }, + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + enum: ["Created", "Accepted", "In-progress", "Completed"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + tags: { + type: "object", + properties: { + update_type: { + type: "string", + enum: ["return", "cancel"], + }, + reason_code: { + type: "string", + minLength: 3, + maxLength: 3, + }, + ttl_approval: { + type: "string", + format: "duration", + }, + ttl_reverseqc: { + type: "string", + format: "duration", + }, + image: { + type: "string", + }, + }, + required: ["update_type"], + allOf: [ + { + if: { + properties: { + update_type: { + const: "return", + }, + reason_code: { type: "string" }, + }, + required: ["update_type"], + }, + then: { required: ["reason_code"] }, + }, + ], + }, + }, + required: ["id", "quantity", "tags"], + }, + }, + payment: { + type: "object", + properties: { + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + settlement_amount: { + type: "string", + }, + settlement_timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "settlement_counterparty", + "settlement_phase", + "settlement_type", + "settlement_amount", + "settlement_timestamp", + ], + }, + }, + }, + required: ["@ondc/org/settlement_details"], + }, + }, + required: ["id", "state", "provider", "items"], + }, + }, + required: ["update_target", "order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js b/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js new file mode 100755 index 0000000..4524f73 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js @@ -0,0 +1,12 @@ +const path = require("path"); +const utils = require("../utils/utils"); +const vl = require("../utils/validateLogUtil"); +const fs = require("fs"); + +const validateLog = async (domain, dirPath) => { + console.log("Inside Log Validation Service..."); + const logsPath = path.join(__dirname, "..", dirPath); + vl.validateLogs(domain, logsPath); +}; + +module.exports = { validateLog }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/services/service.js b/utilities/logistics-b2b/log-verification-utility/services/service.js new file mode 100755 index 0000000..8a67fbb --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/services/service.js @@ -0,0 +1,15 @@ +const { logisticsVal } = require("../utils/logistics/msgValidator"); +const { b2bVal } = require("../utils/b2b/msgValidator"); +const _ = require("lodash"); + +const checkMessage = (domain, element, action, msgIdSet) => { + const busnsErr = {}; + switch (domain) { + case "logistics": + return logisticsVal(element, msgIdSet); + case "b2b": + return b2bVal(element, msgIdSet); + } + return busnsErr; +}; +module.exports = { checkMessage }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js new file mode 100644 index 0000000..6c1bbb4 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -0,0 +1,93 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../dao/dao"); +const utils = require("./utils"); + +const checkContextVal = (payload, Obj, msgIdSet) => { + try { + action = payload.context.action; + if (!Obj.hasOwnProperty(action)) { + Obj[action] = {}; + } + let data = payload.context; + if (data.timestamp) { + let date = data.timestamp; + result = utils.timestampCheck(date); + if (result && result.err === "FORMAT_ERR") { + Obj[action].tmstmpFrmt_err = + "Timestamp not in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format"; + } else if (result && result.err === "INVLD_DT") { + Obj[action].tmstmpFrmt_err = "Timestamp should be in date-time format"; + } + } + + try { + if (action !== "on_status") { + //console.log(`Comparing timestamp of /${action}`); + if (_.gte(dao.getValue("tmpstmp"), payload.context.timestamp)) { + if ( + action === "support" || + action === "track" || + action === "update" || + action === "cancel" + ) { + dao.setValue(`${action}Tmpstmp`, payload.context.timestamp); + } else if ( + action === "on_support" || + action === "on_track" || + action === "on_update" || + action === "on_cancel" + ) { + console.log(dao.getValue(`${action.replace("on_", "")}Tmpstmp`), + payload.context.timestamp); + if ( + _.gte( + dao.getValue(`${action.replace("on_", "")}Tmpstmp`), + payload.context.timestamp + ) + ) { + Obj[action].tmpstmp = `Timestamp for /${action.replace( + "on_", + "" + )} api cannot be greater than or equal to /${action} api`; + } + } + Obj[action].tmpstmp = `Timestamp mismatch for /${action} `; + } else { + if ( + action === "on_search" || + action === "on_init" || + action === "on_confirm" || + action ==="on_update" + ) { + const timeDiff = utils.timeDiff( + payload.context.timestamp, + dao.getValue("tmpstmp") + ); + //console.log(timeDiff); + if (timeDiff > 1000) { + Obj[ + action + ].tmpstmp = `context/timestamp difference between ${action} and ${action.replace( + "on_", + "" + )} should be smaller than 1 sec`; + } + } + } + dao.setValue("tmpstmp", payload.context.timestamp); + } + } catch (error) { + console.log(`Error while comparing timestamp for /${action} api`); + console.trace(error); + } + return Obj; + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${action} API!`); + } else { + console.log(`!!Some error occurred while checking /${action} API`, err); + } + } +}; +module.exports = checkContextVal; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ServicabilityCheck.js b/utilities/logistics-b2b/log-verification-utility/utils/ServicabilityCheck.js new file mode 100644 index 0000000..f739750 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/ServicabilityCheck.js @@ -0,0 +1,68 @@ +const fs = require("fs"); +const utils = require("./utils"); +const constants = require("./constants"); +const path = require("path"); +//const checkOnSelect = require("./retOnSelect"); + +const servicabilityCheck = (element, error) => { + try { + action = element.context.action + console.log(`Running servicability check in /${action}`); + let nonServiceableFlag = 0; + try { + console.log(`Checking fulfillments' state in ${action}`); + on_select = element.message.order; + const ffState = on_select.fulfillments.every((ff) => { + const ffDesc = ff.state.descriptor; + if (ffDesc.code.toLowerCase() === "non-serviceable") { + nonServiceableFlag = 1; + } + return ffDesc.hasOwnProperty("code") + ? ffDesc.code.toLowerCase() === "serviceable" || + ffDesc.code.toLowerCase() === "non-serviceable" + : false; + }); + if (!ffState) { + error.ffStateCode = `Pre-order fulfillment state codes should be used in fulfillments[].state.descriptor.code`; + } + } catch (err) { + console.log( + `!!Error while checking fulfillments' state in /${action}`, + err + ); + } + if (element.hasOwnProperty("error")) { + on_select_error = element.error; + if ( + nonServiceableFlag && + (!on_select_error || + !on_select_error.type === "DOMAIN-ERROR" || + !on_select_error.code === "30009") + ) { + error.notServiceable = `Non Serviceable Domain error should be provided when fulfillment is not serviceable`; + } + else if (nonServiceableFlag && + (on_select_error && + on_select_error.type === "DOMAIN-ERROR" && + on_select_error.code === "30009") + ) { + return true + } + } + else if (!nonServiceableFlag && !element.hasOwnProperty("error")) { + return false + } + return error + } catch (err) { + if (err.code === "ENOENT") { + console.log(`!!File not found for /${action} API!`); + } else { + console.log( + `!!Some error occurred while checking /${action} API`, + err + ); + } + } +}; + +module.exports = servicabilityCheck diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js new file mode 100644 index 0000000..79fa746 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -0,0 +1,91 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkInit = (data, msgIdSet) => { + const initObj = {}; + let init = data; + init = init.message.order; + + let itemsArr = init.items; + let fulfillmentsArr = init.fulfillments; + let onSearchitemsArr; + let providersArr = dao.getValue("providersArr"); + + //provider check + try { + console.log(`Comparing provider object in /init and /on_search`); + if (init.provider) { + onSearchitemsArr = dao.getValue(`${init.provider.id}itemsArr`); + let providerObj = providersArr.filter( + (prov) => prov.id === init.provider.id + ); + if (providerObj?.length < 1) { + initObj.prvdrErr = `Provider with id '${init.provider.id}' does not exist in the catalog provided in /on_search`; + } else { + if ( + (!init?.provider?.locations || + init?.provider?.locations?.length < 1) && + providerObj[0]?.locations?.length > 1 + ) { + initObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + } else if (init?.provider?.locations) { + let providerLocArr = init.provider.locations; + let providerLocExists = false; + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + initObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; + }); + } + } + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.LOG_INIT}`, + error + ); + } + + //item check + try { + console.log(`Comparing item object in /init and /on_search`); + let itemExists = false; + + itemsArr.forEach((item, i) => { + onSearchitemsArr.forEach((element) => { + if (item.id === element.id) itemExists = true; + console.log(item.id, element.id); + }); + if (!itemExists) { + let itemkey = `itemErr${i}`; + initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; + } else { + let itemObj = onSearchitemsArr.filter( + (element) => item.id === element.id + ); + itemObj = itemObj[0]; + } + itemExists = false; + }); + } catch (error) { + console.log( + `!!Error while checking items array in /on_init API`, + error + ); + } + + return initObj; +}; + +module.exports = checkInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js new file mode 100644 index 0000000..4724e59 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -0,0 +1,33 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); +const checkOnSearch = (data, msgIdSet) => { + const onSrchObj = {}; + let onSearch = data; + onSearch = onSearch.message.catalog; + + try { + console.log( + `Saving provider items array in /on_search api` + ); + if (onSearch["providers"]) { + let providers = onSearch["providers"]; + dao.setValue("providersArr", providers); + providers.forEach((provider, i) => { + let itemsArr = provider.items; + const providerId = provider.id; + + dao.setValue(`${providerId}itemsArr`, itemsArr); + }); + } + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return onSrchObj; +}; +module.exports = checkOnSearch; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js new file mode 100644 index 0000000..519d755 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -0,0 +1,194 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnStatus = (data, msgIdSet) => { + let onStatusObj = {}; + let on_status = data; + let contextTime = on_status.context.timestamp; + let messageId = on_status.context.message_id; + + on_status = on_status.message.order; + let ffState; + let orderState = on_status.state; + let items = on_status.items; + let fulfillments = on_status.fulfillments; + let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; + +// try { +// console.log( +// `Checking if message id is unique for different on_status apis` +// ); +// if (msgIdSet.has(messageId)) { +// onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; +// } else { +// msgIdSet.add(messageId); +// } +// } catch (error) { +// console.log(`Error checking message id in /on_status API`); +// } + +// try { +// if (fulfillments.length > 1) { +// console.log( +// `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` +// ); +// fulfillments.forEach((fulfillment) => { +// ffState = fulfillment?.state?.descriptor?.code; +// if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { +// onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; +// } +// }); +// } +// } catch (error) { +// console.log(error); +// } +// try { +// fulfillments.forEach((fulfillment) => { +// ffState = fulfillment?.state?.descriptor?.code; +// console.log( +// `Comparing pickup and delivery timestamps for on_status_${ffState}` +// ); + +// if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD") { +// if (ffState === "Pending" || ffState === "Agent-assigned") { +// if (fulfillment?.start?.time?.timestamp) { +// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; +// } +// if (fulfillment?.end?.time?.timestamp) { +// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; +// } +// } +// if (ffState === "Order-picked-up") { +// if (orderState !== "In-progress") { +// onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; +// } +// pickupTime = fulfillment?.start?.time?.timestamp; +// dao.setValue("pickupTime", pickupTime); +// if (!pickupTime) { +// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; +// } + +// if (_.gt(pickupTime, contextTime)) { +// onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; +// } +// } +// if (ffState === "Out-for-delivery") { +// if (orderState !== "In-progress") { +// onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; +// } +// if (!dao.getValue("pickupTime")) { +// onStatusObj.pickupTimeErr = `Missing /on_status response for fulfillment state - 'Order-picked-up'`; +// } else if ( +// !fulfillment?.start?.time?.timestamp || +// fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") +// ) { +// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; +// } +// if (fulfillment?.end?.time?.timestamp) { +// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; +// } +// } +// if (ffState === "Order-delivered") { +// if (orderState !== "Completed") { +// onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; +// } +// deliveryTime = fulfillment?.end?.time?.timestamp; +// dao.setValue("deliveryTime", deliveryTime); +// if (!dao.getValue("pickupTime")) { +// onStatusObj.pickupTimeErr = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; +// } else if ( +// !fulfillment?.start?.time?.timestamp || +// fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") +// ) { +// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; +// } +// if (!deliveryTime) { +// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; +// } + +// if (_.gte(pickupTime, deliveryTime)) { +// onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; +// } +// } +// if (ffState === "Cancelled") { +// if (orderState !== "Cancelled") { +// onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; +// } +// if (fulfillments.length > 1) { +// if (!dao.getValue("pickupTime")) { +// onStatusObj.msngPickupState = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; +// } else if (!fulfillment.start.time.timestamp) { +// onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; +// } +// } + +// if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { +// if ( +// !_.isEqual( +// dao.getValue("pickupTime"), +// fulfillment.start.time.timestamp +// ) +// ) { +// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; +// } +// } +// if (fulfillment.end.time.timestamp && dao.getValue("deliveryTime")) { +// if ( +// !_.isEqual( +// dao.getValue("delivryTime"), +// fulfillment.end.time.timestamp +// ) +// ) { +// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot change for fulfillment state - ${ffState}`; +// } +// } +// } +// } else if (fulfillment.type === "RTO") { +// if (orderState !== "Cancelled") { +// onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; +// } +// if (ffState === "RTO-Initiated") { +// RtoPickupTime = fulfillment?.start?.time?.timestamp; +// if (RtoPickupTime) { +// dao.setValue("RtoPickupTime", RtoPickupTime); +// } else { +// onStatusObj.rtoPickupTimeErr = `RTO Pickup timestamp is missing for fulfillment state - ${ffState}`; +// } +// if (_.gt(RtoPickupTime, contextTime)) { +// onStatusObj.rtoPickupErr = `RTO Pickup (fulfillments/start/time/timestamp) time cannot be future dated for fulfillment state - ${ffState}`; +// } +// } +// if (ffState === "RTO-Delivered" || ffState === "RTO-Disposed") { +// RtoDeliveredTime = fulfillment?.end?.time?.timestamp; +// console.log(dao.getValue("RtoPickupTime")); +// if (!RtoDeliveredTime && ffState === "RTO-Delivered") +// onStatusObj.rtoDlvryTimeErr = `RTO Delivery timestamp (fulfillments/end/time/timestamp) is missing for fulfillment state - ${ffState}`; +// if ( +// fulfillment.start.time.timestamp && +// dao.getValue("RtoPickupTime") +// ) { +// if ( +// !_.isEqual( +// fulfillment.start.time.timestamp, +// dao.getValue("RtoPickupTime") +// ) +// ) { +// onStatusObj.rtoPickupErr = `RTO Pickup time (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; +// } +// } +// if (RtoDeliveredTime && _.gt(RtoDeliveredTime, contextTime)) { +// onStatusObj.rtoDeliveredErr = `RTO Delivery time (fulfillments/end/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; +// } +// } +// } +// }); +// } catch (error) { +// console.log(`Error checking fulfillments/start in /update`); +// } + + return onStatusObj; +}; + +module.exports = checkOnStatus; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js new file mode 100644 index 0000000..71a8357 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js @@ -0,0 +1,18 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkSearch = (data, msgIdSet) => { + let srchObj = {}; + let search = data; + let contextTime = search.context.timestamp; + search = search.message.intent; + + + dao.setValue("searchObj", search); + + return srchObj; +}; + +module.exports = checkSearch; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js new file mode 100644 index 0000000..34c9a00 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -0,0 +1,20 @@ +const checkOnSearch = require("./b2bOnSearch"); +const checkOnStatus = require("./b2bOnStatus"); +const checkSearch = require("./b2bSearch"); +const _ = require("lodash"); + +const b2bVal = (element, action, msgIdSet) => { + const busnsErr = {}; + switch (action) { + case "search": + return checkSearch(element, msgIdSet); + + case "on_search": + return checkOnSearch(element, msgIdSet); + + case "on_status": + return checkOnStatus(element,msgIdSet) + } + return busnsErr; +}; +module.exports = { b2bVal }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/clean.js b/utilities/logistics-b2b/log-verification-utility/utils/clean.js new file mode 100644 index 0000000..56b79fc --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/clean.js @@ -0,0 +1,19 @@ +const clean = (log) => { + Object + .entries(log) + .forEach(([key, value]) => { + if (value && typeof value === 'object') { + clean(value); + } + if (value && typeof value === 'object' && !Object.keys(value).length || value === null || value === undefined) { + if (Array.isArray(log)) { + log.splice(key, 1); + } else { + delete log[key]; + } + } + }); + return log; +} + +module.exports = clean \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js new file mode 100755 index 0000000..92fbd1c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -0,0 +1,48 @@ +module.exports = Object.freeze({ + RET_CONTEXT_TTL: "PT30S", + RET_CONTEXT_ACTION: "action", + DB_PATH: "dbfiles", + DB_Keys: {"search": {"context": ['timestamp', 'transaction_id', 'message_id', 'city'], + "message": {"intent": {"payment": ['@ondc/org/buyer_app_finder_fee_amount']}}}, + "on_search": {"context": ['bap_id', 'bpp_id'], "message": ['catalog']}}, + LOG_SORTED_INDEX: ['search','on_search','init','on_init','confirm','on_confirm'], + B2B_SORTED_INDEX:['search','on_search','select','on_select','init','on_init','confirm','on_confirm'], + RET_SEARCH: "search", + RET_ONSEARCH: "on_search", + RET_SELECT: "select", + RET_ONSELECT: "on_select", + RET_INIT: "init", + RET_ONINIT: "on_init", + RET_CONFIRM: "confirm", + RET_ONCONFIRM: "on_confirm", + RET_TRACK: "track", + RET_ONTRACK: "on_track", + RET_CANCEL: "cancel", + RET_ONCANCEL: "on_cancel", + RET_UPDATE: "update", + RET_ONUPDATE: "on_update", + RET_STATUS: "status", + RET_ONSTATUS: "on_status", + RET_SUPPORT: "support", + RET_ONSUPPORT: "on_support", + //logistics + LOG_CONTEXT_TTL: "PT30S", + LOG_CONTEXT_ACTION: "action", + LOG_SEARCH: "search", + LOG_ONSEARCH: "on_search", + LOG_INIT: "init", + LOG_ONINIT: "on_init", + LOG_CONFIRM: "confirm", + LOG_ONCONFIRM: "on_confirm", + LOG_TRACK: "track", + LOG_ONTRACK: "on_track", + LOG_CANCEL: "cancel", + LOG_ONCANCEL: "on_cancel", + LOG_UPDATE: "update", + LOG_ONUPDATE: "on_update", + LOG_STATUS: "status", + LOG_ONSTATUS: "on_status", + LOG_SUPPORT: "support", + LOG_ONSUPPORT: "on_support", + +}); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js new file mode 100644 index 0000000..e84fdc9 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -0,0 +1,31 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require ("../utils.js"); + +const checkConfirm = (data, msgIdSet) => { + + let cnfrmObj = {}; + let confirm = data; + + confirm = confirm.message.order; + let rts= confirm?.fulfillments[0]?.tags['@ondc/org/order_ready_to_ship']; + dao.setValue("rts",rts); + const cnfrmOrdrId = confirm.id; + dao.setValue("cnfrmOrdrId", cnfrmOrdrId); + let awbNo= false; + let fulfillments = confirm.fulfillments; + + let p2h2p = dao.getValue("p2h2p") + fulfillments.forEach(fulfillment => { + if(fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo= true; + if(fulfillment?.tags["@ondc/org/order_ready_to_ship"]==='yes' && !fulfillment?.start?.instructions?.short_desc){ + cnfrmObj.instructionsErr=`PCC code is required in /fulfillments/start/instructions when ready_to_ship = 'yes'` + } + }); + + dao.setValue("awbNo",awbNo); + return cnfrmObj; +}; + +module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js new file mode 100644 index 0000000..5ae0d49 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -0,0 +1,124 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkInit = (data, msgIdSet) => { + const initObj = {}; + let init = data; + let p2h2p = false; + init = init.message.order; + + let itemsArr = init.items; + let fulfillmentsArr = init.fulfillments; + let bppFulfillmentsArr = dao.getValue("bppFulfillmentsArr"); + let onSearchitemsArr; + let providersArr = dao.getValue("providersArr"); + + //provider check + try { + console.log(`Comparing provider object in /init and /on_search`); + if (init.provider) { + onSearchitemsArr = dao.getValue(`${init.provider.id}itemsArr`); + let providerObj = providersArr.filter( + (prov) => prov.id === init.provider.id + ); + if (providerObj?.length < 1) { + initObj.prvdrErr = `Provider with id '${init.provider.id}' does not exist in the catalog provided in /on_search`; + } else { + if ( + (!init?.provider?.locations || init?.provider?.locations?.length < 1) && + providerObj[0]?.locations?.length>1 + ) { + initObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + } else if (init?.provider?.locations) { + let providerLocArr = init.provider.locations; + let providerLocExists = false; + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + initObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; + }); + } + } + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.LOG_INIT}`, + error + ); + } + + //item check + try { + console.log(`Comparing item object in /init and /on_search`); + let itemExists = false; + + itemsArr.forEach((item, i) => { + if (item.descriptor.code === "P2H2P") { + p2h2p = true; + } + onSearchitemsArr.forEach((element) => { + if (item.id === element.id) itemExists = true; + console.log(item.id, element.id); + }); + if (!itemExists) { + let itemkey = `itemErr${i}`; + initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; + } else { + let itemObj = onSearchitemsArr.filter( + (element) => item.id === element.id + ); + itemObj = itemObj[0]; + if (item.category_id != itemObj.category_id) { + let itemkey = `catIdErr${i}`; + initObj[ + itemkey + ] = `Category id '${item.category_id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + if (item.descriptor.code != itemObj.descriptor.code) { + let itemkey = `codeErr${i}`; + initObj[ + itemkey + ] = `Descriptor code '${item.descriptor.code}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + fulfillmentsArr.forEach((fulfillment, i) => { + if (fulfillment.id !== itemObj.fulfillment_id) { + let itemkey = `flfillmentErr${i}`; + initObj[ + itemkey + ] = `Fulfillment id '${fulfillment.id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } else { + let bppfulfillment = bppFulfillmentsArr.find( + (element) => element.id === fulfillment.id + ); + if (fulfillment.type !== bppfulfillment.type) { + let itemkey = `flfillmentTypeErr${i}`; + initObj[ + itemkey + ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + } + } + }); + } + itemExists = false; + }); + } catch (error) { + console.log( + `!!Error while checking items array in /${constants.log_INIT}`, + error + ); + } + dao.setValue("p2h2p", p2h2p); + return initObj; +}; +module.exports = checkInit; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js new file mode 100644 index 0000000..95ff20a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -0,0 +1,37 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const utils = require("../utils"); + +const constants = require("../constants"); + +const checkOnConfirm = (data, msgIdSet) => { + let on_confirm = data; + const onCnfrmObj = {}; + + on_confirm = on_confirm.message.order; + let fulfillments = on_confirm.fulfillments; + let rts = dao.getValue("rts"); + let p2h2p = dao.getValue("p2h2p") + let awbNo= dao.getValue("awbNo"); + try { + console.log(`checking start and end time range in fulfillments`); + fulfillments.forEach((fulfillment) => { + if(fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo= true; + console.log(rts) + if (rts === "yes" && !fulfillment?.start?.time?.range && dao.getValue("updateApi")===false) { + onCnfrmObj.strtRangeErr = `start/time/range is required in /fulfillments when ready_to_ship = yes in /confirm`; + } + if (rts === "yes" && !fulfillment?.end?.time?.range && dao.getValue("updateApi")===false) { + onCnfrmObj.endRangeErr = `end/time/range is required in /fulfillments when ready_to_ship = yes in /confirm`; + } + }); + + } catch (error) { + console.log(`Error checking fulfillment object in /on_confirm`); + } + + dao.setValue("awbNo",awbNo); + return onCnfrmObj; +}; +module.exports = checkOnConfirm; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js new file mode 100644 index 0000000..11cd048 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js @@ -0,0 +1,64 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const validateSchema = require("../schemaValidation"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnInit = (data, msgIdSet) => { + let on_init = data; + const onInitObj = {}; + + on_init = on_init.message.order; + let provId = on_init.provider.id; + let itemId = on_init.items[0].id; + let onSearchProvArr = dao.getValue("providersArr"); + + try { + console.log( + `Comparing order quote price and break up in ${constants.LOG_ONINIT}` + ); + if (on_init.hasOwnProperty("quote")) { + if (!utils.hasTwoOrLessDecimalPlaces(on_init.quote.price.value)) { + onInitObj.qteDecimalErr = `Quote price value should not have more than 2 decimal places`; + } + let totalBreakup = 0; + on_init.quote.breakup.forEach((breakup, i) => { + if (!utils.hasTwoOrLessDecimalPlaces(breakup.price.value)) { + let itemkey = `itemPriceErr${i}`; + + onInitObj[ + itemkey + ] = `Price value for '${breakup["@ondc/org/title_type"]}' should not have more than 2 decimal places`; + } + totalBreakup += parseFloat(breakup.price.value); + onSearchProvArr.forEach((provider) => { + if (provider.id === provId) { + provider?.items.forEach((item, i) => { + if (item.id === itemId) { + if (breakup.price.value !== item.price.value) { + let itemKey = `priceArr${i}`; + onInitObj[ + itemKey + ] = `Quote price ${breakup.price.value} for '${breakup["@ondc/org/title_type"]}' does not match item price ${item.price.value} in /on_search`; + } + } + }); + } + }); + }); + + if (parseFloat(on_init.quote.price.value) !== totalBreakup) + onInitObj.quotePriceErr = `Quote price does not match the breakup total in ${constants.LOG_ONINIT}`; + } + } catch (err) { + console.log( + `!!Error fetching order quote price in ${constants.LOG_ONINIT}`, + err + ); + } + + return onInitObj; +}; + +module.exports = checkOnInit; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js new file mode 100644 index 0000000..5f8d71d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js @@ -0,0 +1,112 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnSearch = (data, msgIdSet) => { + const onSrchObj = {}; + let onSearch = data; + let search = dao.getValue("searchObj"); + let validFulfillmentIDs = new Set(); + onSearch = onSearch.message.catalog; + + try { + console.log( + `Checking TAT for category or item in ${constants.LOG_ONSEARCH} api` + ); + if (onSearch.hasOwnProperty("bpp/providers")) { + onSearch["bpp/providers"].forEach((provider) => { + provider.categories.forEach((category) => { + const catName = category.id; + const categoryTime = category.time; + provider.items.forEach((item) => { + const catId = item.category_id; + const itemTime = item.time; + if (catName === catId && !categoryTime && !itemTime) + onSrchObj.TAT = `Either Category level TAT or Item level TAT should be given in ${constants.LOG_ONSEARCH} api for category "${catName}"`; + }); + }); + }); + } + } catch (error) { + console.log(`!!Error while fetching category and item TAT`, error); + } + + //forward and backward shipment + try { + console.log( + `Checking forward and backward shipment in ${constants.LOG_ONSEARCH} api` + ); + + if (onSearch["bpp/fulfillments"]) { + const fulfillments = onSearch["bpp/fulfillments"]; + dao.setValue("bppFulfillmentsArr", fulfillments); + + let hasForwardShipment = false; + let hasBackwardShipment = false; + + for (const fulfillment of fulfillments) { + validFulfillmentIDs.add(fulfillment.id); + if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD") { + hasForwardShipment = true; + } else if ( + fulfillment.type === "RTO" || + fulfillment.type === "Reverse QC" + ) { + hasBackwardShipment = true; + } + } + + if (hasForwardShipment && hasBackwardShipment) { + console.log("Both forward and backward shipments are present."); + } else if (!hasForwardShipment) { + onSrchObj.frwrdShpmnt = `Forward shipment (Prepaid or CoD) is missing in ${constants.LOG_ONSEARCH} api`; + } else if (!hasBackwardShipment) { + onSrchObj.bkwrdshmpnt = `Backward shipment (RTO or Reverse QC) is missing in ${constants.LOG_ONSEARCH} api`; + } + } + } catch (error) { + console.log( + `!!Error while checking forward/backward shipment in ${constants.LOG_ONSEARCH} api`, + error + ); + } + + try { + console.log( + `Checking item fulfillment_id corresponding to one of the ids in bpp/fulfillments in ${constants.LOG_ONSEARCH} api` + ); + if (onSearch["bpp/providers"]) { + let providers = onSearch["bpp/providers"]; + dao.setValue("providersArr", providers); + providers.forEach((provider, i) => { + let itemsArr = provider.items; + const providerId = provider.id; + + dao.setValue(`${providerId}itemsArr`, itemsArr); + itemsArr.forEach((item, j) => { + if (!validFulfillmentIDs.has(item.fulfillment_id)) { + onSrchObj.fulfillmentIDerr = `fulfillment_id of /items/${j} for /bpp/provider/${i} does not match with the id in bpp/fulfillments in ${constants.LOG_ONSEARCH} api`; + } + if ( + item.descriptor.code === "P2H2P" && + !search["@ondc/org/payload_details"].dimensions + ) { + let itemKey = `dimensionErr${j}`; + onSrchObj[ + itemKey + ] = `@ondc/org/payload_details/dimensions is a required property in /search request for 'P2H2P' shipments`; + } + }); + }); + } + } catch (error) { + console.log( + `!!Error while checking fulfillment ids in /items in ${constants.LOG_ONSEARCH} api`, + error + ); + } + + return onSrchObj; +}; +module.exports = checkOnSearch; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js new file mode 100644 index 0000000..06b0eaa --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -0,0 +1,198 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnStatus = (data, msgIdSet) => { + let onStatusObj = {}; + let on_status = data; + let contextTime = on_status.context.timestamp; + let messageId = on_status.context.message_id; + + on_status = on_status.message.order; + let ffState; + let orderState = on_status.state; + let items = on_status.items; + let fulfillments = on_status.fulfillments; + let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; + + // try { + // console.log( + // `Checking if message id is unique for different on_status apis` + // ); + // if (msgIdSet.has(messageId)) { + // onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; + // } else { + // msgIdSet.add(messageId); + // } + // } catch (error) { + // console.log(`Error checking message id in /on_status API`); + // } + + try { + if (fulfillments.length > 1) { + console.log( + `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` + ); + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { + onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; + } + }); + } + } catch (error) { + console.log(error); + } + try { + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + console.log( + `Comparing pickup and delivery timestamps for on_status_${ffState}` + ); + + if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD") { + if (ffState === "Pending" || ffState === "Agent-assigned") { + if (fulfillment?.start?.time?.timestamp) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + if (fulfillment?.end?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + if (ffState === "Order-picked-up") { + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + pickupTime = fulfillment?.start?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; + } + + if (_.gt(pickupTime, contextTime)) { + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; + } + if (fulfillment?.end?.time?.timestamp) { + onStatusObj.delvryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + if (ffState === "Out-for-delivery") { + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + if (!dao.getValue("pickupTime")) { + onStatusObj.pickupTimeErr = `Missing /on_status response for fulfillment state - 'Order-picked-up'`; + } else if ( + !fulfillment?.start?.time?.timestamp || + fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + if (fulfillment?.end?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + if (ffState === "Order-delivered") { + if (orderState !== "Completed") { + onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; + } + deliveryTime = fulfillment?.end?.time?.timestamp; + dao.setValue("deliveryTime", deliveryTime); + if (!dao.getValue("pickupTime")) { + onStatusObj.pickupTimeErr = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; + } else if ( + !fulfillment?.start?.time?.timestamp || + fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + if (!deliveryTime) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; + } + + if (_.gte(pickupTime, deliveryTime)) { + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; + } + } + if (ffState === "Cancelled") { + if (orderState !== "Cancelled") { + onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; + } + if (fulfillments.length > 1) { + if (!dao.getValue("pickupTime")) { + onStatusObj.msngPickupState = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; + } else if (!fulfillment.start.time.timestamp) { + onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; + } + } + + if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { + if ( + !_.isEqual( + dao.getValue("pickupTime"), + fulfillment.start.time.timestamp + ) + ) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + } + if (fulfillment.end.time.timestamp && dao.getValue("deliveryTime")) { + if ( + !_.isEqual( + dao.getValue("delivryTime"), + fulfillment.end.time.timestamp + ) + ) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + } + } + } else if (fulfillment.type === "RTO") { + if (orderState !== "Cancelled") { + onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; + } + if (ffState === "RTO-Initiated") { + RtoPickupTime = fulfillment?.start?.time?.timestamp; + if (RtoPickupTime) { + dao.setValue("RtoPickupTime", RtoPickupTime); + } else { + onStatusObj.rtoPickupTimeErr = `RTO Pickup timestamp is missing for fulfillment state - ${ffState}`; + } + if (_.gt(RtoPickupTime, contextTime)) { + onStatusObj.rtoPickupErr = `RTO Pickup (fulfillments/start/time/timestamp) time cannot be future dated for fulfillment state - ${ffState}`; + } + } + if (ffState === "RTO-Delivered" || ffState === "RTO-Disposed") { + RtoDeliveredTime = fulfillment?.end?.time?.timestamp; + console.log(dao.getValue("RtoPickupTime")); + + if (!RtoDeliveredTime && ffState === "RTO-Delivered") + onStatusObj.rtoDlvryTimeErr = `RTO Delivery timestamp (fulfillments/end/time/timestamp) is missing for fulfillment state - ${ffState}`; + if ( + fulfillment.start.time.timestamp && + dao.getValue("RtoPickupTime") + ) { + if ( + !_.isEqual( + fulfillment.start.time.timestamp, + dao.getValue("RtoPickupTime") + ) + ) { + onStatusObj.rtoPickupErr = `RTO Pickup time (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + } + if (RtoDeliveredTime && _.gt(RtoDeliveredTime, contextTime)) { + onStatusObj.rtoDeliveredErr = `RTO Delivery time (fulfillments/end/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; + } + } + } + }); + } catch (error) { + console.log(`Error checking fulfillments/start in /update`); + } + + return onStatusObj; +}; + +module.exports = checkOnStatus; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js new file mode 100644 index 0000000..3a1fcd5 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js @@ -0,0 +1,47 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnUpdate = (data, msgIdSet) => { + let onUpdtObj = {}; + let on_update = data; + let rts = dao.getValue("rts"); + on_update = on_update.message.order; + let fulfillments = on_update.fulfillments; + let items = on_update.items; + let p2h2p = dao.getValue("p2h2p"); + let awbNo = dao.getValue("awbNo"); + + try { + console.log( + `Checking if start and end time range required in /on_update api` + ); + fulfillments.forEach((fulfillment) => { + if (fulfillment["@ondc/org/awb_no"]) { + awbNo = true; + } + if (!awbNo && p2h2p) { + onUpdtObj.awbNoErr = + "AWB No (@ondc/org/awb_no) is required in /fulfillments for P2H2P shipments (may be provided in /confirm or /update by logistics buyer or /on_confirm or /on_update by LSP)"; + } + if (rts === "yes" && !fulfillment?.start?.time?.range) { + onUpdtObj.strtRangeErr = `start/time/range is required in /fulfillments when ready_to_ship = yes in /update`; + } + if (rts === "yes" && !fulfillment?.end?.time?.range) { + onUpdtObj.endRangeErr = `end/time/range is required in /fulfillments when ready_to_ship = yes in /update`; + } + + if (p2h2p && !fulfillment?.start?.instructions?.images) { + onUpdtObj.shipLblErr = `Shipping label (/start/instructions/images) is required for P2H2P shipments`; + } + }); + } catch (error) { + console.log(`!!Error while checking fulfillments in /on_update api`, error); + } + + + return onUpdtObj; +}; + +module.exports = checkOnUpdate; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js new file mode 100644 index 0000000..1910586 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js @@ -0,0 +1,32 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkSearch = (data, msgIdSet) => { + let srchObj = {}; + let search = data; + let contextTime = search.context.timestamp; + search = search.message.intent; + + try { + console.log(`Checking if holidays are in past date or not`); + let holidays = search?.provider?.time?.schedule?.holidays; + if (holidays && holidays.length > 0) { + holidays.forEach((holiday, i) => { + holidayDate = new Date(holiday); + if (!utils.compareDates(holidayDate, contextTime)) { + let itemKey = `holidayErr${i}`; + srchObj[ + itemKey + ] = `Holiday date '${holiday}' should not be past dated`; + } + }); + } + } catch (error) { + console.log(error); + } + dao.setValue("searchObj", search); + return srchObj; +}; +module.exports = checkSearch; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js new file mode 100644 index 0000000..89a93fa --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js @@ -0,0 +1,46 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkUpdate = (data, msgIdSet) => { + let updtObj = {}; + let update = data; + let p2h2p = dao.getValue("p2h2p"); + let awbNo= dao.getValue("awbNo"); + + dao.setValue("updateApi",true) + + update = update.message.order; + let rts = update?.fulfillments[0]?.tags["@ondc/org/order_ready_to_ship"]; + dao.setValue("rts", rts); + let items = update.items; + let fulfillments = update.fulfillments; + + try { + console.log(`Checking if PCC code required in case of P2P/P2H2P shipments`); + + fulfillments.forEach((fulfillment) => { + + if(fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo= true; + if ( + rts === "yes" && + !p2h2p && + !fulfillment?.start && + !fulfillment?.start?.instructions?.short_desc + ) { + updtObj.startErr = `/fulfillments/start is required when ready_to_ship = yes for P2P shipments`; + } + else if(rts === 'yes' && p2h2p && fulfillment?.start?.instructions?.short_desc){ + + updtObj.instrctnsErr = `Pickup code is not required for P2H2P shipments as shipping label is provided by LSP`; + } + }); + } catch (error) { + console.log(`Error checking fulfillments/start in /update`); + } + dao.setValue("awbNo",awbNo); + return updtObj; +}; + +module.exports = checkUpdate; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js new file mode 100644 index 0000000..44762d2 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js @@ -0,0 +1,44 @@ +const checkConfirm = require("./logConfirm"); +const checkInit = require("./logInit"); +const checkOnConfirm = require("./logOnConfirm"); +const checkOnInit = require("./logOnInit"); +const checkOnSearch = require("./logOnSearch"); +const checkOnUpdate = require("./logOnUpdate"); +const checkUpdate = require("./logUpdate"); +const checkOnStatus = require("./logOnStatus"); +const checkSearch = require("./logSearch"); +const _ = require("lodash"); + +const logisticsVal = (element, action, msgIdSet) => { + const busnsErr = {}; + switch (action) { + case "search": + return checkSearch(element, msgIdSet); + + case "on_search": + return checkOnSearch(element, msgIdSet); + + case "init": + return checkInit(element, msgIdSet); + + case "on_init": + return checkOnInit(element, msgIdSet); + + case "confirm": + return checkConfirm(element, msgIdSet); + + case "on_confirm": + return checkOnConfirm(element, msgIdSet); + + case "update": + return checkUpdate(element,msgIdSet); + + case "on_update": + return checkOnUpdate(element,msgIdSet) + + case "on_status": + return checkOnStatus(element,msgIdSet) + } + return busnsErr; +}; +module.exports = { logisticsVal }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js new file mode 100755 index 0000000..c364870 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js @@ -0,0 +1,95 @@ +const fs = require("fs"); +const path = require("path"); +const constants = require("./constants"); + +const sortMerge = (domain, directory, destination) => { + flowErrObj = {}; + try { + var mergedlogs = []; + files = fs.readdirSync(directory); + + let map; + switch(domain) { + case 'logistics': + map = constants.LOG_SORTED_INDEX + break; + case 'b2b': + map = constants.B2B_SORTED_INDEX + break; + } + + mergedlogs = files.reduce((acc, item) => { + try { + let data = fs.readFileSync(`${directory}/${item}`); + data = JSON.parse(data); + const context = data.context; + if (!context || !context.action) { + console.log( + `Error in file ${item}: Missing 'context' or 'action' property` + ); + return acc; // Skip this data and continue with the next iteration + } + const { action } = data.context; + if (acc.hasOwnProperty(action)) { + acc[action].push(data); + } else { + acc[action] = [data]; + } + return acc; + } catch (error) { + console.log(`Error in file ${item}`); + console.trace(error); + } + }, {}); + + // Sort the arrays within each action based on context.timestamp + for (const action in mergedlogs) { + const array = mergedlogs[action]; + if (array.length > 1) { + array.sort( + (a, b) => + new Date(a.context.timestamp) - new Date(b.context.timestamp) + ); + } + } + + // Sort the mergedlogs object based on the first element of each array's context.timestamp + const sortedmergedlogs = {}; + Object.keys(mergedlogs) + .sort( + (a, b) => + new Date(mergedlogs[a][0].context.timestamp) - + new Date(mergedlogs[b][0].context.timestamp) + ) + .forEach((key) => { + sortedmergedlogs[key] = mergedlogs[key]; + }); + + // Assign the sorted data back to mergedlogs + mergedlogs = sortedmergedlogs; + + Object.entries(mergedlogs).forEach(([action], i, entries) => { + const curAction = action; + if (map.includes(curAction)) { + const curIndex = map.indexOf(curAction); + if (i != curIndex) { + console.log( + `Flow incorrect- current action: ${action}, Current Index:${i}, Index in correct flow:${curIndex}` + ); + flowErrObj[ + i + ] = `Incorrect Flow as per context/timestamps - (${Object.keys( + mergedlogs + )})`; + } + } + }); + + fs.writeFileSync(destination, JSON.stringify(mergedlogs)); + return flowErrObj; + } catch (err) { + console.log(`Error while running merging log files, ${err}`); + console.trace(err); + } +}; +module.exports = { sortMerge }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js b/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js new file mode 100755 index 0000000..b3fe451 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js @@ -0,0 +1,7 @@ +const { validateLogsUtil } = require("./validateLogUtil"); + +const validateLogs = (domain) => { + validateLogsUtil(domain); +}; + +module.exports = { validateLogs }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js b/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js new file mode 100755 index 0000000..2215be8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js @@ -0,0 +1,76 @@ +const dao = require("../dao/dao"); +const fs = require("fs"); +const utils = require("./utils"); +const constants = require("./constants"); +const { checkMessage } = require("../services/service"); +const validateSchema = require("./schemaValidation"); +const path = require("path"); +const checkContextVal = require("./ContextVal"); + +const Validate = (domain, dirPath, msgIdSet, ErrorObj) => { + try { + let log = fs.readFileSync(dirPath); + log = JSON.parse(log); + count = 0; + + // Validating Schema + try { + if (!("Schema" in ErrorObj)) ErrorObj["Schema"] = {}; + schemaObj = ErrorObj["Schema"]; + const vs = validateSchema(domain, log, schemaObj); + console.log(vs); + if (vs != "error") { + Object.assign(schemaObj, vs); + } + } catch (error) { + console.log(`!!Error occurred while performing schema validation`, error); + } + contextObj = ErrorObj["Context"]; + Object.entries(log).forEach(([action, elements]) => { + // Validate schema for each element in the array associated with the action + elements.forEach((element, i) => { + // Validating action context level checks + try { + if (!("Context" in ErrorObj)) ErrorObj["Context"] = {}; + CntxtObj = ErrorObj["Context"]; + //console.log(`Validating timestamp for ${action} api`); + if (action != "search") { + const ValCheck = checkContextVal(element, CntxtObj, msgIdSet); + if (ValCheck != "error") { + Object.assign(CntxtObj, ValCheck); + } + } else { + dao.setValue("tmpstmp", element.context.timestamp); + } + } catch (error) { + console.log( + `!!Error occurred while performing ${action} timestamp validation`, + error + ); + } + + // Business validations + try { + if (!("Message" in ErrorObj)) ErrorObj["Message"] = {}; + ErrorObj["Message"][`${action}_${i}`] = checkMessage( + domain, + element, + action, + msgIdSet, + domain + ); + } catch (error) { + console.log( + `!!Some error occurred while checking /${action} api message`, + error + ); + } + }); + + return ErrorObj; + }); + } catch (error) { + console.log(error); + } +}; +module.exports = Validate; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js b/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js new file mode 100755 index 0000000..ffb20eb --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js @@ -0,0 +1,26 @@ +const schemaValidator = require("../schema/main"); +const path = require("path"); +const fs = require("fs"); + +const validateSchema = (domain, data, errObj) => { + console.log(`Inside Schema Validation for domain: ${domain}`); + + const schmaVldtr = schemaValidator(domain,data); + + const datavld = schmaVldtr; + if (datavld.status === "fail") { + let res = datavld.errors; + let i = 0; + const len = res.length; + while (i < len) { + let key = `schemaErr${i}`; + errObj[key] = `${res[i].details} ${res[i].message}`; + i++; + } + console.log(`Validating Schema completed`); + return errObj; + + } else return "error"; +}; + +module.exports = validateSchema; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js new file mode 100755 index 0000000..a822e98 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -0,0 +1,350 @@ +const path = require("path"); +const _ = require("lodash"); +const rootPath = path.dirname(process.mainModule.filename); + +const retailAPI = [ + "search", + "on_search", + "select", + "on_select", + "init", + "on_init", + "confirm", + "on_confirm", + "status", + "on_status", + "track", + "on_track", + "cancel", + "on_cancel", + "update", + "on_update", + "support", + "on_support", +]; + +const taxNotInlcusive = ["F&B"]; + +const retailSttlmntPhase = ["sale-amount", "withholding-amount", "refund"]; + +const retailSttlmntCntrprty = [ + "buyer", + "buyer-app", + "seller-app", + "logistics-provider", +]; + +const retailPymntTtl = { + "delivery charges": "delivery", + "packing charges": "packing", + tax: "tax", + discount: "discount", + "convenience fee": "misc", +}; + +const retailPaymentType = [ + "ON-ORDER", + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", +]; +const retailFulfillmentState = [ + //pre-order fulfillment states + "Serviceable", + "Non-serviceable", + //post-order fulfillment states + "Pending", + "Packed", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", +]; + +const retailOrderState = [ + "Created", + "Accepted", + "In-progress", + "Completed", + "Cancelled", +]; + +const logFulfillmentState = [ + "Pending", + "Searching-for-Agent", + "Agent-assigned", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", +]; + +const logOrderState = [ + "Created", + "Accepted", + "In-progress", + "Completed", + "Cancelled", +]; + +const bpp_fulfillments = ["Delivery", "Pickup", "Delivery and Pickup"]; //id =1,2,3 +const bpp_provider_days = [ + "1", + "1,2", + "1,2,3", + "1,2,3,4", + "1,2,3,4,5", + "1,2,3,4,5,6", + "1,2,3,4,5,6,7", +]; +const categoriesMap = [ + { + "Standard Delivery": [ + "Immediate Delivery", + "Next Day Delivery", + "Same Day Delivery", + ], + }, + { "Express Delivery": [] }, +]; +const grocery_categories_id = [ + "Fruits and Vegetables", + "Masala & Seasoning", + "Oil & Ghee", + "Gourmet & World Foods", + "Foodgrains", + "Eggs, Meat & Fish", + "Cleaning & Household", + "Beverages", + "Beauty & Hygiene", + "Bakery, Cakes & Dairy", + "Kitchen Accessories", + "Baby Care", + "Snacks & Branded Foods", + "Pet Care", + "Stationery", + "Packaged Commodities", + "Packaged Foods", +]; + +const fnb_categories_id = [ + "Continental", + "Middle Eastern", + "North Indian", + "Pan-Asian", + "Regional Indian", + "South Indian", + "Tex-Mexican", + "World Cuisines", + "Healthy Food", + "Fast Food", + "Desserts", + "Bakes & Cakes", + "Beverages (MTO)", + "F&B", +]; + +const fssai_nos = [ + "brand_owner_FSSAI_license_no", + "other_FSSAI_license_no", + "importer_FSSAI_license_no", +]; + +const cancellation_rid = { + "001": 0, + "002": 0, + "003": 0, + "004": 0, + "005": 0, + "006": 0, + "009": 1, + "010": 1, + "011": 1, + "012": 1, + "013": 1, + "014": 1, + "015": 1, + "016": 0, + "017": 0, + "018": 0, +}; + +const uuidCheck = (data) => { + console.log("***UUID Validation Utils***"); + let uuid = + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + if (!uuid.test(data)) return false; + return true; +}; + +const timestampCheck = (date) => { + //console.log("***Timestamp Check Utils***"); + let dateParsed = new Date(Date.parse(date)); + if (!isNaN(dateParsed)) { + if (dateParsed.toISOString() != date) { + //FORMAT_ERR= Valid date but not in RFC 3339 format + return { err: "FORMAT_ERR" }; + } + } else { + //INVLD_DT= Invalid date-time format + return { err: "INVLD_DT" }; + } +}; + +function compareDates(dateString1, dateString2) { + const date1 = new Date(dateString1); + const date2 = new Date(dateString2); + + const year1 = date1.getUTCFullYear(); + const month1 = date1.getUTCMonth(); + const day1 = date1.getUTCDate(); + + const year2 = date2.getUTCFullYear(); + const month2 = date2.getUTCMonth(); + const day2 = date2.getUTCDate(); + + if ( + year1 > year2 || + (year1 === year2 && month1 > month2) || + (year1 === year2 && month1 === month2 && day1 > day2) + ) { + return true; + } else if ( + year1 < year2 || + (year1 === year2 && month1 < month2) || + (year1 === year2 && month1 === month2 && day1 <= day2) + ) { + return false; + } +} + +const hasTwoOrLessDecimalPlaces = (inputString) => { + const parts = inputString.split("."); + + if (parts.length === 2) { + const decimalPart = parts[1]; + return decimalPart.length <= 2; + } else { + return true; // No decimal part, automatically satisfies the condition + } +}; + +const getObjValues = (obj) => { + let values = ""; + + Object.values(obj).forEach((value) => { + values += `- ${value}\n`; + }); + return values; +}; + +const timeDiff = (time1, time2) => { + const dtime1 = new Date(time1); + const dtime2 = new Date(time2); + + if (isNaN(dtime1 - dtime2)) return 0; + else return dtime1 - dtime2; +}; + +const isArrayEqual = (x, y) => { + flag = _(x).xorWith(y, _.isEqual).isEmpty(); + console.log("FLAG*********", _(x).xorWith(y, _.isEqual).isEmpty()); + return flag; +}; + +const countDecimalDigits = (num) => { + return num.toString().split(".")[1].length; +}; + +const isObjectEqual = (obj1, obj2, parentKey = "") => { + const typeOfObj1 = typeof obj1; + const typeOfObj2 = typeof obj2; + + if (typeOfObj1 !== typeOfObj2) { + return [parentKey]; + } + + if (typeOfObj1 !== "object" || obj1 === null || obj2 === null) { + return obj1 === obj2 ? [] : [parentKey]; + } + + if (Array.isArray(obj1) && Array.isArray(obj2)) { + if (obj1.length !== obj2.length) { + return [parentKey]; + } + + const sortedObj1 = [...obj1].sort(); + const sortedObj2 = [...obj2].sort(); + + for (let i = 0; i < sortedObj1.length; i++) { + const nestedKeys = isObjectEqual( + sortedObj1[i], + sortedObj2[i], + `${parentKey}[${i}]` + ); + if (nestedKeys.length > 0) { + return nestedKeys; + } + } + + return []; + } + + const obj1Keys = Object.keys(obj1); + const obj2Keys = Object.keys(obj2); + + const allKeys = [...new Set([...obj1Keys, ...obj2Keys])]; + + const notEqualKeys = []; + + for (let key of allKeys) { + if (!obj2.hasOwnProperty(key) || !obj1.hasOwnProperty(key)) { + notEqualKeys.push(parentKey ? `${parentKey}/${key}` : key); + continue; + } + + const nestedKeys = isObjectEqual( + obj1[key], + obj2[key], + parentKey ? `${parentKey}/${key}` : key + ); + + if (nestedKeys.length > 0) { + notEqualKeys.push(...nestedKeys); + } + } + + return notEqualKeys; +}; +module.exports = { + uuidCheck, + timestampCheck, + rootPath, + retailAPI, + retailFulfillmentState, + retailOrderState, + logFulfillmentState, + logOrderState, + bpp_fulfillments, + bpp_provider_days, + cancellation_rid, + getObjValues, + isObjectEqual, + retailPaymentType, + retailPymntTtl, + categoriesMap, + compareDates, + hasTwoOrLessDecimalPlaces, + timeDiff, + taxNotInlcusive, + isArrayEqual, + countDecimalDigits, + grocery_categories_id, + fnb_categories_id, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js new file mode 100755 index 0000000..fa00204 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js @@ -0,0 +1,46 @@ +const fs = require("fs"); +const _ = require("lodash"); +const dao = require("../dao/dao"); +const path = require("path"); +const { getObjValues } = require("./utils"); +const {sortMerge} = require("./mergeSort"); +const Validate = require("./schemaVal"); +const clean = require("./clean") + +const validateLogs = (domain, dirPath) => { + + let msgIdSet = new Set(); + let ErrorObj = {}; + + // Sort & Merge the logs + const mergefile = path.join(dirPath, '../merged.json') + ErrorObj["Flow Error"] = sortMerge(domain, dirPath, mergefile); + + // Log Validation + Validate(domain, mergefile, msgIdSet, ErrorObj); + + // Cleaning output report + let log = clean(ErrorObj) + + // Drop DB + try { + console.log("Flushing DB Data"); + dao.dropDB(); + } catch (error) { + console.log("Error while removing LMDB"); + } +try { + // outputfile = `log${flowId}.json` + outputfile= 'log_report.json' + + // let out = getObjValues(ErrorObj['Schema']) +let out = JSON.stringify(ErrorObj,null,4) + fs.writeFileSync(outputfile, out , 'utf-8'); +} catch (error) { + console.log("!!ERROR writing output file",error) +} + + + console.log("Report Generated Successfully!!"); +}; +module.exports = { validateLogs }; \ No newline at end of file From e97e2676d1623cd2e6176da3766c64472f9a070d Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Mon, 18 Sep 2023 21:31:49 +0530 Subject: [PATCH 036/228] Updated Readme --- utilities/logistics-b2b/log-verification-utility/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/README.md b/utilities/logistics-b2b/log-verification-utility/README.md index 3ec03df..f7097a9 100644 --- a/utilities/logistics-b2b/log-verification-utility/README.md +++ b/utilities/logistics-b2b/log-verification-utility/README.md @@ -2,7 +2,7 @@ ### APIs Log Validation tool for Pre-Prod participants -The tool is a NODE.js based utility to check the conformance and compliance of the API logs for [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) based on the examples in the API Contract. +The tool is a NODE.js based utility to check the conformance and compliance of the API logs for [logistics v1.0](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B v2.0.1](https://github.com/ONDC-Official/ONDC-RET-Specifications) based on the examples in the API Contract. ### Tech From 5b20eb8adb6889dc89aecd2d254c3620293755c0 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Mon, 18 Sep 2023 21:41:17 +0530 Subject: [PATCH 037/228] Updated Readme --- .../logistics-b2b/log-verification-utility/README.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/README.md b/utilities/logistics-b2b/log-verification-utility/README.md index f7097a9..1a94dba 100644 --- a/utilities/logistics-b2b/log-verification-utility/README.md +++ b/utilities/logistics-b2b/log-verification-utility/README.md @@ -49,6 +49,8 @@ _Notes:_ > Test cases to be referred here -> [logsitics](https://docs.google.com/document/d/1ttixilM-I6dutEdHL10uzqRFd8RcJlEO_9wBUijtdDc/edit) and [B2B](https://docs.google.com/document/d/10ouiTKLY4dm1KnXCuhFwK38cYd9_aDQ30bklkqnPRkM/edit) +> **Community contributions are welcomed to enhance this utility for future releases.** + > Sample payload for search.json is demonstrated below: ```json @@ -129,8 +131,4 @@ _Notes:_ } } } -``` - -### N.B. - -> - Community contributions are welcomed to enhance this utility for future releases. +``` \ No newline at end of file From 0a68abf17a45c1e96963c0e98eb335fdc7875b00 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Mon, 18 Sep 2023 22:00:17 +0530 Subject: [PATCH 038/228] Custom keyword - validate days --- .../log-verification-utility/.gitignore | 3 +-- .../logistics_api_json_schema/SchemaValidator.js | 13 ++++++++++--- .../logistics_api_json_schema/searchSchema.js | 12 +++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore index 18113cb..5b4e0ec 100755 --- a/utilities/logistics-b2b/log-verification-utility/.gitignore +++ b/utilities/logistics-b2b/log-verification-utility/.gitignore @@ -2,8 +2,7 @@ node_modules package-lock.json *.env .vscode -/public/logs/*.json -/public/* +/public/logs/* verification-logs /utils/*.json /utils/*.txt diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js index df9a194..6130f6a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js @@ -16,7 +16,6 @@ const cancelSchema = require("./cancelSchema"); const supportSchema = require("./supportSchema"); const trackSchema = require("./trackSchema"); const fs = require("fs"); -//const async = require("async"); const path = require("path"); const Ajv = require("ajv"); @@ -30,7 +29,6 @@ const ajv = new Ajv({ }); const addFormats = require("ajv-formats"); -//const masterSchemacopy = require("./masterSchemacopy"); addFormats(ajv); require("ajv-errors")(ajv); @@ -57,6 +55,12 @@ const formatted_error = (errors) => { return error_json; }; +function isEndTimeGreater(data) { + const startTime = parseInt(data.start); + const endTime = parseInt(data.end); + return startTime < endTime +} + const validate_schema = (data, schema) => { let error_list = []; try { @@ -76,7 +80,10 @@ const validate_schema = (data, schema) => { .addSchema(trackSchema) .addSchema(onTrackSchema) .addSchema(cancelSchema) - .addSchema(onCancelSchema); + .addSchema(onCancelSchema) + .addKeyword("isEndTimeGreater", { + validate: (schema, data) => isEndTimeGreater(data) + }); validate = validate.compile(schema); diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js index 987b1e3..696fee6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js @@ -97,6 +97,9 @@ module.exports = { properties: { days: { type: "string", + pattern: "^(?!.*(\\d).*\\1)[1-7](?:,[1-7])*(?![1-7])$", + errorMessage: + "Days format not correct. Ref footnote 9 of 1.1", }, schedule: { type: "object", @@ -116,6 +119,8 @@ module.exports = { type: "array", items: { type: "string", + pattern: "^(?:[01][0-9]|2[0-3])[0-5][0-9]$", + errorMessage: "Must be a valid 24 hour time", }, }, }, @@ -126,11 +131,16 @@ module.exports = { properties: { start: { type: "string", + pattern: "^(?:[01][0-9]|2[0-3])[0-5][0-9]$", }, end: { type: "string", + pattern: "^(?:[01][0-9]|2[0-3])[0-5][0-9]$", }, }, + isEndTimeGreater: true, + errorMessage: 'The "end" time must be greater than the "start" time. Ref footnote 12 of v1.1 .', + required: ["start", "end"], }, }, oneOf: [ @@ -358,4 +368,4 @@ module.exports = { }, required: ["context", "message"], -}; +}; \ No newline at end of file From 5941390b545c843d6758d301b84d1cf2e822e456 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Tue, 19 Sep 2023 13:48:42 +0530 Subject: [PATCH 039/228] Modified return statement --- .../log-verification-utility/services/service.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/services/service.js b/utilities/logistics-b2b/log-verification-utility/services/service.js index 8a67fbb..882ea54 100755 --- a/utilities/logistics-b2b/log-verification-utility/services/service.js +++ b/utilities/logistics-b2b/log-verification-utility/services/service.js @@ -6,9 +6,9 @@ const checkMessage = (domain, element, action, msgIdSet) => { const busnsErr = {}; switch (domain) { case "logistics": - return logisticsVal(element, msgIdSet); + return logisticsVal(element, action, msgIdSet); case "b2b": - return b2bVal(element, msgIdSet); + return b2bVal(element, action, msgIdSet); } return busnsErr; }; From 48c9bb6ae36ade0ab18f58c3491bc932c2f5913f Mon Sep 17 00:00:00 2001 From: AbhijeetONDC <129926794+AbhijeetONDC@users.noreply.github.com> Date: Thu, 21 Sep 2023 10:45:10 +0530 Subject: [PATCH 040/228] feat: ondc crypto sdk nodejs utility added (#31) * feat: ondc crypto sdk nodejs utility added * fix: removed createKeyPair method and unnecessary types * fix: parameters renamed for generic cases --------- Co-authored-by: Abhijeet Singh Rathor --- utilities/.DS_Store | Bin 8196 -> 8196 bytes utilities/ondc-crypto-sdk-nodejs/.gitignore | 2 + utilities/ondc-crypto-sdk-nodejs/.npmignore | 4 + utilities/ondc-crypto-sdk-nodejs/.prettierrc | 5 + utilities/ondc-crypto-sdk-nodejs/README.md | 34 + .../ondc-crypto-sdk-nodejs/package-lock.json | 922 ++++++++++++++++++ utilities/ondc-crypto-sdk-nodejs/package.json | 44 + utilities/ondc-crypto-sdk-nodejs/src/index.ts | 4 + .../ondc-crypto-sdk-nodejs/src/types/index.ts | 48 + .../src/utility/index.ts | 124 +++ .../ondc-crypto-sdk-nodejs/tsconfig.json | 11 + utilities/ondc-crypto-sdk-nodejs/tslint.json | 3 + 12 files changed, 1201 insertions(+) create mode 100644 utilities/ondc-crypto-sdk-nodejs/.gitignore create mode 100644 utilities/ondc-crypto-sdk-nodejs/.npmignore create mode 100644 utilities/ondc-crypto-sdk-nodejs/.prettierrc create mode 100644 utilities/ondc-crypto-sdk-nodejs/README.md create mode 100644 utilities/ondc-crypto-sdk-nodejs/package-lock.json create mode 100644 utilities/ondc-crypto-sdk-nodejs/package.json create mode 100644 utilities/ondc-crypto-sdk-nodejs/src/index.ts create mode 100644 utilities/ondc-crypto-sdk-nodejs/src/types/index.ts create mode 100644 utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts create mode 100644 utilities/ondc-crypto-sdk-nodejs/tsconfig.json create mode 100644 utilities/ondc-crypto-sdk-nodejs/tslint.json diff --git a/utilities/.DS_Store b/utilities/.DS_Store index ca4da9957d2287edaa0c3aed180e9321f631d7f7..1fc751e820bb6232bf82fd6a33a560b7478d5e33 100644 GIT binary patch delta 221 zcmZp1XmOa}&&a(oU^hP__hue}9u{pehJ1!Rh7^Wm23;U7VyI*&U?>5K=`s`pMYDl) z9*~#9kjjuX*-oH|!_3e?N5RmXz)-xoQ^b#HGrPn$mdO_c?FBhF QIXL45B&w?^Hr1O60Jpv|m;e9( delta 42 ycmZp1XmOa}&&atkU^hP_=Vl&(9+u4~MD3Y2HW)B&W|#QJvRPN`7URYST}A*Yat+l0 diff --git a/utilities/ondc-crypto-sdk-nodejs/.gitignore b/utilities/ondc-crypto-sdk-nodejs/.gitignore new file mode 100644 index 0000000..69a671c --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/.gitignore @@ -0,0 +1,2 @@ +node_modules +/lib \ No newline at end of file diff --git a/utilities/ondc-crypto-sdk-nodejs/.npmignore b/utilities/ondc-crypto-sdk-nodejs/.npmignore new file mode 100644 index 0000000..9f4e4c1 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/.npmignore @@ -0,0 +1,4 @@ +/src +/tsconfig.json +/tslint.json +/.prettierrc \ No newline at end of file diff --git a/utilities/ondc-crypto-sdk-nodejs/.prettierrc b/utilities/ondc-crypto-sdk-nodejs/.prettierrc new file mode 100644 index 0000000..a0d1c9a --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 120, + "trailingComma": "all", + "singleQuote": true +} diff --git a/utilities/ondc-crypto-sdk-nodejs/README.md b/utilities/ondc-crypto-sdk-nodejs/README.md new file mode 100644 index 0000000..6444d4b --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/README.md @@ -0,0 +1,34 @@ +A signing and verification utility that is necessary for creation and verification of authentication signature between network participants of ONDC. + +## Signing Authorisation Header + +For signing the verification header, you can use the `createAuthorizationHeader` method. + +```javascript +import { createAuthorizationHeader } from "ondc-crypto-sdk-nodejs" + +const header = await createAuthorizationHeader({ + body: { context: {...}, message: {...} }, + privateKey: privateKey, + subscriberId: "...", // Subscriber ID that you get after registering to ONDC Network + subscriberUniqueKeyId: "584", // Unique Key Id or uKid that you get after registering to ONDC Network + }); +``` + +The method returns a set a unique signature that is ONDC-compliant and can be verified across NPs by looking up your public key from the registry. + +## Verifying Authorisation Header + +For verifying the verification header, you can use the `isSignatureValid` method. + +```javascript +import { isSignatureValid } from "ondc-crypto-sdk-nodejs" + +const isValid = await isSignatureValid({ + header: header, // The Authorisation header sent by other network participants + body: { context: {...}, message: {...} }, + publicKey: publicKey, +}); +``` + +The method returns a boolean value whether the signature is valid or not. diff --git a/utilities/ondc-crypto-sdk-nodejs/package-lock.json b/utilities/ondc-crypto-sdk-nodejs/package-lock.json new file mode 100644 index 0000000..5843a60 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/package-lock.json @@ -0,0 +1,922 @@ +{ + "name": "ondc-crypto-sdk-nodejs", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "ondc-crypto-sdk-nodejs", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "libsodium-wrappers": "^0.7.11", + "lodash": "^4.17.21", + "uuid": "^9.0.0" + }, + "devDependencies": { + "@types/libsodium-wrappers": "^0.7.10", + "@types/lodash": "^4.14.195", + "@types/uuid": "^9.0.2", + "prettier": "^2.8.8", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^5.1.3" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@types/libsodium-wrappers": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz", + "integrity": "sha512-BqI9B92u+cM3ccp8mpHf+HzJ8fBlRwdmyd6+fz3p99m3V6ifT5O3zmOMi612PGkpeFeG/G6loxUnzlDNhfjPSA==", + "dev": true + }, + "node_modules/@types/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, + "node_modules/@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/libsodium": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.11.tgz", + "integrity": "sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A==" + }, + "node_modules/libsodium-wrappers": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz", + "integrity": "sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q==", + "dependencies": { + "libsodium": "^0.7.11" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "dependencies": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "deprecated": "TSLint has been deprecated in favor of ESLint. Please see https://github.com/palantir/tslint/issues/4534 for more information.", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev || >= 4.0.0-dev" + } + }, + "node_modules/tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true, + "bin": { + "tslint-config-prettier-check": "bin/check.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/typescript": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", + "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.5.tgz", + "integrity": "sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", + "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "dev": true + }, + "@babel/highlight": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.5.tgz", + "integrity": "sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@types/libsodium-wrappers": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@types/libsodium-wrappers/-/libsodium-wrappers-0.7.10.tgz", + "integrity": "sha512-BqI9B92u+cM3ccp8mpHf+HzJ8fBlRwdmyd6+fz3p99m3V6ifT5O3zmOMi612PGkpeFeG/G6loxUnzlDNhfjPSA==", + "dev": true + }, + "@types/lodash": { + "version": "4.14.195", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz", + "integrity": "sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg==", + "dev": true + }, + "@types/uuid": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.2.tgz", + "integrity": "sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz", + "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "libsodium": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/libsodium/-/libsodium-0.7.11.tgz", + "integrity": "sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A==" + }, + "libsodium-wrappers": { + "version": "0.7.11", + "resolved": "https://registry.npmjs.org/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz", + "integrity": "sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q==", + "requires": { + "libsodium": "^0.7.11" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true + }, + "resolve": { + "version": "1.22.2", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz", + "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==", + "dev": true, + "requires": { + "is-core-module": "^2.11.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "typescript": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", + "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "dev": true + }, + "uuid": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + } + } +} diff --git a/utilities/ondc-crypto-sdk-nodejs/package.json b/utilities/ondc-crypto-sdk-nodejs/package.json new file mode 100644 index 0000000..94cf7f8 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/package.json @@ -0,0 +1,44 @@ +{ + "name": "ondc-crypto-sdk-nodejs", + "version": "1.0.1", + "description": "A crypto utility for exposing signing and verification functions by ONDC", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "tsc", + "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", + "lint": "tslint -p tsconfig.json", + "prepare": "npm run build", + "prepublishOnly": "npm run lint", + "preversion": "npm run lint", + "version": "npm run format && git add -A src", + "postversion": "git push && git push --tags" + }, + "keywords": [ + "ondc", + "signing", + "verification", + "utility", + "crypto" + ], + "author": "Abhijeet Singh Rathor", + "license": "ISC", + "devDependencies": { + "@types/libsodium-wrappers": "^0.7.10", + "@types/lodash": "^4.14.195", + "@types/uuid": "^9.0.2", + "prettier": "^2.8.8", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^5.1.3" + }, + "files": [ + "lib/**/*" + ], + "dependencies": { + "libsodium-wrappers": "^0.7.11", + "lodash": "^4.17.21", + "uuid": "^9.0.0" + } +} diff --git a/utilities/ondc-crypto-sdk-nodejs/src/index.ts b/utilities/ondc-crypto-sdk-nodejs/src/index.ts new file mode 100644 index 0000000..3dc0be0 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/src/index.ts @@ -0,0 +1,4 @@ +import { createAuthorizationHeader, isSignatureValid } from './utility'; +import { ICreateAuthorizationHeader, IsSignatureValid } from './types'; + +export { createAuthorizationHeader, isSignatureValid, ICreateAuthorizationHeader, IsSignatureValid }; diff --git a/utilities/ondc-crypto-sdk-nodejs/src/types/index.ts b/utilities/ondc-crypto-sdk-nodejs/src/types/index.ts new file mode 100644 index 0000000..eee5c29 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/src/types/index.ts @@ -0,0 +1,48 @@ +export interface ICreateSigningString { + message: string; + created?: string; + expires?: string; +} + +export interface ISignMessage { + signingString: string; + privateKey: string; +} + +export interface GenericObject { + [key: string]: any; +} + +export interface IVerifyMessage { + signedString: string; + signingString: string; + publicKey: string; +} + +export interface IHeaderParts { + expires: string; + created: string; + keyId: string; + signature: string; + [key: string]: any; +} + +export interface IVerifyHeader { + headerParts: IHeaderParts; + body: string; + publicKey: string; +} + +export interface IsSignatureValid { + header: string; + body: any; + publicKey: string; +} +export interface ICreateAuthorizationHeader { + message: GenericObject; + privateKey: string; + bapId: string; + bapUniqueKeyId: string; + expires?: string; + created?: string; +} diff --git a/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts b/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts new file mode 100644 index 0000000..776f996 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts @@ -0,0 +1,124 @@ +import * as _sodium from 'libsodium-wrappers'; +import * as _ from 'lodash'; +import { + GenericObject, + ICreateAuthorizationHeader, + ICreateSigningString, + IHeaderParts, + ISignMessage, + IVerifyHeader, + IVerifyMessage, + IsSignatureValid, +} from '../types'; + +export const createSigningString = async ({ message, created, expires }: ICreateSigningString) => { + if (!created) created = Math.floor(new Date().getTime() / 1000).toString(); + if (!expires) expires = (parseInt(created, 10) + 1 * 60 * 60).toString(); + + await _sodium.ready; + + const sodium = _sodium; + const digest = sodium.crypto_generichash(64, sodium.from_string(message)); + const digestBase64 = sodium.to_base64(digest, _sodium.base64_variants.ORIGINAL); + + const signingString = `(created): ${created} +(expires): ${expires} +digest: BLAKE-512=${digestBase64}`; + + return { signingString, created, expires }; +}; + +export const signMessage = async ({ signingString, privateKey }: ISignMessage) => { + await _sodium.ready; + const sodium = _sodium; + + const signedMessage = sodium.crypto_sign_detached( + signingString, + sodium.from_base64(privateKey, _sodium.base64_variants.ORIGINAL), + ); + return sodium.to_base64(signedMessage, _sodium.base64_variants.ORIGINAL); +}; + +export const createAuthorizationHeader = async ({ + body, + privateKey, + subscriberId, + subscriberUniqueKeyId, + expires, + created, +}: ICreateAuthorizationHeader) => { + const { + signingString, + expires: expiresT, + created: createdT, + } = await createSigningString({ + message: JSON.stringify(body), + created, + expires, + }); + + const signature = await signMessage({ signingString, privateKey }); + + const header = `Signature keyId="${subscriberId}|${subscriberUniqueKeyId}|ed25519",algorithm="ed25519",created="${createdT}",expires="${expiresT}",headers="(created) (expires) digest",signature="${signature}"`; + return header; +}; + +const removeQuotes = (a: string) => { + return a.replace(/^["'](.+(?=["']$))["']$/, '$1'); +}; + +const splitAuthHeader = (authHeader: string): GenericObject | IHeaderParts => { + const header = authHeader.replace('Signature ', ''); + const re = /\s*([^=]+)=([^,]+)[,]?/g; + let m: any; + const parts: GenericObject = {}; + /* tslint:disable-next-line */ + while ((m = re.exec(header)) !== null) { + if (m) { + parts[m[1]] = removeQuotes(m[2]); + } + } + return parts; +}; + +const verifyMessage = async ({ signedString, signingString, publicKey }: IVerifyMessage) => { + try { + await _sodium.ready; + const sodium = _sodium; + return sodium.crypto_sign_verify_detached( + sodium.from_base64(signedString, _sodium.base64_variants.ORIGINAL), + signingString, + sodium.from_base64(publicKey, _sodium.base64_variants.ORIGINAL), + ); + } catch (error) { + return false; + } +}; + +const verifyHeader = async ({ headerParts, body, publicKey }: IVerifyHeader) => { + const { signingString } = await createSigningString({ + message: JSON.stringify(body), + created: headerParts?.created, + expires: headerParts?.expires, + }); + const verified = await verifyMessage({ + signedString: headerParts?.signature, + signingString, + publicKey, + }); + return verified; +}; + +export const isSignatureValid = async ({ header, body, publicKey }: IsSignatureValid) => { + try { + const headerParts = splitAuthHeader(header); + const keyIdSplit = headerParts?.keyId?.split('|'); + const subscriberId = keyIdSplit[0]; + const keyId = keyIdSplit[1]; + + const isValid = await verifyHeader({ headerParts: headerParts as IHeaderParts, body, publicKey }); + return isValid; + } catch (e) { + return false; + } +}; diff --git a/utilities/ondc-crypto-sdk-nodejs/tsconfig.json b/utilities/ondc-crypto-sdk-nodejs/tsconfig.json new file mode 100644 index 0000000..ca4bf6a --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "declaration": true, + "outDir": "./lib", + "strict": true + }, + "include": ["src"], + "exclude": ["node_modules", "**/__tests__/*"] +} diff --git a/utilities/ondc-crypto-sdk-nodejs/tslint.json b/utilities/ondc-crypto-sdk-nodejs/tslint.json new file mode 100644 index 0000000..267f369 --- /dev/null +++ b/utilities/ondc-crypto-sdk-nodejs/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["tslint:recommended", "tslint-config-prettier"] +} From 7d44b6d50a77c1f50799658c9545cd75b24498ff Mon Sep 17 00:00:00 2001 From: nitinmish Date: Sat, 23 Sep 2023 18:23:00 +0530 Subject: [PATCH 041/228] Fixing Padding issue --- .../signing_and_verification/cryptic_utils.py | 7 +- .../signing_and_verification/cryptkey.py | 49 ++++++++++++ utilities/signing_and_verification/scratch.py | 75 +++++++++++++++++++ 3 files changed, 128 insertions(+), 3 deletions(-) create mode 100644 utilities/signing_and_verification/cryptkey.py create mode 100644 utilities/signing_and_verification/scratch.py diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py index c9105f4..651824e 100644 --- a/utilities/signing_and_verification/cryptic_utils.py +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -120,7 +120,7 @@ def generate_key_pairs(): "Crypto_Privatekey": crypto_private_key, "Crypto_Publickey": crypto_public_key} -def encrypt(crypto_private_key, crypto_public_key): +def encrypt(crypto_private_key, crypto_public_key, null): private_key = serialization.load_der_private_key( base64.b64decode(crypto_private_key), password=None @@ -130,7 +130,7 @@ def encrypt(crypto_private_key, crypto_public_key): ) shared_key = private_key.exchange(public_key) cipher = AES.new(shared_key, AES.MODE_ECB) - text = b'ONDC is a Great Initiative!' + text = b'ONDC is a Great Initiative!!' return base64.b64encode(cipher.encrypt(pad(text,AES.block_size))).decode('utf-8') def decrypt(crypto_private_key, crypto_public_key, cipherstring): @@ -144,7 +144,8 @@ def decrypt(crypto_private_key, crypto_public_key, cipherstring): shared_key = private_key.exchange(public_key) cipher = AES.new(shared_key, AES.MODE_ECB) ciphertxt = base64.b64decode(cipherstring) - return cipher.decrypt(ciphertxt).decode('utf-8') + # print(AES.block_size, len(ciphertxt)) + return unpad(cipher.decrypt(ciphertxt), AES.block_size).decode('utf-8') if __name__ == '__main__': fire.Fire() diff --git a/utilities/signing_and_verification/cryptkey.py b/utilities/signing_and_verification/cryptkey.py new file mode 100644 index 0000000..25b5529 --- /dev/null +++ b/utilities/signing_and_verification/cryptkey.py @@ -0,0 +1,49 @@ + +from cryptography.hazmat.primitives import serialization +import base64 +from Cryptodome.Cipher import AES +from Cryptodome.Util.Padding import pad,unpad + +pkey = serialization.load_der_private_key( + base64.b64decode("MC4CAQAwBQYDK2VuBCIEIKh1Dq7Fu82lqQdBQJTHTvBTxtD6hLconopqvVLVy81s"), + password=None +) + +ukey=pkey.public_key() +encstr = base64.b64decode("TaaRFx6fxSbFJO2Lp9Kbap1rZTjAAveAeASr19G7iXI8Meaz6Ok6B4C709pC3GpR".encode('utf-8')) + +uenkey = ukey.public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo +) + +penkey = pkey.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() +) + +print("Local Private Key: ", base64.b64encode(penkey).decode('utf-8')) +print("Local Public Key: ", base64.b64encode(uenkey).decode('utf-8')) +print("ONDC Public Key: ", "MCowBQYDK2VuAyEAa9Wbpvd9SsrpOZFcynyt/TO3x0Yrqyys4NUGIvyxX2Q=") + +myukey = base64.b64encode(uenkey).decode('utf-8') + +ondcpub = (base64.b64decode( + "MCowBQYDK2VuAyEAa9Wbpvd9SsrpOZFcynyt/TO3x0Yrqyys4NUGIvyxX2Q=")) +oenkey = serialization.load_der_public_key(ondcpub) + +shared_key = pkey.exchange(oenkey) +print("Shared Secret: ", base64.b64encode(shared_key).decode('utf-8')) + +# print("Derived Secret: ", base64.b64encode(key).decode('utf-8')) + + +cipher = AES.new(shared_key,AES.MODE_ECB) +dec = cipher.decrypt(encstr) +enc = cipher.encrypt(pad(b'ABCDEFGH', AES.block_size)) +print(dec.decode('utf-8')) +print(base64.b64encode(enc).decode('utf-8')) +estr=cipher.encrypt(pad(b'ABCDEFGH', AES.block_size)) +dstr=cipher.decrypt(estr) +print(unpad(dstr, AES.block_size).decode('utf-8')) \ No newline at end of file diff --git a/utilities/signing_and_verification/scratch.py b/utilities/signing_and_verification/scratch.py new file mode 100644 index 0000000..a3a19d4 --- /dev/null +++ b/utilities/signing_and_verification/scratch.py @@ -0,0 +1,75 @@ + +import json +from cryptography.hazmat.primitives import serialization +import base64 +from Cryptodome.Cipher import AES +from Cryptodome import Random + +rand_gen = Random.new() + +pkey = serialization.load_der_private_key( + base64.b64decode("MC4CAQAwBQYDK2VuBCIEIFl3LqvTWbbT9ws+ZMseya8qdR4H7E4YmBLapKPiRGEc"), + password=None +) + +ukey=pkey.public_key() + +uenkey = ukey.public_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PublicFormat.SubjectPublicKeyInfo +) + +penkey = pkey.private_bytes( + encoding=serialization.Encoding.DER, + format=serialization.PrivateFormat.PKCS8, + encryption_algorithm=serialization.NoEncryption() +) + +print("Local Private Key: ", base64.b64encode(penkey).decode('utf-8')) +print("Local Public Key: ", base64.b64encode(uenkey).decode('utf-8')) +print("ONDC Public Key: ", "MCowBQYDK2VuAyEAa9Wbpvd9SsrpOZFcynyt/TO3x0Yrqyys4NUGIvyxX2Q=") + +myukey = base64.b64encode(uenkey).decode('utf-8') +#"MCowBQYDK2VuAyEAa9Wbpvd9SsrpOZFcynyt/TO3x0Yrqyys4NUGIvyxX2Q=") +ondcpub = (base64.b64decode( + "MCowBQYDK2VuAyEAF2efvGvniY1X7mVwjK+9z17pcrM+hnEYNUKiiUVSuyY=" + ) +) + +oenkey = serialization.load_der_public_key(ondcpub) + +shared_key = pkey.exchange(oenkey) +print("Shared Secret: ", base64.b64encode(shared_key).decode('utf-8')) + +cipher = AES.new(shared_key,AES.MODE_GCM) + +nonce = cipher.nonce + +text = b'aef26da5-12f3-4e95-8bfb-e3398489c4c4' + +cstr,authTag = cipher.encrypt_and_digest(text) + + +ciphdict = { + "cipher": base64.b64encode(cstr).decode('utf-8'), + "hmac": base64.b64encode(authTag).decode('utf-8'), + "nonce": base64.b64encode(nonce).decode('utf-8') +} + +ciphjson = json.dumps(ciphdict, sort_keys=True, indent=2) +print(ciphjson.encode('utf-8').decode('utf-8')) + + +encstr = base64.b64encode(ciphjson.encode('utf-8')).decode('utf-8') +print(encstr) + +decstr = json.loads(base64.b64decode(encstr)) + +cipher1 = AES.new(shared_key,AES.MODE_GCM,nonce=base64.b64decode(decstr["nonce"])) + +dec = cipher1.decrypt_and_verify(base64.b64decode(decstr["cipher"]),base64.b64decode(decstr["hmac"])) + +print("Decrypted Text:", dec.decode('utf-8')) + + + From 539c6ee6d1f9063b65183f27ed2fcccda28befee Mon Sep 17 00:00:00 2001 From: Sahil Sharma <123928721+sahilsharma9@users.noreply.github.com> Date: Mon, 9 Oct 2023 16:59:01 +0530 Subject: [PATCH 042/228] feat(subscribe): added nodejs subscribe utility --- utilities/on_subscibe-service/node/index.js | 99 +++++++++++++++++++ utilities/on_subscibe-service/node/readme.md | 12 +++ .../{ => python}/Readme.md | 0 .../{ => python}/requirements.txt | 0 .../{ => python}/server.py | 0 5 files changed, 111 insertions(+) create mode 100644 utilities/on_subscibe-service/node/index.js create mode 100644 utilities/on_subscibe-service/node/readme.md rename utilities/on_subscibe-service/{ => python}/Readme.md (100%) rename utilities/on_subscibe-service/{ => python}/requirements.txt (100%) rename utilities/on_subscibe-service/{ => python}/server.py (100%) diff --git a/utilities/on_subscibe-service/node/index.js b/utilities/on_subscibe-service/node/index.js new file mode 100644 index 0000000..5b98381 --- /dev/null +++ b/utilities/on_subscibe-service/node/index.js @@ -0,0 +1,99 @@ +// Import required modules +const express = require('express'); // Express framework for handling HTTP requests +const bodyParser = require('body-parser'); // Middleware for parsing request bodies +const crypto = require('crypto'); // Node.js crypto module for encryption and decryption +const _sodium = require('libsodium-wrappers'); + +const port = 3000; // Port on which the server will listen +const PRIVATE_KEY_1 = + 'MC4CAQEwBQYDK2VuBCIEILgcht9h660ZeO36tG+QuHGNcLN9JuAzxHWZl09f57Bh'; +const PUBLIC_KEY_1 = + 'MCowBQYDK2VuAyEAlKHWJWiEiHFGlAJ6TE4VMGaeQUYg5DHEpuQdiq6flnQ='; +const REQUEST_ID = '6a6abf53-674f-4d6d-a52b-62e3fda55e04'; +const SIGNING_PRIVATE_KEY = + '7M2L3q9y5gS/dq21Ly3Y3VtYEwgmGM1tM4n0wce/WgcJcOzvdfKo+AUEulIyQCawS39dc6uicu8NAaEpciPajg=='; + +const htmlFile = ` + + + + + + + + ONDC Site Verification Page + + +`; +// Pre-defined public and private keys +const privateKey = crypto.createPrivateKey({ + key: Buffer.from(PRIVATE_KEY_1, 'base64'), // Decode private key from base64 + format: 'der', // Specify the key format as DER + type: 'pkcs8', // Specify the key type as PKCS#8 +}); +const publicKey = crypto.createPublicKey({ + key: Buffer.from(PUBLIC_KEY_1, 'base64'), // Decode public key from base64 + format: 'der', // Specify the key format as DER + type: 'spki', // Specify the key type as SubjectPublicKeyInfo (SPKI) +}); + +// Calculate the shared secret key using Diffie-Hellman +const sharedKey = crypto.diffieHellman({ + privateKey: privateKey, + publicKey: publicKey, +}); + +// Create an Express application +const app = express(); +app.use(bodyParser.json()); // Middleware to parse JSON request bodies + +// Route for handling subscription requests +app.post('/on_subscribe', function (req, res) { + const { challenge } = req.body; // Extract the 'challenge' property from the request body + const answer = decryptAES256ECB(sharedKey, challenge); // Decrypt the challenge using AES-256-ECB + const resp = { answer: answer }; + res.status(200).json(resp); // Send a JSON response with the answer +}); + +// Route for serving a verification file +app.get('/ondc-site-verification.html', async (req, res) => { + const signedContent = await signMessage(REQUEST_ID, SIGNING_PRIVATE_KEY); + // Replace the placeholder with the actual value + const modifiedHTML = htmlFile.replace(/SIGNED_UNIQUE_REQ_ID/g, signedContent); + // Send the modified HTML as the response + res.send(modifiedHTML); +}); + +// Default route +app.get('/', (req, res) => res.send('Hello World!')); + +// Health check route +app.get('/health', (req, res) => res.send('Health OK!!')); + +app.listen(port, () => console.log(`Example app listening on port ${port}!`)); + +// Decrypt using AES-256-ECB +function decryptAES256ECB(key, encrypted) { + const iv = Buffer.alloc(0); // ECB doesn't use IV + const decipher = crypto.createDecipheriv('aes-256-ecb', key, iv); + let decrypted = decipher.update(encrypted, 'base64', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; +} + +async function signMessage(signingString, privateKey) { + await _sodium.ready; + const sodium = _sodium; + const signedMessage = sodium.crypto_sign_detached( + signingString, + sodium.from_base64(privateKey, _sodium.base64_variants.ORIGINAL) + ); + const signature = sodium.to_base64( + signedMessage, + _sodium.base64_variants.ORIGINAL + ); + return signature; +} diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md new file mode 100644 index 0000000..fa8bf22 --- /dev/null +++ b/utilities/on_subscibe-service/node/readme.md @@ -0,0 +1,12 @@ +# Subscribing to ONDC Registry + +1. Add following constants like below. + +``` +- PRIVATE_KEY_1 = "encrypted private key" +- PUBLIC_KEY_1 = "encrypted public key" +- REQUEST_ID = "request_id which needs to be send in /subscribe" +- SIGNING_PRIVATE_KEY = "signing private key" +``` + +2. Place the index.js file code into your main file, and this utility will host the on_subscribe endpoint as well as html file. diff --git a/utilities/on_subscibe-service/Readme.md b/utilities/on_subscibe-service/python/Readme.md similarity index 100% rename from utilities/on_subscibe-service/Readme.md rename to utilities/on_subscibe-service/python/Readme.md diff --git a/utilities/on_subscibe-service/requirements.txt b/utilities/on_subscibe-service/python/requirements.txt similarity index 100% rename from utilities/on_subscibe-service/requirements.txt rename to utilities/on_subscibe-service/python/requirements.txt diff --git a/utilities/on_subscibe-service/server.py b/utilities/on_subscibe-service/python/server.py similarity index 100% rename from utilities/on_subscibe-service/server.py rename to utilities/on_subscibe-service/python/server.py From 720a096b9a3972906af86a5528558e89d4cde3e7 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 13 Oct 2023 12:13:32 +0530 Subject: [PATCH 043/228] Deep Links --- utilities/deep-links/qr_generate.py | 48 ++++++++++++++++++++++++++ utilities/deep-links/readme.md | 52 +++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100755 utilities/deep-links/qr_generate.py create mode 100644 utilities/deep-links/readme.md diff --git a/utilities/deep-links/qr_generate.py b/utilities/deep-links/qr_generate.py new file mode 100755 index 0000000..ebcb52a --- /dev/null +++ b/utilities/deep-links/qr_generate.py @@ -0,0 +1,48 @@ +import qrcode +import json +import sys + +BASE_URL = "beckn://ondc" + +DEFAULT_PARAMS = { + "context.action": "search" +} + +# Generate deep link +def generate_deep_link(**kwargs): + params = DEFAULT_PARAMS.copy() + params.update(kwargs) + query_string = '&'.join([f"{k}={v}" for k, v in params.items()]) + return f"{BASE_URL}?{query_string}" + +# Generate QR code with deep link embedded + +def generate_qr_code(deep_link, file_name="qr_code.png"): + """ + Generate a QR code from a given deep link. + + Parameters: + - deep_link (str): The deep link to encode in the QR code. + - file_name (str): The name of the file to save the QR code image. Default is "qr_code.png". + + Returns: + - None + """ + qr = qrcode.QRCode( + version=1, + error_correction=qrcode.constants.ERROR_CORRECT_L, + box_size=10, + border=4, + ) + qr.add_data(deep_link) + qr.make(fit=True) + + img = qr.make_image(fill_color="black", back_color="white") + img.save(file_name) + + +query_string=json.loads(sys.argv[1]) +deep_link = generate_deep_link(**query_string) + +# Example usage: +generate_qr_code(deep_link) \ No newline at end of file diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md new file mode 100644 index 0000000..efb87e3 --- /dev/null +++ b/utilities/deep-links/readme.md @@ -0,0 +1,52 @@ +# Beckn Enabled Deep Links + +To facilitate seamless and standardized user interactions across digital ecosystems on ONDC, it is crucial to create a universally recognized and standardized "beckn" URI scheme, similar to what Unified Payments Interface (UPI), and WhatsApp, has achieved for major platforms like Web, Android and iOS, thus enhancing deep linking capabilities for entities using the Beckn protocol. Furthermore, the scheme should have easy integration and accessibility through software languages like Java, Python, among others. + +As the first use case, ONDC proposes to enable QR code (with deep link embedded) features for merchants facilitated by their respective BPPs (Seller Apps in this context). + +Please refer to the detailed [concept note](https://docs.google.com/document/d/17H8gpY1U2dRiZE6DccWYRh__BuVQ2kiMxEw5ZFJ7ULo/edit) on beckn enabled deep links, which details on the deep link schema and example use cases that could be enabled. + +## Steps for generating QR code: + +### Install dependencies: + +``` +pip3 install qrcode +``` + +### Generate query string based on the use case: + +**For the use cases:** + +#### Catalog Access through Seller-Generated QR Codes + +``` +query_string = { + "context.bpp_id": "webapi.magicpin.in", + "message.intent.provider.id": "P1", + "context.domain": "nic2004:52110" + } +``` + +#### Category-Specific Browsing via Seller-Generated QR Codes + +``` +query_string = { + "context.bpp_id": "sellerapp.com", + "message.intent.provider.id": "P1", + "context.domain": "RET10", + "message.intent.category.id": "Foodgrains" + } +``` + +#### And so on for the rest of the use cases... + +### Run this utility + +``` +python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' +``` + +## Buyer App Platform Integration + +Different platforms have different handling mechanisms, for example, Android uses Intent Filters and iOS uses URL schemes or Universal links to identify which apps can handle which URI schemes or use fallback URLs to redirect the consumer to a fallback web URL, usually prompting them to download the relevant app. If multiple apps have registered the same URI scheme, it will either redirect to the default app or prompt the user to select the app they would like to use. Please refer [detailed guide](https://docs.google.com/document/d/1pmwQvF9G37_KwcFViub7m_qYDUjbGLrwvgkv1XZEc08/edit?usp=sharing) on implementation. \ No newline at end of file From a08451a642516115a845a9473c4c35fde526eefb Mon Sep 17 00:00:00 2001 From: Sumitkumar0503 <144911525+Sumitkumar0503@users.noreply.github.com> Date: Tue, 17 Oct 2023 12:04:17 +0530 Subject: [PATCH 044/228] Update readme.md Updated. --- utilities/on_subscibe-service/node/readme.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index fa8bf22..baec16c 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -3,10 +3,10 @@ 1. Add following constants like below. ``` -- PRIVATE_KEY_1 = "encrypted private key" -- PUBLIC_KEY_1 = "encrypted public key" -- REQUEST_ID = "request_id which needs to be send in /subscribe" -- SIGNING_PRIVATE_KEY = "signing private key" +- PRIVATE_KEY_1 = "NP's encryption private key" +- PUBLIC_KEY_1 = "Registry's encryption public key" +- REQUEST_ID = "request_id which is sent in /subscribe" +- SIGNING_PRIVATE_KEY = "NP's signing private key" ``` 2. Place the index.js file code into your main file, and this utility will host the on_subscribe endpoint as well as html file. From 3e504cb1f398f12f3f5550f328f8d807831a7c96 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Thu, 19 Oct 2023 18:30:10 +0530 Subject: [PATCH 045/228] Android manifest --- .../deep-links/android/AndroidManifest.xml | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 utilities/deep-links/android/AndroidManifest.xml diff --git a/utilities/deep-links/android/AndroidManifest.xml b/utilities/deep-links/android/AndroidManifest.xml new file mode 100644 index 0000000..9283e42 --- /dev/null +++ b/utilities/deep-links/android/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From c952867431b5952ca9125039fa1400ef1415ac40 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Wed, 25 Oct 2023 12:07:34 +0530 Subject: [PATCH 046/228] Updated log utility with Reverse geo coding & log server --- .../log-verification-utility/.gitignore | 0 .../log-verification-utility/README.md | 83 +- .../log-verification-utility/index.js | 6 +- .../log-verification-utility/package.json | 14 +- .../log-verification-utility/routes/routes.js | 25 - .../schema/B2B_json_schema/init.js | 2 +- .../schema/B2B_json_schema/on_confirm.js | 2 +- .../schema/B2B_json_schema/on_init.js | 6 +- .../schema/B2B_json_schema/schemaValidator.js | 55 +- .../SchemaValidator.js | 113 +- .../masterSchemacopy.js | 12 - .../{ => v1.1}/cancelSchema.js | 0 .../{ => v1.1}/confirmSchema.js | 34 +- .../{ => v1.1}/initSchema.js | 45 +- .../{ => v1.1}/masterSchema.js | 0 .../{ => v1.1}/onCancelSchema.js | 0 .../{ => v1.1}/onConfirmSchema.js | 22 +- .../{ => v1.1}/onInitSchema.js | 32 +- .../{ => v1.1}/onSearchSchema.js | 2 - .../{ => v1.1}/onStatusSchema.js | 51 +- .../{ => v1.1}/onSupportSchema.js | 12 - .../{ => v1.1}/onTrackSchema.js | 0 .../{ => v1.1}/onUpdateSchema.js | 77 +- .../{ => v1.1}/searchSchema.js | 13 +- .../{ => v1.1}/statusSchema.js | 0 .../{ => v1.1}/supportSchema.js | 0 .../{ => v1.1}/trackSchema.js | 0 .../{ => v1.1}/updateSchema.js | 8 +- .../v1.2}/cancelSchema.js | 180 +-- .../v1.2/common/commonSchema.js | 88 ++ .../v1.2/confirmSchema.js | 1021 +++++++++++++++++ .../v1.2/initSchema.js} | 964 ++++++++-------- .../v1.2/keywords/confirm.js | 14 + .../v1.2/keywords/init.js | 7 + .../v1.2/keywords/onInit.js | 12 + .../v1.2/keywords/search.js | 7 + .../v1.2/masterSchema.js | 103 ++ .../v1.2/onCancelSchema.js | 700 +++++++++++ .../v1.2/onConfirmSchema.js | 826 +++++++++++++ .../v1.2/onInitSchema.js | 457 ++++++++ .../v1.2/onSearchSchema.js | 365 ++++++ .../v1.2/onStatusSchema.js | 773 +++++++++++++ .../v1.2/onSupportSchema.js | 99 ++ .../v1.2/onTrackSchema.js | 160 +++ .../v1.2/onUpdateSchema.js | 421 +++++++ .../v1.2/searchSchema.js | 351 ++++++ .../v1.2}/statusSchema.js | 173 +-- .../v1.2/supportSchema.js | 86 ++ .../v1.2/trackSchema.js | 93 ++ .../v1.2/updateSchema.js | 285 +++++ .../log-verification-utility/schema/main.js | 21 +- .../retail_api_json_schema/SchemaValidator.js | 174 --- .../retail_api_json_schema/initSchema.js | 273 ----- .../retail_api_json_schema/onCancelSchema.js | 19 - .../retail_api_json_schema/onConfirmSchema.js | 473 -------- .../retail_api_json_schema/onInitSchema.js | 322 ------ .../onSearchBPCSchema.js | 610 ---------- .../onSearchGrocerySchema.js | 490 -------- .../onSearchItemValidations.js | 201 ---- .../retail_api_json_schema/onSearchSchema.js | 583 ---------- .../onSearchfashionSchema.js | 490 -------- .../retail_api_json_schema/onSelectSchema.js | 175 --- .../retail_api_json_schema/onStatusSchema.js | 548 --------- .../retail_api_json_schema/onSupportSchema.js | 14 - .../retail_api_json_schema/onTrackSchema.js | 13 - .../retail_api_json_schema/onUpdateSchema.js | 486 -------- .../retail_api_json_schema/searchSchema.js | 140 --- .../retail_api_json_schema/selectSchema.js | 170 --- .../retail_api_json_schema/updateSchema.js | 201 ---- .../server/routes/routes.js | 48 + .../log-verification-utility/server/server.js | 12 + .../server/utils/fileHandler.js | 51 + .../services/cbCheck.service.js | 4 +- .../services/service.js | 2 +- .../utils/ContextVal.js | 49 +- .../b2b/b2bConfirm.js} | 0 .../utils/b2b/b2bOnConfirm.js | 0 .../utils/b2b/b2bOnInit.js | 0 .../utils/b2b/b2bOnUpdate.js | 0 .../utils/b2b/b2bSelect.js | 0 .../utils/b2b/b2bUpdate.js | 0 .../utils/b2b/msgValidator.js | 24 + .../utils/constants.js | 171 ++- .../utils/logistics/csvToJson.js | 23 + .../utils/logistics/logConfirm.js | 81 +- .../utils/logistics/logInit.js | 19 +- .../utils/logistics/logOnCancel.js | 91 ++ .../utils/logistics/logOnConfirm.js | 8 +- .../utils/logistics/logOnInit.js | 25 +- .../utils/logistics/logOnSearch.js | 79 +- .../utils/logistics/logOnStatus.js | 55 +- .../utils/logistics/logOnUpdate.js | 18 +- .../utils/logistics/logSearch.js | 47 +- .../utils/logistics/logUpdate.js | 17 +- .../utils/logistics/msgValidator.js | 6 +- .../utils/logistics/pinToStd.json | 1 + .../utils/logistics/readLogFiles.js | 28 + .../utils/mergeSort.js | 61 +- .../utils/ret.cbCheck.util.js | 4 +- .../utils/reverseGeoCoding.js | 23 + .../utils/schemaVal.js | 36 +- .../utils/schemaValidation.js | 1 + .../log-verification-utility/utils/utils.js | 6 + .../utils/validateLogUtil.js | 38 +- 104 files changed, 7650 insertions(+), 6580 deletions(-) mode change 100755 => 100644 utilities/logistics-b2b/log-verification-utility/.gitignore delete mode 100755 utilities/logistics-b2b/log-verification-utility/routes/routes.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/cancelSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/confirmSchema.js (97%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/initSchema.js (93%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/masterSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onCancelSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onConfirmSchema.js (96%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onInitSchema.js (91%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onSearchSchema.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onStatusSchema.js (95%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onSupportSchema.js (92%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onTrackSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/onUpdateSchema.js (88%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/searchSchema.js (95%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/statusSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/supportSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/trackSchema.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/{ => v1.1}/updateSchema.js (98%) rename utilities/logistics-b2b/log-verification-utility/schema/{retail_api_json_schema => logistics_api_json_schema/v1.2}/cancelSchema.js (69%) mode change 100755 => 100644 create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js rename utilities/logistics-b2b/log-verification-utility/schema/{retail_api_json_schema/confirmSchema.js => logistics_api_json_schema/v1.2/initSchema.js} (55%) mode change 100755 => 100644 create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/masterSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js rename utilities/logistics-b2b/log-verification-utility/schema/{retail_api_json_schema => logistics_api_json_schema/v1.2}/statusSchema.js (69%) mode change 100755 => 100644 create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js delete mode 100755 utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js create mode 100644 utilities/logistics-b2b/log-verification-utility/server/routes/routes.js create mode 100644 utilities/logistics-b2b/log-verification-utility/server/server.js create mode 100644 utilities/logistics-b2b/log-verification-utility/server/utils/fileHandler.js rename utilities/logistics-b2b/log-verification-utility/{schema/retail_api_json_schema/postConfirmValidations.js => utils/b2b/b2bConfirm.js} (100%) mode change 100755 => 100644 create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnUpdate.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bUpdate.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/csvToJson.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/readLogFiles.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore old mode 100755 new mode 100644 diff --git a/utilities/logistics-b2b/log-verification-utility/README.md b/utilities/logistics-b2b/log-verification-utility/README.md index 1a94dba..cab5c99 100644 --- a/utilities/logistics-b2b/log-verification-utility/README.md +++ b/utilities/logistics-b2b/log-verification-utility/README.md @@ -1,8 +1,11 @@ -# ONDC-LOG-VALIDATION +# ONDC-LOG-VERIFICATION-SERVER -### APIs Log Validation tool for Pre-Prod participants +### APIs Log Verification tool for Pre-Prod participants -The tool is a NODE.js based utility to check the conformance and compliance of the API logs for [logistics v1.0](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B v2.0.1](https://github.com/ONDC-Official/ONDC-RET-Specifications) based on the examples in the API Contract. +The tool is a NODE.js based server to check the conformance and compliance of the API logs for [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) based on the examples in the API Contract. + +The Log Verification Server is a tool designed to validate log files. It offers an endpoint `/validate/` that allows users to send a directory path containing log files for verification. The directory can have single log file or all the log files for the complete flow. In case of single log files, if sent in sequence will validate the complete flow for same transaction id. +The server responds with a log report, indicating any errors found in the log files. ### Tech @@ -11,46 +14,86 @@ The tool is a NODE.js based utility to check the conformance and compliance of t - [[lodash](https://www.npmjs.com/package/lodash)] - [[ajv](https://ajv.js.org/)] -## Steps to run the utility +## Steps to run the server -Log Validation Tool requires [Node.js](https://nodejs.org/) to run. +Log Verification Server requires [Node.js](https://nodejs.org/) to run. -1. Clone the repository, navigate to log-validation-utility and install the dependencies. +1. Clone the repository, navigate to log-verification-utility and install the dependencies. ```sh -cd log-validation-utility +cd log-verification-utility npm i ``` -2. Move all the API payloads inside "/public/logs" folder or mention the path to the logs folder as demonstrated in the next step. +2. Set up the .env file in root directory with the following configuration: -3. Run the utility in the following format +```code +MAPPLS_API_KEY= +PORT= +``` +To get the api_key, refer to this link: https://developer.mappls.com/mapping/reverse-geocoding-api - > node index.js "domain" "/path/to/logs/folder/" +3. Start the server with the following command: ```sh -node index.js logistics ./public/logs/ -node index.js b2b ./public/logs/ +npm run server:start ``` +The server will be up and running at `http://localhost:3000` + +4. The server provides an HTTP endpoint for log file verification: + +```code +http://localhost:3000/validate/ +``` + +Example endpoint for Logistics + +**`` +http://localhost:3000/validate/logistics +``** -4. A text report (**log_report.json**) will be generated upon successful execution of the utility. - +Example endpoint for B2B + +**`` +http://localhost:3000/validate/b2b +``** + +5. Send a POST request to the endpoint with the following parameters: + +```code +logPath: +``` + +6. Example using Postman: + +``` +Url: http://localhost:3000/validate/logistics +Request body json: { + "logPath": "Documents/projects/v1.2.0-logs/Ref-logistics-app/flow2" +} +``` + +7. Example user cURL: + +``` +curl -X POST -d "logPath=/path/to/log/files" http://localhost:3000/validate/logistics +``` + +8. Upon successful validation, the server will respond with a log report in JSON format. The log report will indicate any errors found in the log files. _Notes:_ > There must be a separate payload for every API. -> The utility validates all the payloads as documented in the examples for respective domains: +> The server validates all the payloads as documented in the examples for respective domains: * [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) * [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) > Test cases to be referred here -> [logsitics](https://docs.google.com/document/d/1ttixilM-I6dutEdHL10uzqRFd8RcJlEO_9wBUijtdDc/edit) and [B2B](https://docs.google.com/document/d/10ouiTKLY4dm1KnXCuhFwK38cYd9_aDQ30bklkqnPRkM/edit) -> **Community contributions are welcomed to enhance this utility for future releases.** - > Sample payload for search.json is demonstrated below: ```json @@ -131,4 +174,8 @@ _Notes:_ } } } -``` \ No newline at end of file +``` + +### N.B. + +> - Community contributions are welcomed to enhance this server for future releases. diff --git a/utilities/logistics-b2b/log-verification-utility/index.js b/utilities/logistics-b2b/log-verification-utility/index.js index 7db2481..1d6bf54 100755 --- a/utilities/logistics-b2b/log-verification-utility/index.js +++ b/utilities/logistics-b2b/log-verification-utility/index.js @@ -1,6 +1,7 @@ const { validateLog } = require("./services/cbCheck.service"); const fs = require("fs"); const path = require("path"); +require("dotenv").config(); try { if (process.argv.length < 3) { @@ -15,14 +16,15 @@ try { const logpath = process.argv[3] || "./public/logs/"; //Read Log directory - fs.readdir(logpath, (err, files) =>{ + fs.readdir(logpath, (err, files) => { try { if (err) { console.log(`Some error occurred while reading files from ${path}`); } else if (!files.length) { console.log(`${path} folder is empty!!`); } else { - validateLog(domain, logpath); + console.log("INDEX", logpath); + validateLog(domain, logpath); } } catch (error) { console.log(`Error while reading logs folder`, error); diff --git a/utilities/logistics-b2b/log-verification-utility/package.json b/utilities/logistics-b2b/log-verification-utility/package.json index 4dd4e33..d6d3ea4 100755 --- a/utilities/logistics-b2b/log-verification-utility/package.json +++ b/utilities/logistics-b2b/log-verification-utility/package.json @@ -4,7 +4,11 @@ "description": "Log Verification ONDC", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "server:dev": "nodemon ./server/server.js --ignore public/", + "server:start": "node ./server/server.js", + "verify:logistics": "node index.js logistics", + "verify:retail": "node index.js retail", + "verify:b2b": "node index.js b2b" }, "repository": { "type": "git", @@ -20,8 +24,14 @@ "ajv": "^8.12.0", "ajv-errors": "^3.0.0", "ajv-formats": "^2.1.1", + "ajv-merge-patch": "^5.0.1", + "dotenv": "^16.3.1", + "express": "^4.18.2", "lmdb": "^2.7.5", - "lodash": "^4.17.21" + "lodash": "^4.17.21", + "multer": "^1.4.5-lts.1", + "node-fetch": "^2.6.1", + "nodemon": "^3.0.1" }, "keywords": [] } diff --git a/utilities/logistics-b2b/log-verification-utility/routes/routes.js b/utilities/logistics-b2b/log-verification-utility/routes/routes.js deleted file mode 100755 index 741eb7b..0000000 --- a/utilities/logistics-b2b/log-verification-utility/routes/routes.js +++ /dev/null @@ -1,25 +0,0 @@ -const express = require("express"); -const router = express.Router(); -const service = require("../services/service"); -const { validateLog } = require("../services/cbCheck.service"); - -router.post("/validateSchema/:path", (req, res) => { - const path = req.params.path; - const data = req.body; - const result = service.schemaValidation(domain, data, path); - res.json(result); -}); - -router.post("/CheckContext/:path", (req, res) => { - const path = req.params.path; - const data = req.body.context; - const result = service.checkContext(data, path); - res.json(result); -}); - -router.post("/ValidateLog/:domain", (req, res) => { - const domain = req.params.domain; - validateLog(domain); -}); - -module.exports = router; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js index 9e0fb0e..6e28291 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js @@ -410,7 +410,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["INCOTERMS", "DELIVERY_DUTY"], + enum: ["INCOTERMS", "NAMED_PLACE_OF_DELIVERY"], }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js index 88a1c73..2c5efa0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js @@ -64,7 +64,7 @@ module.exports = { type: "string", allOf: [ { - const: { $data: "/init/0/context/message_id" }, + const: { $data: "/confirm/0/context/message_id" }, errorMessage: "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js index 4f9117a..cf70261 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js @@ -473,7 +473,11 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "Discount", "Packing charges", "delivery ", "tax", "misc"] + enum: ["item", "delivery", + "packing", + "tax", + "discount", + "misc"] }, price: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js index aa79eae..33d77c1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -16,19 +16,6 @@ const fs = require("fs"); //const async = require("async"); const path = require("path"); -const Ajv = require("ajv"); -const ajv = new Ajv({ - allErrors: true, - strict: false, - strictRequired: false, - strictTypes: false, - $data: true, -}); -const addFormats = require("ajv-formats"); - -addFormats(ajv); -require("ajv-errors")(ajv); - const formatted_error = (errors) => { error_list = []; let status = ""; @@ -52,26 +39,36 @@ const formatted_error = (errors) => { }; const validate_schema = (data, schema) => { + const Ajv = require("ajv"); + const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + $data: true, + }); + const addFormats = require("ajv-formats"); + + addFormats(ajv); + require("ajv-errors")(ajv); let error_list = []; try { validate = ajv - .addSchema(searchSchema) - .addSchema(onSearchSchema) - .addSchema(selectSchema) - .addSchema(onSelectSchema) - .addSchema(initSchema) - .addSchema(onInitSchema) - .addSchema(confirmSchema) - .addSchema(onConfirmSchema) - .addSchema(updateSchema) - .addSchema(onUpdateSchema) - .addSchema(statusSchema) - .addSchema(onStatusSchema) + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(selectSchema) + .addSchema(onSelectSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema); + validate = validate.compile(schema); - - validate = validate.compile(schema); - const valid = validate(data); if (!valid) { error_list = validate.errors; @@ -89,5 +86,5 @@ const validate_schema_b2b_master = (data) => { }; module.exports = { - validate_schema_b2b_master + validate_schema_b2b_master, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js index 6130f6a..2ad474a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js @@ -1,37 +1,9 @@ -const onConfirmSchema = require("./onConfirmSchema"); -const onInitSchema = require("./onInitSchema"); -const onSearchSchema = require("./onSearchSchema"); -const onTrackSchema = require("./onTrackSchema"); -const onSupportSchema = require("./onSupportSchema"); -const onStatusSchema = require("./onStatusSchema"); -const onCancelSchema = require("./onCancelSchema"); -const onUpdateSchema = require("./onUpdateSchema"); -const searchSchema = require("./searchSchema"); -const initSchema = require("./initSchema"); -const masterSchema = require("./masterSchema"); -const confirmSchema = require("./confirmSchema"); -const statusSchema = require("./statusSchema"); -const updateSchema = require("./updateSchema"); -const cancelSchema = require("./cancelSchema"); -const supportSchema = require("./supportSchema"); -const trackSchema = require("./trackSchema"); const fs = require("fs"); -const path = require("path"); - -const Ajv = require("ajv"); -const ajv = new Ajv({ - allErrors: true, - strict: false, - strictRequired: false, - strictTypes: false, - verbose: true, - $data: true, -}); - -const addFormats = require("ajv-formats"); - -addFormats(ajv); -require("ajv-errors")(ajv); +//const async = require("async"); +const { isLengthValid } = require("./v1.2/keywords/init"); +const { isQuoteMatching } = require("./v1.2/keywords/onInit"); +const { isFutureDated } = require("./v1.2/keywords/confirm"); +const { isEndTimeGreater } = require("./v1.2/keywords/search"); const formatted_error = (errors) => { error_list = []; @@ -55,13 +27,57 @@ const formatted_error = (errors) => { return error_json; }; -function isEndTimeGreater(data) { - const startTime = parseInt(data.start); - const endTime = parseInt(data.end); - return startTime < endTime -} +const loadSchema = (schemaType, version) => { + try { + return require(`./${version}/${schemaType}Schema.js`); + } catch (error) { + console.log("Error Occurred while importing", error); + } +}; + +const validate_schema = (data, schema, version) => { + const searchSchema = loadSchema("search", version); + const onSearchSchema = loadSchema("onSearch", version); + + const initSchema = loadSchema("init", version); + const onInitSchema = loadSchema("onInit", version); + + const confirmSchema = loadSchema("confirm", version); + const onConfirmSchema = loadSchema("onConfirm", version); -const validate_schema = (data, schema) => { + const updateSchema = loadSchema("update", version); + const onUpdateSchema = loadSchema("onUpdate", version); + + const statusSchema = loadSchema("status", version); + const onStatusSchema = loadSchema("onStatus", version); + + const supportSchema = loadSchema("support", version); + const onSupportSchema = loadSchema("onSupport", version); + + const trackSchema = loadSchema("track", version); + const onTrackSchema = loadSchema("onTrack", version); + + const cancelSchema = loadSchema("cancel", version); + const onCancelSchema = loadSchema("onCancel", version); + + const commonSchemaV1_2 = require("./v1.2/common/commonSchema"); + + const Ajv = require("ajv"); + const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + verbose: true, + $data: true, + schemaIs: "id", + }); + + const addFormats = require("ajv-formats"); + + addFormats(ajv); + require("ajv-errors")(ajv); + require('ajv-merge-patch')(ajv); let error_list = []; try { validate = ajv @@ -82,7 +98,17 @@ const validate_schema = (data, schema) => { .addSchema(cancelSchema) .addSchema(onCancelSchema) .addKeyword("isEndTimeGreater", { - validate: (schema, data) => isEndTimeGreater(data) + validate: (schema, data) => isEndTimeGreater(data), + }) + .addSchema(commonSchemaV1_2) + .addKeyword("isQuoteMatching", { + validate: (schema, data) => isQuoteMatching(data), + }) + .addKeyword("isFutureDated", { + validate: (schema, data) => isFutureDated(data), + }) + .addKeyword("isLengthValid", { + validate: (schema, data) => isLengthValid(data), }); validate = validate.compile(schema); @@ -99,11 +125,12 @@ const validate_schema = (data, schema) => { return error_list; }; -const validate_schema_master = (data) => { - error_list = validate_schema(data, masterSchema); +const validate_schema_master = (data, version) => { + const masterSchema = loadSchema("master", version); + error_list = validate_schema(data, masterSchema, version); return formatted_error(error_list); }; module.exports = { validate_schema_master, -}; \ No newline at end of file +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js deleted file mode 100644 index 0c8265f..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchemacopy.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/masterSchemaCopy", - type: "object", - properties: { - search: { - $ref: "searchSchema1#", - }, - on_search: { - $ref: "onSearchSchema1#", - }, - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/cancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/cancelSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/cancelSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/cancelSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js similarity index 97% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index 8c025fb..55f5a4c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -40,7 +40,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -645,7 +645,8 @@ module.exports = { const: { $data: "/on_init/0/message/order/payment/collected_by", }, - errorMessage: "mismatches in /payment in /on_init and /confirm", + errorMessage: + "mismatches in /payment in /on_init and /confirm", }, type: { type: "string", @@ -653,7 +654,8 @@ module.exports = { const: { $data: "/on_init/0/message/order/payment/type", }, - errorMessage: "mismatches in /payment in /on_init and /confirm", + errorMessage: + "mismatches in /payment in /on_init and /confirm", }, "@ondc/org/settlement_details": { type: "array", @@ -719,11 +721,7 @@ module.exports = { }, }, }, - required: [ - "collected_by", - "type", - "@ondc/org/settlement_details", - ], + required: ["collected_by", "type"], }, "@ondc/org/linked_order": { type: "object", @@ -863,7 +861,7 @@ module.exports = { "/search/0/message/intent/@ondc~1org~1payload_details/weight/value", }, errorMessage: - "Payload weight mismatches in /search and /confirm", + "Payload weight mismatches from /search", }, }, required: ["unit", "value"], @@ -905,24 +903,6 @@ module.exports = { }, required: ["order"], }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, - init: { - type: "array", - items: { - $ref: "initSchema#", - }, - }, - on_init: { - type: "array", - items: { - $ref: "onInitSchema#", - }, - }, }, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js similarity index 93% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js index 336bc64..1419fff 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js @@ -40,7 +40,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -51,7 +51,7 @@ module.exports = { }, errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", - } + }, ], }, timestamp: { @@ -60,7 +60,7 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, }, required: [ @@ -208,7 +208,7 @@ module.exports = { }, email: { type: "string", - format: "email" + format: "email", }, }, required: ["phone"], @@ -238,13 +238,13 @@ module.exports = { type: "string", minLength: 3, not: { const: { $data: "1/locality" } }, - errorMessage:"cannot be equal to locality" + errorMessage: "cannot be equal to locality", }, building: { type: "string", minLength: 3, not: { const: { $data: "1/locality" } }, - errorMessage:"cannot be equal to locality" + errorMessage: "cannot be equal to locality", }, locality: { type: "string", @@ -284,7 +284,7 @@ module.exports = { }, email: { type: "string", - format: "email" + format: "email", }, }, required: ["phone", "email"], @@ -293,7 +293,7 @@ module.exports = { required: ["location", "contact"], }, }, - additionalProperties:false, + additionalProperties: false, required: ["id", "type", "start", "end"], }, }, @@ -310,14 +310,13 @@ module.exports = { type: "string", minLength: 3, not: { const: { $data: "1/locality" } }, - errorMessage:"cannot be equal to locality" - + errorMessage: "cannot be equal to locality", }, building: { type: "string", minLength: 3, not: { const: { $data: "1/locality" } }, - errorMessage:"cannot be equal to locality" + errorMessage: "cannot be equal to locality", }, locality: { type: "string", @@ -355,7 +354,7 @@ module.exports = { }, email: { type: "string", - format:"email" + format: "email", }, created_at: { type: "string", @@ -435,35 +434,19 @@ module.exports = { }, }, ], - required: [ - "settlement_counterparty", - "settlement_type", - ], + required: ["settlement_counterparty", "settlement_type"], }, }, }, required: ["@ondc/org/settlement_details"], }, }, - additionalProperties:false, - required: ["provider", "items", "fulfillments", "billing"] + additionalProperties: false, + required: ["provider", "items", "fulfillments", "billing"], }, }, required: ["order"], }, - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, - }, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/masterSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/masterSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/masterSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onCancelSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onCancelSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onCancelSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js similarity index 96% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js index 5be9e68..60e9acd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js @@ -56,18 +56,6 @@ module.exports = { }, errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - { - not: { - const: { $data: "/init/0/context/message_id" }, - }, - errorMessage: "Message ID should be unique", - }, - { - not: { - const: { $data: "/search/0/context/message_id" }, - }, - errorMessage: "Message ID should be unique", } ], }, @@ -514,31 +502,31 @@ module.exports = { search: { type: "array", items: { - $ref: "searchSchema#", + $ref: "http://example.com/schema/searchSchema#", }, }, on_search: { type: "array", items: { - $ref: "onSearchSchema#", + $ref: "http://example.com/schema/onSearchSchema#", }, }, init: { type: "array", items: { - $ref: "initSchema#", + $ref: "http://example.com/schema/initSchema#", }, }, on_init: { type: "array", items: { - $ref: "onInitSchema#", + $ref: "http://example.com/schema/onInitSchema#", }, }, confirm: { type: "array", items: { - $ref: "confirmSchema#", + $ref: "http://example.com/schema/confirmSchema#", }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js similarity index 91% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js index fee04d1..9ffb1c5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js @@ -40,7 +40,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -57,12 +57,6 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - { - not: { - const: { $data: "/search/0/context/message_id" }, - }, - errorMessage: "Message ID should be unique", - } ], }, timestamp: { @@ -106,7 +100,9 @@ module.exports = { properties: { id: { type: "string", - const: { $data: "/init/0/message/order/provider/locations/0/id" }, + const: { + $data: "/init/0/message/order/provider/locations/0/id", + }, }, }, }, @@ -243,7 +239,7 @@ module.exports = { required: ["type", "collected_by"], }, }, - additionalProperties:false, + additionalProperties: false, required: ["provider", "items", "quote", "payment"], // anyOf: [ // { @@ -265,24 +261,6 @@ module.exports = { }, required: ["order"], }, - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - init: { - type: "array", - items: { - $ref: "initSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, }, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js index eda6346..8d63e64 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js @@ -1,5 +1,3 @@ -const { error } = require("ajv/dist/vocabularies/applicator/dependencies"); - module.exports = { $id: "http://example.com/schema/onSearchSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js similarity index 95% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js index 06b5e20..2f32512 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js @@ -40,7 +40,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -51,7 +51,7 @@ module.exports = { }, errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", - } + }, ], }, timestamp: { @@ -100,7 +100,7 @@ module.exports = { id: { type: "string", const: { $data: "/init/0/message/order/provider/id" }, - errorMessage:"mismatches between /init and /on_status" + errorMessage: "mismatches between /init and /on_status", }, locations: { type: "array", @@ -604,14 +604,13 @@ module.exports = { created_at: { type: "string", const: { $data: "/confirm/0/message/order/created_at" }, - errorMessage: - "mismatches in /confirm and /on_status", + errorMessage: "mismatches in /confirm and /on_status", }, updated_at: { - type: "string" + type: "string", }, }, - additionalProperties:false, + additionalProperties: false, if: { properties: { state: { const: "Cancelled" } } }, then: { required: [ @@ -623,7 +622,7 @@ module.exports = { "fulfillments", "payment", "billing", - "tags" + "tags", ], }, else: { @@ -642,42 +641,6 @@ module.exports = { }, required: ["order"], }, - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, - init: { - type: "array", - items: { - $ref: "initSchema#", - }, - }, - on_init: { - type: "array", - items: { - $ref: "onInitSchema#", - }, - }, - confirm: { - type: "array", - items: { - $ref: "confirmSchema#", - }, - }, - status: { - type: "array", - items: { - $ref: "statusSchema#", - }, - }, }, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSupportSchema.js similarity index 92% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSupportSchema.js index 17b891f..614b945 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onSupportSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSupportSchema.js @@ -95,17 +95,5 @@ module.exports = { required: ["phone", "email", "uri"], }, }, - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onTrackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onTrackSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onTrackSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onTrackSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js similarity index 88% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js index 73b0146..97937c7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js @@ -40,7 +40,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -56,7 +56,7 @@ module.exports = { }, errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", - } + }, ], }, timestamp: { @@ -220,29 +220,47 @@ module.exports = { }, "@ondc/org/ewaybillno": { type: "string", - const: { $data: "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ewaybillno" }, + const: { + $data: + "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ewaybillno", + }, }, "@ondc/org/ebnexpirydate": { type: "string", format: "date-time", - const: { $data: "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ebnexpirydate"}, + const: { + $data: + "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ebnexpirydate", + }, }, }, - additionalProperties:false, + additionalProperties: false, required: ["id", "type", "start"], }, }, created_at: { type: "string", const: { $data: "/confirm/0/message/order/created_at" }, - errorMessage: - "mismatches in /confirm and /on_update", + errorMessage: "mismatches in /confirm and /on_update", }, updated_at: { type: "string", + allOf: [ + { + not: { + const: { $data: "/confirm/0/message/order/created_at" }, + }, + errorMessage: + "should be greater than order/created_at ${3/context/timestamp} in /confirm", + }, + // { + // maximum: { $data: "3/context/timestamp" }, + // errorMessage: "should not be future dated w.r.t context/timestamp ${3/context/timestamp}", + // }, + ], }, }, - additionalProperties:false, + additionalProperties: false, required: ["id", "state", "items", "fulfillments", "updated_at"], // oneOf: [ @@ -299,49 +317,6 @@ module.exports = { }, required: ["order"], }, - - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, - init: { - type: "array", - items: { - $ref: "initSchema#", - }, - }, - on_init: { - type: "array", - items: { - $ref: "onInitSchema#", - }, - }, - confirm: { - type: "array", - items: { - $ref: "confirmSchema#", - }, - }, - on_confirm: { - type: "array", - items: { - $ref: "onConfirmSchema#", - }, - }, - update: { - type: "array", - items: { - $ref: "updateSchema#", - }, - }, }, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js similarity index 95% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js index 696fee6..ba45573 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js @@ -136,7 +136,7 @@ module.exports = { end: { type: "string", pattern: "^(?:[01][0-9]|2[0-3])[0-5][0-9]$", - }, + }, }, isEndTimeGreater: true, errorMessage: 'The "end" time must be greater than the "start" time. Ref footnote 12 of v1.1 .', @@ -207,6 +207,15 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{1,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{1,15})?)$", + allOf: [ + { + not: { + const: { $data: "3/start/location/gps" }, + }, + errorMessage: + "cannot be equal to start/location/gps '${3/start/location/gps}'", + }, + ], errorMessage: "Incorrect gps value", }, address: { @@ -312,7 +321,7 @@ module.exports = { ], }, dangerous_goods: { - type: "boolean" + type: "boolean", // const: "true", // errorMessage: // "is an optional property and should be set when payload includes hazardous goods", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/statusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/statusSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/statusSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/statusSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/supportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/supportSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/supportSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/supportSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/trackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/trackSchema.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/trackSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/trackSchema.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js similarity index 98% rename from utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js index 6c7d8e7..113906e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js @@ -371,7 +371,7 @@ module.exports = { value: { type: "number", const: { $data: "/search/0/message/intent/@ondc~1org~1payload_details/weight/value" }, - errorMessage:"Payload weight mismatches in /search and /update" + errorMessage:"Payload weight mismatches from /search" }, }, required: ["unit", "value"], @@ -397,19 +397,19 @@ module.exports = { confirm: { type: "array", items: { - $ref: "confirmSchema#", + $ref: "http://example.com/schema/confirmSchema#", }, }, on_confirm: { type: "array", items: { - $ref: "onConfirmSchema#", + $ref: "http://example.com/schema/onConfirmSchema#", }, }, on_update: { type: "array", items: { - $ref: "onUpdateSchema#", + $ref: "http://example.com/schema/onUpdateSchema#", }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js old mode 100755 new mode 100644 similarity index 69% rename from utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js index 74e1260..5e38d72 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/cancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js @@ -1,85 +1,95 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "cancel", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order_id: { - type: "string", - }, - cancellation_reason_id: { - type: "string", - minLength: 3, - maxLength: 3, - }, - }, - required: ["order_id", "cancellation_reason_id"], - }, - }, - required: ["context", "message"], -}; +module.exports = { + $id: "http://example.com/schema/cancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "cancel", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + cancellation_reason_id: { + type: "string", + }, + }, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js new file mode 100644 index 0000000..5986621 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js @@ -0,0 +1,88 @@ +module.exports = { + $id: "http://example.com/schema/commonSchema", + type: "object", + properties: { + addressFormat: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid: true, + errorMessage: "name + building + locality < 190 chars", + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["person", "location", "contact"], + }, + priceFormat: { + type: "object", + properties: { + currency: { type: "string" }, + value: { type: "string" }, + }, + required: ["currency", "value"], + }, + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js new file mode 100644 index 0000000..5939573 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -0,0 +1,1021 @@ +const constants = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/on_search/0/context/city" }, + }, + action: { + type: "string", + const: "confirm", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + const: "Created", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + }, + }, + }, + required: ["id"], + // oneOf: [ + // { + // required: [ + // "/on_search/0/message/catalog/bpp~1providers/0/locations", + // "locations", + // ], + // }, + // { + // not: { + // required: [ + // "/on_search/0/message/catalog/bpp~1providers/0/locations", + // ], + // }, + // }, + // ], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, + }, + category_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, + }, + fulfillment_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor", "fulfillment_id"], + // anyOf: [ + // { + // allOf: [ + // { + // properties: { + // id: { + // const: { + // $data: + // "/on_search/0/message/catalog/bpp~1providers/0/items/0/id", + // }, + // }, + // }, + // }, + // { + // properties: { + // category_id: { + // const: { + // $data: + // "/on_search/0/message/catalog/bpp~1providers/0/items/0/category_id", + // }, + // }, + // }, + // }, + // ], + // }, + // { + // allOf: [ + // { + // properties: { + // id: { + // const: { + // $data: + // "/on_search/0/message/catalog/bpp~1providers/1/items/0/id", + // }, + // }, + // }, + // }, + // { + // properties: { + // category_id: { + // const: { + // $data: + // "/on_search/0/message/catalog/bpp~1providers/1/items/0/category_id", + // }, + // }, + // }, + // }, + // ], + // }, + // ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + errorMessage: "mismatches in /on_init and /confirm.", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: constants.TITLE_TYPE, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + const: "INR", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + "@ondc/org/awb_no": { + type: "string", + pattern: "^[0-9]{11,16}$", + errorMessage: "should be 11-16 digits", + }, + start: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + duration: { + type: "string", + format: "duration", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/start/location/gps", + }, + errorMessage: + "does not match start location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + code: { + type: "string", + enum: constants.PCC_CODE, + }, + }, + required: ["code", "short_desc"], + allOf: [ + { + if: { properties: { code: { const: "1" } } }, + then: { + properties: { + short_desc: { + minLength: 10, + maxLength: 10, + pattern: "^[0-9]{10}$", + errorMessage: "should be a 10 digit number", + }, + }, + }, + }, + { + if: { + properties: { code: { enum: ["2", "3", "4"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + }, + }, + ], + }, + }, + required: ["person", "location", "contact"], + }, + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/end/location/gps", + }, + errorMessage: + "does not match end location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: + "name + building + locality < 190 chars & each of name / building / locality > 3 chars; name != locality", + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + code: { + type: "string", + enum: constants.DCC_CODE, + }, + }, + required: ["code", "short_desc"], + allOf: [ + { + if: { properties: { code: { const: "3" } } }, + then: { + properties: { + short_desc: { + maxLength: 0, + errorMessage: "is not required", + }, + }, + }, + }, + { + if: { + properties: { code: { enum: ["1", "2"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + }, + }, + ], + }, + }, + required: ["person", "location", "contact"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.FULFILLMENT_TAGS_CODE, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.FULFILLMENT_TAGS_LIST_CODE, + }, + value: { + type: "string", + enum: constants.FULFILLMENT_TAGS_LIST_VALUE, + }, + }, + required: ["code", "value"], + }, + }, + }, + + required: ["code", "list"], + }, + minItems: 2, + errorMessage: + "both 'state' and 'rto_action' tags are required", + }, + }, + + required: ["id", "type", "start", "end", "tags"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + const: { + $data: "/init/0/message/order/billing/address/name", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + building: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/building", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + locality: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/locality", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + city: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/city", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + state: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/state", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + country: { + type: "string", + const: { + $data: "/init/0/message/order/billing/address/country", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + area_code: { + type: "string", + const: { + $data: + "/init/0/message/order/billing/address/area code", + }, + errorMessage: + "mismatches in /billing in /init and /confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + const: { + $data: "/init/0/message/order/billing/tax_number", + }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + created_at: { + type: "string", + const: { + $data: "/init/0/message/order/billing/created_at", + }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + updated_at: { + type: "string", + const: { + $data: "/init/0/message/order/billing/updated_at", + }, + errorMessage: "mismatches in /billing in /init and /confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "address", + "phone", + "tax_number", + "created_at", + "updated_at", + ], + }, + payment: { + type: "object", + properties: { + "@ondc/org/collection_amount": { + type: "string", + const: { + $data: + "/search/0/message/intent/payment/@ondc~1org~1collection_amount", + }, + errorMessage: "mismatches in /payment from /search", + }, + collected_by: { + type: "string", + enum: constants.PAYMENT_COLLECTEDBY, + const: { + $data: "/on_init/0/message/order/payment/collected_by", + }, + errorMessage: + "mismatches in /payment in /on_init and /confirm", + }, + type: { + type: "string", + enum: constants.PAYMENT_TYPE, + const: { + $data: "/on_init/0/message/order/payment/type", + }, + errorMessage: + "mismatches in /payment in /on_init and /confirm", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + "bank_name", + "branch_name", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: ["collected_by", "type"], + }, + "@ondc/org/linked_order": { + type: "object", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + category_id: { + type: "string", + enum: constants.CATEGORIES, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["count", "measure"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "category_id", + "descriptor", + "quantity", + "price", + ], + }, + }, + provider: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + + required: [ + "name", + "locality", + "city", + "state", + "area_code", + ], + }, + }, + required: ["descriptor", "address"], + }, + order: { + type: "object", + properties: { + id: { + type: "string", + }, + weight: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + const: { + $data: + "/search/0/message/intent/@ondc~1org~1payload_details/weight/value", + }, + errorMessage: + "Payload weight mismatches from /search", + }, + }, + required: ["unit", "value"], + }, + dimensions: { + type: "object", + properties: { + length: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + breadth: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + height: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["length", "breadth", "height"], + }, + }, + required: ["id", "weight"], + }, + }, + required: ["items", "provider", "order"], + }, + created_at: { + type: "string", + format: "date-time", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "billing", + "payment", + "@ondc/org/linked_order", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + isFutureDated: true, + errorMessage: + "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js old mode 100755 new mode 100644 similarity index 55% rename from utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 4c6212f..96c01da --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -1,490 +1,474 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "confirm", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - id: { - type: "string", - }, - state: { - type: "string", - const: "Created", - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - fulfillment_id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - }, - required: ["id", "fulfillment_id", "quantity"], - }, - }, - billing: { - type: "object", - properties: { - name: { type: "string" }, - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - email: { type: "string", format: "email" }, - phone: { type: "string" }, - created_at: { - type: "string", - format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - updated_at: { - type: "string", - format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - }, - required: [ - "name", - "address", - "phone", - "created_at", - "updated_at", - ], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - const: "Delivery", - }, - tracking: { - type: "boolean", - }, - end: { - type: "object", - properties: { - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - contact: { - type: "object", - properties: { - email: { - type: "string", - format: "email", - }, - phone: { - type: "string", - }, - }, - required: ["phone"], - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "object", - properties: { - name: { - type: "string", - }, - building: { - type: "string", - }, - locality: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - country: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - }, - required: ["gps", "address"], - }, - }, - required: ["person", "contact", "location"], - }, - }, - required: ["id", "type", "tracking", "end"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { type: "string", minLength: 1 }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string" }, - }, - required: ["value", "currency"], - }, - "@ondc/org/item_id": { type: "string" }, - item: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["value", "currency"], - }, - }, - required: ["price"], - }, - "@ondc/org/item_quantity": { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - "@ondc/org/title_type": { - type: "string", - enum: [ - "item", - "delivery", - "packing", - "tax", - "misc", - "discount", - ], - }, - }, - required: [ - "price", - "title", - "@ondc/org/title_type", - "@ondc/org/item_id", - ], - }, - }, - - ttl: { type: "string", format: "duration" }, - }, - required: ["ttl", "price", "breakup"], - }, - payment: { - type: "object", - properties: { - status: { type: "string", const: "PAID" }, - type: { type: "string", const: "ON-ORDER" }, - collected_by: { type: "string", const: "BAP" }, - params: { - type: "object", - properties: { - amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - transaction_id: { type: "string" }, - currency: { type: "string" }, - }, - required: ["amount", "currency", "transaction_id"], - }, - "@ondc/org/buyer_app_finder_fee_type": { - type: "string", - enum: ["percent", "amount"], - }, - "@ondc/org/buyer_app_finder_fee_amount": { - type: "string", - pattern: "^(\\d*.?\\d{1,2})$", - }, - "@ondc/org/settlement_details": { - type: "array", - items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - allOf: [ - { - if: { - properties: { - settlement_type: { - const: "upi", - }, - }, - }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "neft", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - ], - }, - }, - }, - required: [ - "status", - "type", - "params", - "collected_by", - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_details", - ], - }, - created_at: { type: "string", format: "date-time" }, - updated_at: { type: "string", format: "date-time" }, - }, - required: [ - "id", - "state", - "provider", - "items", - "billing", - "fulfillments", - "quote", - "payment", - "created_at", - "updated_at", - ], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "init", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + const: { $data: "3/fulfillments/0/id" }, + errorMessage: + "should be mapped to the id - ${3/fulfillments/0/id} in /fulfillments", + }, + category_id: { + type: "string", + enum: constants.CATEGORY_ID, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.SHIPMENT_TYPE, + }, + }, + + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor", "fulfillment_id"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.FULFILLMENT_TYPE, + }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/start/location/gps", + }, + errorMessage: + "does not match start location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid:true, + errorMessage:"name + building + locality < 190 chars", + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/end/location/gps", + }, + errorMessage: + "does not match end location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid:true, + errorMessage:"name + building + locality < 190 chars", + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["location", "contact"], + }, + }, + additionalProperties: false, + required: ["id", "type", "start", "end"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid: true, + errorMessage: "name + building + locality < 190 chars", + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + pattern: "^[0-9]{2}[A-Z]{5}[0-9]{4}[0-9A-Z]{4}$", + errorMessage: "should be valid", + }, + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + created_at: { + type: "string", + const: { $data: "4/context/timestamp" }, + errorMessage: + "does not match context timestamp - ${4/context/timestamp} ", + }, + updated_at: { + type: "string", + const: { $data: "4/context/timestamp" }, + errorMessage: + "does not match context timestamp - ${4/context/timestamp} ", + }, + }, + required: [ + "name", + "address", + "tax_number", + "phone", + "email", + "created_at", + "updated_at", + ], + }, + payment: { + type: "object", + properties: { + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + enum: constants.SETTLEMENT_TYPE, + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + type: { + type: "string", + enum: constants.PAYMENT_TYPE, + const: { $data: "/search/0/message/intent/payment/type" }, + errorMessage:"should be same as in /search - ${/search/0/message/intent/payment/type}" + }, + }, + required: ["type"], + }, + }, + additionalProperties: false, + required: ["provider", "items", "fulfillments", "billing"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js new file mode 100644 index 0000000..239d106 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js @@ -0,0 +1,14 @@ +module.exports = { + isFutureDated: (data) => { + const contextTime = data?.context?.timestamp; + const created_at = data?.message?.order?.created_at; + const updated_at = data?.message?.order?.updated_at; + console.log(contextTime,updated_at); + if ( + (created_at && created_at > contextTime) || + (updated_at && updated_at > contextTime) + ) + return false; + return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js new file mode 100644 index 0000000..18a4db3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js @@ -0,0 +1,7 @@ +module.exports = { + isLengthValid: (data) => { + if (data.name.length + data.building.length + data.locality.length > 190) + return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js new file mode 100644 index 0000000..d9a2b1d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -0,0 +1,12 @@ +module.exports = { + isQuoteMatching: (data) => { + const quotePrice = parseFloat(data?.price?.value); + const breakupArr = data.breakup; + let totalBreakup = 0; + breakupArr.forEach((breakup) => { + totalBreakup += parseFloat(breakup?.price?.value); + }); + if (quotePrice != totalBreakup) return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js new file mode 100644 index 0000000..6588a9e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js @@ -0,0 +1,7 @@ +module.exports = { + isEndTimeGreater: (data) => { + const startTime = parseInt(data.start); + const endTime = parseInt(data.end); + return startTime < endTime; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/masterSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/masterSchema.js new file mode 100644 index 0000000..40b0880 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/masterSchema.js @@ -0,0 +1,103 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + }, + support: { + type: "array", + items: { + $ref: "supportSchema#", + }, + }, + on_support: { + type: "array", + items: { + $ref: "onSupportSchema#", + }, + }, + track: { + type: "array", + items: { + $ref: "trackSchema#", + }, + }, + on_track: { + type: "array", + items: { + $ref: "onTrackSchema#", + }, + }, + cancel: { + type: "array", + items: { + $ref: "cancelSchema#", + }, + }, + on_cancel: { + type: "array", + items: { + $ref: "onCancelSchema#", + }, + }, + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js new file mode 100644 index 0000000..7b6cee0 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -0,0 +1,700 @@ +const constants = require("../../../utils/constants"); +const { TITLE_TYPE, CANCELLATION_CODE } = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onCancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "on_cancel", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + { + const: { $data: "/cancel/0/context/message_id" }, + errorMessage: + "Message ID should be same as /cancel: ${/cancel/0/context/message_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/id", + }, + }, + state: { + type: "string", + enum: ["Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id"], + }, + cancellation: { + type: "object", + properties: { + cancelled_by: { type: "string" }, + reason: { + type: "object", + properties: { + id: { type: "string", enum: CANCELLATION_CODE }, + }, + }, + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + category_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor", "fulfillment_id"], + }, + }, + quote: { + type: "object", + properties: { + price: { + $ref: "commonSchema#/properties/priceFormat", + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: TITLE_TYPE, + }, + price: { + $ref: "commonSchema#/properties/priceFormat", + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.FULFILLMENT_TYPE + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Cancelled", "RTO-Initiated","RTO-Disposed"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + "@ondc/org/awb_no": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1awb_no", + }, + }, + tracking: { + type: "boolean", + const: { + $data: + "/on_confirm/0/message/order/fulfillments/0/tracking", + }, + }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + }, + instructions: { + code: { type: "string" }, + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid: true, + errorMessage: + "name + building + locality < 190 chars", + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + }, + + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + }, + instructions: { + code: { type: "string" }, + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid: true, + errorMessage: + "name + building + locality < 190 chars", + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + }, + agent: { + type: "object", + properties: { + name: { + type: "string", + }, + phone: { + type: "string", + }, + }, + }, + vehicle: { + type: "object", + properties: { + registration: { + type: "string", + }, + }, + required: ["registration"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + const: "rto_event", + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.CANCELLATION_TAGS_LIST, + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + }, + }, + }, + additionalProperties: false, + + if: { properties: { type: { const: "Delivery" } } }, + then: { + properties: { + start: { + properties: { + time: { required: ["range"] }, + }, + required: ["time", "person", "location", "contact"], + }, + + end: { + properties: { + time: { required: ["range"] }, + }, + required: ["time", "person", "location", "contact"], + }, + }, + required: [ + "id", + "type", + "state", + "start", + "end", + "tracking", + "agent", + "vehicle", + "tags", + ], + }, + else: { + properties: { + start: { + properties: { + time: { required: ["timestamp"] }, + }, + required: ["time"], + }, + }, + required: ["id", "type", "state", "start"], + }, + }, + }, + billing: { + allOf: [ + { + $ref: "onConfirmSchema#/properties/message/properties/order/properties/billing", + }, + { + $data: "/on_confirm/0/message/order/billing", + }, + ], + }, + payment: { + type: "object", + properties: { + "@ondc/org/collection_amount": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payment/@ondc~1org~1collection_amount", + }, + }, + type: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/payment/type", + }, + }, + collected_by: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/payment/collected_by", + }, + }, + time: { + type: "object", + properties: { + timestamp: { + type: "string", + format: "date-time", + }, + }, + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + settlement_status: { + type: "string", + }, + settlement_reference: { + type: "string", + }, + settlement_timestamp: { + type: "string", + }, + }, + + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: ["type", "collected_by"], + }, + "@ondc/org/linked_order": { + allOf: [ + { + $ref: "onConfirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + }, + { + $data: "/on_confirm/0/message/order/@ondc~1org~1linked_order", + }, + ], + }, + created_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/created_at", + }, + errorMessage: "mismatches in /confirm and /on_cancel", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "fulfillments", + "billing", + "payment", + "@ondc/org/linked_order", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + + }, + isFutureDated: true, + errorMessage: "created_at/updated_at must not be future dated", + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js new file mode 100644 index 0000000..67e8adf --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -0,0 +1,826 @@ +const constants = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { + $data: "/on_search/0/context/city", + }, + }, + action: { + type: "string", + const: "on_confirm", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { + $data: "/search/0/context/transaction_id", + }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { + $data: "/confirm/0/context/message_id", + }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/confirm/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + { + not: { + const: { + $data: "/init/0/context/message_id", + }, + }, + errorMessage: "Message ID should be unique", + }, + { + not: { + const: { + $data: "/search/0/context/message_id", + }, + }, + errorMessage: "Message ID should be unique", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/confirm/0/message/order/id", + }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/on_cancel/0/message/order/provider/id", + }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/init/0/message/order/provider/locations/0/id", + }, + }, + }, + required: ["id"], + }, + }, + }, + required: ["id"], + // oneOf: [ + // { + // required: [ + // "/confirm/0/message/order/provider/locations", + // "locations", + // ], + // }, + // { + // not: { + // required: [ + // "/confirm/0/message/order/provider/locations", + // "locations", + // ], + // }, + // }, + // ], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/id", + }, + }, + fulfillment_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, + }, + category_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/confirm/0/message/order/quote/price/value", + }, + errorMessage: "mismatches from /confirm", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: constants.TITLE_TYPE, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + const: "INR", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/confirm/0/message/order/fulfillments/0/id", + }, + }, + type: { + type: "string", + const: { + $data: "/confirm/0/message/order/fulfillments/0/type", + }, + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: "Pending", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + "@ondc/org/awb_no": { + type: "string", + pattern: "^[0-9]{11,16}$", + errorMessage: "should be 11-16 digits", + const: { + $data: + "/confirm/0/message/order/fulfillments/0/@ondc~1org~1awb_no", + }, + }, + tracking: { + type: "boolean", + }, + start: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: + "/confirm/0/message/order/fulfillments/0/start/person/name", + }, + }, + }, + required: ["name"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/confirm/0/message/order/fulfillments/0/start/location/gps", + }, + errorMessage: + "does not match start location in /confirm", + }, + address: { + allOf: [ + { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + { + $data: + "/confirm/0/message/order/fulfillments/0/start/location/address", + }, + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + allOf: [ + { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + { + $data: + "/confirm/0/message/order/fulfillments/0/start/contact", + }, + ], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + code: { + type: "string", + enum: constants.PCC_CODE, + }, + }, + required: ["code", "short_desc"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + }, + }, + }, + required: ["person", "location", "contact", "time"], + }, + + end: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: + "/confirm/0/message/order/fulfillments/0/end/person/name", + }, + }, + }, + required: ["name"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/confirm/0/message/order/fulfillments/0/end/location/gps", + }, + errorMessage: + "does not match start location in /confirm", + }, + address: { + allOf: [ + { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + minLength: 3, + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + { + $data: + "/confirm/0/message/order/fulfillments/0/end/location/address", + }, + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + allOf: [ + { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + { + $data: + "/confirm/0/message/order/fulfillments/0/end/contact", + }, + ], + }, + instructions: { + type: "object", + properties: { + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + code: { + type: "string", + enum: constants.PCC_CODE, + }, + }, + required: ["code", "short_desc"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + }, + }, + }, + required: ["person", "location", "contact"], + }, + agent: { + type: "object", + properties: { + name: { type: "string" }, + phone: { type: "string" }, + }, + }, + vehicle: { + type: "object", + properties: { + registration: { + type: "string", + }, + }, + required: ["registration"], + }, + + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.FULFILLMENT_TAGS_LIST_CODE, + }, + value: { + type: "string", + enum: constants.FULFILLMENT_TAGS_LIST_VALUE, + }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + }, + }, + required: [ + "id", + "type", + "state", + "start", + "tracking", + "end", + "tags", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/name", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + const: { + $data: "/confirm/0/message/order/billing/address/name", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + building: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/building", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + locality: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/locality", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + city: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/city", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + state: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/state", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + country: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/country", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + area_code: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/area code", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/tax_number", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + phone: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/phone", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + email: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/email", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + created_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/created_at", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + updated_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/updated_at", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_confirm", + }, + }, + additionalProperties: false, + required: [ + "name", + "address", + "phone", + "tax_number", + "created_at", + "updated_at", + ], + }, + payment: { + allOf: [ + { + $ref: "confirmSchema#/properties/message/properties/order/properties/payment", + }, + { + $data: "/confirm/0/message/order/payment", + }, + ], + }, + "@ondc/org/linked_order": { + allOf: [ + { + $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + }, + { + $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + }, + ], + }, + created_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/created_at", + }, + errorMessage: "mismatches in /confirm and /on_confirm", + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "does not match context/timestamp - ${3/context/timestamp}", + }, + }, + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "created_at", + "updated_at", + "@ondc/org/linked_order", + "payment", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js new file mode 100644 index 0000000..256c54c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -0,0 +1,457 @@ +const constants = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_init", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/init/0/message/order/provider/locations/0/id", + }, + }, + }, + }, + + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, + }, + fulfillment_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, + }, + }, + required: ["id", "fulfillment_id"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: constants.TITLE_TYPE, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + ttl: { + type: "string", + format: "duration", + }, + }, + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.FULFILLMENT_TYPE, + }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/start/location/gps", + }, + errorMessage: + "does not match start location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + + not: { const: { $data: "1/locality" } }, + }, + building: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone"], + }, + }, + required: ["location", "contact"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + const: { + $data: + "/search/0/message/intent/fulfillment/end/location/gps", + }, + errorMessage: + "does not match end location in search", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["location", "contact"], + }, + }, + required: ["id", "type", "start", "end"], + }, + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.PAYMENT_TYPE, + }, + collected_by: { + type: "string", + enum: constants.PAYMENT_COLLECTEDBY, + }, + + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { + properties: { + type: { enum: ["ON-ORDER", "POST-FULFILLMENT"] }, + }, + }, + then: { + properties: { + collected_by: { const: "BAP" }, + }, + }, + else: { + properties: { + collected_by: { const: "BPP" }, + }, + }, + + required: ["type", "collected_by"], + }, + }, + required: ["provider", "items", "quote", "payment", "fulfillments"], + // anyOf: [ + // { + // required: [ + // "/on_search/0/message/catalog/bpp~1providers/0/locations", + // "provider_location", + // ], + // errorMessage:"provider/location is required in /init if it was returned in /on_search" + // }, + // { + // not: { + // required: [ + // "/on_search/0/message/catalog/bpp~1providers/0/locations", + // ], + // }, + // }, + // ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js new file mode 100644 index 0000000..7fa3dfe --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js @@ -0,0 +1,365 @@ +const { error } = require("ajv/dist/vocabularies/applicator/dependencies"); +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_search", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + "bpp/descriptor": { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + "bpp/providers": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + required: ["name", "short_desc", "long_desc"], + }, + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + enum:constants.CATEGORY_ID + }, + time: { + type: "object", + properties: { + label: { + type: "string", + const: "TAT", + }, + duration: { + type: "string", + format: "duration", + }, + timestamp:{ + type:"string", + format:"date" + } + }, + required: ["label", "duration","timestamp"], + }, + }, + required: ["id"], + anyOf: [ + { + properties: { + id: { const: "Immediate Delivery" }, + time: { + type: "object", + properties: { + duration: { + type: "string", + pattern: "^PT([1-5][1-9]|60)?M$", + errorMessage: + "Duration is not correct as per Immediate Delivery", + }, + }, + required: ["label", "duration"], + }, + }, + required: ["id", "time"], + }, + { + not: { + properties: { + id: { const: "Immediate Delivery" }, + time: { + type: "object", + properties: { + duration: { + type: "string", + pattern: "^PT([1-5][1-9]|60)?M$", + }, + }, + required: ["label", "duration"], + }, + }, + required: ["id", "time"], + }, + }, + ], + }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + }, + address: { + type: "object", + properties: { + street: { + type: "string", + }, + city: { + type: "string", + }, + area_code: { + type: "string", + }, + state: { + type: "string", + }, + }, + required: ["street", "city", "area_code", "state"], + }, + }, + required: [], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + category_id: { + type: "string", + enum:constants.CATEGORY_ID + }, + fulfillment_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.SHIPMENT_TYPE + }, + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + required: ["code", "name", "short_desc", "long_desc"], + // if: { properties: { code: { const: "P2H2P" } } }, + // then: { + // required: [ + // "/search/0/message/intent/@ondc~1org~1payload_details/dimensions", + // ], + // errorMessage: + // "dimensions are required in /search for P2H2P shipments ${/search/0/message/intent/@ondc~1org~1payload_details/dimensions}", + // }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + const: "TAT", + }, + duration: { + type: "string", + format: "duration" + }, + timestamp: { + type: "string", + format: "date", + }, + }, + required: ["label", "duration", "timestamp"], + }, + }, + required: [ + "id", + "category_id", + "fulfillment_id", + "descriptor", + "price", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.FULFILLMENT_TYPE, + }, + }, + required: ["id", "type"], + }, + }, + }, + if: { + properties: { + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { const: "Immediate Delivery" }, + }, + }, + }, + }, + not: { + required: ["locations"], + }, + errorMessage: + "Locations is only required when shipment has to be dropped off at LSP location; not required for P2P", + }, + + required: [ + "id", + "descriptor", + "categories", + "items", + "fulfillments", + ], + }, + }, + }, + additionalProperties: false, + required: ["bpp/descriptor", "bpp/providers"], + }, + }, + required: ["catalog"], + }, + }, + + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js new file mode 100644 index 0000000..c51b0f2 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -0,0 +1,773 @@ +const constants = require("../../../utils/constants"); +const { + ORDER_STATE, + CANCELLATION_CODE, + TITLE_TYPE, + FULFILLMENT_STATE, +} = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_status", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ORDER_STATE, + }, + cancellation: { + cancelled_by: { type: "string" }, + reason: { + type: "object", + properties: { + reason: { type: "string", enum: CANCELLATION_CODE }, + }, + }, + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/init/0/message/order/provider/id", + }, + errorMessage: "mismatches between /init and /on_status", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/init/0/message/order/provider/locations/0/id", + }, + errorMessage: "mismatches between /init and /on_status", + }, + }, + }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { + type: "string", + }, + category_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor", "fulfillment_id"], + }, + }, + quote: { + type: "object", + properties: { + price: { + $ref: "commonSchema#/properties/priceFormat", + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: TITLE_TYPE, + }, + price: { + $ref: "commonSchema#/properties/priceFormat", + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + required: ["price", "breakup"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + type: { + type: "string", + enum: constants.FULFILLMENT_TYPE, + }, + "@ondc/org/awb_no": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: FULFILLMENT_STATE, + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + tracking: { + type: "boolean", + }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + }, + instructions: { + code: { type: "string" }, + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid: true, + errorMessage: + "name + building + locality < 190 chars", + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + }, + end: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + }, + instructions: { + code: { type: "string" }, + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + building: { + type: "string", + minLength: 3, + not: { const: { $data: "1/locality" } }, + errorMessage: "cannot be equal to locality", + }, + locality: { + type: "string", + minLength: 3, + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + country: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + isLengthValid: true, + errorMessage: + "name + building + locality < 190 chars", + }, + }, + required: ["gps", "address"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + format: "email", + }, + }, + required: ["phone", "email"], + }, + }, + }, + agent: { + type: "object", + properties: { + name: { + type: "string", + }, + phone: { + type: "string", + }, + }, + }, + vehicle: { + type: "object", + properties: { + registration: { + type: "string", + }, + }, + required: ["registration"], + }, + "@ondc/org/ewaybillno": { + type: "string", + }, + "@ondc/org/ebnexpirydate": { + type: "string", + }, + }, + + if: { properties: { type: { const: "Delivery" } } }, + then: { + properties: { + start: { + properties: { + time: { required: ["range"] }, + }, + required: ["time", "person", "location", "contact"], + }, + + end: { + properties: { + time: { required: ["range"] }, + }, + required: ["time", "person", "location", "contact"], + }, + }, + required: ["id", "type", "state", "tracking", "start", "end"], + }, + else: { + properties: { + start: { + properties: { + time: { required: ["timestamp"] }, + }, + required: ["time"], + }, + }, + required: ["id", "type", "state", "start"], + }, + }, + }, + payment: { + type: "object", + properties: { + "@ondc/org/collection_amount": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payment/@ondc~1org~1collection_amount", + }, + }, + type: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/payment/type", + }, + }, + collected_by: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/payment/collected_by", + }, + }, + time: { + type: "object", + properties: { + timestamp: { + type: "string", + format: "date-time", + }, + }, + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + settlement_status: { + type: "string", + }, + settlement_reference: { + type: "string", + }, + settlement_timestamp: { + type: "string", + }, + }, + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: ["type", "collected_by"], + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/name", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + address: { + type: "object", + properties: { + name: { + type: "string", + not: { const: { $data: "1/locality" } }, + const: { + $data: "/confirm/0/message/order/billing/address/name", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + building: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/building", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + locality: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/locality", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + city: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/city", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + state: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/address/state", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + country: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/country", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + area_code: { + type: "string", + const: { + $data: + "/confirm/0/message/order/billing/address/area code", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + }, + required: [ + "name", + "building", + "locality", + "city", + "state", + "country", + "area_code", + ], + }, + tax_number: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/tax_number", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + phone: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/phone", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + email: { + type: "string", + const: { + $data: "/confirm/0/message/order/billing/email", + }, + errorMessage: + "mismatches in /billing in /confirm and /on_status", + }, + }, + + required: ["name", "address", "phone", "email", "tax_number"], + }, + "@ondc/org/linked_order": { + allOf: [ + { + $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + }, + { + $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + }, + ], + }, + created_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/created_at", + }, + errorMessage: "mismatches in /confirm and /on_update", + }, + updated_at: { + type: "string", + }, + }, + additionalProperties: false, + if: { properties: { state: { const: "Cancelled" } } }, + then: { + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "payment", + "billing", + "cancellation", + ], + }, + else: { + required: [ + "id", + "state", + "provider", + "items", + "quote", + "fulfillments", + "payment", + "billing", + ], + }, + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js new file mode 100644 index 0000000..ce2c9d3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js @@ -0,0 +1,99 @@ +module.exports = { + $id: "http://example.com/schema/onSupportSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_support", + }, + core_version: { + type: "string", + const:"1.2.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/support/0/context/message_id" }, + errorMessage: + "Message ID should be same as /support: ${/support/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + uri: { + type: "string", + }, + }, + required: ["phone", "email", "uri"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js new file mode 100644 index 0000000..43c055f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js @@ -0,0 +1,160 @@ +const constants = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onTrackSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { $data: "/search/0/context/city" }, + }, + action: { + type: "string", + const: "on_track", + }, + core_version: { + type: "string", + const:"1.2.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/track/0/context/message_id" }, + errorMessage: + "Message ID should be same as /track: ${/track/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + tracking: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, + }, + url: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + time: { + type: "object", + properties: { + timestamp: { + type: "string", + }, + }, + required: ["timestamp"], + }, + updated_at: { + type: "string", + }, + }, + required: ["gps", "time", "updated_at"], + }, + status: { + type: "string", + enum: constants.TRACKING_STATUS, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["path"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["lat_lng", "sequence"], + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + }, + }, + required: ["id", "location", "status"], + }, + }, + required: ["tracking"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js new file mode 100644 index 0000000..ca15f23 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -0,0 +1,421 @@ +const { + ORDER_STATE, + TITLE_TYPE, + FULFILLMENT_STATE, +} = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { + $data: "/confirm/0/context/city", + }, + }, + action: { + type: "string", + const: "on_update", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { + $data: "/search/0/context/transaction_id", + }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { + $data: "/update/0/context/message_id", + }, + errorMessage: + "Message ID should be same as /update: ${/update/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/confirm/0/message/order/id", + }, + }, + state: { + type: "string", + enum: ORDER_STATE, + }, + provider: { + type: "object", + properties: { + id: { type: "string" }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { type: "string" }, + }, + }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_id: { type: "string" }, + category_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + }, + }, + required: ["id", "fulfillment_id", "category_id", "descriptor"], + }, + }, + quote: { + type: "object", + properties: { + price: { + $ref: "commonSchema#/properties/priceFormat", + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { type: "string" }, + "@ondc/org/title_type": { + type: "string", + enum: TITLE_TYPE, + }, + price: { + $ref: "commonSchema#/properties/priceFormat", + }, + }, + required: [ + "@ondc/org/item_id", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { type: "string", enum: FULFILLMENT_STATE }, + }, + }, + }, + }, + "@ondc/org/awb_no": { + type: "string", + }, + tracking: { + type: "boolean", + }, + start: { + $merge: { + with: { + type: "object", + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + allOf: [ + { + type: "object", + properties: { + code: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + { + $data: + "/update/0/message/order/fulfillments/0/start/instructions", + }, + ], + }, + }, + }, + source: { + $ref: "commonSchema#/properties/addressFormat", + }, + }, + required: ["time"], + }, + end: { + type: "object", + allOf: [ + { + properties: { + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time", + }, + end: { + type: "string", + format: "date-time", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + format: "date-time", + }, + }, + required: ["range"], + }, + instructions: { + allOf: [ + { + type: "object", + properties: { + code: { type: "string" }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["code", "short_desc"], + }, + { + $data: + "/update/0/message/order/fulfillments/0/end/instructions", + }, + ], + }, + }, + }, + { + $ref: "commonSchema#/properties/addressFormat", + }, + ], + required: ["time"], + }, + agent: { + type: "object", + properties: { + name: { + type: "string", + }, + phone: { + type: "string", + }, + }, + }, + "@ondc/org/ewaybillno": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ewaybillno", + }, + }, + "@ondc/org/ebnexpirydate": { + type: "string", + format: "date-time", + const: { + $data: + "/on_confirm/0/message/order/fulfillments/0/@ondc~1org~1ebnexpirydate", + }, + }, + }, + required: ["id", "type", "start", "state", "tracking"], + }, + }, + billing: { + allOf: [ + { + $ref: "confirmSchema#/properties/message/properties/order/properties/billing", + }, + { + $data: "/confirm/0/message/order/billing", + }, + ], + }, + payment: { + allOf: [ + { + $ref: "onConfirmSchema#/properties/message/properties/order/properties/payment", + }, + { + $data: "/on_confirm/0/message/order/payment", + }, + ], + }, + "@ondc/org/linked_order": { + allOf: [ + { + $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + }, + { + $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + }, + ], + }, + created_at: { + type: "string", + const: { + $data: "/confirm/0/message/order/created_at", + }, + errorMessage: "mismatches in /confirm and /on_update", + }, + updated_at: { + type: "string", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "items", + "fulfillments", + "updated_at", + "@ondc/org/linked_order", + "payment", + "billing", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js new file mode 100644 index 0000000..f8649d8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js @@ -0,0 +1,351 @@ +const constants = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "search", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + category: { + type: "object", + properties: { + id: { + type: "string", + enum: constants.CATEGORY_ID, + }, + }, + required: ["id"], + }, + provider: { + type: "object", + properties: { + time: { + type: "object", + properties: { + days: { + type: "string", + pattern: "^(?!.*(\\d).*\\1)[1-7](?:,[1-7])*(?![1-7])$", + errorMessage: + "Days format not correct. Ref footnote 9 of 1.1", + }, + schedule: { + type: "object", + properties: { + holidays: { + type: "array", + items: { + type: "string", + format: "date", + }, + }, + }, + required: ["holidays"], + }, + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^(?:[01][0-9]|2[0-3])[0-5][0-9]$", + }, + end: { + type: "string", + pattern: "^(?:[01][0-9]|2[0-3])[0-5][0-9]$", + }, + }, + isEndTimeGreater: true, + errorMessage: + 'The "end" time must be greater than the "start" time', + required: ["start", "end"], + }, + }, + required: ["days", "schedule", "range"], + }, + }, + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.FULFILLMENT_TYPE, + }, + start: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{1,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{1,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + end: { + type: "object", + properties: { + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{1,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{1,15})?)$", + allOf: [ + { + not: { + const: { $data: "3/start/location/gps" }, + }, + errorMessage: + "cannot be equal to start/location/gps '${3/start/location/gps}'", + }, + ], + errorMessage: "Incorrect gps value", + }, + address: { + type: "object", + properties: { + area_code: { + type: "string", + }, + }, + required: ["area_code"], + }, + }, + required: ["gps", "address"], + }, + }, + required: ["location"], + }, + }, + required: ["type", "start", "end"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.PAYMENT_TYPE, + }, + "@ondc/org/collection_amount": { + type: "string", + }, + }, + required: ["type"], + // if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + // then: { + // required: ["@ondc/org/collection_amount", "type"], + // errorMessage: + // "@ondc/org/collection_amount is required for payment type 'ON-FULFILLMENT'", + // }, + // else: { required: ["type"] } + allOf: [ + { + if: { + properties: { type: { const: "ON-FULFILLMENT" } }, + }, + then: { + required: ["@ondc/org/collection_amount"], + }, + }, + { + if: { + properties: { + type: { enum: ["ON-ORDER", "POST-FULFILLMENT"] }, + }, + }, + then: { + not: { required: ["@ondc/org/collection_amount"] }, + errorMessage: + "@ondc/org/collection_amount is required only for payment/type 'ON-FULFILLMENT'", + }, + }, + ], + }, + "@ondc/org/payload_details": { + type: "object", + properties: { + weight: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + minimum: 0 + }, + }, + required: ["unit", "value"], + }, + dimensions: { + type: "object", + properties: { + length: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + minimum: 0 + }, + }, + required: ["unit", "value"], + }, + breadth: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + minimum: 0 + }, + }, + required: ["unit", "value"], + }, + height: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + minimum: 0 + }, + }, + required: ["unit", "value"], + }, + }, + required: ["length", "breadth", "height"], + }, + category: { + type: "string", + enum: constants.CATEGORIES, + }, + dangerous_goods: { + type: "boolean", + }, + value: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["weight", "category", "value"], + }, + }, + required: [ + "category", + "provider", + "fulfillment", + "@ondc/org/payload_details", + "payment", + ], + }, + }, + required: ["intent"], + }, + }, + + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js old mode 100755 new mode 100644 similarity index 69% rename from utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js rename to utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js index c12164f..779d729 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/statusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js @@ -1,80 +1,93 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "status", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order_id: { - type: "string", - }, - }, - required: ["order_id"], - }, - }, - required: ["context", "message"], -}; +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "status", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js new file mode 100644 index 0000000..474fa1a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js @@ -0,0 +1,86 @@ +module.exports = { + $id: "http://example.com/schema/supportSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "support", + }, + core_version: { + type: "string", + const:"1.2.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + const: { $data: "/support/0/context/message_id" }, + errorMessage: + "Message ID should be same as /init: ${/support/0/context/message_id}", + }, + timestamp: { + type: "string", + format:"date-time" + }, + ttl: { + type: "string", + const :"PT30S" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + ref_id: { + type: "string", + }, + }, + required: ["ref_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js new file mode 100644 index 0000000..0f9d5b3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js @@ -0,0 +1,93 @@ +module.exports = { + $id: "http://example.com/schema/trackSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + }, + action: { + type: "string", + const: "track", + }, + core_version: { + type: "string", + const:"1.2.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + } + ], + }, + timestamp: { + type: "string", + format:"date-time" + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + } + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js new file mode 100644 index 0000000..ba71a39 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -0,0 +1,285 @@ +const { + PCC_CODE, + DCC_CODE, + FULFILLMENT_TAGS_LIST_CODE, + FULFILLMENT_TAGS_LIST_VALUE, +} = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + const: "nic2004:60232", + }, + country: { + type: "string", + }, + city: { + type: "string", + const: { + $data: "/on_search/0/context/properties/city", + }, + }, + action: { + type: "string", + const: "update", + }, + core_version: { + type: "string", + const: "1.2.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { + $data: "/search/0/context/transaction_id", + }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "country", + "city", + "action", + "core_version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + const: "fulfillment", + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/confirm/0/message/order/id", + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: "/confirm/0/message/order/items/0/id", + }, + }, + category_id: { + type: "string", + const: { + $data: "/confirm/0/message/order/items/0/category_id", + }, + }, + descriptor: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: + "/confirm/0/message/order/items/0/descriptor/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["id", "category_id", "descriptor"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + "@ondc/org/awb_no": { + type: "string", + }, + start: { + type: "object", + properties: { + instructions: { + type: "object", + properties: { + code: { + type: "string", + enum: PCC_CODE, + }, + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + if: { + properties: { + code: { + const: "1", + }, + }, + }, + then: { + properties: { + short_desc: { + type: "string", + minLength: 10, + maxLength: 10, + }, + }, + }, + else: { + if: { + properties: { + code: { + const: "2", + }, + }, + }, + then: { + properties: { + short_desc: { + type: "string", + maxLength: 6, + }, + }, + }, + }, + required: ["code", "short_desc"], + }, + }, + additionalProperties: false, + // required: ["instructions"], + }, + end: { + type: "object", + properties: { + instructions: { + type: "object", + properties: { + code: { + type: "string", + enum: DCC_CODE, + }, + name: { + type: "string", + }, + short_desc: { + type: "string", + maxLength: 6, + }, + long_desc: { + type: "string", + }, + }, + required: ["code", "short_desc"], + }, + }, + additionalProperties: false, + // required: ["instructions"], + }, + tags: { + allOf: [ + { + $ref: "confirmSchema#/properties/message/properties/order/properties/fulfillments/items/properties/tags", + }, + ], + }, + }, + additionalProperties: false, + required: ["id", "type", "tags"], + }, + }, + "@ondc/org/linked_order": { + allOf: [ + { + $merge: { + source: { + $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + }, + with: { + required: ["items", "order"], + }, + }, + }, + { + $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + }, + ], + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + isFutureDated: true, + errorMessage: "updated_at must not be future dated", + required: ["id", "items", "fulfillments", "updated_at"], + }, + }, + required: ["update_target", "order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/main.js b/utilities/logistics-b2b/log-verification-utility/schema/main.js index 1959fa9..3abb175 100755 --- a/utilities/logistics-b2b/log-verification-utility/schema/main.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/main.js @@ -1,20 +1,25 @@ -const retailSchemaValidator = require("./retail_api_json_schema/SchemaValidator"); -const {validate_schema_master} = require("./logistics_api_json_schema/SchemaValidator"); -const {validate_schema_b2b_master} = require("./B2B_json_schema/schemaValidator"); +const { getVersion } = require("../utils/utils"); +const { + validate_schema_master, +} = require("./logistics_api_json_schema/SchemaValidator"); +const { + validate_schema_b2b_master, +} = require("./B2B_json_schema/schemaValidator"); const fs = require("fs"); -const validate_schema_for_domain_json = (vertical, data) => { +const validate_schema_for_domain_json = (vertical, data, version) => { + version = getVersion(data); switch (vertical) { case "logistics": - res = validate_schema_master(data); + res = validate_schema_master(data, version); return res; case "b2b": - res = validate_schema_b2b_master(data); - return res; + res = validate_schema_b2b_master(data); + return res; default: console.log("Invalid Domain!!"); } }; -module.exports = validate_schema_for_domain_json; \ No newline at end of file +module.exports = validate_schema_for_domain_json; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js deleted file mode 100755 index 6283a62..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/SchemaValidator.js +++ /dev/null @@ -1,174 +0,0 @@ -const onConfirmSchema = require("./onConfirmSchema"); -const onInitSchema = require("./onInitSchema"); -const onSearchSchema = require("./onSearchSchema"); -const onSelectSchema = require("./onSelectSchema"); -const onTrackSchema = require("./onTrackSchema"); -const onSupportSchema = require("./onSupportSchema"); -const onStatusSchema = require("./onStatusSchema"); -const onCancelSchema = require("./onCancelSchema"); -const onUpdateSchema = require("./onUpdateSchema"); -const searchSchema = require("./searchSchema"); -const selectSchema = require("./selectSchema"); -const initSchema = require("./initSchema"); -const confirmSchema = require("./confirmSchema"); -const statusSchema = require("./statusSchema"); -const updateSchema = require("./updateSchema"); -const cancelSchema = require("./cancelSchema"); - -const Ajv = require("ajv"); -const ajv = new Ajv({allErrors: true,strict: "log",}); -const addFormats = require("ajv-formats"); -addFormats(ajv); -require("ajv-errors")(ajv); - -const formatted_error = (errors) => { - error_list = []; - let status = ""; - errors.forEach((error) => { - error_dict = { - message: `${error.message}${ - error.params.allowedValues ? ` (${error.params.allowedValues})` : "" - }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ - error.params.additionalProperty - ? ` (${error.params.additionalProperty})` - : "" - }`, - details: error.instancePath, - }; - error_list.push(error_dict); - }); - if (error_list.length === 0) status = "pass"; - else status = "fail"; - error_json = { errors: error_list, status: status }; - return error_json; -}; - -const validate_schema = (data, schema) => { - let error_list = []; - validate = ajv.compile(schema); - const valid = validate(data); - if (!valid) { - error_list = validate.errors; - } - return error_list; -}; - -const validate_schema_search_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = searchSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_search_retail_for_json = (data) => { - // transformed_item_data = transform_on_search_schema(data); - error_list = validate_schema(data, (schema = onSearchSchema)); - return formatted_error(error_list); -}; - -const validate_schema_select_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = selectSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_select_retail_for_json = (data) => { - item_data = data["message"]["order"]; - error_list = validate_schema(item_data, (schema = onSelectSchema)); - return formatted_error(error_list); -}; - -const validate_schema_init_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = initSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_init_retail_for_json = (data) => { - item_data = data["message"]["order"]; - error_list = validate_schema(item_data, (schema = onInitSchema)); - return formatted_error(error_list); -}; - -const validate_schema_confirm_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = confirmSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_confirm_retail_for_json = (data) => { - item_data = data["message"]["order"]; - error_list = validate_schema(item_data, (schema = onConfirmSchema)); - return formatted_error(error_list); -}; - -const validate_schema_status_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = statusSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_status_retail_for_json = (data) => { - item_data = data["message"]["order"]; - error_list = validate_schema(item_data, (schema = onStatusSchema)); - return formatted_error(error_list); -}; - -const validate_schema_cancel_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = cancelSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_cancel_retail_for_json = (data) => { - item_data = data["message"]["order"]; - error_list = validate_schema(item_data, (schema = onCancelSchema)); - return formatted_error(error_list); -}; - -const validate_schema_update_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = updateSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_update_retail_for_json = (data) => { - item_data = data["message"]["order"]; - error_list = validate_schema(item_data, (schema = onUpdateSchema)); - return formatted_error(error_list); -}; - -const validate_schema_track_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = trackSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_track_retail_for_json = (data) => { - item_data = data["message"]; - error_list = validate_schema(item_data, (schema = onTrackSchema)); - return formatted_error(error_list); -}; - -const validate_schema_support_retail_for_json = (data) => { - error_list = validate_schema(data, (schema = supportSchema)); - return formatted_error(error_list); -}; - -const validate_schema_on_support_retail_for_json = (data) => { - item_data = data["message"]; - error_list = validate_schema(item_data, (schema = onSupportSchema)); - return formatted_error(error_list); -}; - -module.exports = { - validate_schema_search_retail_for_json, - validate_schema_select_retail_for_json, - validate_schema_init_retail_for_json, - validate_schema_confirm_retail_for_json, - validate_schema_update_retail_for_json, - validate_schema_status_retail_for_json, - validate_schema_track_retail_for_json, - validate_schema_cancel_retail_for_json, - validate_schema_support_retail_for_json, - validate_schema_on_cancel_retail_for_json, - validate_schema_on_confirm_retail_for_json, - validate_schema_on_init_retail_for_json, - validate_schema_on_search_retail_for_json, - validate_schema_on_select_retail_for_json, - validate_schema_on_status_retail_for_json, - validate_schema_on_support_retail_for_json, - validate_schema_on_track_retail_for_json, - validate_schema_on_update_retail_for_json, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js deleted file mode 100755 index 8b7019c..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/initSchema.js +++ /dev/null @@ -1,273 +0,0 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "init", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - minLength: 1, - }, - fulfillment_id: { - type: "string", - minLength: 1, - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - }, - required: ["id", "fulfillment_id", "quantity"], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - }, - address: { - type: "object", - properties: { - name: { - type: "string", - }, - building: { - type: "string", - }, - locality: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - country: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - tax_number: { - type: "string", - }, - email: { - type: "string", - format: "email", - }, - phone: { - type: "string", - }, - created_at: { - type: "string", - format: "date-time", - }, - updated_at: { - type: "string", - format: "date-time", - }, - }, - required: [ - "name", - "address", - "phone", - "created_at", - "updated_at", - ], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - const: "Delivery", - }, - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "object", - properties: { - name: { - type: "string", - }, - building: { - type: "string", - }, - locality: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - country: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - }, - required: ["gps", "address"], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - }, - required: ["phone"], - }, - }, - required: ["location", "contact"], - }, - }, - required: ["id", "type", "end"], - }, - }, - }, - required: ["provider", "items", "billing", "fulfillments"], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js deleted file mode 100755 index 53fb7d0..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onCancelSchema.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - type: "object", - properties: { - id: { type: "string" }, - state: { type: "string", pattern: "^(?!s*$).+" }, - tags: { - type: "object", - properties: { - cancellation_reason_id: { - type: "string", - minLength: 3, - maxLength: 3, - }, - }, - required: ["cancellation_reason_id"], - }, - }, - required: ["id", "state", "tags"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js deleted file mode 100755 index 0eead46..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onConfirmSchema.js +++ /dev/null @@ -1,473 +0,0 @@ -module.exports = { - type: "object", - properties: { - id: { type: "string" }, - state: { type: "string", enum: ["Created", "Accepted", "Cancelled"] }, - provider: { - type: "object", - properties: { - id: { type: "string" }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - }, - required: ["id"], - }, - }, - rateable: { type: "boolean" }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - fulfillment_id: { type: "string" }, - quantity: { - type: "object", - properties: { - count: { type: "integer" }, - }, - required: ["count"], - }, - }, - required: ["id", "quantity", "fulfillment_id"], - }, - }, - - billing: { - type: "object", - properties: { - name: { type: "string" }, - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - email: { type: "string", format: "email" }, - phone: { type: "string" }, - created_at: { - type: "string", - format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - updated_at: { - type: "string", - format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - }, - required: ["name", "address", "phone", "created_at", "updated_at"], - }, - - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - "@ondc/org/provider_name": { type: "string" }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { type: "string", const: "Pending" }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - type: { type: "string", const: "Delivery" }, - tracking: { type: "boolean" }, - start: { - type: "object", - properties: { - location: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - }, - required: ["name"], - }, - gps: { type: "string" }, - }, - required: ["id", "descriptor", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time", - }, - end: { - type: "string", - format: "date-time", - }, - }, - required: ["start", "end"], - }, - }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - email: { type: "string" }, - }, - required: ["phone"], - }, - }, - required: ["location", "time", "contact"], - }, - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - gps: { type: "string" }, - }, - required: ["address", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time", - }, - end: { - type: "string", - format: "date-time", - }, - }, - required: ["start", "end"], - }, - }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - }, - required: ["phone"], - }, - }, - required: ["location", "time", "contact"], - }, - }, - required: [ - "id", - "@ondc/org/provider_name", - "state", - "type", - "tracking", - "start", - "end", - ], - }, - }, - - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { type: "string", minLength: 1 }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string" }, - }, - required: ["value", "currency"], - }, - "@ondc/org/item_id": { type: "string" }, - item: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - }, - required: ["price"], - }, - "@ondc/org/item_quantity": { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - "@ondc/org/title_type": { - type: "string", - enum: [ - "item", - "delivery", - "packing", - "tax", - "misc", - "discount", - ], - }, - }, - required: [ - "price", - "title", - "@ondc/org/title_type", - "@ondc/org/item_id", - ], - }, - }, - - ttl: { type: "string", format: "duration" }, - }, - required: ["ttl", "price", "breakup"], - }, - payment: { - type: "object", - properties: { - status: { type: "string", const: "PAID" }, - type: { type: "string", const: "ON-ORDER" }, - collected_by: { type: "string", const: "BAP" }, - params: { - type: "object", - properties: { - amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - transaction_id: { type: "string" }, - currency: { type: "string" }, - }, - required: ["amount", "currency", "transaction_id"], - }, - "@ondc/org/buyer_app_finder_fee_type": { - type: "string", - enum: ["percent", "amount"], - }, - "@ondc/org/buyer_app_finder_fee_amount": { - type: "string", - pattern: "^(\\d*.?\\d{1,2})$", - }, - "@ondc/org/settlement_details": { - type: "array", - items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - allOf: [ - { - if: { - properties: { - settlement_type: { - const: "upi", - }, - }, - }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "neft", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - ], - }, - }, - }, - required: [ - "status", - "type", - "params", - "collected_by", - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_details", - ], - // allOf: [ - // { - // if: { - // properties: { - // status: { - // const: "PAID", - // }, - // }, - // atPath: "1", - // }, - // then: { properties: { type: { const: "ON-ORDER" } } }, - // }, - // ], - }, - created_at: { type: "string", format: "date-time" }, - updated_at: { type: "string", format: "date-time" }, - }, - required: [ - "payment", - "fulfillments", - "quote", - "items", - "id", - "state", - "provider", - "billing", - "created_at", - "updated_at", - ], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js deleted file mode 100755 index 2c883d7..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onInitSchema.js +++ /dev/null @@ -1,322 +0,0 @@ -module.exports = { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { type: "string" }, - }, - required: ["id"], - }, - provider_location: { - type: "object", - properties: { - id: { type: "string" }, - }, - required: ["id"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", pattern: "^(?!s*$).+" }, - fulfillment_id: { type: "string" }, - quantity: { - type: "object", - properties: { - count: { type: "integer" }, - }, - required: ["count"], - }, - }, - required: ["id", "fulfillment_id", "quantity"], - }, - }, - billing: { - type: "object", - properties: { - name: { type: "string" }, - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - email: { type: "string", format: "email" }, - phone: { type: "string" }, - created_at: { type: "string", format: "date-time" }, - updated_at: { type: "string", format: "date-time" }, - }, - required: ["name", "address", "phone", "created_at", "updated_at"], - }, - - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - type: { type: "string", const: "Delivery" }, - tracking: { type: "boolean" }, - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - gps: { type: "string" }, - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - }, - required: ["gps", "address"], - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - email: { type: "string", format: "email" }, - }, - required: ["phone"], - }, - }, - required: ["location", "contact"], - }, - }, - - required: ["id", "type", "end"], - }, - }, - - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { type: "string", minLength: 1 }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string" }, - }, - required: ["value", "currency"], - }, - "@ondc/org/item_id": { type: "string" }, - item: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - }, - required: ["price"], - }, - "@ondc/org/item_quantity": { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - "@ondc/org/title_type": { - type: "string", - enum: [ - "item", - "delivery", - "packing", - "tax", - "misc", - "discount", - ], - }, - }, - required: [ - "price", - "title", - "@ondc/org/title_type", - "@ondc/org/item_id", - ], - }, - }, - - ttl: { type: "string", format: "duration" }, - }, - required: ["ttl", "price", "breakup"], - }, - - payment: { - type: "object", - properties: { - "@ondc/org/buyer_app_finder_fee_type": { - type: "string", - enum: ["percent", "amount"], - }, - "@ondc/org/buyer_app_finder_fee_amount": { - type: "string", - pattern: "^(\\d*.?\\d{1,2})$", - }, - "@ondc/org/settlement_details": { - type: "array", - items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - allOf: [ - { - if: { - properties: { - settlement_type: { - const: "upi", - }, - }, - }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "neft", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - ], - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - }, - }, - }, - required: [ - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_details", - ], - }, - }, - required: [ - "payment", - "fulfillments", - "billing", - "quote", - "items", - "provider", - "provider_location", - ], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js deleted file mode 100755 index 8162718..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchBPCSchema.js +++ /dev/null @@ -1,610 +0,0 @@ -module.exports = { - type: "object", - properties: { - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - type: { type: "string" }, - }, - required: ["id"], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - type: { type: "string" }, - }, - required: ["id"], - }, - }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - }, - }, - providers: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", pattern: "^(?!s*$).+" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - code: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - }, - }, - rating: { type: "string" }, - ttl: { type: "string" }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - gps: { type: "string" }, - address: { type: "string" }, - city: { - type: "object", - properties: { - code: { type: "string" }, - name: { type: "string" }, - }, - }, - state: { - type: "object", - properties: { - code: { type: "string" }, - }, - }, - country: { - type: "object", - properties: { - code: { type: "string" }, - }, - }, - area_code: { type: "string" }, - }, - }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string" }, - list: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string" }, - value: { type: "string" }, - }, - }, - }, - }, - }, - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", pattern: "^(?!s*$).+" }, - parent_item_id: { type: "string", pattern: "^(?!s*$).+" }, - descriptor: { - type: "object", - properties: { - name: { type: "string", pattern: "^(?!s*$).+" }, - code: { type: "string", pattern: "^(?!s*$).+" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - media: { - type: "array", - items: { - type: "object", - properties: { - mimetype: { - type: "string", - pattern: "^(?!s*$).+", - }, - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - }, - }, - }, - }, - manufacturer: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - }, - contact: { - type: "object", - properties: { - name: { - type: "string", - }, - address: { - type: "object", - properties: { - full: { - type: "string", - }, - }, - }, - }, - }, - phone: { - type: "string", - pattern: - "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", - }, - }, - }, - price: { - type: "object", - properties: { - currency: { type: "string", pattern: "^(?!s*$).+" }, - value: { type: "string", pattern: "^d*.?d*$" }, - offered_value: { type: "string", pattern: "^d*.?d*$" }, - maximum_value: { type: "string", pattern: "^d*.?d*$" }, - }, - require: ["currency", "value"], - }, - - quantity: { - type: "object", - properties: { - unitized: { - type: "object", - properties: { - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - }, - }, - }, - available: { - type: "object", - properties: { - count: { - type: "string", - pattern: "^d*$", - }, - }, - }, - maximum: { - type: "object", - properties: { - count: { type: "string", pattern: "^d*$" }, - }, - }, - }, - }, - category_ids: { - type: "array", - items: { - type: "string", - minItems: 1, - pattern: "^(?!s*$).+", - }, - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - minItems: 1, - pattern: "^(?!s*$).+", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - payment_ids: { - type: "array", - items: { - type: "string", - enum: ["1", "2"], - }, - }, - "add-ons": { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - code: { - type: "string", - }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - pattern: "^(?!s*$).+", - }, - value: { - type: "string", - pattern: "^d*.?d*$", - }, - offered_value: { - type: "string", - }, - maximum_value: { - type: "string", - }, - }, - }, - }, - }, - }, - cancellation_terms: { - type: "array", - items: { - anyOf: [ - { - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - }, - }, - }, - refund_eligible: { - type: "string", - }, - }, - required: ["fulfillment_state", "refund_eligible"], - }, - { - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - }, - }, - }, - return_policy: { - type: "object", - properties: { - return_eligible: { - type: "string", - }, - return_within: { - type: "string", - }, - fulfillment_managed_by: { - type: "string", - }, - return_location: { - type: "object", - properties: { - address: { - type: "string", - }, - gps: { - type: "string", - }, - }, - }, - }, - required: [ - "return_eligible", - "return_within", - "return_location", - ], - }, - }, - required: ["fulfillment_state", "return_policy"], - }, - ], - }, - minLength: 2, - }, - - replacement_terms: { - type: "array", - items: { - type: "object", - properties: { - replace_within: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["replace_within"], - }, - }, - rating: { type: "string" }, - matched: { type: "string" }, - time: { - type: "object", - properties: { - label: { type: "string" }, - range: { - type: "object", - properties: { - start: { - type: "string", - pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - end: { - type: "string", - pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - }, - }, - }, - }, - recommended: { type: "string" }, - tags: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string" }, - list: { - type: "array", - items: { - type: "object", - properties: { - code: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["code", "value"], - }, - }, - }, - }, - }, - }, - required: [ - "id", - "parent_item_id", - "descriptor", - "manufacturer", - "price", - "quantity", - "category_ids", - "fulfillment_ids", - "location_ids", - "payment_ids", - "cancellation_terms", - "replacement_terms", - "matched", - "recommended", - "tags", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - contact: { - type: "object", - properties: { - phone: { - type: "string", - pattern: - "^((+){0,1}91(s){0,1}(-){0,1}(s){0,1}){0,1}98(s){0,1}(-){0,1}(s){0,1}[1-9]{1}[0-9]{7}$", - }, - email: { - type: "string", - pattern: - "^([a-zA-Z0-9_-.]+)@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.)|(([a-zA-Z0-9-]+.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(]?)$", - }, - }, - }, - }, - }, - }, - - offers: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - code: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - required: ["url"], - }, - }, - media: { - type: "array", - items: { - type: "object", - properties: { - mimetype: { - type: "string", - pattern: "^(?!s*$).+", - }, - url: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - }, - }, - }, - }, - time: { - type: "object", - properties: { - label: { type: "string" }, - range: { - type: "object", - properties: { - start: { type: "string" }, - end: { type: "string" }, - }, - }, - }, - }, - item_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - category_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - pattern: "^(?!s*$).+", - }, - }, - }, - }, - }, - }, - }, - }, - }, - required: ["fulfillments", "payments", "descriptor", "providers"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js deleted file mode 100755 index a161f69..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchGrocerySchema.js +++ /dev/null @@ -1,490 +0,0 @@ -onSearchGrocerySchema = { - "type": "object", - "properties": { - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "payments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "providers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "rating": {"type": "string"}, - "ttl": {"type": "string"}, - "locations": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "gps": {"type": "string"}, - "address": {"type": "string"}, - "city": {"type": "object", - "properties": { - "code": {"type": "string"}, - "name": {"type": "string"}, - } - }, - "state": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "country": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "area_code": {"type": "string"}, - } - } - }, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "value": {"type": "string"}, - } - }} - } - } - }, - "items": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "parent_item_id": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "code": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - }, - }, - "manufacturer": {"type": "object", - "properties": { - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - } - }, - "contact": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "address": { - "type": "object", - "properties": { - "full": { - "type": "string"}, - } - }, - } - }, - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} - } - }, - "price": {"type": "object", - "properties": { - "currency": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "maximum_value": {"type": "string", - "pattern": "^\d*\.?\d*$"} - }, - "require": ["currency", "value"], - }, - - "quantity": {"type": "object", - "properties": { - "unitized": {"type": "object", - "properties": { - "measure": { - "type": "object", - "properties": { - "unit": { - "type": "string"}, - "value": { - "type": "string"} - - } - }, - } - }, - "available": {"type": "object", - "properties": { - "count": { - "type": "string", - "pattern": "^\d*$"} - - } - }, - "maximum": {"type": "object", - "properties": { - "count": {"type": "string", - "pattern": "^\d*$"} - } - }, - } - }, - "category_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "fulfillment_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "payment_ids": {"type": "array", - "items": { - "type": "string", - "enum": ["1", "2"]}}, - "add-ons": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "code": { - "type": "string"}, - "short_desc": { - "type": "string"}, - "long_desc": { - "type": "string"}, - "images": { - "type": "array", - "items": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "url"] - - } - } - } - }, - "price": {"type": "object", - "properties": { - "currency": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "value": { - "type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": { - "type": "string"}, - "maximum_value": { - "type": "string"} - } - }, - } - } - }, - "cancellation_terms": {"type": "array", - "items": {"anyOf": [ - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "refund_eligible": { - "type": "string"}, - }, - "required": [ - "fulfillment_state", - "refund_eligible"] - }, - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "return_policy": { - "type": "object", - "properties": { - "return_eligible": { - "type": "string"}, - "return_within": { - "type": "string"}, - "fulfillment_managed_by": { - "type": "string"}, - "return_location": { - "type": "object", - "properties": { - "address": { - "type": "string"}, - "gps": { - "type": "string"} - } - } - }, - "required": [ - "return_eligible", - "return_within", - "return_location", - ] - } - }, - "required": [ - "fulfillment_state", - "return_policy"] - } - ]}, - "minLength": 2 - }, - - "replacement_terms": {"type": "array", - "items": {"type": "object", - "properties": { - "replace_within": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "replace_within"] - } - }, - "rating": {"type": "string"}, - "matched": {"type": "string"}, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, - "end": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} - } - }, - } - }, - "recommended": {"type": "string"}, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": { - "type": "string"}, - "value": { - "type": "string"}, - }, - "required": [ - "code", - "value"] - } - }, - } - } - } - }, - "required": ["id", "parent_item_id", "descriptor", - "manufacturer", "price", "quantity", - "category_ids", "fulfillment_ids", "location_ids", - "payment_ids", - "cancellation_terms", "replacement_terms", - "matched", "recommended", "tags"], - } - }, - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "contact": {"type": "object", - "properties": { - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, - "email": {"type": "string", - "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} - } - } - }, - } - }, - - "offers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - } - }, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string"}, - "end": {"type": "string"} - } - }, - } - }, - "item_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "category_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - } - } - }, - - }, - - } - }, - - }, - "required": ["fulfillments", "payments", "descriptor", "providers"] - -} diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js deleted file mode 100755 index bce2ac3..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchItemValidations.js +++ /dev/null @@ -1,201 +0,0 @@ -onSearchRules = [ - { - if: { properties: { "@ondc/org/returnable": { const: false } } }, - then: { - not: { - required: ["@ondc/org/return_window"], - error_message: "return window is available when returnable is false", - }, - }, - }, - - { - if: { - properties: { - category_id: { - enum: [ - "F&B", - "Continental", - "Middle Eastern", - "North Indian", - "Pan-Asian", - "Regional Indian", - "South Indian", - "Tex-Mexican", - "World Cuisines", - "Healthy Food", - "Fast Food", - "Desserts", - "Bakes & Cakes", - "Beverages (MTO)", - ], - }, - }, - }, - then: { - required: ["@ondc/org/fssai_license_no"], - }, - }, - { - if: { - properties: { - category_id: { - enum: [ - "Gourmet & World Foods", - "Beverages", - "Bakery, Cakes & Dairy", - "Snacks & Branded Foods", - ], - }, - }, - }, - then: { - required: ["@ondc/org/fssai_license_no"], - }, - }, - - { - if: { properties: { "@ondc/org/returnable": { const: false } } }, - then: { - required: ["@ondc/org/return_window"], - }, - }, - - { - if: { - properties: { - category_id: { - enum: [ - "Masala & Seasoning", - "Oil & Ghee", - "Foodgrains", - "Eggs, Meat & Fish", - "Cleaning & Household", - "Beauty & Hygiene", - "Kitchen Accessories", - "Baby Care", - "Pet Care", - "Stationery", - ], - }, - }, - }, - then: { - required: ["@ondc/org/statutory_reqs_packaged_commodities"], - }, - }, - - { - if: { - properties: { - category_id: { - enum: [ - "Gourmet & World Foods", - "Beverages", - "Bakery, Cakes & Dairy", - "Snacks & Branded Foods", - ], - }, - }, - }, - then: { - required: ["@ondc/org/statutory_reqs_prepackaged_food"], - }, - }, - { - if: { - properties: { - category_id: { - const: "Fruits and Vegetables", - }, - }, - }, - then: { - required: ["@ondc/org/mandatory_reqs_veggies_fruits"], - }, - }, - - { - if: { - properties: { - category_id: { - enum: [ - "Continental", - "Middle Eastern", - "North Indian", - "Pan-Asian", - "Regional Indian", - "South Indian", - "Tex-Mexican", - "World Cuisines", - "Healthy Food", - "Fast Food", - "Desserts", - "Bakes & Cakes", - "Beverages (MTO)", - "F&B", - ], - }, - }, - }, - then: { - required: ["tags"], - }, - }, - { - if: { - properties: { - category_id: { - enum: [ - "Gourmet & World Foods", - "Beverages", - "Bakery, Cakes & Dairy", - "Snacks & Branded Foods", - ], - }, - }, - }, - then: { - required: ["tags"], - }, - }, - { - if: { - properties: { - category_id: { - enum: [ - "F&B", - "Continental", - "Middle Eastern", - "North Indian", - "Pan-Asian", - "Regional Indian", - "South Indian", - "Tex-Mexican", - "World Cuisines", - "Healthy Food", - "Fast Food", - "Desserts", - "Bakes & Cakes", - "Beverages (MTO)", - ], - }, - }, - }, - then: { - properties: { - descriptor: { - required: ["name", "symbol", "short_desc", "long_desc"], - }, - }, - }, - else: { - properties: { - descriptor: { - required: ["name", "symbol", "short_desc", "long_desc", "images"], - }, - }, - }, - }, -]; -module.exports = { onSearchRules }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js deleted file mode 100755 index 4b08957..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchSchema.js +++ /dev/null @@ -1,583 +0,0 @@ -const onSearchItemValidations = require("./onSearchItemValidations"); - -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { type: "string" }, - country: { type: "string" }, - city: { type: "string" }, - action: { type: "string" }, - core_version: { type: "string" }, - bap_id: { type: "string" }, - bap_uri: { type: "string" }, - transaction_id: { type: "string", format: "uuid" }, - message_id: { type: "string" }, - timestamp: { type: "string", format: "date-time" }, - ttl: { type: "string", format: "duration" }, - bpp_uri: { type: "string" }, - bpp_id: { type: "string" }, - }, - }, - message: { - type: "object", - properties: { - catalog: { - type: "object", - properties: { - "bpp/fulfillments": { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - type: { - type: "string", - enum: [ - "Delivery", - "Self-Pickup", - "Delivery and Self-Pickup", - ], - }, - }, - }, - }, - "bpp/descriptor": { - type: "object", - properties: { - name: { type: "string" }, - symbol: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["name", "symbol", "long_desc", "short_desc", "images"], - }, - "bpp/providers": { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - time: { - type: "object", - properties: { - label: { type: "string", enum: ["enable", "disable"] }, - timestamp: { type: "string", format: "date-time" }, - }, - required: ["label", "timestamp"], - }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - symbol: { type: "string" }, - short_desc: { type: "string" }, - long_desc: { type: "string" }, - images: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: [ - "name", - "symbol", - "long_desc", - "short_desc", - "images", - ], - }, - ttl: { type: "string", format: "duration" }, - "@ondc/org/fssai_license_no": { - type: "string", - minLength: 14, - maxLength: 14, - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - gps: { type: "string" }, - address: { - type: "object", - properties: { - street: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - required: ["street", "city", "area_code", "state"], - }, - - circle: { - type: "object", - properties: { - gps: { - type: "string", - }, - radius: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - }, - }, - }, - time: { - type: "object", - oneOf: [ - { - $ref: "#/components/schemas/fixedTimings", - }, - { - $ref: "#/components/schemas/splitTimings", - }, - ], - }, - }, - required: ["id", "address", "gps", "time"], - }, - }, - items: { - type: "array", - minItems: 1, - items: { - type: "object", - properties: { - id: { type: "string" }, - quantity: { - type: "object", - properties: { - maximum: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - }, - available: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - }, - }, - }, - category_id: { - type: "string", - enum: [ - "Fruits and Vegetables", - "Masala & Seasoning", - "Oil & Ghee", - "Gourmet & World Foods", - "Foodgrains", - "Eggs, Meat & Fish", - "Cleaning & Household", - "Beverages", - "Beauty & Hygiene", - "Bakery, Cakes & Dairy", - "Kitchen Accessories", - "Baby Care", - "Snacks & Branded Foods", - "Pet Care", - "Stationery", - "Continental", - "Middle Eastern", - "North Indian", - "Pan-Asian", - "Regional Indian", - "South Indian", - "Tex-Mexican", - "World Cuisines", - "Healthy Food", - "Fast Food", - "Desserts", - "Bakes & Cakes", - "Beverages (MTO)", - "Home Decor", - "Home Furnishings", - "Furniture", - "Garden and Outdoor Products", - "Home Improvement", - "Cookware and Dining", - "Storage and Organisation", - ], - }, - - // "@ondc/org/fssai_license_no": { - // type: "string", - // pattern: "^[a-zA-Z0-9]+$", - // }, - fulfillment_id: { type: "string" }, - location_id: { type: "string" }, - recommended: { type: "boolean" }, - "@ondc/org/returnable": { - type: "boolean", - }, - "@ondc/org/seller_pickup_return": { - type: "boolean", - }, - "@ondc/org/return_window": { - type: "string", - }, - "@ondc/org/cancellable": { - type: "boolean", - }, - "@ondc/org/time_to_ship": { - type: "string", - format: "duration", - }, - "@ondc/org/available_on_cod": { - type: "boolean", - }, - "@ondc/org/contact_details_consumer_care": { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - not: { - type: "string", - pattern: "^0$", - }, - }, - - maximum_value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - not: { type: "string", pattern: "^0$" }, - }, - }, - required: ["value", "maximum_value", "currency"], - }, - tags: { - type: "object", - properties: { - veg: { - type: "string", - enum: ["yes", "no", "Yes", "No"], - }, - non_veg: { - type: "string", - enum: ["yes", "no", "Yes", "No"], - }, - }, - required: ["veg", "non_veg"], - }, - "@ondc/org/statutory_reqs_prepackaged_food": { - type: "object", - properties: { - nutritional_info: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - importer_FSSAI_license_no: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - brand_owner_FSSAI_license_no: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - other_FSSAI_license_no: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - additives_info: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - }, - required: ["nutritional_info", "additives_info"], - oneOf: [ - { - required: ["importer_FSSAI_license_no"], - properties: { - importer_FSSAI_license_no: { - type: "string", - }, - }, - }, - { - required: ["brand_owner_FSSAI_license_no"], - properties: { - brand_owner_FSSAI_license_no: { - type: "string", - }, - }, - }, - { - required: ["other_FSSAI_license_no"], - properties: { - other_FSSAI_license_no: { - type: "string", - }, - }, - }, - ], - }, - "@ondc/org/statutory_reqs_packaged_commodities": { - type: "object", - properties: { - manufacturer_or_packer_name: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - manufacturer_or_packer_address: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - common_or_generic_name_of_commodity: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - net_quantity_or_measure_of_commodity_in_pkg: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - month_year_of_manufacture_packing_import: { - type: "string", - pattern: "^(?!\\s*$).+", - }, - }, - required: [ - "manufacturer_or_packer_name", - "manufacturer_or_packer_address", - "common_or_generic_name_of_commodity", - "month_year_of_manufacture_packing_import", - "net_quantity_or_measure_of_commodity_in_pkg", - ], - }, - "@ondc/org/mandatory_reqs_veggies_fruits": { - type: "object", - properties: { - net_quantity: { - type: "string", - minLength: 1, - }, - }, - required: ["net_quantity"], - }, - - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - symbol: { type: "string" }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - minItems: 1, - items: { - type: "string", - }, - }, - }, - }, - }, - - allOf: onSearchItemValidations.on_search_rules, - required: [ - "id", - "category_id", - "@ondc/org/contact_details_consumer_care", - "price", - "descriptor", - "@ondc/org/returnable", - "location_id", - "fulfillment_id", - "@ondc/org/cancellable", - "@ondc/org/available_on_cod", - "@ondc/org/time_to_ship", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - contact: { - type: "object", - properties: { - phone: { - type: "string", - minLength: 10, - maxLength: 11, - }, - email: { type: "string", format: "email" }, - }, - required: ["phone"], - }, - }, - required: ["contact"], - }, - }, - - tags: { - type: "array", - items: { - type: "object", - properties: { - code: { type: "string", const: "serviceability" }, - list: { - type: "array", - items: { - type: "object", - properties: { - code: { - type: "string", - enum: [ - "location", - "category", - "type", - "val", - "unit", - ], - }, - value: { type: "string" }, - }, - required: ["code", "value"], - }, - }, - }, - required: ["code", "list"], - }, - }, - }, - required: [ - "items", - "id", - "time", - "descriptor", - "locations", - "fulfillments", - "tags", - "ttl", - ], - }, - }, - }, - required: ["bpp/fulfillments", "bpp/descriptor", "bpp/providers"], - }, - }, - required: ["catalog"], - }, - }, - required: ["context", "message"], - components: { - schemas: { - fixedTimings: { - type: "object", - properties: { - days: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - minLength: 4, - maxLength: 4, - }, - end: { - type: "string", - minLength: 4, - maxLength: 4, - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays"], - additionalProperties: false, - }, - }, - required: ["days", "range", "schedule"], - }, - splitTimings: { - type: "object", - properties: { - days: { - type: "string", - }, - - schedule: { - type: "object", - properties: { - holidays: { - type: "array", - items: { - type: "string", - }, - }, - frequency: { - type: "string", - format: "duration", - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays", "frequency", "times"], - }, - }, - required: ["days", "schedule"], - additionalProperties: false, - }, - }, - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js deleted file mode 100755 index 0068133..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSearchfashionSchema.js +++ /dev/null @@ -1,490 +0,0 @@ -onSearchFashionSchema = { - "type": "object", - "properties": { - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "payments": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "type": {"type": "string"} - }, - "required": ["id"] - } - }, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "providers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - } - }, - "rating": {"type": "string"}, - "ttl": {"type": "string"}, - "locations": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "gps": {"type": "string"}, - "address": {"type": "string"}, - "city": {"type": "object", - "properties": { - "code": {"type": "string"}, - "name": {"type": "string"}, - } - }, - "state": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "country": {"type": "object", - "properties": { - "code": {"type": "string"}, - } - }, - "area_code": {"type": "string"}, - } - } - }, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "value": {"type": "string"}, - } - }} - } - } - }, - "items": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string", "pattern": "^(?!\s*$).+"}, - "parent_item_id": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "code": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - }, - }, - "manufacturer": {"type": "object", - "properties": { - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - } - }, - "contact": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "address": { - "type": "object", - "properties": { - "full": { - "type": "string"}, - } - }, - } - }, - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"} - } - }, - "price": {"type": "object", - "properties": { - "currency": {"type": "string", - "pattern": "^(?!\s*$).+"}, - "value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": {"type": "string", - "pattern": "^\d*\.?\d*$"}, - "maximum_value": {"type": "string", - "pattern": "^\d*\.?\d*$"} - }, - "require": ["currency", "value"], - }, - - "quantity": {"type": "object", - "properties": { - "unitized": {"type": "object", - "properties": { - "measure": { - "type": "object", - "properties": { - "unit": { - "type": "string"}, - "value": { - "type": "string"} - - } - }, - } - }, - "available": {"type": "object", - "properties": { - "count": { - "type": "string", - "pattern": "^\d*$"} - - } - }, - "maximum": {"type": "object", - "properties": { - "count": {"type": "string", - "pattern": "^\d*$"} - } - }, - } - }, - "category_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "fulfillment_ids": {"type": "array", - "items": { - "type": "string", "minItems": 1, - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "payment_ids": {"type": "array", - "items": { - "type": "string", - "enum": ["1", "2"]}}, - "add-ons": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": { - "type": "string"}, - "code": { - "type": "string"}, - "short_desc": { - "type": "string"}, - "long_desc": { - "type": "string"}, - "images": { - "type": "array", - "items": { - "type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "url"] - - } - } - } - }, - "price": {"type": "object", - "properties": { - "currency": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "value": { - "type": "string", - "pattern": "^\d*\.?\d*$"}, - "offered_value": { - "type": "string"}, - "maximum_value": { - "type": "string"} - } - }, - } - } - }, - "cancellation_terms": {"type": "array", - "items": {"anyOf": [ - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "refund_eligible": { - "type": "string"}, - }, - "required": [ - "fulfillment_state", - "refund_eligible"] - }, - {"type": "object", - "properties": { - "fulfillment_state": { - "type": "object", - "properties": { - "descriptor": { - "type": "object", - "properties": { - "code": { - "type": "string"} - } - }, - } - }, - "return_policy": { - "type": "object", - "properties": { - "return_eligible": { - "type": "string"}, - "return_within": { - "type": "string"}, - "fulfillment_managed_by": { - "type": "string"}, - "return_location": { - "type": "object", - "properties": { - "address": { - "type": "string"}, - "gps": { - "type": "string"} - } - } - }, - "required": [ - "return_eligible", - "return_within", - "return_location", - ] - } - }, - "required": [ - "fulfillment_state", - "return_policy"] - } - ]}, - "minLength": 2 - }, - - "replacement_terms": {"type": "array", - "items": {"type": "object", - "properties": { - "replace_within": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": [ - "replace_within"] - } - }, - "rating": {"type": "string"}, - "matched": {"type": "string"}, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"}, - "end": {"type": "string", - "pattern": "^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$"} - } - }, - } - }, - "recommended": {"type": "string"}, - "tags": {"type": "array", - "items": {"type": "object", - "properties": { - "code": {"type": "string"}, - "list": {"type": "array", - "items": {"type": "object", - "properties": { - "code": { - "type": "string"}, - "value": { - "type": "string"}, - }, - "required": [ - "code", - "value"] - } - }, - } - } - } - }, - "required": ["id", "parent_item_id", "descriptor", - "manufacturer", "price", "quantity", - "category_ids", "fulfillment_ids", "location_ids", - "payment_ids", - "cancellation_terms", "replacement_terms", - "matched", "recommended", "tags"], - } - }, - "fulfillments": {"type": "array", - "items": {"type": "object", - "properties": { - "contact": {"type": "object", - "properties": { - "phone": {"type": "string", - "pattern": "^((\+){0,1}91(\s){0,1}(\-){0,1}(\s){0,1}){0,1}98(\s){0,1}(\-){0,1}(\s){0,1}[1-9]{1}[0-9]{7}$"}, - "email": {"type": "string", - "pattern": "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"} - } - } - }, - } - }, - - "offers": {"type": "array", - "items": {"type": "object", - "properties": { - "id": {"type": "string"}, - "descriptor": {"type": "object", - "properties": { - "name": {"type": "string"}, - "code": {"type": "string"}, - "short_desc": {"type": "string"}, - "long_desc": {"type": "string"}, - "images": {"type": "array", - "items": {"type": "object", - "properties": { - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - }, - "required": ["url"] - - } - }, - "media": {"type": "array", - "items": {"type": "object", - "properties": { - "mimetype": { - "type": "string", - "pattern": "^(?!\s*$).+"}, - "url": { - "type": "string", - "pattern": "^(?!\s*$).+"} - } - } - }, - } - }, - "time": {"type": "object", - "properties": { - "label": {"type": "string"}, - "range": {"type": "object", - "properties": { - "start": {"type": "string"}, - "end": {"type": "string"} - } - }, - } - }, - "item_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "category_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - "location_ids": {"type": "array", - "items": { - "type": "string", - "pattern": "^(?!\s*$).+"}}, - } - } - }, - - }, - - } - }, - - }, - "required": ["fulfillments", "payments", "descriptor", "providers"] - -} diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js deleted file mode 100755 index 4450640..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSelectSchema.js +++ /dev/null @@ -1,175 +0,0 @@ -module.exports = { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { type: "string" }, - }, - required: ["id"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", minLength: 1 }, - fulfillment_id: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["id", "fulfillment_id"], - }, - }, - - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { type: "string", minLength: 1 }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string" }, - }, - required: ["value", "currency"], - }, - "@ondc/org/item_id": { type: "string" }, - item: { - type: "object", - properties: { - quantity: { - type: "object", - properties: { - maximum: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - }, - available: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - }, - }, - }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - }, - }, - required: ["price", "quantity"], - }, - "@ondc/org/item_quantity": { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - "@ondc/org/title_type": { - type: "string", - enum: [ - "item", - "delivery", - "packing", - "tax", - "misc", - "discount", - ], - }, - }, - required: [ - "price", - "title", - "@ondc/org/title_type", - "@ondc/org/item_id", - ], - }, - }, - - ttl: { type: "string", format: "duration" }, - }, - required: ["ttl", "price", "breakup"], - }, - - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string", pattern: "^(?!s*$).+" }, - "@ondc/org/provider_name": { type: "string" }, - tracking: { type: "boolean" }, - "@ondc/org/category": { - type: "string", - enum: [ - "Express Delivery", - "Standard Delivery", - "Immediate Delivery", - "Same Day Delivery", - "Next Day Delivery", - ], - }, - "@ondc/org/TAT": { type: "string", format: "duration" }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: ["Serviceable", "Non-serviceable"], - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - }, - - required: [ - "id", - "@ondc/org/provider_name", - "state", - "@ondc/org/category", - "@ondc/org/TAT", - ], - }, - }, - }, - required: ["provider", "items", "fulfillments", "quote"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js deleted file mode 100755 index faae4e4..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onStatusSchema.js +++ /dev/null @@ -1,548 +0,0 @@ -const postConfirmRules = require("./postConfirmValidations"); - -module.exports = { - type: "object", - properties: { - id: { type: "string" }, - state: { - type: "string", - enum: ["Created", "Accepted", "In-progress", "Completed", "Cancelled"], - }, - provider: { - type: "object", - properties: { - id: { type: "string" }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - }, - required: ["id"], - }, - }, - rateable: { type: "boolean" }, - }, - required: ["id", "locations"], - }, - - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - fulfillment_id: { type: "string" }, - quantity: { - type: "object", - properties: { - count: { type: "integer" }, - }, - required: ["count"], - }, - tags: { - type: "object", - properties: { - status: { - type: "string", - enum: [ - "Return_Initiated", - "Return_Approved", - "Return_Rejected", - "Return_Picked", - "Return_Delivered", - "Liquidated", - "Cancelled", - ], - }, - }, - required: ["status"], - }, - }, - required: ["id", "quantity", "fulfillment_id"], - }, - }, - - billing: { - type: "object", - properties: { - name: { type: "string" }, - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - email: { type: "string", format: "email" }, - phone: { type: "string" }, - created_at: { - type: "string", - format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - updated_at: { - type: "string", - format: "date-time", - // pattern: "^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$", - }, - }, - required: ["name", "address", "phone", "created_at", "updated_at"], - }, - - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - "@ondc/org/provider_name": { type: "string" }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: [ - "Pending", - "Packed", - "Order-picked-up", - "Out-for-delivery", - "Order-delivered", - "RTO-Initiated", - "RTO-Delivered", - "RTO-Disposed", - "Cancelled", - ], - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - type: { - type: "string", - enum: ["Delivery", "Self-Pickup", "Reverse QC"], - }, - tracking: { type: "boolean" }, - start: { - type: "object", - properties: { - location: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - images: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["name"], - }, - gps: { type: "string" }, - }, - required: ["id", "descriptor", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time", - }, - end: { - type: "string", - format: "date-time", - }, - }, - required: ["start", "end"], - }, - timestamp: { - type: "string", - format: "date-time", - }, - }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - email: { type: "string" }, - }, - required: ["phone"], - }, - }, - required: ["location", "time", "contact"], - }, - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - gps: { type: "string" }, - }, - required: ["address", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time", - }, - end: { - type: "string", - format: "date-time", - }, - }, - required: ["start", "end"], - }, - timestamp: { - type: "string", - format: "date-time", - }, - }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - }, - required: ["phone"], - }, - }, - required: ["location", "time", "contact"], - }, - }, - required: [ - "id", - "@ondc/org/provider_name", - "state", - "type", - "tracking", - "start", - "end", - ], - }, - }, - - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { type: "string", minLength: 1 }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string" }, - }, - required: ["value", "currency"], - }, - "@ondc/org/item_id": { type: "string" }, - item: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - }, - required: ["price"], - }, - "@ondc/org/item_quantity": { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - "@ondc/org/title_type": { - type: "string", - enum: [ - "item", - "delivery", - "packing", - "tax", - "misc", - "discount", - ], - }, - }, - required: [ - "price", - "title", - "@ondc/org/title_type", - "@ondc/org/item_id", - ], - }, - }, - - ttl: { type: "string", format: "duration" }, - }, - required: ["ttl", "price", "breakup"], - }, - payment: { - type: "object", - properties: { - status: { type: "string", const: "PAID" }, - type: { type: "string", const: "ON-ORDER" }, - collected_by: { type: "string", const: "BAP" }, - params: { - type: "object", - properties: { - amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - transaction_id: { type: "string" }, - currency: { type: "string" }, - }, - required: ["amount", "currency", "transaction_id"], - }, - "@ondc/org/buyer_app_finder_fee_type": { - type: "string", - enum: ["percent", "amount"], - }, - "@ondc/org/buyer_app_finder_fee_amount": { - type: "string", - pattern: "^(\\d*.?\\d{1,2})$", - }, - "@ondc/org/settlement_details": { - type: "array", - items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - allOf: [ - { - if: { - properties: { - settlement_type: { - const: "upi", - }, - }, - }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "neft", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - ], - }, - }, - }, - required: [ - "status", - "type", - "params", - "collected_by", - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_details", - ], - // allOf: [ - // { - // if: { - // properties: { - // status: { - // const: "PAID", - // }, - // }, - // atPath: "1", - // }, - // then: { properties: { type: { const: "ON-ORDER" } } }, - // }, - // ], - }, - documents: { - type: "array", - items: { - type: "object", - properties: { - url: { type: "string" }, - label: { type: "string", const: "Invoice" }, - }, - }, - }, - tags: { - type: "object", - properties: { - cancellation_reason_id: { - type: "string", - maxLength: 3, - minLength: 3, - }, - }, - }, - created_at: { type: "string", format: "date-time" }, - updated_at: { type: "string", format: "date-time" }, - }, - // allOf: postConfirmRules, - required: [ - "payment", - "fulfillments", - "quote", - "items", - "id", - "state", - "provider", - "billing", - "created_at", - "updated_at", - ], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js deleted file mode 100755 index 96dacab..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onSupportSchema.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - format: "email", - }, - uri: { type: "string" }, - }, - required: ["phone"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js deleted file mode 100755 index e232a05..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onTrackSchema.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - type: "object", - properties: { - tracking: { - type: "object", - properties: { - url: { type: "string" }, - status: { type: "string", enum: ["active", "inactive"] }, - }, - required: ["status"], - }, - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js deleted file mode 100755 index 2a979f4..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/onUpdateSchema.js +++ /dev/null @@ -1,486 +0,0 @@ -const postConfirmRules = require("./postConfirmValidations"); - -module.exports = { - type: "object", - properties: { - id: { type: "string" }, - state: { - type: "string", - enum: ["Created", "Accepted", "In-progress", "Completed", "Cancelled"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - fulfillment_id: { type: "string" }, - quantity: { - type: "object", - properties: { - count: { type: "integer" }, - }, - required: ["count"], - }, - tags: { - type: "object", - properties: { - status: { - type: "string", - enum: [ - "Return_Initiated", - "Return_Approved", - "Return_Rejected", - "Return_Picked", - "Return_Delivered", - "Liquidated", - "Cancelled", - ], - }, - }, - required: ["status"], - }, - }, - required: ["id", "quantity", "fulfillment_id"], - }, - }, - - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { type: "string" }, - "@ondc/org/provider_name": { type: "string" }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: [ - "Pending", - "Packed", - "Order-picked-up", - "Out-for-delivery", - "Order-delivered", - "RTO-Initiated", - "RTO-Delivered", - "RTO-Disposed", - "Cancelled", - ], - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - type: { - type: "string", - enum: ["Delivery", "Self-Pickup", "Reverse QC"], - }, - tracking: { type: "boolean" }, - start: { - type: "object", - properties: { - location: { - type: "object", - properties: { - id: { type: "string" }, - descriptor: { - type: "object", - properties: { - name: { type: "string" }, - images: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["name"], - }, - gps: { type: "string" }, - }, - required: ["id", "descriptor", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time", - }, - end: { - type: "string", - format: "date-time", - }, - }, - required: ["start", "end"], - }, - timestamp: { - type: "string", - format: "date-time", - }, - }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - email: { type: "string" }, - }, - required: ["phone"], - }, - }, - required: ["location", "time", "contact"], - }, - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - address: { - type: "object", - properties: { - name: { type: "string" }, - building: { type: "string" }, - locality: { type: "string" }, - city: { type: "string" }, - state: { type: "string" }, - country: { type: "string" }, - area_code: { type: "string" }, - }, - required: [ - "name", - "building", - "locality", - "city", - "state", - "country", - "area_code", - ], - }, - gps: { type: "string" }, - }, - required: ["address", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time", - }, - end: { - type: "string", - format: "date-time", - }, - }, - required: ["start", "end"], - }, - timestamp: { - type: "string", - format: "date-time", - }, - }, - required: ["range"], - }, - instructions: { - type: "object", - properties: { - name: { type: "string" }, - short_desc: { type: "string" }, - }, - }, - contact: { - type: "object", - properties: { - phone: { type: "string" }, - }, - required: ["phone"], - }, - }, - required: ["location", "time", "contact"], - }, - }, - required: [ - "id", - "@ondc/org/provider_name", - "state", - "type", - "tracking", - "start", - "end", - ], - }, - }, - - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { type: "string", minLength: 1 }, - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string" }, - }, - required: ["value", "currency"], - }, - "@ondc/org/item_id": { type: "string" }, - item: { - type: "object", - properties: { - price: { - type: "object", - properties: { - value: { - type: "string", - minLength: 1, - pattern: "^(\\d*.?\\d{1,2})$", - }, - currency: { type: "string", pattern: "^(?!s*$).+" }, - }, - required: ["value", "currency"], - }, - }, - required: ["price"], - }, - "@ondc/org/item_quantity": { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - "@ondc/org/title_type": { - type: "string", - enum: [ - "item", - "delivery", - "packing", - "tax", - "misc", - "discount", - ], - }, - }, - required: [ - "price", - "title", - "@ondc/org/title_type", - "@ondc/org/item_id", - ], - }, - }, - - ttl: { type: "string", format: "duration" }, - }, - required: ["ttl", "price", "breakup"], - }, - payment: { - type: "object", - properties: { - status: { type: "string", const: "PAID" }, - type: { type: "string", const: "ON-ORDER" }, - collected_by: { type: "string", const: "BAP" }, - params: { - type: "object", - properties: { - amount: { type: "string", pattern: "^(\\d*.?\\d{1,2})$" }, - transaction_id: { type: "string" }, - currency: { type: "string" }, - }, - required: ["amount", "currency", "transaction_id"], - }, - "@ondc/org/buyer_app_finder_fee_type": { - type: "string", - enum: ["percent", "amount"], - }, - "@ondc/org/buyer_app_finder_fee_amount": { - type: "string", - pattern: "^(\\d*.?\\d{1,2})$", - }, - "@ondc/org/settlement_details": { - type: "array", - items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - enum: ["upi", "neft", "rtgs"], - }, - upi_address: { type: "string", pattern: "^(?!s*$).+" }, - settlement_bank_account_no: { - type: "string", - pattern: "^(?!s*$).+", - }, - settlement_ifsc_code: { - type: "string", - pattern: "^(?!s*$).+", - }, - bank_name: { type: "string" }, - beneficiary_name: { - type: "string", - }, - branch_name: { type: "string" }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - ], - allOf: [ - { - if: { - properties: { - settlement_type: { - const: "upi", - }, - }, - }, - then: { - required: ["upi_address"], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "rtgs", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - { - if: { - properties: { - settlement_type: { - const: "neft", - }, - }, - }, - then: { - required: [ - "settlement_ifsc_code", - "settlement_bank_account_no", - "bank_name", - "branch_name", - ], - }, - }, - ], - }, - }, - }, - required: [ - "status", - "type", - "params", - "collected_by", - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_details", - ], - // allOf: [ - // { - // if: { - // properties: { - // status: { - // const: "PAID", - // }, - // }, - // atPath: "1", - // }, - // then: { properties: { type: { const: "ON-ORDER" } } }, - // }, - // ], - }, - documents: { - type: "array", - items: { - type: "object", - properties: { - url: { type: "string" }, - label: { type: "string", const: "Invoice" }, - }, - }, - }, - tags: { - type: "object", - properties: { - cancellation_reason_id: { - type: "string", - maxLength: 3, - minLength: 3, - }, - }, - }, - created_at: { type: "string", format: "date-time" }, - updated_at: { type: "string", format: "date-time" }, - }, - // allOf: postConfirmRules, - required: [ - "payment", - "fulfillments", - "quote", - "items", - "id", - "state", - "created_at", - "updated_at", - ], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js deleted file mode 100755 index 9eb1efd..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/searchSchema.js +++ /dev/null @@ -1,140 +0,0 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "search", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - intent: { - type: "object", - properties: { - item: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: ["descriptor"], - }, - fulfillment: { - type: "object", - properties: { - type: { - type: "string", - const: "Delivery", - }, - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "object", - properties: { - area_code: { - type: "string", - }, - }, - required: ["area_code"], - }, - }, - required: ["gps"], - }, - }, - required: ["location"], - }, - }, - required: ["type", "end"], - }, - payment: { - type: "object", - properties: { - "@ondc/org/buyer_app_finder_fee_type": { - type: "string", - enum: ["percent", "amount"], - }, - "@ondc/org/buyer_app_finder_fee_amount": { - type: "string", - }, - }, - required: [ - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - ], - }, - }, - required: ["item", "fulfillment", "payment"], - }, - }, - required: ["intent"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js deleted file mode 100755 index dfd110d..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/selectSchema.js +++ /dev/null @@ -1,170 +0,0 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "select", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - location_id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - }, - required: ["id", "location_id", "quantity"], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - end: { - type: "object", - properties: { - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "object", - properties: { - area_code: { - type: "string", - }, - }, - required: ["area_code"], - }, - }, - required: ["gps", "address"], - }, - }, - required: ["location"], - }, - }, - required: ["end"], - }, - }, - billing: { - type: "object", - properties: { - tax_number: { - type: "string", - }, - }, - required: ["tax_number"], - }, - }, - required: ["provider", "items", "fulfillments"], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js deleted file mode 100755 index 2bf87e6..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/updateSchema.js +++ /dev/null @@ -1,201 +0,0 @@ -module.exports = { - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - const: "nic2004:52110", - }, - action: { - type: "string", - const: "update", - }, - country: { - type: "string", - }, - city: { - type: "string", - }, - core_version: { - type: "string", - const: "1.1.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - format: "uuid", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - format: "duration", - }, - }, - required: [ - "domain", - "action", - "country", - "city", - "core_version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - update_target: { - type: "string", - enum: ["item", "payment"], - }, - order: { - type: "object", - properties: { - id: { - type: "string", - }, - state: { - type: "string", - enum: ["Created", "Accepted", "In-progress", "Completed"], - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - tags: { - type: "object", - properties: { - update_type: { - type: "string", - enum: ["return", "cancel"], - }, - reason_code: { - type: "string", - minLength: 3, - maxLength: 3, - }, - ttl_approval: { - type: "string", - format: "duration", - }, - ttl_reverseqc: { - type: "string", - format: "duration", - }, - image: { - type: "string", - }, - }, - required: ["update_type"], - allOf: [ - { - if: { - properties: { - update_type: { - const: "return", - }, - reason_code: { type: "string" }, - }, - required: ["update_type"], - }, - then: { required: ["reason_code"] }, - }, - ], - }, - }, - required: ["id", "quantity", "tags"], - }, - }, - payment: { - type: "object", - properties: { - "@ondc/org/settlement_details": { - type: "array", - items: { - type: "object", - properties: { - settlement_counterparty: { - type: "string", - }, - settlement_phase: { - type: "string", - }, - settlement_type: { - type: "string", - }, - settlement_amount: { - type: "string", - }, - settlement_timestamp: { - type: "string", - format: "date-time", - }, - }, - required: [ - "settlement_counterparty", - "settlement_phase", - "settlement_type", - "settlement_amount", - "settlement_timestamp", - ], - }, - }, - }, - required: ["@ondc/org/settlement_details"], - }, - }, - required: ["id", "state", "provider", "items"], - }, - }, - required: ["update_target", "order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js b/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js new file mode 100644 index 0000000..2ba5383 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js @@ -0,0 +1,48 @@ +const fs = require("fs"); +const path = require("path"); +const express = require("express"); +const router = express.Router(); +const { + SUPPORTED_DOMAINS_SORTED_INDEX, + FULL_ACTION_LIST, + SERVER_LOG_DEST, + ...constants +} = require("../../utils/constants"); +const validate_schema_for_domain_json = require("../../schema/main"); +const { validateLogs } = require("../../utils/validateLogUtil"); +const readLogFiles = require("../../utils/logistics/readLogFiles"); + +router.get("/", (req, res) => { + res.json({ msg: "Head over to /validate for route validation" }); +}); + +// Route defined to validate logs + +router.post("/validate/:domain", async (req, res) => { + try { + const { logPath } = req.body; + const { domain } = req.params; + + /* -------- Input validation ------- */ + if (!logPath) + return res.status(400).json({ msg: 'Req Body needs to have "logPath"' }); + + if (!Object.keys(SUPPORTED_DOMAINS_SORTED_INDEX).includes(domain)) + return res + .status(404) + .json({ msg: `Domain ${domain} not supported yet!` }); + + /* ------ End of Input validation ------- */ + + const destination = await readLogFiles(domain, logPath); + await validateLogs(domain, logPath, destination); + const logReport = JSON.parse( + fs.readFileSync(path.join(destination, "log_report.json")).toString() + ); + return res.json({ logReport }); + } catch (error) { + return res.status(500).json({ msg: "Error occurred while report generation" }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/server/server.js b/utilities/logistics-b2b/log-verification-utility/server/server.js new file mode 100644 index 0000000..4e99167 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/server/server.js @@ -0,0 +1,12 @@ +const express = require('express') +const router = require("./routes/routes") +const app = express() +const port = process.env.PORT || 3000 + +app.use(express.json()) +app.use(express.urlencoded({extended: true})) +app.use(router) + +app.listen(port, () => { + console.log(`Log Validation running on PORT ${port}`) +}) \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/server/utils/fileHandler.js b/utilities/logistics-b2b/log-verification-utility/server/utils/fileHandler.js new file mode 100644 index 0000000..d5b330d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/server/utils/fileHandler.js @@ -0,0 +1,51 @@ +const { FULL_ACTION_LIST, SERVER_LOG_DEST } = require("../../utils/constants"); +const path = require("path"); + +const multer = require("multer"); +// const multiStorage = multer.diskStorage({ +// destination: (req, file, cb) => { +// // initial upload path +// console.log("Hello", req.files.search[0]) +// const data = JSON.parse(req.files[0].buffer.toString()); +// if (!(data && data.context && data.context.transaction_id)) cb(Error("No file found!"), undefined); +// let destination = path.join( +// __dirname, +// SERVER_LOG_DEST, +// data.context.transaction_id +// ); + +// cb(null, destination); +// }, +// filename: (_req, file, callback) => { +// callback( +// null, +// file.fieldname + path.extname(file.originalname).toLowerCase() +// ); +// }, +// }); + + +const multiStorage = multer.memoryStorage({}); +const singleStorage = multer.memoryStorage({}); + +const fileFilter = (_req, file, callback) => { + // Check ext + const extname = /json/.test(path.extname(file.originalname).toLowerCase()); + // Check mime + const mimetype = /json/.test(file.mimetype); + + if (mimetype && extname) { + return callback(null, true); + } else { + return callback(null, false); + } +}; + +const uploadMultiple = multer({ storage: multiStorage, fileFilter }); +const uploadSingle = multer({storage: singleStorage, fileFilter}); + +const logsUpload = uploadMultiple.fields( + FULL_ACTION_LIST.map((name) => ({ name, maxCount: 1 })) +); +const logUpload = uploadSingle.single("log") +module.exports = { logsUpload, logUpload }; diff --git a/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js b/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js index 4524f73..3ef2327 100755 --- a/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js +++ b/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js @@ -4,9 +4,9 @@ const vl = require("../utils/validateLogUtil"); const fs = require("fs"); const validateLog = async (domain, dirPath) => { - console.log("Inside Log Validation Service..."); + console.log("Inside Log Validation Service...", dirPath); const logsPath = path.join(__dirname, "..", dirPath); - vl.validateLogs(domain, logsPath); + await vl.validateLogs(domain, logsPath); }; module.exports = { validateLog }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/services/service.js b/utilities/logistics-b2b/log-verification-utility/services/service.js index 882ea54..42886b6 100755 --- a/utilities/logistics-b2b/log-verification-utility/services/service.js +++ b/utilities/logistics-b2b/log-verification-utility/services/service.js @@ -2,7 +2,7 @@ const { logisticsVal } = require("../utils/logistics/msgValidator"); const { b2bVal } = require("../utils/b2b/msgValidator"); const _ = require("lodash"); -const checkMessage = (domain, element, action, msgIdSet) => { +const checkMessage = async (domain, element, action, msgIdSet) => { const busnsErr = {}; switch (domain) { case "logistics": diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 6c1bbb4..4513deb 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -2,28 +2,45 @@ const fs = require("fs"); const _ = require("lodash"); const dao = require("../dao/dao"); const utils = require("./utils"); +const { error } = require("console"); -const checkContextVal = (payload, Obj, msgIdSet) => { +const checkContextVal = (payload, msgIdSet, i) => { try { + action = payload.context.action; - if (!Obj.hasOwnProperty(action)) { - Obj[action] = {}; - } + console.log(`Checking context validations for ${action}`); + // if (!Obj.hasOwnProperty(action)) { + // Obj = {}; + // } + let Obj = {}; let data = payload.context; if (data.timestamp) { let date = data.timestamp; result = utils.timestampCheck(date); if (result && result.err === "FORMAT_ERR") { - Obj[action].tmstmpFrmt_err = + Obj.tmstmpFrmt_err = "Timestamp not in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format"; } else if (result && result.err === "INVLD_DT") { - Obj[action].tmstmpFrmt_err = "Timestamp should be in date-time format"; + Obj.tmstmpFrmt_err = "Timestamp should be in date-time format"; + } + } + try { + console.log(`Comparing Message Id of /${action}`); + if (!action.includes("on_") || action ==="on_status" || action ==="on_update") { + if (msgIdSet.has(payload.context.message_id)) { + Obj.msgIdErr = + "Message Id cannot be same for different sets of APIs"; + } else { + msgIdSet.add(payload.context.message_id); + } } + } catch (error) { + console.log(error); } try { if (action !== "on_status") { - //console.log(`Comparing timestamp of /${action}`); + console.log(`Comparing timestamp of /${action}`); if (_.gte(dao.getValue("tmpstmp"), payload.context.timestamp)) { if ( action === "support" || @@ -38,27 +55,29 @@ const checkContextVal = (payload, Obj, msgIdSet) => { action === "on_update" || action === "on_cancel" ) { - console.log(dao.getValue(`${action.replace("on_", "")}Tmpstmp`), - payload.context.timestamp); + console.log( + dao.getValue(`${action.replace("on_", "")}Tmpstmp`), + payload.context.timestamp + ); if ( _.gte( dao.getValue(`${action.replace("on_", "")}Tmpstmp`), payload.context.timestamp ) ) { - Obj[action].tmpstmp = `Timestamp for /${action.replace( + Obj.tmpstmpErr = `Timestamp for /${action.replace( "on_", "" )} api cannot be greater than or equal to /${action} api`; } } - Obj[action].tmpstmp = `Timestamp mismatch for /${action} `; + Obj.tmpstmpErr = `Timestamp mismatch for /${action} `; } else { if ( action === "on_search" || action === "on_init" || action === "on_confirm" || - action ==="on_update" + action === "on_update" ) { const timeDiff = utils.timeDiff( payload.context.timestamp, @@ -66,9 +85,7 @@ const checkContextVal = (payload, Obj, msgIdSet) => { ); //console.log(timeDiff); if (timeDiff > 1000) { - Obj[ - action - ].tmpstmp = `context/timestamp difference between ${action} and ${action.replace( + Obj.tmpstmpErr = `context/timestamp difference between ${action} and ${action.replace( "on_", "" )} should be smaller than 1 sec`; @@ -90,4 +107,4 @@ const checkContextVal = (payload, Obj, msgIdSet) => { } } }; -module.exports = checkContextVal; \ No newline at end of file +module.exports = checkContextVal; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/postConfirmValidations.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js old mode 100755 new mode 100644 similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/retail_api_json_schema/postConfirmValidations.js rename to utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js new file mode 100644 index 0000000..e69de29 diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js new file mode 100644 index 0000000..e69de29 diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnUpdate.js new file mode 100644 index 0000000..e69de29 diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js new file mode 100644 index 0000000..e69de29 diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bUpdate.js new file mode 100644 index 0000000..e69de29 diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index 34c9a00..bfe17c0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -1,4 +1,10 @@ +const checkConfirm = require("./b2bConfirm"); +const checkInit = require("./b2bInit"); +const checkOnConfirm = require("./b2bOnConfirm"); +const checkOnInit = require("./b2bOnInit"); const checkOnSearch = require("./b2bOnSearch"); +const checkOnUpdate = require("./b2bOnUpdate"); +const checkUpdate = require("./b2bUpdate"); const checkOnStatus = require("./b2bOnStatus"); const checkSearch = require("./b2bSearch"); const _ = require("lodash"); @@ -12,6 +18,24 @@ const b2bVal = (element, action, msgIdSet) => { case "on_search": return checkOnSearch(element, msgIdSet); + case "init": + return checkInit(element, msgIdSet); + + case "on_init": + return checkOnInit(element, msgIdSet); + + case "confirm": + return checkConfirm(element, msgIdSet); + + case "on_confirm": + return checkOnConfirm(element, msgIdSet); + + case "update": + return checkUpdate(element,msgIdSet); + + case "on_update": + return checkOnUpdate(element,msgIdSet) + case "on_status": return checkOnStatus(element,msgIdSet) } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 92fbd1c..3092b2a 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -2,11 +2,58 @@ module.exports = Object.freeze({ RET_CONTEXT_TTL: "PT30S", RET_CONTEXT_ACTION: "action", DB_PATH: "dbfiles", - DB_Keys: {"search": {"context": ['timestamp', 'transaction_id', 'message_id', 'city'], - "message": {"intent": {"payment": ['@ondc/org/buyer_app_finder_fee_amount']}}}, - "on_search": {"context": ['bap_id', 'bpp_id'], "message": ['catalog']}}, - LOG_SORTED_INDEX: ['search','on_search','init','on_init','confirm','on_confirm'], - B2B_SORTED_INDEX:['search','on_search','select','on_select','init','on_init','confirm','on_confirm'], + DB_Keys: { + search: { + context: ["timestamp", "transaction_id", "message_id", "city"], + message: { + intent: { payment: ["@ondc/org/buyer_app_finder_fee_amount"] }, + }, + }, + on_search: { context: ["bap_id", "bpp_id"], message: ["catalog"] }, + }, + SUPPORTED_DOMAINS_SORTED_INDEX: { + logistics: 'LOG_SORTED_INDEX', + b2b: 'B2B_SORTED_INDEX', + }, // must match mergesort.js + SERVER_LOG_DEST: "/public/server", + FULL_ACTION_LIST: [ + "search", + "on_search", + "select", + "on_select", + "init", + "on_init", + "confirm", + "on_confirm", + "track", + "on_track", + "cancel", + "on_cancel", + "update", + "on_update", + "status", + "on_status", + "support", + "on_support", + ], + LOG_SORTED_INDEX: [ + "search", + "on_search", + "init", + "on_init", + "confirm", + "on_confirm", + ], + B2B_SORTED_INDEX: [ + "search", + "on_search", + "select", + "on_select", + "init", + "on_init", + "confirm", + "on_confirm", + ], RET_SEARCH: "search", RET_ONSEARCH: "on_search", RET_SELECT: "select", @@ -25,24 +72,98 @@ module.exports = Object.freeze({ RET_ONSTATUS: "on_status", RET_SUPPORT: "support", RET_ONSUPPORT: "on_support", - //logistics - LOG_CONTEXT_TTL: "PT30S", - LOG_CONTEXT_ACTION: "action", - LOG_SEARCH: "search", - LOG_ONSEARCH: "on_search", - LOG_INIT: "init", - LOG_ONINIT: "on_init", - LOG_CONFIRM: "confirm", - LOG_ONCONFIRM: "on_confirm", - LOG_TRACK: "track", - LOG_ONTRACK: "on_track", - LOG_CANCEL: "cancel", - LOG_ONCANCEL: "on_cancel", - LOG_UPDATE: "update", - LOG_ONUPDATE: "on_update", - LOG_STATUS: "status", - LOG_ONSTATUS: "on_status", - LOG_SUPPORT: "support", - LOG_ONSUPPORT: "on_support", - + //logistics + LOG_CONTEXT_TTL: "PT30S", + LOG_CONTEXT_ACTION: "action", + LOG_SEARCH: "search", + LOG_ONSEARCH: "on_search", + LOG_INIT: "init", + LOG_ONINIT: "on_init", + LOG_CONFIRM: "confirm", + LOG_ONCONFIRM: "on_confirm", + LOG_TRACK: "track", + LOG_ONTRACK: "on_track", + LOG_CANCEL: "cancel", + LOG_ONCANCEL: "on_cancel", + LOG_UPDATE: "update", + LOG_ONUPDATE: "on_update", + LOG_STATUS: "status", + LOG_ONSTATUS: "on_status", + LOG_SUPPORT: "support", + LOG_ONSUPPORT: "on_support", + FULFILLMENT_TYPE: ["Delivery", "Return", "RTO"], + CATEGORY_ID: [ + "Express Delivery", + "Standard Delivery", + "Immediate Delivery", + "Same Day Delivery", + "Next Day Delivery", + ], + PAYMENT_TYPE: ["ON-ORDER", "ON-FULFILLMENT", "POST-FULFILLMENT"], + PAYMENT_COLLECTEDBY: ["BAP", "BPP"], + UNITS_WEIGHT: ["kilogram", "gram"], + UNITS_DIMENSIONS: ["centimeter", "meter"], + CATEGORIES: [ + "Grocery", + "F&B", + "Fashion", + "BPC", + "Electronics", + "Home & Decor", + "Pharma", + "Agriculture", + "Mobility", + ], + SHIPMENT_TYPE: ["P2P", "P2H2P"], + SETTLEMENT_TYPE: ["upi", "neft", "rtgs"], + TITLE_TYPE: ["delivery", "rto", "reverseqc","tax"], + PCC_CODE: ["1", "2", "3", "4"], + DCC_CODE: ["1", "2", "3"], + FULFILLMENT_TAGS_CODE: ["state", "rto_action","weather_check"], + FULFILLMENT_TAGS_LIST_CODE: ["ready_to_ship", "return_to_origin"], + FULFILLMENT_TAGS_LIST_VALUE: ["yes", "no"], + TRACKING_STATUS: ["active", "inactive"], + ORDER_STATE: ["Created", "Accepted", "Cancelled", "In-progress","Completed"], + CANCELLATION_CODE: [ + "001", + "002", + "003", + "004", + "005", + "006", + "008", + "009", + "010", + "011", + "012", + "013", + "014", + "015", + "016", + "017", + "018", + "019", + "020", + "021", + ], + FULFILLMENT_STATE: [ + "Pending", + "Searching-for-Agent", + "Agent-assigned", + "Out-for-pickup", + "Pickup-failed", + "Pickup-rescheduled", + "Order-picked-up", + "In-transit", + "At-destination-hub", + "Out-for-delivery", + "Delivery-failed", + "Delivery-rescheduled", + "Order-delivered", + "RTO-Initiated", + "RTO-Delivered", + "RTO-Disposed", + "Cancelled", + ], + CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/csvToJson.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/csvToJson.js new file mode 100644 index 0000000..a087cc0 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/csvToJson.js @@ -0,0 +1,23 @@ +const fs = require('fs'); +const path = require('path'); + + const convertCSVtoJson = async (fileName) => { + const data = fs.readFileSync(path.join(__dirname, fileName), 'utf8'); + let dataStr = data.split('\n'); + let dataToStr = dataStr.map((elem) => { + const elemArr = elem.split(','); + const key = elemArr[0]; + const obj = {}; + obj[key] = elemArr[elemArr.length - 1].trim('\r'); + return obj; + }); + + const finalObj = {}; + dataToStr.forEach((elem) => { + finalObj[Object.keys(elem)[0]] = elem[Object.keys(elem)[0]]; + }) + fs.writeFileSync(path.join(__dirname, 'pinToStd.json'), `${JSON.stringify(finalObj)}`, 'utf8'); + return; +}; + +module.exports = convertCSVtoJson; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index e84fdc9..388cbaa 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -1,31 +1,80 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const constants = require("../constants"); -const utils = require ("../utils.js"); +const utils = require("../utils.js"); const checkConfirm = (data, msgIdSet) => { - let cnfrmObj = {}; let confirm = data; + let version = confirm.context.core_version; + let onSearchProvArr = dao.getValue("providersArr"); + confirm = confirm.message.order; + let rts; + if (confirm.provider.locations && confirm.provider.locations.length > 1) + dao.setValue("confirm_locations", confirm.provider.locations); - confirm = confirm.message.order; - let rts= confirm?.fulfillments[0]?.tags['@ondc/org/order_ready_to_ship']; - dao.setValue("rts",rts); - const cnfrmOrdrId = confirm.id; - dao.setValue("cnfrmOrdrId", cnfrmOrdrId); - let awbNo= false; + if (version === "1.1.0") + rts = confirm?.fulfillments[0]?.tags["@ondc/org/order_ready_to_ship"]; + else { + let fulTags = confirm?.fulfillments[0].tags; + fulTags.forEach((tag) => { + if (tag.code === "state") { + const lists = tag.list; + lists.forEach((list) => { + if (list.code === "ready_to_ship") { + rts = list.value; + } + }); + } + }); + } + let provId = confirm.provider.id; + let items = confirm.items; + + try { + console.log( + `Comparing item duration and timestamp in /on_search and /confirm` + ); + 2; + items.forEach((item) => { + if (item.time) { + onSearchProvArr.forEach((provider) => { + if (provider.id === provId) { + const onSearchItemsObj = provider.items; + onSearchItemsObj.forEach((onSrchItem) => { + console.log(onSrchItem); + if (onSrchItem.id === item.id) { + if (onSrchItem?.time?.duration !== item?.time?.duration) + cnfrmObj.itemDurationErr = `item duration does not match with the one provided in /on_search (LSP can send NACK)`; + if (onSrchItem?.time?.timestamp !== item?.time?.timestamp) + cnfrmObj.itemTmstmpErr = `item timestamp does not match with the one provided in /on_search (LSP can send NACK)`; + } + }); + } + }); + } + }); + } catch (error) {} + + dao.setValue("rts", rts); + const cnfrmOrdrId = confirm.id; + dao.setValue("cnfrmOrdrId", cnfrmOrdrId); + let awbNo = false; let fulfillments = confirm.fulfillments; - let p2h2p = dao.getValue("p2h2p") - fulfillments.forEach(fulfillment => { - if(fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo= true; - if(fulfillment?.tags["@ondc/org/order_ready_to_ship"]==='yes' && !fulfillment?.start?.instructions?.short_desc){ - cnfrmObj.instructionsErr=`PCC code is required in /fulfillments/start/instructions when ready_to_ship = 'yes'` + let p2h2p = dao.getValue("p2h2p"); + fulfillments.forEach((fulfillment) => { + if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; + if ( + rts === "yes" && + !fulfillment?.start?.instructions?.short_desc + ) { + cnfrmObj.instructionsErr = `fulfillments/start/instructions are required when ready_to_ship = 'yes'`; } }); - - dao.setValue("awbNo",awbNo); - return cnfrmObj; + + dao.setValue("awbNo", awbNo); + return cnfrmObj; }; module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index 5ae0d49..72f30bf 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -4,6 +4,13 @@ const constants = require("../constants"); const utils = require("../utils"); const checkInit = (data, msgIdSet) => { + const billing = data.message.order.billing + const billingAdd= billing.address + const len = billingAdd.name.length + billingAdd.building.length +billingAdd.locality.length + console.log(billingAdd.name.length,billingAdd.building.length,billingAdd.locality.length); + console.log("length",len); + if (billingAdd.name.length + billingAdd.building.length +billingAdd.locality.length > 190) return true + else false const initObj = {}; let init = data; let p2h2p = false; @@ -20,10 +27,10 @@ const checkInit = (data, msgIdSet) => { console.log(`Comparing provider object in /init and /on_search`); if (init.provider) { onSearchitemsArr = dao.getValue(`${init.provider.id}itemsArr`); - let providerObj = providersArr.filter( + let providerObj = providersArr?.filter( (prov) => prov.id === init.provider.id ); - if (providerObj?.length < 1) { + if (!providerObj || providerObj?.length < 1) { initObj.prvdrErr = `Provider with id '${init.provider.id}' does not exist in the catalog provided in /on_search`; } else { if ( @@ -63,11 +70,11 @@ const checkInit = (data, msgIdSet) => { console.log(`Comparing item object in /init and /on_search`); let itemExists = false; - itemsArr.forEach((item, i) => { + itemsArr?.forEach((item, i) => { if (item.descriptor.code === "P2H2P") { p2h2p = true; } - onSearchitemsArr.forEach((element) => { + onSearchitemsArr?.forEach((element) => { if (item.id === element.id) itemExists = true; console.log(item.id, element.id); }); @@ -98,10 +105,10 @@ const checkInit = (data, msgIdSet) => { itemkey ] = `Fulfillment id '${fulfillment.id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; } else { - let bppfulfillment = bppFulfillmentsArr.find( + let bppfulfillment = bppFulfillmentsArr?.find( (element) => element.id === fulfillment.id ); - if (fulfillment.type !== bppfulfillment.type) { + if (fulfillment.type !== bppfulfillment?.type) { let itemkey = `flfillmentTypeErr${i}`; initObj[ itemkey diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js new file mode 100644 index 0000000..3e0e952 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -0,0 +1,91 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnCancel = (data, msgIdSet) => { + let onCancelObj = {}; + let on_cancel = data; + let contextTime = on_cancel.context.timestamp; + let messageId = on_cancel.context.message_id; + + on_cancel = on_cancel.message.order; + let ffState; + let orderState = on_cancel.state; + let items = on_cancel.items; + let fulfillments = on_cancel.fulfillments; + let RtoPickupTime; + + + try { + if (fulfillments.length > 1) { + console.log( + `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` + ); + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + if ((fulfillment.type === "Prepaid" || fulfillment.type === "Delivery") && ffState !== "Cancelled") { + onCancelObj.flflmntstErr = `In case of RTO, fulfillment with type '${fulfillment.type}' needs to be 'Cancelled'`; + } + }); + } + } catch (error) { + console.log(error); + } + try { + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + console.log( + `Comparing pickup and delivery timestamps for on_cancel_${ffState}` + ); + + if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery") { + + if (ffState === "Cancelled") { + if (orderState !== "Cancelled") { + onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; + } + if (fulfillments.length > 1) { + if (!fulfillment.start.time.timestamp) { + onCancelObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; + } + } + + if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { + if ( + !_.isEqual( + dao.getValue("pickupTime"), + fulfillment.start.time.timestamp + ) + ) { + onCancelObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + } + + } + } else if (fulfillment.type === "RTO" || fulfillment.type === "Return") { + if (orderState !== "Cancelled") { + onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; + } + if (ffState === "RTO-Initiated") { + RtoPickupTime = fulfillment?.start?.time?.timestamp; + console.log(RtoPickupTime); + if (RtoPickupTime) { + dao.setValue("RtoPickupTime", RtoPickupTime); + } else { + onCancelObj.rtoPickupTimeErr = `RTO Pickup (fulfillments/start/time/timestamp) time is missing for fulfillment state - ${ffState}`; + } + if (_.gt(RtoPickupTime, contextTime)) { + onCancelObj.rtoPickupErr = `RTO Pickup (fulfillments/start/time/timestamp) time cannot be future dated for fulfillment state - ${ffState}`; + } + } + } + }); + } catch (error) { + console.log(`Error checking fulfillments/start in /on_cancel`); + } + + return onCancelObj; +}; + +module.exports = checkOnCancel; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 95ff20a..910679e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -18,11 +18,13 @@ const checkOnConfirm = (data, msgIdSet) => { console.log(`checking start and end time range in fulfillments`); fulfillments.forEach((fulfillment) => { if(fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo= true; - console.log(rts) - if (rts === "yes" && !fulfillment?.start?.time?.range && dao.getValue("updateApi")===false) { + console.log("rts",rts) + + if (rts === "yes" && !fulfillment?.start?.time?.range) { + onCnfrmObj.strtRangeErr = `start/time/range is required in /fulfillments when ready_to_ship = yes in /confirm`; } - if (rts === "yes" && !fulfillment?.end?.time?.range && dao.getValue("updateApi")===false) { + if (rts === "yes" && !fulfillment?.end?.time?.range) { onCnfrmObj.endRangeErr = `end/time/range is required in /fulfillments when ready_to_ship = yes in /confirm`; } }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js index 11cd048..638e31f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js @@ -11,9 +11,9 @@ const checkOnInit = (data, msgIdSet) => { on_init = on_init.message.order; let provId = on_init.provider.id; - let itemId = on_init.items[0].id; + let onSearchProvArr = dao.getValue("providersArr"); - + try { console.log( `Comparing order quote price and break up in ${constants.LOG_ONINIT}` @@ -32,24 +32,33 @@ const checkOnInit = (data, msgIdSet) => { ] = `Price value for '${breakup["@ondc/org/title_type"]}' should not have more than 2 decimal places`; } totalBreakup += parseFloat(breakup.price.value); - onSearchProvArr.forEach((provider) => { + + onSearchProvArr?.forEach((provider) => { + if (provider.id === provId) { provider?.items.forEach((item, i) => { - if (item.id === itemId) { - if (breakup.price.value !== item.price.value) { + + if ( + item.id === breakup["@ondc/org/item_id"] && + (breakup["@ondc/org/title_type"] === "delivery") + ) { + if (parseFloat(on_init.quote.price.value) !== parseFloat(item.price.value)) { let itemKey = `priceArr${i}`; onInitObj[ itemKey - ] = `Quote price ${breakup.price.value} for '${breakup["@ondc/org/title_type"]}' does not match item price ${item.price.value} in /on_search`; + ] = `Quote price ${parseFloat(on_init.quote.price.value)} for item id '${breakup["@ondc/org/item_id"]}' does not match item price ${item.price.value} in /on_search`; } } + }); + + } }); }); if (parseFloat(on_init.quote.price.value) !== totalBreakup) - onInitObj.quotePriceErr = `Quote price does not match the breakup total in ${constants.LOG_ONINIT}`; + onInitObj.quotePriceErr = `Quote price ${parseFloat(on_init.quote.price.value)} does not match the breakup total ${totalBreakup} in ${constants.LOG_ONINIT}`; } } catch (err) { console.log( @@ -61,4 +70,4 @@ const checkOnInit = (data, msgIdSet) => { return onInitObj; }; -module.exports = checkOnInit; \ No newline at end of file +module.exports = checkOnInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js index 5f8d71d..52f78c8 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js @@ -2,10 +2,13 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const constants = require("../constants"); const utils = require("../utils"); +const {reverseGeoCodingCheck} = require("../reverseGeoCoding") const checkOnSearch = (data, msgIdSet) => { const onSrchObj = {}; let onSearch = data; + let core_version = onSearch.context.core_version; + let timestamp = onSearch.context.timestamp; let search = dao.getValue("searchObj"); let validFulfillmentIDs = new Set(); onSearch = onSearch.message.catalog; @@ -19,27 +22,55 @@ const checkOnSearch = (data, msgIdSet) => { provider.categories.forEach((category) => { const catName = category.id; const categoryTime = category.time; + const currentDate = timestamp.split('T')[0]; + const dateObj = new Date(currentDate); + const nextDate = new Date(dateObj.setDate(dateObj.getDate() + 1)).toISOString().split('T')[0]; + const categoryTimestamp = core_version == "1.1.0" ? categoryTime?.timestamp?.split('T')[0] : categoryTime?.timestamp; + if((catName == 'Same Day Delivery' || catName == 'Immediate Delivery') && categoryTimestamp && categoryTimestamp != currentDate){ + onSrchObj.TAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` + } + if(catName == 'Next Day Delivery' && categoryTimestamp && categoryTimestamp != nextDate){ + onSrchObj.TAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` + } provider.items.forEach((item) => { const catId = item.category_id; const itemTime = item.time; + const itemTimestamp = core_version == "1.1.0" ? itemTime?.timestamp?.split('T')[0] : itemTime?.timestamp; if (catName === catId && !categoryTime && !itemTime) onSrchObj.TAT = `Either Category level TAT or Item level TAT should be given in ${constants.LOG_ONSEARCH} api for category "${catName}"`; + if((catId == 'Same Day Delivery' || catId == 'Immediate Delivery') && itemTimestamp && itemTimestamp != currentDate){ + onSrchObj.TAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` + } + if(catId == 'Next Day Delivery' && itemTimestamp && itemTimestamp != nextDate){ + onSrchObj.TAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` + } }); }); }); } } catch (error) { - console.log(`!!Error while fetching category and item TAT`, error); + console.log( + `!!Error while fetching category and item TAT`, + error + ); } + //forward and backward shipment try { console.log( `Checking forward and backward shipment in ${constants.LOG_ONSEARCH} api` ); - if (onSearch["bpp/fulfillments"]) { - const fulfillments = onSearch["bpp/fulfillments"]; + if ( + onSearch["bpp/fulfillments"] || + onSearch["bpp/providers"][0].fulfillments + ) { + const fulfillments = + core_version === "1.1.0" + ? onSearch["bpp/fulfillments"] + : onSearch["bpp/providers"][0].fulfillments; + dao.setValue("bppFulfillmentsArr", fulfillments); let hasForwardShipment = false; @@ -47,22 +78,24 @@ const checkOnSearch = (data, msgIdSet) => { for (const fulfillment of fulfillments) { validFulfillmentIDs.add(fulfillment.id); - if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD") { + if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery") { hasForwardShipment = true; } else if ( fulfillment.type === "RTO" || - fulfillment.type === "Reverse QC" + fulfillment.type === "Reverse QC" || fulfillment.type === "Return" ) { hasBackwardShipment = true; } } if (hasForwardShipment && hasBackwardShipment) { - console.log("Both forward and backward shipments are present."); + console.log( + "Both forward and backward shipments are present." + ); } else if (!hasForwardShipment) { - onSrchObj.frwrdShpmnt = `Forward shipment (Prepaid or CoD) is missing in ${constants.LOG_ONSEARCH} api`; + onSrchObj.frwrdShpmnt = `Forward shipment is missing in fulfillments in ${constants.LOG_ONSEARCH} api`; } else if (!hasBackwardShipment) { - onSrchObj.bkwrdshmpnt = `Backward shipment (RTO or Reverse QC) is missing in ${constants.LOG_ONSEARCH} api`; + onSrchObj.bkwrdshmpnt = `Backward shipment is missing in fulfillments in ${constants.LOG_ONSEARCH} api`; } } } catch (error) { @@ -82,11 +115,11 @@ const checkOnSearch = (data, msgIdSet) => { providers.forEach((provider, i) => { let itemsArr = provider.items; const providerId = provider.id; - + dao.setValue(`${providerId}itemsArr`, itemsArr); itemsArr.forEach((item, j) => { if (!validFulfillmentIDs.has(item.fulfillment_id)) { - onSrchObj.fulfillmentIDerr = `fulfillment_id of /items/${j} for /bpp/provider/${i} does not match with the id in bpp/fulfillments in ${constants.LOG_ONSEARCH} api`; + onSrchObj.fulfillmentIDerr = `fulfillment_id - ${item.fulfillment_id} of /items/${j} does not match with any id in fulfillments array in ${constants.LOG_ONSEARCH} api`; } if ( item.descriptor.code === "P2H2P" && @@ -107,6 +140,30 @@ const checkOnSearch = (data, msgIdSet) => { ); } + // RGC checks on bpp/provider + + console.log(`Checking Reverse Geocoding on bpp/providers`); + if (onSearch.hasOwnProperty("bpp/providers")) { + onSearch["bpp/providers"].forEach((provider) => { + if (provider.hasOwnProperty("locations")) { + provider.locations.forEach( + async ({ id, gps, address: { area_code } }) => { + try { + const [lat, long] = gps.split(","); + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) + onSrchObj[ + "bpp/provider:location:" + id + ":RGC" + ] = `Reverse Geocoding for location ID ${id} failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } catch (error) { + console.log("bpp/providers error: ", error); + } + } + ); + } + }); + } + return onSrchObj; }; -module.exports = checkOnSearch; \ No newline at end of file +module.exports = checkOnSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index 06b0eaa..1093c5c 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -16,18 +16,6 @@ const checkOnStatus = (data, msgIdSet) => { let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; - // try { - // console.log( - // `Checking if message id is unique for different on_status apis` - // ); - // if (msgIdSet.has(messageId)) { - // onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; - // } else { - // msgIdSet.add(messageId); - // } - // } catch (error) { - // console.log(`Error checking message id in /on_status API`); - // } try { if (fulfillments.length > 1) { @@ -36,8 +24,8 @@ const checkOnStatus = (data, msgIdSet) => { ); fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; - if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { - onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; + if ((fulfillment.type === "Prepaid" || fulfillment.type === "Delivery") && ffState !== "Cancelled") { + onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Delivery/Prepaid' needs to in 'Cancelled' state`; } }); } @@ -51,7 +39,7 @@ const checkOnStatus = (data, msgIdSet) => { `Comparing pickup and delivery timestamps for on_status_${ffState}` ); - if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD") { + if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery") { if (ffState === "Pending" || ffState === "Agent-assigned") { if (fulfillment?.start?.time?.timestamp) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; @@ -71,24 +59,28 @@ const checkOnStatus = (data, msgIdSet) => { } if (_.gt(pickupTime, contextTime)) { - onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; } if (fulfillment?.end?.time?.timestamp) { onStatusObj.delvryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; } } if (ffState === "Out-for-delivery") { + if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } - if (!dao.getValue("pickupTime")) { - onStatusObj.pickupTimeErr = `Missing /on_status response for fulfillment state - 'Order-picked-up'`; + if (!fulfillment?.start?.time?.timestamp) { + { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; + } } else if ( - !fulfillment?.start?.time?.timestamp || + dao.getValue("pickupTime") && fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } + if (fulfillment?.end?.time?.timestamp) { onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; } @@ -98,19 +90,24 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; } deliveryTime = fulfillment?.end?.time?.timestamp; + dao.setValue("deliveryTime", deliveryTime); - if (!dao.getValue("pickupTime")) { - onStatusObj.pickupTimeErr = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; + if (!fulfillment?.start?.time?.timestamp) { + { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; + } } else if ( - !fulfillment?.start?.time?.timestamp || fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } + if (!deliveryTime) { onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; } - + if (_.gt(deliveryTime, contextTime)) { + onStatusObj.tmstmpErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } if (_.gte(pickupTime, deliveryTime)) { onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; } @@ -148,25 +145,25 @@ const checkOnStatus = (data, msgIdSet) => { } } } - } else if (fulfillment.type === "RTO") { + } else if (fulfillment.type === "RTO" || fulfillment.type === "Return") { if (orderState !== "Cancelled") { onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } - if (ffState === "RTO-Initiated") { + if (ffState === "RTO-Initiated" && fulfillment.type === "Prepaid" ) { RtoPickupTime = fulfillment?.start?.time?.timestamp; + console.log(RtoPickupTime); if (RtoPickupTime) { dao.setValue("RtoPickupTime", RtoPickupTime); } else { - onStatusObj.rtoPickupTimeErr = `RTO Pickup timestamp is missing for fulfillment state - ${ffState}`; + onStatusObj.rtoPickupTimeErr = `RTO Pickup (fulfillments/start/time/timestamp) time is missing for fulfillment state - ${ffState}`; } if (_.gt(RtoPickupTime, contextTime)) { onStatusObj.rtoPickupErr = `RTO Pickup (fulfillments/start/time/timestamp) time cannot be future dated for fulfillment state - ${ffState}`; } } + if (ffState === "RTO-Delivered" || ffState === "RTO-Disposed") { RtoDeliveredTime = fulfillment?.end?.time?.timestamp; - console.log(dao.getValue("RtoPickupTime")); - if (!RtoDeliveredTime && ffState === "RTO-Delivered") onStatusObj.rtoDlvryTimeErr = `RTO Delivery timestamp (fulfillments/end/time/timestamp) is missing for fulfillment state - ${ffState}`; if ( @@ -189,7 +186,7 @@ const checkOnStatus = (data, msgIdSet) => { } }); } catch (error) { - console.log(`Error checking fulfillments/start in /update`); + console.log(`Error checking fulfillments/start in /on_status`); } return onStatusObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js index 3a1fcd5..251b8a6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js @@ -6,13 +6,24 @@ const utils = require("../utils.js"); const checkOnUpdate = (data, msgIdSet) => { let onUpdtObj = {}; let on_update = data; + let contextTimestamp = on_update?.context?.timestamp; let rts = dao.getValue("rts"); on_update = on_update.message.order; let fulfillments = on_update.fulfillments; let items = on_update.items; let p2h2p = dao.getValue("p2h2p"); let awbNo = dao.getValue("awbNo"); + let locationsPresent = dao.getValue("confirm_locations"); + if (on_update?.updated_at > contextTimestamp) { + onUpdtObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; + } + + if (locationsPresent) { + if (!_.isEqual(on_update?.provider?.locations, locationsPresent)) { + onUpdtObj.locationsErr = `order/provider/locations mismatch between /confirm and /on_update` + } + } try { console.log( `Checking if start and end time range required in /on_update api` @@ -25,6 +36,10 @@ const checkOnUpdate = (data, msgIdSet) => { onUpdtObj.awbNoErr = "AWB No (@ondc/org/awb_no) is required in /fulfillments for P2H2P shipments (may be provided in /confirm or /update by logistics buyer or /on_confirm or /on_update by LSP)"; } + if (awbNo && !p2h2p) { + onUpdtObj.awbNoErr = + "AWB No (@ondc/org/awb_no) is not required for P2P fulfillments"; + } if (rts === "yes" && !fulfillment?.start?.time?.range) { onUpdtObj.strtRangeErr = `start/time/range is required in /fulfillments when ready_to_ship = yes in /update`; } @@ -40,8 +55,7 @@ const checkOnUpdate = (data, msgIdSet) => { console.log(`!!Error while checking fulfillments in /on_update api`, error); } - return onUpdtObj; }; -module.exports = checkOnUpdate; \ No newline at end of file +module.exports = checkOnUpdate; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js index 1910586..1847fc0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js @@ -1,14 +1,22 @@ const _ = require("lodash"); +const fs = require("fs"); +const path = require("path"); const dao = require("../../dao/dao"); const constants = require("../constants"); const utils = require("../utils.js"); +const {reverseGeoCodingCheck} = require("../reverseGeoCoding") -const checkSearch = (data, msgIdSet) => { +const checkSearch = async (data, msgIdSet) => { let srchObj = {}; let search = data; let contextTime = search.context.timestamp; search = search.message.intent; + const { + start: { location: startLocation }, + end: { location: endLocation }, + } = data.message.intent.fulfillment; + try { console.log(`Checking if holidays are in past date or not`); let holidays = search?.provider?.time?.schedule?.holidays; @@ -24,9 +32,42 @@ const checkSearch = (data, msgIdSet) => { }); } } catch (error) { - console.log(error); + console.log("Error while checking holidays", error); + } + + console.log("Checking Reverse Geocoding for `start` location in `fullfilment`") + try { + const [lat, long] = startLocation.gps.split(",") + const area_code = startLocation.address.area_code + const match = await reverseGeoCodingCheck(lat, long, area_code) + if(!match) srchObj['RGC-start-Err'] = `Reverse Geocoding for \`start\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.` + } catch (error) { + console.log("Error in start location", error) + } + + // check for context cityCode and fulfillment start location + try { + const pinToStd = JSON.parse(fs.readFileSync(path.join(__dirname,'pinToStd.json'), 'utf8')); + const stdCode = data.context.city.split(':')[1]; + const area_code = startLocation?.address?.area_code; + if(pinToStd[area_code] && pinToStd[area_code] != stdCode){ + srchObj['CityCode-Err'] = `CityCode ${stdCode} should match the city for the fulfillment start location ${area_code}, ${pinToStd[area_code]}`; + } + } catch (err) { + console.error("Error in city code check: ", err.message); + } + + console.log("Checking Reverse Geocoding for `end` location in `fullfilment`") + try { + const [lat, long] = endLocation.gps.split(",") + const area_code = endLocation.address.area_code + const match = await reverseGeoCodingCheck(lat, long, area_code) + if(!match) srchObj['RGC-end-Err'] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.` + } catch (error) { + console.log("Error in end location",error) } + console.log("srchObj from search:", srchObj) dao.setValue("searchObj", search); return srchObj; }; -module.exports = checkSearch; \ No newline at end of file +module.exports = checkSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js index 89a93fa..a97eec7 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js @@ -6,13 +6,28 @@ const utils = require("../utils.js"); const checkUpdate = (data, msgIdSet) => { let updtObj = {}; let update = data; + let version = update.context.core_version; let p2h2p = dao.getValue("p2h2p"); let awbNo= dao.getValue("awbNo"); dao.setValue("updateApi",true) update = update.message.order; - let rts = update?.fulfillments[0]?.tags["@ondc/org/order_ready_to_ship"]; + if (version === "1.1.0") + rts = update?.fulfillments[0]?.tags["@ondc/org/order_ready_to_ship"]; +else { + let fulTags = update?.fulfillments[0].tags; + fulTags.forEach((tag) => { + if (tag.code === "state") { + const lists = tag.list; + lists.forEach((list) => { + if (list.code === "ready_to_ship") { + rts = list.value; + } + }); + } + }); +} dao.setValue("rts", rts); let items = update.items; let fulfillments = update.fulfillments; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js index 44762d2..c7679dc 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js @@ -6,10 +6,11 @@ const checkOnSearch = require("./logOnSearch"); const checkOnUpdate = require("./logOnUpdate"); const checkUpdate = require("./logUpdate"); const checkOnStatus = require("./logOnStatus"); +const checkOnCancel = require("./logOnCancel"); const checkSearch = require("./logSearch"); const _ = require("lodash"); -const logisticsVal = (element, action, msgIdSet) => { +const logisticsVal = async (element, action, msgIdSet) => { const busnsErr = {}; switch (action) { case "search": @@ -38,6 +39,9 @@ const logisticsVal = (element, action, msgIdSet) => { case "on_status": return checkOnStatus(element,msgIdSet) + + case "on_cancel": + return checkOnCancel(element,msgIdSet) } return busnsErr; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json b/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json new file mode 100644 index 0000000..4875211 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json @@ -0,0 +1 @@ +{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"08414","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/readLogFiles.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/readLogFiles.js new file mode 100644 index 0000000..5bd2edb --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/readLogFiles.js @@ -0,0 +1,28 @@ +const fs = require('fs'); +const path = require('path'); +const { SERVER_LOG_DEST } = require('../constants'); + +const readLogFiles = async (domain, logPath) => { + try { + const files = fs.readdirSync(logPath); + const firstFileData = fs.readFileSync( + path.join( + logPath, + files.filter((filename) => filename.match(/\.json$/))[0] + ) + ); + const destination = path.join( + __dirname, + "../../", + SERVER_LOG_DEST, + domain, + JSON.parse(firstFileData.toString()).context.transaction_id + ); + fs.mkdirSync(destination, { recursive: true }); + return destination; + } catch (err) { + throw err; + } +}; + +module.exports = readLogFiles; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js index c364870..61aa6db 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js @@ -6,42 +6,58 @@ const sortMerge = (domain, directory, destination) => { flowErrObj = {}; try { var mergedlogs = []; + files = fs.readdirSync(directory); let map; - switch(domain) { - case 'logistics': - map = constants.LOG_SORTED_INDEX + switch (domain) { + case "logistics": + map = constants.LOG_SORTED_INDEX; break; - case 'b2b': - map = constants.B2B_SORTED_INDEX + case "b2b": + map = constants.B2B_SORTED_INDEX; break; } mergedlogs = files.reduce((acc, item) => { + // Skip processing if the file name matches "merged.json" or "log_report.json" + if (item === "merged.json" || item === "log_report.json") { + return acc; + } try { - let data = fs.readFileSync(`${directory}/${item}`); - data = JSON.parse(data); - const context = data.context; - if (!context || !context.action) { - console.log( - `Error in file ${item}: Missing 'context' or 'action' property` - ); - return acc; // Skip this data and continue with the next iteration - } - const { action } = data.context; - if (acc.hasOwnProperty(action)) { + if (item.match(/\.json$/)) { + let data = fs.readFileSync(`${directory}/${item}`); + data = JSON.parse(data); + const context = data.context; + if (!context || !context.action) { + console.log( + `Error in file ${item}: Missing 'context' or 'action' property` + ); + return acc; // Skip this data and continue with the next iteration + } + const { action } = data.context; + + if (!acc[action]) { + acc[action] = []; + } + acc[action].push(data); - } else { - acc[action] = [data]; + return acc; } - return acc; } catch (error) { console.log(`Error in file ${item}`); console.trace(error); } }, {}); + let oldLogs; + if(fs.existsSync(destination)){ + oldLogs = fs.readFileSync(destination, 'utf8'); + } + + oldLogs = oldLogs ? JSON.parse(oldLogs) : {}; + mergedlogs = { ...oldLogs, ...mergedlogs }; + // Sort the arrays within each action based on context.timestamp for (const action in mergedlogs) { const array = mergedlogs[action]; @@ -77,14 +93,15 @@ const sortMerge = (domain, directory, destination) => { `Flow incorrect- current action: ${action}, Current Index:${i}, Index in correct flow:${curIndex}` ); flowErrObj[ - i + 0 ] = `Incorrect Flow as per context/timestamps - (${Object.keys( mergedlogs )})`; + } } }); - + fs.writeFileSync(destination, JSON.stringify(mergedlogs)); return flowErrObj; } catch (err) { @@ -92,4 +109,4 @@ const sortMerge = (domain, directory, destination) => { console.trace(err); } }; -module.exports = { sortMerge }; \ No newline at end of file +module.exports = { sortMerge }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js b/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js index b3fe451..6f84937 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ret.cbCheck.util.js @@ -1,7 +1,7 @@ const { validateLogsUtil } = require("./validateLogUtil"); -const validateLogs = (domain) => { - validateLogsUtil(domain); +const validateLogs = async (domain) => { + await validateLogsUtil(domain); }; module.exports = { validateLogs }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js b/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js new file mode 100644 index 0000000..dc1abfc --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js @@ -0,0 +1,23 @@ +/** + * + * @param {string} lat The Latitude Coordinate upto 6 decimal place + * @param {string } long The Longgitude Coordinate upto 6 decimal place + * @param {string} area_code The Area Code to check the above lat-long pair against + * @returns {boolean} Returns `true` if `area_code` matched lat-long pair + */ + require("dotenv").config(); +const reverseGeoCodingCheck = async (lat, long, area_code) => { + var fetch = require("node-fetch"); + var requestOptions = { + method: "GET", + }; + try { + const res = await fetch(`https://apis.mappls.com/advancedmaps/v1/${process.env.MAPPLS_API_KEY}/rev_geocode?lat=${lat}&lng=${long}`, requestOptions); + const response = await res.json(); + return response.results[0].pincode === area_code + } catch (error) { + console.log(error); + } +}; + +module.exports = { reverseGeoCodingCheck }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js b/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js index 2215be8..2cf1e92 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/schemaVal.js @@ -7,11 +7,10 @@ const validateSchema = require("./schemaValidation"); const path = require("path"); const checkContextVal = require("./ContextVal"); -const Validate = (domain, dirPath, msgIdSet, ErrorObj) => { +const Validate = async (domain, dirPath, msgIdSet, ErrorObj) => { try { let log = fs.readFileSync(dirPath); log = JSON.parse(log); - count = 0; // Validating Schema try { @@ -26,19 +25,22 @@ const Validate = (domain, dirPath, msgIdSet, ErrorObj) => { console.log(`!!Error occurred while performing schema validation`, error); } contextObj = ErrorObj["Context"]; - Object.entries(log).forEach(([action, elements]) => { - // Validate schema for each element in the array associated with the action - elements.forEach((element, i) => { + for (const [action, elements] of Object.entries(log)) { + for (const [i, element] of elements.entries()) { // Validating action context level checks try { if (!("Context" in ErrorObj)) ErrorObj["Context"] = {}; - CntxtObj = ErrorObj["Context"]; + // CntxtObj = ErrorObj["Context"]; //console.log(`Validating timestamp for ${action} api`); if (action != "search") { - const ValCheck = checkContextVal(element, CntxtObj, msgIdSet); - if (ValCheck != "error") { - Object.assign(CntxtObj, ValCheck); - } + ErrorObj["Context"][`${action}_${i}`] = checkContextVal( + element, + msgIdSet, + i + ); + // if (ValCheck != "error") { + // Object.assign(CntxtObj, ValCheck); + // } } else { dao.setValue("tmpstmp", element.context.timestamp); } @@ -52,12 +54,11 @@ const Validate = (domain, dirPath, msgIdSet, ErrorObj) => { // Business validations try { if (!("Message" in ErrorObj)) ErrorObj["Message"] = {}; - ErrorObj["Message"][`${action}_${i}`] = checkMessage( + ErrorObj["Message"][`${action}_${i}`] = await checkMessage( domain, element, action, - msgIdSet, - domain + msgIdSet ); } catch (error) { console.log( @@ -65,12 +66,11 @@ const Validate = (domain, dirPath, msgIdSet, ErrorObj) => { error ); } - }); - - return ErrorObj; - }); + } + } + return ErrorObj; } catch (error) { console.log(error); } }; -module.exports = Validate; \ No newline at end of file +module.exports = Validate; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js b/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js index ffb20eb..aa69b0d 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/schemaValidation.js @@ -8,6 +8,7 @@ const validateSchema = (domain, data, errObj) => { const schmaVldtr = schemaValidator(domain,data); const datavld = schmaVldtr; + // console.log("DATA validation", datavld) if (datavld.status === "fail") { let res = datavld.errors; let i = 0; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index a822e98..2ca83d8 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -197,6 +197,10 @@ const timestampCheck = (date) => { } }; +const getVersion = (data) => { + if (data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; + else return "v1.2"; +}; function compareDates(dateString1, dateString2) { const date1 = new Date(dateString1); const date2 = new Date(dateString2); @@ -322,6 +326,7 @@ const isObjectEqual = (obj1, obj2, parentKey = "") => { return notEqualKeys; }; + module.exports = { uuidCheck, timestampCheck, @@ -342,6 +347,7 @@ module.exports = { compareDates, hasTwoOrLessDecimalPlaces, timeDiff, + getVersion, taxNotInlcusive, isArrayEqual, countDecimalDigits, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js index fa00204..d8b0b0e 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js @@ -3,24 +3,27 @@ const _ = require("lodash"); const dao = require("../dao/dao"); const path = require("path"); const { getObjValues } = require("./utils"); -const {sortMerge} = require("./mergeSort"); +const { sortMerge } = require("./mergeSort"); const Validate = require("./schemaVal"); -const clean = require("./clean") - -const validateLogs = (domain, dirPath) => { +//const flowVal = require("./retail/businessVal"); +const clean = require("./clean"); +const validateLogs = async (domain, dirPath, outputDestination = "") => { let msgIdSet = new Set(); let ErrorObj = {}; + if (outputDestination.length === 0) outputDestination = dirPath; // Sort & Merge the logs - const mergefile = path.join(dirPath, '../merged.json') + const mergefile = path.join(outputDestination, "merged.json"); + console.log("MERGE FILE PATH", mergefile); ErrorObj["Flow Error"] = sortMerge(domain, dirPath, mergefile); // Log Validation - Validate(domain, mergefile, msgIdSet, ErrorObj); + await Validate(domain, mergefile, msgIdSet, ErrorObj); + // console.log("ERROR object in validateLogUtil", ErrorObj); // Cleaning output report - let log = clean(ErrorObj) + let log = clean(ErrorObj); // Drop DB try { @@ -29,18 +32,17 @@ const validateLogs = (domain, dirPath) => { } catch (error) { console.log("Error while removing LMDB"); } -try { - // outputfile = `log${flowId}.json` - outputfile= 'log_report.json' + try { + // outputfile = `log${flowId}.json` + outputfile = path.join(outputDestination, "log_report.json"); - // let out = getObjValues(ErrorObj['Schema']) -let out = JSON.stringify(ErrorObj,null,4) - fs.writeFileSync(outputfile, out , 'utf-8'); -} catch (error) { - console.log("!!ERROR writing output file",error) -} - + // let out = getObjValues(ErrorObj['Schema']) + let out = JSON.stringify(ErrorObj, null, 4); + fs.writeFileSync(outputfile, out, "utf-8"); + } catch (error) { + console.log("!!ERROR writing output file", error); + } console.log("Report Generated Successfully!!"); }; -module.exports = { validateLogs }; \ No newline at end of file +module.exports = { validateLogs }; From 341f71f496409d920a1a91a64535ee9c94808c38 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Tue, 31 Oct 2023 10:44:58 +0530 Subject: [PATCH 047/228] Schema changes --- .../schema/B2B_json_schema/on_select.js | 2 +- .../logistics_api_json_schema/v1.1/onConfirmSchema.js | 4 ++-- .../logistics_api_json_schema/v1.1/onUpdateSchema.js | 3 +++ .../schema/logistics_api_json_schema/v1.1/updateSchema.js | 3 +++ .../logistics_api_json_schema/v1.2/onUpdateSchema.js | 7 ++++++- .../log-verification-utility/utils/b2b/b2bInit.js | 2 +- .../log-verification-utility/utils/b2b/msgValidator.js | 8 ++++---- .../utils/logistics/logConfirm.js | 2 +- .../utils/logistics/logOnSearch.js | 8 ++++---- .../log-verification-utility/utils/logistics/logSearch.js | 2 +- 10 files changed, 26 insertions(+), 15 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js index bc7da76..c0be4d1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js @@ -220,7 +220,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "Discount", "Packing charges", "delivery ", "tax", "misc"] + enum: ["item", "discount", "Packing charges", "delivery ", "tax", "misc"] }, price: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js index 60e9acd..fe562dd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js @@ -278,7 +278,7 @@ module.exports = { required: ["range"], }, }, - required: ["time"], + //required: ["time"], }, end: { type: "object", @@ -302,7 +302,7 @@ module.exports = { required: ["range"], }, }, - required: ["time"], + //required: ["time"], }, agent: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js index 97937c7..02e9fa3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js @@ -123,6 +123,9 @@ module.exports = { properties: { id: { type: "string", + const: { + $data: "/confirm/0/message/order/fulfillments/0/id", + }, }, type: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js index 113906e..f9607d4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/updateSchema.js @@ -135,6 +135,9 @@ module.exports = { properties: { id: { type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, }, type: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index ca15f23..3858485 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -130,7 +130,12 @@ module.exports = { id: { type: "string", }, - fulfillment_id: { type: "string" }, + fulfillment_id: { + type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, + }, category_id: { type: "string", }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index 79fa746..fde9a90 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -18,7 +18,7 @@ const checkInit = (data, msgIdSet) => { console.log(`Comparing provider object in /init and /on_search`); if (init.provider) { onSearchitemsArr = dao.getValue(`${init.provider.id}itemsArr`); - let providerObj = providersArr.filter( + let providerObj = providersArr?.filter( (prov) => prov.id === init.provider.id ); if (providerObj?.length < 1) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index bfe17c0..158c99a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -30,11 +30,11 @@ const b2bVal = (element, action, msgIdSet) => { case "on_confirm": return checkOnConfirm(element, msgIdSet); - case "update": - return checkUpdate(element,msgIdSet); + // case "update": + // return checkUpdate(element,msgIdSet); - case "on_update": - return checkOnUpdate(element,msgIdSet) + // case "on_update": + // return checkOnUpdate(element,msgIdSet) case "on_status": return checkOnStatus(element,msgIdSet) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 388cbaa..391ca39 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -42,7 +42,7 @@ const checkConfirm = (data, msgIdSet) => { if (provider.id === provId) { const onSearchItemsObj = provider.items; onSearchItemsObj.forEach((onSrchItem) => { - console.log(onSrchItem); + //console.log(onSrchItem); if (onSrchItem.id === item.id) { if (onSrchItem?.time?.duration !== item?.time?.duration) cnfrmObj.itemDurationErr = `item duration does not match with the one provided in /on_search (LSP can send NACK)`; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js index 52f78c8..5e1ac22 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js @@ -27,10 +27,10 @@ const checkOnSearch = (data, msgIdSet) => { const nextDate = new Date(dateObj.setDate(dateObj.getDate() + 1)).toISOString().split('T')[0]; const categoryTimestamp = core_version == "1.1.0" ? categoryTime?.timestamp?.split('T')[0] : categoryTime?.timestamp; if((catName == 'Same Day Delivery' || catName == 'Immediate Delivery') && categoryTimestamp && categoryTimestamp != currentDate){ - onSrchObj.TAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` + onSrchObj.catTAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` } if(catName == 'Next Day Delivery' && categoryTimestamp && categoryTimestamp != nextDate){ - onSrchObj.TAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` + onSrchObj.catTAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` } provider.items.forEach((item) => { const catId = item.category_id; @@ -39,10 +39,10 @@ const checkOnSearch = (data, msgIdSet) => { if (catName === catId && !categoryTime && !itemTime) onSrchObj.TAT = `Either Category level TAT or Item level TAT should be given in ${constants.LOG_ONSEARCH} api for category "${catName}"`; if((catId == 'Same Day Delivery' || catId == 'Immediate Delivery') && itemTimestamp && itemTimestamp != currentDate){ - onSrchObj.TAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` + onSrchObj.itemTAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` } if(catId == 'Next Day Delivery' && itemTimestamp && itemTimestamp != nextDate){ - onSrchObj.TAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` + onSrchObj.itemTAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` } }); }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js index 1847fc0..a387442 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js @@ -66,7 +66,7 @@ const checkSearch = async (data, msgIdSet) => { } catch (error) { console.log("Error in end location",error) } - console.log("srchObj from search:", srchObj) + //console.log("srchObj from search:", srchObj) dao.setValue("searchObj", search); return srchObj; }; From d43c937fa54b2e680591a4bb15353b195727e60c Mon Sep 17 00:00:00 2001 From: ssumitkv Date: Wed, 8 Nov 2023 12:06:18 +0530 Subject: [PATCH 048/228] Updated node service readme.md --- utilities/on_subscibe-service/node/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index baec16c..ef7f741 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -4,7 +4,7 @@ ``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key" +- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging doc (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" ``` From 5db644222b75817e03f40010c474c429826eb40c Mon Sep 17 00:00:00 2001 From: Aditya Patil Date: Sat, 11 Nov 2023 11:21:35 +0530 Subject: [PATCH 049/228] Fix auth header string and optimise code --- utilities/signing_and_verification/cryptic_utils.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py index 651824e..b1ad6fc 100644 --- a/utilities/signing_and_verification/cryptic_utils.py +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -69,12 +69,11 @@ def create_authorisation_header(request_body=request_body_raw_text, created=None signing_key = create_signing_string(hash_message(request_body), created=created, expires=expires) signature = sign_response(signing_key, private_key=os.getenv("PRIVATE_KEY")) - #signature = sign_response(signing_key, private_key="unkLJfHZRmKf88Ac5zv6Wb5caVbYN9Uav0XJ5OOyitdbVo4xZhS8g23JLKY9Ve66uAAL/zrl0PGjpwkvp0d3eA==") subscriber_id = os.getenv("SUBSCRIBER_ID", "buyer-app.ondc.org") unique_key_id = os.getenv("UNIQUE_KEY_ID", "207") - header = f'"Signature keyId=\\"{subscriber_id}|{unique_key_id}|ed25519\\",algorithm=\\"ed25519\\",created=' \ - f'\\"{created}\\",expires=\\"{expires}\\",headers=\\"(created) (expires) digest\\",signature=\\"{signature}\\""' + header = f'"Signature keyId="{subscriber_id}|{unique_key_id}|ed25519",algorithm="ed25519",created=' \ + f'"{created}",expires="{expires}",headers="(created) (expires) digest",signature="{signature}""' return header @@ -120,6 +119,7 @@ def generate_key_pairs(): "Crypto_Privatekey": crypto_private_key, "Crypto_Publickey": crypto_public_key} + def encrypt(crypto_private_key, crypto_public_key, null): private_key = serialization.load_der_private_key( base64.b64decode(crypto_private_key), @@ -133,6 +133,7 @@ def encrypt(crypto_private_key, crypto_public_key, null): text = b'ONDC is a Great Initiative!!' return base64.b64encode(cipher.encrypt(pad(text,AES.block_size))).decode('utf-8') + def decrypt(crypto_private_key, crypto_public_key, cipherstring): private_key = serialization.load_der_private_key( base64.b64decode(crypto_private_key), @@ -147,5 +148,6 @@ def decrypt(crypto_private_key, crypto_public_key, cipherstring): # print(AES.block_size, len(ciphertxt)) return unpad(cipher.decrypt(ciphertxt), AES.block_size).decode('utf-8') + if __name__ == '__main__': fire.Fire() From fe5ed71ead469271bd1504e9e708cdc28885cf0b Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Mon, 11 Dec 2023 17:36:15 +0530 Subject: [PATCH 050/228] Validations added --- .../log-verification-utility/README.md | 21 +- .../schema/B2B_json_schema/confirm.js | 8 +- .../schema/B2B_json_schema/init.js | 65 ++-- .../B2B_json_schema/keywords/confirm.js | 14 + .../schema/B2B_json_schema/keywords/init.js | 7 + .../schema/B2B_json_schema/keywords/onInit.js | 12 + .../schema/B2B_json_schema/keywords/search.js | 7 + .../schema/B2B_json_schema/on_confirm.js | 7 +- .../schema/B2B_json_schema/on_init.js | 11 +- .../schema/B2B_json_schema/on_search.js | 16 +- .../schema/B2B_json_schema/on_select.js | 3 + .../schema/B2B_json_schema/on_status.js | 129 +++---- .../schema/B2B_json_schema/on_update.js | 4 + .../schema/B2B_json_schema/schemaValidator.js | 18 +- .../SchemaValidator.js | 2 +- .../v1.1/initSchema.js | 6 +- .../v1.1/onConfirmSchema.js | 15 +- .../v1.1/onInitSchema.js | 15 + .../v1.1/onSearchSchema.js | 75 ++-- .../v1.1/onStatusSchema.js | 46 ++- .../v1.1/onUpdateSchema.js | 23 +- .../v1.1/searchSchema.js | 3 +- .../v1.2/common/commonSchema.js | 7 +- .../v1.2/confirmSchema.js | 53 ++- .../v1.2/initSchema.js | 2 +- .../v1.2/keywords/confirm.js | 6 +- .../v1.2/keywords/onInit.js | 1 + .../v1.2/onCancelSchema.js | 78 +++-- .../v1.2/onConfirmSchema.js | 88 ++++- .../v1.2/onInitSchema.js | 7 + .../v1.2/onSearchSchema.js | 21 +- .../v1.2/onStatusSchema.js | 44 ++- .../v1.2/onTrackSchema.js | 15 +- .../v1.2/onUpdateSchema.js | 144 +++++--- .../v1.2/searchSchema.js | 2 - .../v1.2/updateSchema.js | 125 +++++-- .../server/routes/routes.js | 201 ++++++++++- .../utils/ContextVal.js | 25 +- .../utils/b2b/b2bInit.js | 32 +- .../utils/b2b/b2bOnSearch.js | 34 +- .../utils/b2b/b2bOnStatus.js | 327 +++++++++--------- .../utils/b2b/b2bSearch.js | 47 ++- .../utils/b2b/msgValidator.js | 12 +- .../utils/b2b/pinToStd.json | 1 + .../utils/constants.js | 4 +- .../utils/logistics/logConfirm.js | 20 +- .../utils/logistics/logInit.js | 1 + .../utils/logistics/logOnCancel.js | 51 ++- .../utils/logistics/logOnConfirm.js | 18 +- .../utils/logistics/logOnInit.js | 35 +- .../utils/logistics/logOnSearch.js | 123 ++++--- .../utils/logistics/logOnStatus.js | 43 ++- .../utils/logistics/logOnTrack.js | 27 ++ .../utils/logistics/logOnUpdate.js | 4 + .../utils/logistics/logSearch.js | 2 +- .../utils/logistics/pinToStd.json | 2 +- .../utils/testSchemaValidation.js | 5 + .../log-verification-utility/utils/utils.js | 32 ++ .../utils/validateLogUtil.js | 1 - 59 files changed, 1486 insertions(+), 661 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/pinToStd.json create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/testSchemaValidation.js diff --git a/utilities/logistics-b2b/log-verification-utility/README.md b/utilities/logistics-b2b/log-verification-utility/README.md index cab5c99..0fe8c7f 100644 --- a/utilities/logistics-b2b/log-verification-utility/README.md +++ b/utilities/logistics-b2b/log-verification-utility/README.md @@ -4,8 +4,7 @@ The tool is a NODE.js based server to check the conformance and compliance of the API logs for [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) based on the examples in the API Contract. -The Log Verification Server is a tool designed to validate log files. It offers an endpoint `/validate/` that allows users to send a directory path containing log files for verification. The directory can have single log file or all the log files for the complete flow. In case of single log files, if sent in sequence will validate the complete flow for same transaction id. -The server responds with a log report, indicating any errors found in the log files. +The Log Verification Server is a tool designed to validate log files for the [logistics](https://docs.google.com/document/d/10GpEuKZE2g96DFJT3HKq6wIEMhPC-kkMZhXNn2jHHXc/edit?pli=1) and [B2B](https://github.com/ONDC-Official/ONDC-RET-Specifications) domains. It offers an endpoint that allows users to submit a directory path containing log files for verification. The server then responds with a log report, indicating any errors found in the log files. ### Tech @@ -27,11 +26,10 @@ cd log-verification-utility npm i ``` -2. Set up the .env file in root directory with the following configuration: +2. Set up the .env file with the following configuration: ```code MAPPLS_API_KEY= -PORT= ``` To get the api_key, refer to this link: https://developer.mappls.com/mapping/reverse-geocoding-api @@ -48,26 +46,11 @@ The server will be up and running at `http://localhost:3000` http://localhost:3000/validate/ ``` -Example endpoint for Logistics - -**`` -http://localhost:3000/validate/logistics -``** - -Example endpoint for B2B - -**`` -http://localhost:3000/validate/b2b -``** - 5. Send a POST request to the endpoint with the following parameters: - ```code logPath: ``` - 6. Example using Postman: - ``` Url: http://localhost:3000/validate/logistics Request body json: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js index 935ca04..7406994 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js @@ -119,11 +119,13 @@ module.exports = { locations: { type: "array", const: { $data: "/init/0/message/order/provider/locations" }, + errorMessage:"mismatch from /init", items: { type: "object", properties: { id: { type: "string", + }, }, required: ["id"], @@ -274,7 +276,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -361,7 +363,7 @@ module.exports = { type: "string", }, }, - required: ["phone", "email"], + required: ["phone"], }, customer: { type: "object", @@ -499,7 +501,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "Discount", "Packing charges", "delivery ", "tax", "misc"] + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] }, price: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js index 6e28291..36e4048 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js @@ -58,8 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", - + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -71,7 +70,7 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", @@ -80,7 +79,8 @@ module.exports = { ttl: { type: "string", const: { $data: "2/message/order/provider/ttl" }, - errorMessage:"should match provider ttl - ${2/message/order/provider/ttl}" + errorMessage: + "should match provider ttl - ${2/message/order/provider/ttl}", }, }, required: [ @@ -118,7 +118,10 @@ module.exports = { properties: { id: { type: "string", - const: { $data: "/select/0/message/order/provider/locations/0/id"} + const: { + $data: + "/select/0/message/order/provider/locations/0/id", + }, }, }, required: ["id"], @@ -126,7 +129,7 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, }, required: ["id", "locations", "ttl"], @@ -182,7 +185,7 @@ module.exports = { properties: { code: { type: "string", - enum:["BUYER_TERMS"] + enum: ["BUYER_TERMS"], }, }, required: ["code"], @@ -197,7 +200,7 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_REQ","PACKAGING_REQ"] + enum: ["ITEM_REQ", "PACKAGING_REQ"], }, }, required: ["code"], @@ -254,6 +257,12 @@ module.exports = { phone: { type: "string", }, + created_at: { + type: "string", + }, + updated_at: { + type: "string", + }, }, additionalProperties: false, required: ["name", "address", "state", "city", "tax_id", "phone"], @@ -282,7 +291,8 @@ module.exports = { properties: { gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", errorMessage: "Incorrect gps value", }, address: { @@ -384,7 +394,7 @@ module.exports = { }, }, required: ["person"], - }, + }, tags: { type: "array", items: { @@ -410,7 +420,10 @@ module.exports = { properties: { code: { type: "string", - enum: ["INCOTERMS", "NAMED_PLACE_OF_DELIVERY"], + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], }, }, required: ["code"], @@ -453,22 +466,20 @@ module.exports = { }, payments: { type: "array", - items: - { - type: "object", - properties: { - type: { - type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], - }, + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], }, - required: ["type"], }, - + required: ["type"], + }, }, tags: { type: "array", @@ -508,7 +519,7 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: [ "provider", "items", @@ -523,4 +534,4 @@ module.exports = { }, }, required: ["context", "message"], -}; \ No newline at end of file +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js new file mode 100644 index 0000000..239d106 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js @@ -0,0 +1,14 @@ +module.exports = { + isFutureDated: (data) => { + const contextTime = data?.context?.timestamp; + const created_at = data?.message?.order?.created_at; + const updated_at = data?.message?.order?.updated_at; + console.log(contextTime,updated_at); + if ( + (created_at && created_at > contextTime) || + (updated_at && updated_at > contextTime) + ) + return false; + return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js new file mode 100644 index 0000000..18a4db3 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js @@ -0,0 +1,7 @@ +module.exports = { + isLengthValid: (data) => { + if (data.name.length + data.building.length + data.locality.length > 190) + return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js new file mode 100644 index 0000000..d9a2b1d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js @@ -0,0 +1,12 @@ +module.exports = { + isQuoteMatching: (data) => { + const quotePrice = parseFloat(data?.price?.value); + const breakupArr = data.breakup; + let totalBreakup = 0; + breakupArr.forEach((breakup) => { + totalBreakup += parseFloat(breakup?.price?.value); + }); + if (quotePrice != totalBreakup) return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js new file mode 100644 index 0000000..6588a9e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js @@ -0,0 +1,7 @@ +module.exports = { + isEndTimeGreater: (data) => { + const startTime = parseInt(data.start); + const endTime = parseInt(data.end); + return startTime < endTime; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js index 2c5efa0..201216f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js @@ -282,7 +282,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -421,7 +421,7 @@ module.exports = { type: "string", }, }, - required: ["phone", "email"], + required: ["phone"], }, }, required: ["type", "location", "time", "contact"], @@ -627,6 +627,9 @@ module.exports = { type: "string", }, }, + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js index cf70261..5de61bb 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js @@ -269,7 +269,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -473,11 +473,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "delivery", - "packing", - "tax", - "discount", - "misc"] + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] }, price: { type: "object", @@ -552,6 +548,9 @@ module.exports = { type: "string", }, }, + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js index c9b2f76..461cb7c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -75,14 +75,14 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", format: "date-time", }, ttl: { - type: "string" + type: "string", }, }, required: [ @@ -116,7 +116,7 @@ module.exports = { }, type: { type: "string", - enum: ["Delivery", "Self-Pickup"] + enum: ["Delivery", "Self-Pickup"], }, }, required: ["id", "type"], @@ -224,7 +224,7 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, locations: { type: "array", @@ -248,7 +248,6 @@ module.exports = { properties: { code: { type: "string", - pattern: "^(std:?[0-9]{2,3})$" }, name: { type: "string", @@ -261,7 +260,6 @@ module.exports = { properties: { code: { type: "string", - pattern: "^(std:?[0-9]{2,3})$" }, }, required: ["code"], @@ -279,7 +277,7 @@ module.exports = { type: "string", }, }, - additionalProperties:false, + additionalProperties: false, required: [ "id", "gps", @@ -951,7 +949,7 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: ["fulfillments", "payments", "descriptor", "providers"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js index c0be4d1..3a97ae2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js @@ -320,6 +320,9 @@ module.exports = { format: "duration" }, }, + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", required: ["price", "breakup", "ttl"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js index d9a732c..c687d03 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -155,6 +155,7 @@ module.exports = { required: ["count"], }, }, + additionalProperties: false, required: ["selected"], }, }, @@ -279,7 +280,8 @@ module.exports = { }, gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", errorMessage: "Incorrect gps value", }, address: { @@ -325,15 +327,21 @@ module.exports = { properties: { start: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], }, timestamp: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["range"], @@ -428,23 +436,23 @@ module.exports = { { properties: { state: { - const: "Order-picked-up" + const: "Order-picked-up", }, stops: { type: "array", items: { properties: { type: { - const: "start" + const: "start", }, time: { - required: ["range", "timestamp"] - } - } - } - } - } - } + required: ["range", "timestamp"], + }, + }, + }, + }, + }, + }, ], }, }, @@ -559,6 +567,9 @@ module.exports = { type: "string", }, }, + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", required: ["price", "breakup", "ttl"], }, payments: { @@ -587,6 +598,9 @@ module.exports = { }, type: { type: "string", + const: { + $data: "/on_confirm/0/message/order/payments/0/type", + }, enum: [ "PRE-FULFILLMENT", "ON-FULFILLMENT", @@ -595,6 +609,10 @@ module.exports = { }, collected_by: { type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/collected_by", + }, enum: ["BAP", "BPP"], }, "@ondc/org/buyer_app_finder_fee_type": { @@ -692,20 +710,18 @@ module.exports = { documents: { type: "array", - items: - { - type: "object", - properties: { - url: { - type: "string", - }, - label: { - type: "string", - }, + items: { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", }, - required: ["url", "label"], }, - + required: ["url", "label"], + }, }, created_at: { type: "string", @@ -737,72 +753,7 @@ module.exports = { }, required: ["order"], }, - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, - select: { - type: "array", - items: { - $ref: "selectSchema#", - }, - }, - on_select: { - type: "array", - items: { - $ref: "onSelectSchema#", - }, - }, - init: { - type: "array", - items: { - $ref: "initSchema#", - }, - }, - on_init: { - type: "array", - items: { - $ref: "onInitSchema#", - }, - }, - confirm: { - type: "array", - items: { - $ref: "confirmSchema#", - }, - }, - on_confirm: { - type: "array", - items: { - $ref: "onConfirmSchema#", - }, - }, - update: { - type: "array", - items: { - $ref: "updateSchema#", - }, - }, - on_update: { - type: "array", - items: { - $ref: "onUpdateSchema#", - }, - }, - status: { - type: "array", - items: { - $ref: "statusSchema#", - }, - }, }, + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js index ed5e80a..d87b56d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js @@ -375,9 +375,13 @@ module.exports = { properties: { start: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js index 33d77c1..43fb234 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -11,6 +11,10 @@ const confirmSchema = require("./confirm"); const statusSchema = require("./status"); const updateSchema = require("./update"); const onStatusSchema = require("./on_status"); +const { isLengthValid } = require("./keywords/init"); +const { isQuoteMatching } = require("./keywords/onInit"); +const { isFutureDated } = require("./keywords/confirm"); +const { isEndTimeGreater } = require("./keywords/search"); const fs = require("fs"); //const async = require("async"); @@ -65,7 +69,19 @@ const validate_schema = (data, schema) => { .addSchema(updateSchema) .addSchema(onUpdateSchema) .addSchema(statusSchema) - .addSchema(onStatusSchema); + .addSchema(onStatusSchema) + .addKeyword("isEndTimeGreater", { + validate: (schema, data) => isEndTimeGreater(data), + }) + .addKeyword("isQuoteMatching", { + validate: (schema, data) => isQuoteMatching(data), + }) + .addKeyword("isFutureDated", { + validate: (schema, data) => isFutureDated(data), + }) + .addKeyword("isLengthValid", { + validate: (schema, data) => isLengthValid(data), + }); validate = validate.compile(schema); diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js index 2ad474a..b080a31 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/SchemaValidator.js @@ -77,7 +77,7 @@ const validate_schema = (data, schema, version) => { addFormats(ajv); require("ajv-errors")(ajv); - require('ajv-merge-patch')(ajv); + require("ajv-merge-patch")(ajv); let error_list = []; try { validate = ajv diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js index 1419fff..51e46f8 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js @@ -243,8 +243,6 @@ module.exports = { building: { type: "string", minLength: 3, - not: { const: { $data: "1/locality" } }, - errorMessage: "cannot be equal to locality", }, locality: { type: "string", @@ -336,6 +334,8 @@ module.exports = { }, }, additionalProperties: false, + isLengthValid:true, + errorMessage:"name + building + locality < 190 chars", required: [ "name", "building", @@ -348,6 +348,8 @@ module.exports = { }, tax_number: { type: "string", + pattern: "^[0-9]{2}[A-Z]{5}[0-9]{4}[0-9A-Z]{4}$", + errorMessage: "should be valid", }, phone: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js index fe562dd..a217f6b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onConfirmSchema.js @@ -161,8 +161,6 @@ module.exports = { }, quote: { type: "object", - const: { $data: "/confirm/0/message/order/quote" }, - errorMessage: "object mismatches in /confirm and /on_confirm.", properties: { price: { type: "object", @@ -267,9 +265,13 @@ module.exports = { properties: { start: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], @@ -278,7 +280,7 @@ module.exports = { required: ["range"], }, }, - //required: ["time"], + }, end: { type: "object", @@ -291,9 +293,13 @@ module.exports = { properties: { start: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], @@ -302,7 +308,7 @@ module.exports = { required: ["range"], }, }, - //required: ["time"], + }, agent: { type: "object", @@ -344,6 +350,7 @@ module.exports = { }, }, + additionalProperties:false, required: ["id", "type", "state", "tracking"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js index 9ffb1c5..1a244ca 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onInitSchema.js @@ -236,6 +236,21 @@ module.exports = { }, }, }, + if: { + properties: { + type: { enum: ["ON-ORDER", "POST-FULFILLMENT"] }, + }, + }, + then: { + properties: { + collected_by: { const: "BAP" }, + }, + }, + else: { + properties: { + collected_by: { const: "BPP" }, + }, + }, required: ["type", "collected_by"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js index 8d63e64..8187249 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onSearchSchema.js @@ -40,8 +40,7 @@ module.exports = { type: "string", const: { $data: "/search/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", - + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -58,7 +57,7 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", @@ -283,6 +282,9 @@ module.exports = { }, value: { type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", }, }, required: ["currency", "value"], @@ -297,11 +299,11 @@ module.exports = { duration: { type: "string", format: "duration", - errorMessage: "${2/time/duration}", }, timestamp: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["label", "duration", "timestamp"], @@ -317,45 +319,44 @@ module.exports = { }, }, }, - if: - { - properties: { - categories: { - type: "array", - items: { - type: "object", - properties: { - id: { const: "Immediate Delivery" }, - }, + if: { + properties: { + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { const: "Immediate Delivery" }, }, }, }, - not: { - required: ["locations"], - }, }, - // { - // not: { - // properties: { - // categories: { - // type: "array", - // items: { - // type: "object", - // properties: { - // id: { const: "Immediate Delivery" }, - // }, - // }, - // }, - // }, - // }, - // }, - else:{ - required: ["id", "descriptor", "categories", "items"], - } + not: { + required: ["locations"], + }, + }, + // { + // not: { + // properties: { + // categories: { + // type: "array", + // items: { + // type: "object", + // properties: { + // id: { const: "Immediate Delivery" }, + // }, + // }, + // }, + // }, + // }, + // }, + else: { + required: ["id", "descriptor", "categories", "items"], + }, }, }, }, - additionalProperties:false, + additionalProperties: false, required: ["bpp/fulfillments", "bpp/descriptor", "bpp/providers"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js index 2f32512..fb38da1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js @@ -163,6 +163,9 @@ module.exports = { }, value: { type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", }, }, required: ["currency", "value"], @@ -186,19 +189,21 @@ module.exports = { }, value: { type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", }, }, required: ["currency", "value"], }, }, - required: [ - "@ondc/org/item_id", - "@ondc/org/title_type", - "price", - ], + required: ["@ondc/org/title_type", "price"], }, }, }, + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", required: ["price", "breakup"], }, fulfillments: { @@ -253,9 +258,17 @@ module.exports = { properties: { start: { type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], @@ -301,9 +314,17 @@ module.exports = { properties: { start: { type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], @@ -455,12 +476,19 @@ module.exports = { }, }, }, - if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + if: { + properties: { + type: { enum: ["ON-ORDER", "POST-FULFILLMENT"] }, + }, + }, then: { properties: { - collected_by: { - const: "BPP", - }, + collected_by: { const: "BAP" }, + }, + }, + else: { + properties: { + collected_by: { const: "BPP" }, }, }, required: ["type", "collected_by"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js index 02e9fa3..c0722c7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onUpdateSchema.js @@ -45,11 +45,6 @@ module.exports = { message_id: { type: "string", allOf: [ - { - const: { $data: "/update/0/context/message_id" }, - errorMessage: - "Message ID should be same as /update: ${/update/0/context/message_id}", - }, { not: { const: { $data: "1/transaction_id" }, @@ -100,15 +95,23 @@ module.exports = { properties: { id: { type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, }, category_id: { type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, }, descriptor: { type: "object", properties: { code: { type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, }, }, }, @@ -144,11 +147,13 @@ module.exports = { properties: { start: { type: "string", - minimum: { $data: "7/context/timestamp" }, - errorMessage: "${7/context/timestamp}", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], @@ -183,9 +188,13 @@ module.exports = { properties: { start: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js index ba45573..fd47ce2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js @@ -46,7 +46,7 @@ module.exports = { }, timestamp: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$" }, ttl: { type: "string", @@ -344,7 +344,6 @@ module.exports = { }, required: [ "category", - "provider", "fulfillment", "@ondc/org/payload_details", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js index 5986621..9a9ed5a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js @@ -80,7 +80,12 @@ module.exports = { type: "object", properties: { currency: { type: "string" }, - value: { type: "string" }, + value: { + type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", + }, }, required: ["currency", "value"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 5939573..5f77fae 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -270,6 +270,7 @@ module.exports = { }, }, }, + additionalProperties: false, required: ["price", "breakup"], }, fulfillments: { @@ -302,7 +303,7 @@ module.exports = { }, duration: { type: "string", - format: "duration", + format: "duration" }, location: { type: "object", @@ -407,7 +408,7 @@ module.exports = { properties: { short_desc: { maxLength: 6, - pattern: "^[0-9]{1,6}$", + pattern: "^[a-zA-Z0-9]{1,6}$", errorMessage: "should not be an empty string or have more than 6 digits", }, @@ -513,7 +514,7 @@ module.exports = { enum: constants.DCC_CODE, }, }, - required: ["code", "short_desc"], + required: ["code"], allOf: [ { if: { properties: { code: { const: "3" } } }, @@ -534,11 +535,12 @@ module.exports = { properties: { short_desc: { maxLength: 6, - pattern: "^[0-9]{1,6}$", + pattern: "^[a-zA-Z0-9]{1,6}$", errorMessage: "should not be an empty string or have more than 6 digits", }, }, + required: ["short_desc"], }, }, ], @@ -793,14 +795,39 @@ module.exports = { }, }, }, - if: { properties: { type: { const: "ON-FULFILLMENT" } } }, - then: { - properties: { - collected_by: { - const: "BPP", + allOf: [ + { + if: { + properties: { type: { const: "ON-FULFILLMENT" } }, + }, + then: { + required: ["@ondc/org/collection_amount"], }, }, - }, + { + if: { + properties: { + type: { enum: ["ON-ORDER", "POST-FULFILLMENT"] }, + }, + }, + then: { + not: { required: ["@ondc/org/collection_amount"] }, + errorMessage: + "@ondc/org/collection_amount is required only for payment/type 'ON-FULFILLMENT'", + }, + }, + { + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + }, + ], + required: ["collected_by", "type"], }, "@ondc/org/linked_order": { @@ -1014,8 +1041,8 @@ module.exports = { required: ["order"], }, }, - isFutureDated: true, - errorMessage: - "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", + // isFutureDated: true, + // errorMessage: + // "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 96c01da..7ac6ff0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -464,7 +464,7 @@ module.exports = { }, }, additionalProperties: false, - required: ["provider", "items", "fulfillments", "billing"], + required: ["provider", "items", "fulfillments", "billing","payment"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js index 239d106..1ccc7d0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/confirm.js @@ -3,12 +3,14 @@ module.exports = { const contextTime = data?.context?.timestamp; const created_at = data?.message?.order?.created_at; const updated_at = data?.message?.order?.updated_at; - console.log(contextTime,updated_at); + if ( (created_at && created_at > contextTime) || (updated_at && updated_at > contextTime) - ) + ) { return false; + } + return true; }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index d9a2b1d..172c10e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -6,6 +6,7 @@ module.exports = { breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); }); + // console.log(quotePrice,totalBreakup); if (quotePrice != totalBreakup) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 7b6cee0..860fa2d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -194,6 +194,9 @@ module.exports = { }, }, required: ["price", "breakup"], + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", }, fulfillments: { @@ -206,7 +209,7 @@ module.exports = { }, type: { type: "string", - enum: constants.FULFILLMENT_TYPE + enum: constants.FULFILLMENT_TYPE, }, state: { type: "object", @@ -216,7 +219,10 @@ module.exports = { properties: { code: { type: "string", - enum: ["Cancelled", "RTO-Initiated","RTO-Disposed"], + enum: [ + "Cancelled", + "RTO-Initiated" + ], }, }, required: ["code"], @@ -233,10 +239,6 @@ module.exports = { }, tracking: { type: "boolean", - const: { - $data: - "/on_confirm/0/message/order/fulfillments/0/tracking", - }, }, start: { type: "object", @@ -249,18 +251,21 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, - required: ["start", "end"], + required: ["start"], }, timestamp: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, }, @@ -368,18 +373,21 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, - required: ["start", "end"], + required: ["start"], }, timestamp: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, }, @@ -543,17 +551,7 @@ module.exports = { required: ["time", "person", "location", "contact"], }, }, - required: [ - "id", - "type", - "state", - "start", - "end", - "tracking", - "agent", - "vehicle", - "tags", - ], + required: ["id", "type", "state", "start", "end", "tracking"], }, else: { properties: { @@ -677,6 +675,31 @@ module.exports = { }, }, additionalProperties: false, + + // if: { + // properties: { + // cancellation: { + // properties: { + // reason: { + // properties: { + // id: { + // enum: ["011", "012", "013", "014", "015"], + // }, + // }, + // }, + // }, + // }, + // }, + // }, + // then: { + // properties: { + // fulfillments: { + // required: ["tags"], + // errorMessage: "tags required when RTO is triggered", + // }, + // }, + // }, + required: [ "id", "state", @@ -692,9 +715,8 @@ module.exports = { }, required: ["order"], }, - }, - isFutureDated: true, - errorMessage: "created_at/updated_at must not be future dated", + // isFutureDated: true, + // errorMessage: "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 67e8adf..ad3d244 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -255,6 +255,7 @@ module.exports = { }, }, }, + additionalProperties: false, required: ["price", "breakup"], }, fulfillments: { @@ -415,6 +416,36 @@ module.exports = { }, }, required: ["code", "short_desc"], + allOf: [ + { + if: { properties: { code: { const: "1" } } }, + then: { + properties: { + short_desc: { + minLength: 10, + maxLength: 10, + pattern: "^[0-9]{10}$", + errorMessage: "should be a 10 digit number", + }, + }, + }, + }, + { + if: { + properties: { code: { enum: ["2", "3", "4"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[a-zA-Z0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + }, + }, + ], }, time: { type: "object", @@ -424,11 +455,17 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], @@ -436,7 +473,7 @@ module.exports = { }, }, }, - required: ["person", "location", "contact", "time"], + required: ["person", "location", "contact"], }, end: { @@ -548,10 +585,39 @@ module.exports = { }, code: { type: "string", - enum: constants.PCC_CODE, + enum: constants.DCC_CODE, }, }, - required: ["code", "short_desc"], + required: ["code"], + allOf: [ + { + if: { properties: { code: { const: "3" } } }, + then: { + properties: { + short_desc: { + maxLength: 0, + errorMessage: "is not required", + }, + }, + }, + }, + { + if: { + properties: { code: { enum: ["1", "2"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[a-zA-Z0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + required: ["short_desc"], + }, + }, + ], }, time: { type: "object", @@ -561,11 +627,17 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], @@ -633,6 +705,7 @@ module.exports = { ], }, }, + billing: { type: "object", properties: { @@ -804,6 +877,7 @@ module.exports = { errorMessage: "does not match context/timestamp - ${3/context/timestamp}", }, + }, required: [ "id", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js index 256c54c..a372264 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -138,6 +138,9 @@ module.exports = { }, value: { type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", }, }, required: ["currency", "value"], @@ -162,6 +165,9 @@ module.exports = { }, value: { type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", }, }, required: ["currency", "value"], @@ -179,6 +185,7 @@ module.exports = { format: "duration", }, }, + required: ["price", "breakup", "ttl"], isQuoteMatching: true, errorMessage: "price is not matching with the total breakup price", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js index 7fa3dfe..203bb8c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js @@ -127,7 +127,7 @@ module.exports = { properties: { id: { type: "string", - enum:constants.CATEGORY_ID + enum: constants.CATEGORY_ID, }, time: { type: "object", @@ -140,12 +140,12 @@ module.exports = { type: "string", format: "duration", }, - timestamp:{ - type:"string", - format:"date" - } + timestamp: { + type: "string", + format: "date", + }, }, - required: ["label", "duration","timestamp"], + required: ["label", "duration", "timestamp"], }, }, required: ["id"], @@ -235,7 +235,7 @@ module.exports = { }, category_id: { type: "string", - enum:constants.CATEGORY_ID + enum: constants.CATEGORY_ID, }, fulfillment_id: { type: "string", @@ -245,7 +245,7 @@ module.exports = { properties: { code: { type: "string", - enum: constants.SHIPMENT_TYPE + enum: constants.SHIPMENT_TYPE, }, name: { type: "string", @@ -275,6 +275,9 @@ module.exports = { }, value: { type: "string", + pattern: "^[0-9]+(\\.[0-9]{1,2})?$", + errorMessage: + "precision for all prices in quote can be maximum of 2 decimal digits", }, }, required: ["currency", "value"], @@ -288,7 +291,7 @@ module.exports = { }, duration: { type: "string", - format: "duration" + format: "duration", }, timestamp: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index c51b0f2..348df28 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -198,6 +198,9 @@ module.exports = { }, }, required: ["price", "breakup"], + isQuoteMatching: true, + errorMessage: + "price is not matching with the total breakup price", }, fulfillments: { type: "array", @@ -242,18 +245,27 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], }, timestamp: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, }, @@ -360,18 +372,27 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], }, timestamp: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, }, @@ -543,6 +564,10 @@ module.exports = { $data: "/on_confirm/0/message/order/payment/type", }, }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, collected_by: { type: "string", const: { @@ -554,7 +579,10 @@ module.exports = { properties: { timestamp: { type: "string", - format: "date-time", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, }, @@ -600,7 +628,7 @@ module.exports = { }, }, }, - required: ["type", "collected_by"], + required: ["type", "collected_by","status"], }, billing: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js index 43c055f..5b6ba08 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onTrackSchema.js @@ -23,7 +23,7 @@ module.exports = { }, core_version: { type: "string", - const:"1.2.0" + const: "1.2.0", }, bap_id: { type: "string", @@ -106,19 +106,23 @@ module.exports = { properties: { timestamp: { type: "string", + format: "date-time", }, }, required: ["timestamp"], }, updated_at: { type: "string", + format: "date-time", }, }, + required: ["gps", "time", "updated_at"], }, status: { type: "string", - enum: constants.TRACKING_STATUS, + enum: ["active"], + errorMessage: `should be 'active' if tracking is enabled` }, tags: { type: "array", @@ -127,7 +131,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["path"], + enum: constants.TRACK_TAGS_CODE, }, list: { type: "array", @@ -136,7 +140,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["lat_lng", "sequence"], + enum: constants.TRACK_TAGS_LIST_CODE, }, value: { type: "string", @@ -156,5 +160,8 @@ module.exports = { required: ["tracking"], }, }, + // isTrackingFutureDated: true, + // errorMessage: + // "time/timestamp or updated_at in /location cannot be future dated w.r.t context/timestamp", required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index 3858485..aad1d92 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); const { ORDER_STATE, TITLE_TYPE, @@ -54,13 +55,6 @@ module.exports = { message_id: { type: "string", allOf: [ - { - const: { - $data: "/update/0/context/message_id", - }, - errorMessage: - "Message ID should be same as /update: ${/update/0/context/message_id}", - }, { not: { const: { $data: "1/transaction_id" }, @@ -129,6 +123,7 @@ module.exports = { properties: { id: { type: "string", + const: { $data: "/init/0/message/order/items/0/id" }, }, fulfillment_id: { type: "string", @@ -138,12 +133,19 @@ module.exports = { }, category_id: { type: "string", + const: { + $data: "/init/0/message/order/items/0/category_id", + }, }, descriptor: { type: "object", properties: { code: { type: "string", + const: { + $data: + "/init/0/message/order/items/0/descriptor/code", + }, }, }, }, @@ -221,11 +223,13 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["start", "end"], @@ -238,28 +242,55 @@ module.exports = { required: ["range"], }, instructions: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.PCC_CODE, + }, + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + + required: ["code", "short_desc"], allOf: [ { - type: "object", - properties: { - code: { type: "string" }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "string", + if: { properties: { code: { const: "1" } } }, + then: { + properties: { + short_desc: { + minLength: 10, + maxLength: 10, + pattern: "^[0-9]{10}$", + errorMessage: + "should be a 10 digit number", }, }, }, }, { - $data: - "/update/0/message/order/fulfillments/0/start/instructions", + if: { + properties: { + code: { enum: ["2", "3", "4"] }, + }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[a-zA-Z0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + }, }, ], }, @@ -284,46 +315,70 @@ module.exports = { properties: { start: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, end: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, - }, + }, required: ["start", "end"], }, timestamp: { type: "string", - format: "date-time", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" }, }, required: ["range"], }, instructions: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.DCC_CODE, + }, + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + }, + required: ["code"], allOf: [ { - type: "object", - properties: { - code: { type: "string" }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "string", + if: { properties: { code: { const: "3" } } }, + then: { + properties: { + short_desc: { + maxLength: 0, + errorMessage: "is not required", }, }, }, - required: ["code", "short_desc"], }, { - $data: - "/update/0/message/order/fulfillments/0/end/instructions", + if: { + properties: { code: { enum: ["1", "2"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[a-zA-Z0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + required: ["short_desc"], + }, }, ], }, @@ -404,6 +459,7 @@ module.exports = { }, updated_at: { type: "string", + format:"date-time" }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js index f8649d8..3c7def9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js @@ -127,7 +127,6 @@ module.exports = { required: ["start", "end"], }, }, - required: ["days", "schedule", "range"], }, }, }, @@ -336,7 +335,6 @@ module.exports = { }, required: [ "category", - "provider", "fulfillment", "@ondc/org/payload_details", "payment", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index ba71a39..34098a6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -146,6 +146,9 @@ module.exports = { properties: { id: { type: "string", + const: { + $data: "/init/0/message/order/items/0/fulfillment_id", + }, }, type: { type: "string", @@ -173,40 +176,38 @@ module.exports = { type: "string", }, }, - if: { - properties: { - code: { - const: "1", - }, - }, - }, - then: { - properties: { - short_desc: { - type: "string", - minLength: 10, - maxLength: 10, - }, - }, - }, - else: { - if: { - properties: { - code: { - const: "2", + + required: ["code", "short_desc"], + allOf: [ + { + if: { properties: { code: { const: "1" } } }, + then: { + properties: { + short_desc: { + minLength: 10, + maxLength: 10, + pattern: "^[0-9]{10}$", + errorMessage: "should be a 10 digit number", + }, }, }, }, - then: { - properties: { - short_desc: { - type: "string", - maxLength: 6, + { + if: { + properties: { code: { enum: ["2", "3", "4"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[a-zA-Z0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, }, }, }, - }, - required: ["code", "short_desc"], + ], }, }, additionalProperties: false, @@ -227,24 +228,76 @@ module.exports = { }, short_desc: { type: "string", - maxLength: 6, }, long_desc: { type: "string", }, }, - required: ["code", "short_desc"], + required: ["code"], + allOf: [ + { + if: { properties: { code: { const: "3" } } }, + then: { + properties: { + short_desc: { + maxLength: 0, + errorMessage: "is not required", + }, + }, + }, + }, + { + if: { + properties: { code: { enum: ["1", "2"] } }, + }, + then: { + properties: { + short_desc: { + maxLength: 6, + pattern: "^[a-zA-Z0-9]{1,6}$", + errorMessage: + "should not be an empty string or have more than 6 digits", + }, + }, + required: ["short_desc"], + }, + }, + ], }, }, additionalProperties: false, // required: ["instructions"], }, tags: { - allOf: [ - { - $ref: "confirmSchema#/properties/message/properties/order/properties/fulfillments/items/properties/tags", + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["state"] + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ready_to_ship"] + }, + value: { + type: "string", + enum: ["yes","no"] + }, + }, + required: ["code", "value"], + }, + }, }, - ], + + required: ["code", "list"], + }, }, }, additionalProperties: false, @@ -273,13 +326,13 @@ module.exports = { format: "date-time", }, }, - isFutureDated: true, - errorMessage: "updated_at must not be future dated", + required: ["id", "items", "fulfillments", "updated_at"], }, }, required: ["update_target", "order"], }, }, + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js b/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js index 2ba5383..1f4780e 100644 --- a/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js +++ b/utilities/logistics-b2b/log-verification-utility/server/routes/routes.js @@ -11,12 +11,76 @@ const { const validate_schema_for_domain_json = require("../../schema/main"); const { validateLogs } = require("../../utils/validateLogUtil"); const readLogFiles = require("../../utils/logistics/readLogFiles"); +// const { logsUpload, logUpload } = require("../utils/fileHandler"); router.get("/", (req, res) => { res.json({ msg: "Head over to /validate for route validation" }); }); -// Route defined to validate logs +// /validate/flow/:domain + +// router.post("/validate/local/single", async (req, res) => { +// const { domain, path: filePath } = req.body; +// if (!domain || !filePath) +// return res +// .status(400) +// .json({ msg: 'Req Body needs to have "domain" and "path"' }); + +// if (!Object.keys(SUPPORTED_DOMAINS_SORTED_INDEX).includes(domain)) +// return res.status(404).json({ msg: `Domain ${domain} not supported yet!` }); +// try { +// const file = fs.readFileSync(path.join(filePath)); + +// const fileData = JSON.parse(file.toString()); + +// const action = fileData.context.action; + +// const individualSchemaErrors = validate_schema_for_domain_json(domain, { +// [action]: [fileData], +// }); +// const destination = path.join( +// __dirname, +// "../../", +// SERVER_LOG_DEST, +// domain, +// fileData.context.transaction_id, +// "logs" +// ); +// const dirExists = fs.existsSync(destination); +// try { +// fs.mkdirSync(destination, { recursive: true }); + +// fs.writeFileSync( +// path.join(destination, action + ".json"), +// JSON.stringify(fileData) +// ); +// } catch (error) { +// console.log(error); +// return res.status(500).json({ msg: "Error occurred while storing file" }); +// } + +// if (dirExists) { +// var fullLogReport = {}; +// validateLogs(domain, destination, path.join(destination, "..")).then( +// () => { +// fullLogReport = JSON.parse( +// fs +// .readFileSync(path.join(destination, "../log_report.json")) +// .toString() +// ); +// return res.json({ individualSchemaErrors, fullLogReport }); +// } +// ); +// } else { +// return res.json({ individualSchemaErrors }); +// } +// } catch (error) { +// console.log("Error:", error); +// if (error.code === "ENOENT") +// return res.status(400).json({ msg: "File/Path does not exist" }); +// return res.status(500).json({ msg: "Error occurred" }); +// } +// }); router.post("/validate/:domain", async (req, res) => { try { @@ -45,4 +109,137 @@ router.post("/validate/:domain", async (req, res) => { } }); -module.exports = router; \ No newline at end of file +// router.post("/validate/single/:domain", logUpload, async (req, res) => { +// if (!req.file) +// return res.status(403).json({ msg: "Invalid or no file sent" }); +// const domain = req.params.domain; +// if (!Object.keys(SUPPORTED_DOMAINS_SORTED_INDEX).includes(domain)) +// return res.status(404).json({ msg: `Domain ${domain} not supported yet!` }); + +// const fileData = JSON.parse(req.file.buffer.toString()); + +// const destination = path.join( +// __dirname, +// "../../", +// SERVER_LOG_DEST, +// domain, +// fileData.context.transaction_id, +// "logs" +// ); +// const dirExists = fs.existsSync(destination); +// const action = fileData.context.action; +// try { +// fs.mkdirSync(destination, { recursive: true }); + +// fs.writeFileSync( +// path.join(destination, action + ".json"), +// JSON.stringify(fileData) +// ); +// } catch (error) { +// console.log(error); +// return res.status(500).json({ msg: "Error occurred while storing file" }); +// } + +// const individualSchemaErrors = validate_schema_for_domain_json(domain, { +// [action]: [fileData], +// }); + +// if (dirExists) { +// var logReport = {}; +// validateLogs(domain, destination, path.join(destination, "..")).then(() => { +// logReport = JSON.parse( +// fs.readFileSync(path.join(destination, "../log_report.json")).toString() +// ); +// return res.json({ individualSchemaErrors, logReport }); +// }); +// } else { +// return res.json({ individualSchemaErrors }); +// } +// }); + +// router.post("/validate/multiple/:domain", logsUpload, async (req, res) => { +// if (!req.files || req.files.length === 0) +// return res.status(400).json({ msg: "No files sent" }); +// const domain = req.params.domain; +// if (!Object.keys(SUPPORTED_DOMAINS_SORTED_INDEX).includes(domain)) +// return res.status(404).json({ msg: `Domain ${domain} not supported yet!` }); + +// const domainSortedIndex = constants[SUPPORTED_DOMAINS_SORTED_INDEX[domain]]; +// // Check if all compulsory files are present & no extra files are sent +// if ( +// !domainSortedIndex.every((logName) => +// Object.keys(req.files).includes(logName) +// ) +// ) +// return res.status(400).json({ msg: "All files not detected" }); + +// const firstFileData = JSON.parse( +// req.files[Object.keys(req.files)[0]][0].buffer.toString() +// ); +// const destination = path.join( +// __dirname, +// "../../", +// SERVER_LOG_DEST, +// domain, +// firstFileData.context.transaction_id, +// "logs" +// ); +// if (fs.existsSync(destination)) +// fs.rmdirSync(destination, { recursive: true }); +// // return res.status(403).json({msg: "Log Report for that Transaction ID already recorded."}) + +// fs.mkdirSync(destination, { recursive: true }); + +// for (file of Object.values(req.files)) { +// const fileData = JSON.parse(file[0].buffer.toString()); +// const action = fileData.context.action; +// fs.writeFileSync( +// path.join(destination, action + ".json"), +// JSON.stringify(fileData) +// ); +// } + +// var logReport = {}; +// validateLogs(domain, destination, path.join(destination, "..")) +// .then(() => { +// logReport = JSON.parse( +// fs.readFileSync(path.join(destination, "../log_report.json")).toString() +// ); +// return res.json({ logReport }); +// }) +// .catch((error) => { +// console.log("Error", error); +// return res +// .status(500) +// .json({ msg: "Error Occured during report generation" }); +// }); + +// // const log_generation_success = +// // (await validateLog(domain, destination)) && true; +// // return res.json({ +// // domain, +// // files: Object.keys(req.files), +// // log_generation_success, +// // }); +// }); + +// router.post("/validateSchema/:path", (req, res) => { +// const path = req.params.path; +// const data = req.body; +// const result = service.schemaValidation(domain, data, path); +// res.json(result); +// }); + +// router.post("/CheckContext/:path", (req, res) => { +// const path = req.params.path; +// const data = req.body.context; +// const result = service.checkContext(data, path); +// res.json(result); +// }); + +// router.post("/ValidateLog/:domain", (req, res) => { +// const domain = req.params.domain; +// validateLog(domain); +// }); + +module.exports = router; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 4513deb..7d0ceb7 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -6,7 +6,6 @@ const { error } = require("console"); const checkContextVal = (payload, msgIdSet, i) => { try { - action = payload.context.action; console.log(`Checking context validations for ${action}`); // if (!Obj.hasOwnProperty(action)) { @@ -14,6 +13,21 @@ const checkContextVal = (payload, msgIdSet, i) => { // } let Obj = {}; let data = payload.context; + let domain = payload.context.domain; + let maxTimeDiff = 0; + if (domain === "ONDC:RET10") { + maxTimeDiff = 5000; + if (action === "init") { + maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); + dao.setValue("maxTimeDiff", maxTimeDiff); + } else if (action === "on_init") { + maxTimeDiff = dao.getValue("maxTimeDiff"); + } + } else if (domain === "nic2004:60232") { + maxTimeDiff = 1000; + } + + console.log("time difference", maxTimeDiff); if (data.timestamp) { let date = data.timestamp; result = utils.timestampCheck(date); @@ -26,10 +40,9 @@ const checkContextVal = (payload, msgIdSet, i) => { } try { console.log(`Comparing Message Id of /${action}`); - if (!action.includes("on_") || action ==="on_status" || action ==="on_update") { + if (action.includes("on_")) { if (msgIdSet.has(payload.context.message_id)) { - Obj.msgIdErr = - "Message Id cannot be same for different sets of APIs"; + Obj.msgIdErr = "Message Id cannot be same for different sets of APIs"; } else { msgIdSet.add(payload.context.message_id); } @@ -84,11 +97,11 @@ const checkContextVal = (payload, msgIdSet, i) => { dao.getValue("tmpstmp") ); //console.log(timeDiff); - if (timeDiff > 1000) { + if (timeDiff > maxTimeDiff) { Obj.tmpstmpErr = `context/timestamp difference between ${action} and ${action.replace( "on_", "" - )} should be smaller than 1 sec`; + )} should be within ${maxTimeDiff / 1000} seconds`; } } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index fde9a90..d63e0cb 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -33,20 +33,23 @@ const checkInit = (data, msgIdSet) => { } else if (init?.provider?.locations) { let providerLocArr = init.provider.locations; let providerLocExists = false; - providerLocArr.forEach((location, i) => { - providerObj[0]?.locations?.forEach((element) => { - console.log(location.id, element.id); - if (location.id === element.id) providerLocExists = true; + if (providerLocArr) { + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + initObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; }); - if (!providerLocExists) { - let itemkey = `providerLocErr${i}`; - initObj[ - itemkey - ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; - } - providerLocExists = false; - }); + } } } } @@ -79,10 +82,7 @@ const checkInit = (data, msgIdSet) => { itemExists = false; }); } catch (error) { - console.log( - `!!Error while checking items array in /on_init API`, - error - ); + console.log(`!!Error while checking items array in /on_init API`, error); } return initObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 4724e59..a4dd00b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -2,15 +2,15 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const constants = require("../constants"); const utils = require("../utils"); -const checkOnSearch = (data, msgIdSet) => { +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); + +const checkOnSearch = async (data, msgIdSet) => { const onSrchObj = {}; let onSearch = data; onSearch = onSearch.message.catalog; try { - console.log( - `Saving provider items array in /on_search api` - ); + console.log(`Saving provider items array in /on_search api`); if (onSearch["providers"]) { let providers = onSearch["providers"]; dao.setValue("providersArr", providers); @@ -28,6 +28,30 @@ const checkOnSearch = (data, msgIdSet) => { ); } + if (onSearch.hasOwnProperty("providers")) { + const providers = onSearch["providers"]; + for (let i = 0; i < providers.length; i++) { + const provider = providers[i]; + if (provider.hasOwnProperty("locations")) { + const locations = provider.locations; + for (let j = 0; j < locations.length; j++) { + const { id, gps, area_code } = locations[j]; + try { + const [lat, long] = gps.split(","); + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) { + onSrchObj[ + "bpp/provider:location:" + id + ":RGC" + ] = `Reverse Geocoding for location ID ${id} failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } + } catch (error) { + console.log("bpp/providers error: ", error); + } + } + } + } + } + return onSrchObj; }; -module.exports = checkOnSearch; \ No newline at end of file +module.exports = checkOnSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 519d755..6facef2 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -16,178 +16,163 @@ const checkOnStatus = (data, msgIdSet) => { let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; -// try { -// console.log( -// `Checking if message id is unique for different on_status apis` -// ); -// if (msgIdSet.has(messageId)) { -// onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; -// } else { -// msgIdSet.add(messageId); -// } -// } catch (error) { -// console.log(`Error checking message id in /on_status API`); -// } - -// try { -// if (fulfillments.length > 1) { -// console.log( -// `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` -// ); -// fulfillments.forEach((fulfillment) => { -// ffState = fulfillment?.state?.descriptor?.code; -// if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { -// onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; -// } -// }); -// } -// } catch (error) { -// console.log(error); -// } -// try { -// fulfillments.forEach((fulfillment) => { -// ffState = fulfillment?.state?.descriptor?.code; -// console.log( -// `Comparing pickup and delivery timestamps for on_status_${ffState}` -// ); - -// if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD") { -// if (ffState === "Pending" || ffState === "Agent-assigned") { -// if (fulfillment?.start?.time?.timestamp) { -// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; -// } -// if (fulfillment?.end?.time?.timestamp) { -// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; -// } -// } -// if (ffState === "Order-picked-up") { -// if (orderState !== "In-progress") { -// onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; -// } -// pickupTime = fulfillment?.start?.time?.timestamp; -// dao.setValue("pickupTime", pickupTime); -// if (!pickupTime) { -// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; -// } - -// if (_.gt(pickupTime, contextTime)) { -// onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; -// } -// } -// if (ffState === "Out-for-delivery") { -// if (orderState !== "In-progress") { -// onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; -// } -// if (!dao.getValue("pickupTime")) { -// onStatusObj.pickupTimeErr = `Missing /on_status response for fulfillment state - 'Order-picked-up'`; -// } else if ( -// !fulfillment?.start?.time?.timestamp || -// fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") -// ) { -// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; -// } -// if (fulfillment?.end?.time?.timestamp) { -// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; -// } -// } -// if (ffState === "Order-delivered") { -// if (orderState !== "Completed") { -// onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; -// } -// deliveryTime = fulfillment?.end?.time?.timestamp; -// dao.setValue("deliveryTime", deliveryTime); -// if (!dao.getValue("pickupTime")) { -// onStatusObj.pickupTimeErr = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; -// } else if ( -// !fulfillment?.start?.time?.timestamp || -// fulfillment?.start?.time?.timestamp !== dao.getValue("pickupTime") -// ) { -// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; -// } -// if (!deliveryTime) { -// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; -// } - -// if (_.gte(pickupTime, deliveryTime)) { -// onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; -// } -// } -// if (ffState === "Cancelled") { -// if (orderState !== "Cancelled") { -// onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; -// } -// if (fulfillments.length > 1) { -// if (!dao.getValue("pickupTime")) { -// onStatusObj.msngPickupState = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; -// } else if (!fulfillment.start.time.timestamp) { -// onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; -// } -// } - -// if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { -// if ( -// !_.isEqual( -// dao.getValue("pickupTime"), -// fulfillment.start.time.timestamp -// ) -// ) { -// onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; -// } -// } -// if (fulfillment.end.time.timestamp && dao.getValue("deliveryTime")) { -// if ( -// !_.isEqual( -// dao.getValue("delivryTime"), -// fulfillment.end.time.timestamp -// ) -// ) { -// onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot change for fulfillment state - ${ffState}`; -// } -// } -// } -// } else if (fulfillment.type === "RTO") { -// if (orderState !== "Cancelled") { -// onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; -// } -// if (ffState === "RTO-Initiated") { -// RtoPickupTime = fulfillment?.start?.time?.timestamp; -// if (RtoPickupTime) { -// dao.setValue("RtoPickupTime", RtoPickupTime); -// } else { -// onStatusObj.rtoPickupTimeErr = `RTO Pickup timestamp is missing for fulfillment state - ${ffState}`; -// } -// if (_.gt(RtoPickupTime, contextTime)) { -// onStatusObj.rtoPickupErr = `RTO Pickup (fulfillments/start/time/timestamp) time cannot be future dated for fulfillment state - ${ffState}`; -// } -// } -// if (ffState === "RTO-Delivered" || ffState === "RTO-Disposed") { -// RtoDeliveredTime = fulfillment?.end?.time?.timestamp; -// console.log(dao.getValue("RtoPickupTime")); -// if (!RtoDeliveredTime && ffState === "RTO-Delivered") -// onStatusObj.rtoDlvryTimeErr = `RTO Delivery timestamp (fulfillments/end/time/timestamp) is missing for fulfillment state - ${ffState}`; -// if ( -// fulfillment.start.time.timestamp && -// dao.getValue("RtoPickupTime") -// ) { -// if ( -// !_.isEqual( -// fulfillment.start.time.timestamp, -// dao.getValue("RtoPickupTime") -// ) -// ) { -// onStatusObj.rtoPickupErr = `RTO Pickup time (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; -// } -// } -// if (RtoDeliveredTime && _.gt(RtoDeliveredTime, contextTime)) { -// onStatusObj.rtoDeliveredErr = `RTO Delivery time (fulfillments/end/time/timestamp) cannot be future dated for fulfillment state - ${ffState}`; -// } -// } -// } -// }); -// } catch (error) { -// console.log(`Error checking fulfillments/start in /update`); -// } + // try { + // console.log( + // `Checking if message id is unique for different on_status apis` + // ); + // if (msgIdSet.has(messageId)) { + // onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; + // } else { + // msgIdSet.add(messageId); + // } + // } catch (error) { + // console.log(`Error checking message id in /on_status API`); + // } + // try { + // if (fulfillments.length > 1) { + // console.log( + // `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` + // ); + // fulfillments.forEach((fulfillment) => { + // ffState = fulfillment?.state?.descriptor?.code; + // if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { + // onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; + // } + // }); + // } + // } catch (error) { + // console.log(error); + // } + try { + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + console.log( + `Comparing pickup and delivery timestamps for on_status_${ffState}` + ); + //Pending,Packed,Agent-assigned + if (fulfillment.type === "Delivery") { + if ( + ffState === "Pending" || + ffState === "Agent-assigned" || + ffState === "Packed" + ) { + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + if (stop?.time?.timestamp) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + //Order-picked-up + + if (ffState === "Order-picked-up") { + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; + } + + if (_.gt(pickupTime, contextTime)) { + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + + + //Out-for-delivery + if (ffState === "Out-for-delivery") { + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; + } else if ( + dao.getValue("pickupTime") && + fulfillment?.start?.time?.timestamp !== + dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + + //Order-delivered + if (ffState === "Order-delivered") { + if (orderState !== "Completed") { + onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; + } else if ( + dao.getValue("pickupTime") && + fulfillment?.start?.time?.timestamp !== + dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + deliveryTime = stop?.time?.timestamp; + dao.setValue("deliveryTime", deliveryTime); + + if (!deliveryTime) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; + } + if (_.gt(deliveryTime, contextTime)) { + onStatusObj.tmstmpErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + if (_.gte(pickupTime, deliveryTime)) { + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; + } + } + }); + } + + + + + } + }); + } catch (error) { + console.log(`Error checking fulfillments/start in /on_status`); + } + console.log(onStatusObj); return onStatusObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js index 71a8357..726d5fa 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js @@ -1,18 +1,59 @@ const _ = require("lodash"); +const fs = require("fs"); +const path = require("path"); const dao = require("../../dao/dao"); const constants = require("../constants"); const utils = require("../utils.js"); +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); -const checkSearch = (data, msgIdSet) => { +const checkSearch = async (data, msgIdSet) => { let srchObj = {}; let search = data; let contextTime = search.context.timestamp; search = search.message.intent; + const stops = data?.message?.intent?.fulfillment?.stops; + let startLocation, endLocation; + stops.forEach((stop) => { + if (stop.type === "start") { + startLocation = stop.location; + } + if (stop.type === "end") { + endLocation = stop.location; + } + }); - dao.setValue("searchObj", search); + console.log("Checking Reverse Geocoding for `end` location in `fullfilment`"); + try { + const [lat, long] = endLocation.gps.split(","); + const area_code = endLocation.area_code; + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) + srchObj[ + "RGC-end-Err" + ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } catch (error) { + console.log("Error in end location", error); + } + + // check for context cityCode and fulfillment end location + try { + const pinToStd = JSON.parse( + fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + ); + const stdCode = data.context?.location?.city?.code.split(":")[1]; + const area_code = endLocation?.area_code; + if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { + srchObj[ + "CityCode-Err" + ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + } + } catch (err) { + console.error("Error in city code check: ", err.message); + } + dao.setValue("searchObj", search); return srchObj; }; -module.exports = checkSearch; \ No newline at end of file +module.exports = checkSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index 158c99a..e15deca 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -21,14 +21,14 @@ const b2bVal = (element, action, msgIdSet) => { case "init": return checkInit(element, msgIdSet); - case "on_init": - return checkOnInit(element, msgIdSet); + // case "on_init": + // return checkOnInit(element, msgIdSet); - case "confirm": - return checkConfirm(element, msgIdSet); + // case "confirm": + // return checkConfirm(element, msgIdSet); - case "on_confirm": - return checkOnConfirm(element, msgIdSet); + // case "on_confirm": + // return checkOnConfirm(element, msgIdSet); // case "update": // return checkUpdate(element,msgIdSet); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/pinToStd.json b/utilities/logistics-b2b/log-verification-utility/utils/b2b/pinToStd.json new file mode 100644 index 0000000..4875211 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/pinToStd.json @@ -0,0 +1 @@ +{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"08414","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 3092b2a..5e039d0 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -120,9 +120,11 @@ module.exports = Object.freeze({ PCC_CODE: ["1", "2", "3", "4"], DCC_CODE: ["1", "2", "3"], FULFILLMENT_TAGS_CODE: ["state", "rto_action","weather_check"], - FULFILLMENT_TAGS_LIST_CODE: ["ready_to_ship", "return_to_origin"], + FULFILLMENT_TAGS_LIST_CODE: ["ready_to_ship", "return_to_origin","raining"], FULFILLMENT_TAGS_LIST_VALUE: ["yes", "no"], TRACKING_STATUS: ["active", "inactive"], + TRACK_TAGS_CODE:["config","order","path"], + TRACK_TAGS_LIST_CODE:["id","attr","type","lat_lng","sequence"], ORDER_STATE: ["Created", "Accepted", "Cancelled", "In-progress","Completed"], CANCELLATION_CODE: [ "001", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 391ca39..72d9b7f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -6,10 +6,19 @@ const utils = require("../utils.js"); const checkConfirm = (data, msgIdSet) => { let cnfrmObj = {}; let confirm = data; + const contextTimestamp= confirm.context.timestamp let version = confirm.context.core_version; let onSearchProvArr = dao.getValue("providersArr"); confirm = confirm.message.order; let rts; + + if (confirm?.updated_at > contextTimestamp) { + cnfrmObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; + } + if (confirm?.created_at > contextTimestamp) { + cnfrmObj.createdAtErr = `order/created_at cannot be future dated w.r.t context/timestamp`; + } + if (confirm.provider.locations && confirm.provider.locations.length > 1) dao.setValue("confirm_locations", confirm.provider.locations); @@ -42,7 +51,6 @@ const checkConfirm = (data, msgIdSet) => { if (provider.id === provId) { const onSearchItemsObj = provider.items; onSearchItemsObj.forEach((onSrchItem) => { - //console.log(onSrchItem); if (onSrchItem.id === item.id) { if (onSrchItem?.time?.duration !== item?.time?.duration) cnfrmObj.itemDurationErr = `item duration does not match with the one provided in /on_search (LSP can send NACK)`; @@ -64,11 +72,13 @@ const checkConfirm = (data, msgIdSet) => { let p2h2p = dao.getValue("p2h2p"); fulfillments.forEach((fulfillment) => { + let avgPickupTime= fulfillment.start.time.duration; + + if(avgPickupTime!==dao.getValue("avgPickupTime")){ + cnfrmObj.avgPckupErr=`Average Pickup Time mismatches from the one provided in /on_search` + } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; - if ( - rts === "yes" && - !fulfillment?.start?.instructions?.short_desc - ) { + if (rts === "yes" && !fulfillment?.start?.instructions?.short_desc) { cnfrmObj.instructionsErr = `fulfillments/start/instructions are required when ready_to_ship = 'yes'`; } }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index 72f30bf..4907554 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -47,6 +47,7 @@ const checkInit = (data, msgIdSet) => { if (location.id === element.id) providerLocExists = true; }); + if (!providerLocExists) { let itemkey = `providerLocErr${i}`; initObj[ diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index 3e0e952..731db03 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -7,6 +7,7 @@ const checkOnCancel = (data, msgIdSet) => { let onCancelObj = {}; let on_cancel = data; let contextTime = on_cancel.context.timestamp; + let version = on_cancel.context.core_version; let messageId = on_cancel.context.message_id; on_cancel = on_cancel.message.order; @@ -14,17 +15,26 @@ const checkOnCancel = (data, msgIdSet) => { let orderState = on_cancel.state; let items = on_cancel.items; let fulfillments = on_cancel.fulfillments; - let RtoPickupTime; + let RtoPickupTime; + const created_at = on_cancel.created_at; + const updated_at = on_cancel.updated_at; + + if (created_at > contextTime || updated_at > contextTime) { + onCancelObj.crtdAtTimeErr = `order/created_at or updated_at should not be future dated w.r.t context/timestamp`; + } try { - if (fulfillments.length > 1) { + if (fulfillments?.length > 1) { console.log( `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` ); fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; - if ((fulfillment.type === "Prepaid" || fulfillment.type === "Delivery") && ffState !== "Cancelled") { + if ( + (fulfillment.type === "Prepaid" || fulfillment.type === "Delivery") && + ffState !== "Cancelled" + ) { onCancelObj.flflmntstErr = `In case of RTO, fulfillment with type '${fulfillment.type}' needs to be 'Cancelled'`; } }); @@ -39,8 +49,11 @@ const checkOnCancel = (data, msgIdSet) => { `Comparing pickup and delivery timestamps for on_cancel_${ffState}` ); - if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery") { - + if ( + fulfillment.type === "Prepaid" || + fulfillment.type === "CoD" || + fulfillment.type === "Delivery" + ) { if (ffState === "Cancelled") { if (orderState !== "Cancelled") { onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; @@ -50,7 +63,9 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - + if(fulfillment.tracking===true){ + onStatusObj.trackErr=`fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled` + } if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( !_.isEqual( @@ -61,12 +76,34 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } } - + console.log('comparing RTO fulfillment id with /on_search'); + //checking RTO id matching with /on_search + if (version === "1.2.0") { + let fulTags = fulfillment?.tags; + let rtoID; + fulTags.forEach((tag) => { + if (tag.code === "rto_event") { + const lists = tag.list; + lists.forEach((list) => { + if (list.code === "rto_id") { + rtoID = list.value; + if (rtoID !== dao.getValue("rtoID")) { + onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${dao.getValue("rtoID")}' in /fulfillments`; + } + } + }); + } + }); + } } } else if (fulfillment.type === "RTO" || fulfillment.type === "Return") { if (orderState !== "Cancelled") { onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } + console.log(fulfillment.id,dao.getValue("rtoID")); + if(fulfillment.id!==dao.getValue("rtoID")){ + onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${dao.getValue("rtoID")}' in /fulfillments`; + } if (ffState === "RTO-Initiated") { RtoPickupTime = fulfillment?.start?.time?.timestamp; console.log(RtoPickupTime); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 910679e..ce4ce33 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -8,15 +8,31 @@ const constants = require("../constants"); const checkOnConfirm = (data, msgIdSet) => { let on_confirm = data; const onCnfrmObj = {}; - + const contextTimestamp= on_confirm.context.timestamp on_confirm = on_confirm.message.order; + let items= on_confirm.items; let fulfillments = on_confirm.fulfillments; let rts = dao.getValue("rts"); let p2h2p = dao.getValue("p2h2p") let awbNo= dao.getValue("awbNo"); + + if (on_confirm?.updated_at > contextTimestamp) { + onCnfrmObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; + } + if (on_confirm?.created_at > contextTimestamp) { + onCnfrmObj.createdAtErr = `order/created_at cannot be future dated w.r.t context/timestamp`; + } + + let categoryId; + items.forEach(item=>{ + categoryId=item.category_id; + }) try { console.log(`checking start and end time range in fulfillments`); fulfillments.forEach((fulfillment) => { + if(categoryId==='Immediate Delivery' && fulfillment.tracking !== true){ + onCnfrmObj.trckErr= `tracking should be enabled (true) for hyperlocal (Immediate Delivery)` + } if(fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo= true; console.log("rts",rts) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js index 638e31f..d53e7f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js @@ -14,6 +14,11 @@ const checkOnInit = (data, msgIdSet) => { let onSearchProvArr = dao.getValue("providersArr"); + console.log(dao.getValue("providerLoc"),on_init.provider_location); + if(dao.getValue("providerLoc")===false && on_init.provider_location){ + onInitObj.prvdrLocErr=`Provider location should be provided only if returned in /on_search, also it is used where the shipment has to be dropped at LSP location` + } + try { console.log( `Comparing order quote price and break up in ${constants.LOG_ONINIT}` @@ -32,33 +37,39 @@ const checkOnInit = (data, msgIdSet) => { ] = `Price value for '${breakup["@ondc/org/title_type"]}' should not have more than 2 decimal places`; } totalBreakup += parseFloat(breakup.price.value); - + onSearchProvArr?.forEach((provider) => { - if (provider.id === provId) { provider?.items.forEach((item, i) => { - if ( item.id === breakup["@ondc/org/item_id"] && - (breakup["@ondc/org/title_type"] === "delivery") + breakup["@ondc/org/title_type"] === "delivery" ) { - if (parseFloat(on_init.quote.price.value) !== parseFloat(item.price.value)) { + if ( + parseFloat(on_init.quote.price.value) !== + parseFloat(item.price.value) + ) { let itemKey = `priceArr${i}`; - onInitObj[ - itemKey - ] = `Quote price ${parseFloat(on_init.quote.price.value)} for item id '${breakup["@ondc/org/item_id"]}' does not match item price ${item.price.value} in /on_search`; + onInitObj[itemKey] = `Quote price ${parseFloat( + on_init.quote.price.value + )} for item id '${ + breakup["@ondc/org/item_id"] + }' does not match item price ${ + item.price.value + } in /on_search`; } } - }); - - } }); }); if (parseFloat(on_init.quote.price.value) !== totalBreakup) - onInitObj.quotePriceErr = `Quote price ${parseFloat(on_init.quote.price.value)} does not match the breakup total ${totalBreakup} in ${constants.LOG_ONINIT}`; + onInitObj.quotePriceErr = `Quote price ${parseFloat( + on_init.quote.price.value + )} does not match the breakup total ${totalBreakup} in ${ + constants.LOG_ONINIT + }`; } } catch (err) { console.log( diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js index 5e1ac22..f295472 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js @@ -2,9 +2,9 @@ const _ = require("lodash"); const dao = require("../../dao/dao"); const constants = require("../constants"); const utils = require("../utils"); -const {reverseGeoCodingCheck} = require("../reverseGeoCoding") +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); -const checkOnSearch = (data, msgIdSet) => { +const checkOnSearch = async (data, msgIdSet) => { const onSrchObj = {}; let onSearch = data; let core_version = onSearch.context.core_version; @@ -12,7 +12,7 @@ const checkOnSearch = (data, msgIdSet) => { let search = dao.getValue("searchObj"); let validFulfillmentIDs = new Set(); onSearch = onSearch.message.catalog; - + let avgPickupTime; try { console.log( `Checking TAT for category or item in ${constants.LOG_ONSEARCH} api` @@ -22,40 +22,62 @@ const checkOnSearch = (data, msgIdSet) => { provider.categories.forEach((category) => { const catName = category.id; const categoryTime = category.time; - const currentDate = timestamp.split('T')[0]; + const currentDate = timestamp.split("T")[0]; const dateObj = new Date(currentDate); - const nextDate = new Date(dateObj.setDate(dateObj.getDate() + 1)).toISOString().split('T')[0]; - const categoryTimestamp = core_version == "1.1.0" ? categoryTime?.timestamp?.split('T')[0] : categoryTime?.timestamp; - if((catName == 'Same Day Delivery' || catName == 'Immediate Delivery') && categoryTimestamp && categoryTimestamp != currentDate){ - onSrchObj.catTAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` + const nextDate = new Date(dateObj.setDate(dateObj.getDate() + 1)) + .toISOString() + .split("T")[0]; + const categoryTimestamp = + core_version == "1.1.0" + ? categoryTime?.timestamp?.split("T")[0] + : categoryTime?.timestamp; + + if ( + (catName == "Same Day Delivery" || + catName == "Immediate Delivery") && + categoryTimestamp && + categoryTimestamp != currentDate + ) { + onSrchObj.catTAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}`; } - if(catName == 'Next Day Delivery' && categoryTimestamp && categoryTimestamp != nextDate){ - onSrchObj.catTAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` + if ( + catName == "Next Day Delivery" && + categoryTimestamp && + categoryTimestamp != nextDate + ) { + onSrchObj.catTAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}`; } provider.items.forEach((item) => { const catId = item.category_id; const itemTime = item.time; - const itemTimestamp = core_version == "1.1.0" ? itemTime?.timestamp?.split('T')[0] : itemTime?.timestamp; + const itemTimestamp = + core_version == "1.1.0" + ? itemTime?.timestamp?.split("T")[0] + : itemTime?.timestamp; if (catName === catId && !categoryTime && !itemTime) onSrchObj.TAT = `Either Category level TAT or Item level TAT should be given in ${constants.LOG_ONSEARCH} api for category "${catName}"`; - if((catId == 'Same Day Delivery' || catId == 'Immediate Delivery') && itemTimestamp && itemTimestamp != currentDate){ - onSrchObj.itemTAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}` - } - if(catId == 'Next Day Delivery' && itemTimestamp && itemTimestamp != nextDate){ - onSrchObj.itemTAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}` - } + if ( + (catId == "Same Day Delivery" || catId == "Immediate Delivery") && + itemTimestamp && + itemTimestamp != currentDate + ) { + onSrchObj.itemTAT = `For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. ${currentDate}`; + } + if ( + catId == "Next Day Delivery" && + itemTimestamp && + itemTimestamp != nextDate + ) { + onSrchObj.itemTAT = `For Next Day Delivery, TAT date should be the next date i.e. ${nextDate}`; + } }); }); }); } } catch (error) { - console.log( - `!!Error while fetching category and item TAT`, - error - ); + console.log(`!!Error while fetching category and item TAT`, error); } - //forward and backward shipment try { console.log( @@ -78,20 +100,26 @@ const checkOnSearch = (data, msgIdSet) => { for (const fulfillment of fulfillments) { validFulfillmentIDs.add(fulfillment.id); - if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery") { + if ( + fulfillment.type === "Prepaid" || + fulfillment.type === "CoD" || + fulfillment.type === "Delivery" + ) { hasForwardShipment = true; + avgPickupTime= fulfillment?.start?.time?.duration + dao.setValue("avgPickupTime",avgPickupTime) } else if ( fulfillment.type === "RTO" || - fulfillment.type === "Reverse QC" || fulfillment.type === "Return" + fulfillment.type === "Reverse QC" || + fulfillment.type === "Return" ) { hasBackwardShipment = true; + if (fulfillment.type === "RTO") dao.setValue("rtoID", fulfillment.id); } } if (hasForwardShipment && hasBackwardShipment) { - console.log( - "Both forward and backward shipments are present." - ); + console.log("Both forward and backward shipments are present."); } else if (!hasForwardShipment) { onSrchObj.frwrdShpmnt = `Forward shipment is missing in fulfillments in ${constants.LOG_ONSEARCH} api`; } else if (!hasBackwardShipment) { @@ -139,29 +167,40 @@ const checkOnSearch = (data, msgIdSet) => { error ); } - + let providerLoc = false; // RGC checks on bpp/provider console.log(`Checking Reverse Geocoding on bpp/providers`); if (onSearch.hasOwnProperty("bpp/providers")) { - onSearch["bpp/providers"].forEach((provider) => { + const providers = onSearch["bpp/providers"]; + for (let i = 0; i < providers.length; i++) { + const provider = providers[i]; if (provider.hasOwnProperty("locations")) { - provider.locations.forEach( - async ({ id, gps, address: { area_code } }) => { - try { - const [lat, long] = gps.split(","); - const match = await reverseGeoCodingCheck(lat, long, area_code); - if (!match) - onSrchObj[ - "bpp/provider:location:" + id + ":RGC" - ] = `Reverse Geocoding for location ID ${id} failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; - } catch (error) { - console.log("bpp/providers error: ", error); + const locations = provider.locations; + if (locations?.length > 1) { + providerLoc = true; + } + for (let j = 0; j < locations.length; j++) { + const { + id, + gps, + address: { area_code }, + } = locations[j]; + try { + const [lat, long] = gps.split(","); + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) { + onSrchObj[ + "bpp/provider:location:" + id + ":RGC" + ] = `Reverse Geocoding for location ID ${id} failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; } + } catch (error) { + console.log("bpp/providers error: ", error); } - ); + } } - }); + dao.setValue("providerLoc", providerLoc); + } } return onSrchObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index 1093c5c..abda338 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -15,16 +15,32 @@ const checkOnStatus = (data, msgIdSet) => { let items = on_status.items; let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; + let paymentStatus = on_status?.payment?.status; + if (on_status.state === "Complete" && payment.type === "ON-FULFILLMENT") { + if (paymentStatus !== "PAID") { + onStatusObj.pymntStatusErr = `Payment status should be 'PAID' once the order is complete for payment type 'ON-FULFILLMENT'`; + } + if (!on_status?.payment?.time) { + onStatusObj.pymntTimeErr = `Payment time should be recorded once the order is complete for payment type 'ON-FULFILLMENT'`; + } + } + let categoryId; + items.forEach((item) => { + categoryId = item.category_id; + }); try { - if (fulfillments.length > 1) { + if (fulfillments?.length > 1) { console.log( `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` ); fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; - if ((fulfillment.type === "Prepaid" || fulfillment.type === "Delivery") && ffState !== "Cancelled") { + if ( + (fulfillment.type === "Prepaid" || fulfillment.type === "Delivery") && + ffState !== "Cancelled" + ) { onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Delivery/Prepaid' needs to in 'Cancelled' state`; } }); @@ -39,7 +55,17 @@ const checkOnStatus = (data, msgIdSet) => { `Comparing pickup and delivery timestamps for on_status_${ffState}` ); - if (fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery") { + if ( + fulfillment.type === "Prepaid" || + fulfillment.type === "CoD" || + fulfillment.type === "Delivery" + ) { + if ( + categoryId === "Immediate Delivery" && + fulfillment.tracking !== true + ) { + onStatusObj.trckErr = `tracking should be enabled (true) for hyperlocal (Immediate Delivery)`; + } if (ffState === "Pending" || ffState === "Agent-assigned") { if (fulfillment?.start?.time?.timestamp) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; @@ -66,7 +92,6 @@ const checkOnStatus = (data, msgIdSet) => { } } if (ffState === "Out-for-delivery") { - if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } @@ -92,7 +117,7 @@ const checkOnStatus = (data, msgIdSet) => { deliveryTime = fulfillment?.end?.time?.timestamp; dao.setValue("deliveryTime", deliveryTime); - if (!fulfillment?.start?.time?.timestamp) { + if (!fulfillment?.start?.time?.timestamp) { { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } @@ -123,7 +148,9 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - + if(fulfillment.tracking===true){ + onStatusObj.trackErr=`fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled` + } if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( !_.isEqual( @@ -149,7 +176,7 @@ const checkOnStatus = (data, msgIdSet) => { if (orderState !== "Cancelled") { onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } - if (ffState === "RTO-Initiated" && fulfillment.type === "Prepaid" ) { + if (ffState === "RTO-Initiated" && fulfillment.type === "Prepaid") { RtoPickupTime = fulfillment?.start?.time?.timestamp; console.log(RtoPickupTime); if (RtoPickupTime) { @@ -161,7 +188,7 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.rtoPickupErr = `RTO Pickup (fulfillments/start/time/timestamp) time cannot be future dated for fulfillment state - ${ffState}`; } } - + if (ffState === "RTO-Delivered" || ffState === "RTO-Disposed") { RtoDeliveredTime = fulfillment?.end?.time?.timestamp; if (!RtoDeliveredTime && ffState === "RTO-Delivered") diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js new file mode 100644 index 0000000..440291e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js @@ -0,0 +1,27 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnTrack = (data, msgIdSet) => { + let onTrackObj = {}; + let on_track = data; + let contextTimestamp = on_track?.context?.timestamp; + + on_track = on_track.message.tracking; + + + if (on_track?.location.updated_at > contextTimestamp) { + onTrackObj.updatedAtErr = `tracking/location/updated_at cannot be future dated w.r.t context/timestamp`; + } + + + if (on_track?.location.time.timestamp > contextTimestamp) { + onTrackObj.updatedAtErr = `tracking/location/time/timestamp cannot be future dated w.r.t context/timestamp`; + } + + + return onTrackObj; +}; + +module.exports = checkOnTrack; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js index 251b8a6..f6ab610 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js @@ -29,6 +29,7 @@ const checkOnUpdate = (data, msgIdSet) => { `Checking if start and end time range required in /on_update api` ); fulfillments.forEach((fulfillment) => { + const ffState = fulfillment?.state?.descriptor?.code if (fulfillment["@ondc/org/awb_no"]) { awbNo = true; } @@ -43,6 +44,9 @@ const checkOnUpdate = (data, msgIdSet) => { if (rts === "yes" && !fulfillment?.start?.time?.range) { onUpdtObj.strtRangeErr = `start/time/range is required in /fulfillments when ready_to_ship = yes in /update`; } + if (fulfillment?.start?.time?.timestamp || fulfillment?.end?.time?.timestamp) { + onUpdtObj.tmpstmpErr = `start/time/timestamp or end/time/timestamp cannot be provided in /fulfillments when fulfillment state is ${ffState}`; + } if (rts === "yes" && !fulfillment?.end?.time?.range) { onUpdtObj.endRangeErr = `end/time/range is required in /fulfillments when ready_to_ship = yes in /update`; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js index a387442..2144d35 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js @@ -66,7 +66,7 @@ const checkSearch = async (data, msgIdSet) => { } catch (error) { console.log("Error in end location",error) } - //console.log("srchObj from search:", srchObj) + dao.setValue("searchObj", search); return srchObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json b/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json index 4875211..0e70a6b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/pinToStd.json @@ -1 +1 @@ -{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"08414","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file +{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"040","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/testSchemaValidation.js b/utilities/logistics-b2b/log-verification-utility/utils/testSchemaValidation.js new file mode 100644 index 0000000..a511025 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/testSchemaValidation.js @@ -0,0 +1,5 @@ +const {validate_schema_master}= require("../schema/logistics_api_json_schema/SchemaValidator"); +const data = require("./test.json") + +const errors=validate_schema_master(data) +console.log(errors); \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 2ca83d8..55e29ab 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -228,6 +228,37 @@ function compareDates(dateString1, dateString2) { } } +function iso8601DurationToSeconds(duration) { + const unitMap = { + 'D': 24 * 60 * 60 * 1000, // Days to seconds + 'H': 60 * 60 * 1000, // Hours to seconds + 'M': 60 * 1000, // Minutes to seconds + 'S': 1000 // Seconds + }; + + if (duration.startsWith("P")) { + duration = duration.slice(1); // Remove the 'P' at the beginning + } + + let totalSeconds = 0; + let currentNumber = ""; + for (const char of duration) { + if (!isNaN(char)) { + currentNumber += char; + } else if (char in unitMap) { + totalSeconds += parseInt(currentNumber) * unitMap[char]; + currentNumber = ""; + } + } + + return totalSeconds; +} + +// Example usages: +console.log(iso8601DurationToSeconds("P6D")); // 518400 seconds (6 days) +console.log(iso8601DurationToSeconds("PT30S")); // 30 seconds +console.log(iso8601DurationToSeconds("PT2H30M")); // 9000 seconds (2 hours 30 minutes) + const hasTwoOrLessDecimalPlaces = (inputString) => { const parts = inputString.split("."); @@ -346,6 +377,7 @@ module.exports = { categoriesMap, compareDates, hasTwoOrLessDecimalPlaces, + iso8601DurationToSeconds, timeDiff, getVersion, taxNotInlcusive, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js index d8b0b0e..c9b6d71 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js @@ -5,7 +5,6 @@ const path = require("path"); const { getObjValues } = require("./utils"); const { sortMerge } = require("./mergeSort"); const Validate = require("./schemaVal"); -//const flowVal = require("./retail/businessVal"); const clean = require("./clean"); const validateLogs = async (domain, dirPath, outputDestination = "") => { From 3cf103d0ef050f611f5672e6c1336cde8a369101 Mon Sep 17 00:00:00 2001 From: Sahil Sharma <123928721+sahilsharma9@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:01:03 +0530 Subject: [PATCH 051/228] feat: node.js lookup service --- utilities/vlookup/node.js/README.md | 65 ++++++++++++ utilities/vlookup/node.js/index.js | 147 ++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 utilities/vlookup/node.js/README.md create mode 100644 utilities/vlookup/node.js/index.js diff --git a/utilities/vlookup/node.js/README.md b/utilities/vlookup/node.js/README.md new file mode 100644 index 0000000..b93686d --- /dev/null +++ b/utilities/vlookup/node.js/README.md @@ -0,0 +1,65 @@ +# ONDC VLookup Service + +This repository contains a simple Express.js server that facilitates the ONDC (Open Network for Digital Commerce) VLookup service. The VLookup service allows you to perform lookups in the ONDC registry and obtain relevant information based on specified parameters. + +## Getting Started + +### Prerequisites + +- Node.js installed on your machine + +### Installation + +1. Clone this repository to your local machine. +2. Navigate to the project directory in the terminal. +3. Run `npm install` to install the required dependencies. + +### Usage + +1. Start the server by running `node index.js` in the terminal. +2. The server will run on http://localhost:9900. + +## Routes + +### VLookup + +Perform a VLookup operation by sending a POST request to `http://localhost:9900/vlookup`. The payload should be in the following format: + +```json +{ + "senderSubscriberId": "your_subscriber_id", + "privateKey": "your_private_key", + + //search parameters of the NP whose details need to be fetched from registry + + "domain": "ONDC:RET10", + "subscriberId": "subscriber_id", // subscriber_id you want to lookup + "country": "IND", // country + "type": "buyerApp", //buyerApp, sellerApp, gateway + "city": "std:022", // city code + "env": "staging" //staging,preprod,prod +} +``` + +## Signature + +Sign your data by sending a POST request to [http://localhost:9900/vlookup/sign](http://localhost:9900/vlookup/sign). The payload should be the same as for the VLookup route. The response will include a signature. + +## Important Note + +Make sure to replace the sample private key with your actual private key. + +## Dependencies + +- Express.js +- sodium-native +- crypto +- axios + +## Contributing + +Feel free to contribute to the development of this project by submitting pull requests. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. diff --git a/utilities/vlookup/node.js/index.js b/utilities/vlookup/node.js/index.js new file mode 100644 index 0000000..9b831cc --- /dev/null +++ b/utilities/vlookup/node.js/index.js @@ -0,0 +1,147 @@ +const express = require("express"); +const sodium = require("sodium-native"); +const crypto = require("crypto"); +const axios = require("axios"); +const app = express(); +const port = 9900; + +const createSigningString = (data) => { + const { country, domain, type, city, subscriberId } = data; + return [country, domain, type, city, subscriberId].join("|"); +}; + +const getEnvDetails = (env) => { + let envLink = ""; + if (env === "preprod") { + envLink = "https://preprod.registry.ondc.org/ondc/vlookup"; + } else if (env === "prod") { + envLink = "https://prod.registry.ondc.org/vlookup"; + } else if (env === "staging") { + envLink = "https://staging.registry.ondc.org/vlookup"; + } else { + throw new Error("Unsupported environment"); + } + return envLink; +}; + +const fetchRegistryResponse = async ( + requestId, + timestamp, + signature, + searchParameters, + senderSubscriberId, + envLink +) => { + try { + const response = await axios.post(envLink, { + sender_subscriber_id: senderSubscriberId, + request_id: requestId, + timestamp, + search_parameters: searchParameters, + signature, + }); + return response; + } catch (error) { + return error; + } +}; + +const getVLookUpData = async (signature, data) => { + try { + const requestId = crypto.randomUUID(); + const timestamp = new Date().toISOString(); + const { country, domain, type, city, subscriberId } = data; + const searchParameters = { + country, + domain, + type, + city, + subscriber_id: subscriberId, + }; + const senderSubscriberId = data.senderSubscriberId; + const envLink = getEnvDetails(data.env); + + const res = await fetchRegistryResponse( + requestId, + timestamp, + signature, + searchParameters, + senderSubscriberId, + envLink + ); + return res; + } catch (error) { + logError("getVLookUpData", error); + throw error; + } +}; + +const signData = (message, privateKey) => { + const signature = new Uint8Array(sodium.crypto_sign_BYTES); + sodium.crypto_sign_detached(signature, message, privateKey); + return signature; +}; + +const sign = (signingString, privateKey) => { + let privateKeyBytes = Buffer.from(privateKey, "base64"); + const message = Buffer.from(signingString); + + if (privateKeyBytes.length !== sodium.crypto_sign_SECRETKEYBYTES) { + return "Invalid private key length"; + } + privateKey = new Uint8Array(privateKeyBytes); + + const signature = signData(message, privateKey); + + signatureBase64 = Buffer.from(signature).toString("base64"); + + return signatureBase64; +}; + +const vLookUp = async (data) => { + try { + const signingString = createSigningString(data); + const signature = sign(signingString, data.privateKey); + let res = await getVLookUpData(signature, data); + res = res.data; + return res; + } catch (error) { + logError("vLookUp", error); + throw error; + } +}; + +const logError = (location, error) => { + console.error(`Error in ${location}:`, error); +}; + +app.use(express.json()); + +// Route for signing your data +app.post("/vlookup/sign", (req, res) => { + try { + const data = req.body; + const signingString = createSigningString(data); + const signature = sign(signingString, data.privateKey); + res.status(200).send({ success: true, signature }); + } catch (error) { + logError("/vlookup/sign", error); + res.status(400).send({ success: false, response: error.message }); + } +}); + +// Route for vlookup +app.post("/vlookup", async (req, res) => { + try { + const response = await vLookUp(req.body); + res.status(200).send({ success: true, response }); + } catch (error) { + logError("/vlookup", error); + res.status(400).send({ success: false, response: error.message }); + } +}); + +// Start the server +app.listen(port, () => { + console.log(`Server is running on http://localhost:${port}`); +}); From d7a7c1e710408a0a8b57c782ceccdba0fc112685 Mon Sep 17 00:00:00 2001 From: Sahil Sharma <123928721+sahilsharma9@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:28:35 +0530 Subject: [PATCH 052/228] ref: added package.json and .gitignore --- utilities/vlookup/node.js/.gitignore | 2 ++ utilities/vlookup/node.js/README.md | 2 +- utilities/vlookup/node.js/package.json | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 utilities/vlookup/node.js/.gitignore create mode 100644 utilities/vlookup/node.js/package.json diff --git a/utilities/vlookup/node.js/.gitignore b/utilities/vlookup/node.js/.gitignore new file mode 100644 index 0000000..49e0fc6 --- /dev/null +++ b/utilities/vlookup/node.js/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/package-lock.json \ No newline at end of file diff --git a/utilities/vlookup/node.js/README.md b/utilities/vlookup/node.js/README.md index b93686d..9e13889 100644 --- a/utilities/vlookup/node.js/README.md +++ b/utilities/vlookup/node.js/README.md @@ -16,7 +16,7 @@ This repository contains a simple Express.js server that facilitates the ONDC (O ### Usage -1. Start the server by running `node index.js` in the terminal. +1. Start the server by running `npm start` in the terminal. 2. The server will run on http://localhost:9900. ## Routes diff --git a/utilities/vlookup/node.js/package.json b/utilities/vlookup/node.js/package.json new file mode 100644 index 0000000..8a69f84 --- /dev/null +++ b/utilities/vlookup/node.js/package.json @@ -0,0 +1,18 @@ +{ + "name": "vlookup-service", + "version": "1.0.0", + "description": "This repository contains a simple Express.js server that facilitates the ONDC (Open Network for Digital Commerce) VLookup service. The VLookup service allows you to perform lookups in the ONDC registry and obtain relevant information based on specified parameters.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node index.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^1.6.2", + "crypto": "^1.0.1", + "express": "^4.18.2", + "sodium-native": "^4.0.4" + } +} From 724fe7fa9f4efb9dba9abc1f597ffa6f642f7ba5 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Dec 2023 11:10:22 +0530 Subject: [PATCH 053/228] minor bug fixes --- .../347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json | 1 + .../6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json | 1 + .../schema/B2B_json_schema/on_confirm.js | 2 -- .../schema/B2B_json_schema/on_init.js | 3 +-- .../schema/B2B_json_schema/on_select.js | 3 +-- .../schema/B2B_json_schema/on_status.js | 3 +-- .../schema/B2B_json_schema/select.js | 6 ++++-- .../logistics_api_json_schema/v1.1/initSchema.js | 1 - .../logistics_api_json_schema/v1.1/onStatusSchema.js | 3 +-- .../logistics_api_json_schema/v1.1/searchSchema.js | 1 - .../v1.2/common/commonSchema.js | 1 - .../logistics_api_json_schema/v1.2/confirmSchema.js | 3 +-- .../logistics_api_json_schema/v1.2/initSchema.js | 5 ++--- .../logistics_api_json_schema/v1.2/onCancelSchema.js | 11 ++++------- .../logistics_api_json_schema/v1.2/onInitSchema.js | 3 +-- .../logistics_api_json_schema/v1.2/onStatusSchema.js | 9 +++------ .../logistics_api_json_schema/v1.2/searchSchema.js | 2 -- 17 files changed, 21 insertions(+), 37 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json new file mode 100644 index 0000000..3e428f9 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json @@ -0,0 +1 @@ +{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:32.568Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Express Delivery"},"fulfillment":{"type":"Delivery","end":{"location":{"gps":"28.5080098, 77.0909696","address":{"area_code":"122016"}}},"start":{"location":{"gps":"12.9298689, 77.6848366","address":{"area_code":"560103"}}}},"provider":{"time":{"range":{"start":"0000","end":"2359"},"days":"1,2,3,4,5,6,7","schedule":{"holidays":[]}}},"payment":{"type":"POST-FULFILLMENT"},"@ondc/org/payload_details":{"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}},"value":{"currency":"INR","value":"2000.0"},"category":"Grocery","weight":{"unit":"gram","value":10}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:33.338Z","ttl":"PT30S"},"message":{"catalog":{"bpp/descriptor":{"name":"Ecom Express Private Limited"},"bpp/providers":[{"id":"I1","descriptor":{"name":"Ecom Express Private Limited","short_desc":"Ecom Express Private Limited","long_desc":"Ecom Express Private Limited"},"categories":[{"id":"Express Delivery","time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}],"fulfillments":[{"id":"1","type":"Delivery"},{"id":"2","type":"RTO"}],"items":[{"id":"1","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"1","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}},{"id":"2","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"2","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}]}]}}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.110Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.906Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}}}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.642Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"code":"4","short_desc":"1368","long_desc":"QR code will be attached to package"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:20:59.374Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.973Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"short_desc":"1368","long_desc":"QR code will be attached to package","code":"4"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:39.973Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"889d3a90-9a20-4289-bb83-b05809918520","timestamp":"2023-12-18T13:38:54.815Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","items":[{"id":"1","descriptor":{"code":"P2H2P"},"category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"@ondc/org/awb_no":"110919056165"}],"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:32:39.165Z"},"update_target":"fulfillment"}}],"on_update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"246cb466-8ac5-40b6-a586-08c8bdc1c72b","timestamp":"2023-12-18T13:38:55.288Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Accepted","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:55.288Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11457434-00a2-434d-bc7f-16eff98e3737","timestamp":"2023-12-18T13:39:37.639Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:39:37.639Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"0bf1fd6a-8e8f-4fc1-aad2-79152c0237b4","timestamp":"2023-12-18T13:40:21.368Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Initiated"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:40:21.368Z","created_at":"2023-12-07T14:20:59.374Z"}}},{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"2119685b-9816-4571-b6bd-4f428ee12812","timestamp":"2023-12-18T13:41:34.451Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Delivered"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:41:34.451Z","created_at":"2023-12-07T14:20:59.374Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json new file mode 100644 index 0000000..bc99584 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json @@ -0,0 +1 @@ +{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.783Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Immediate Delivery"},"provider":{"time":{"days":"1,2,3,4,5,6","schedule":{"holidays":[]},"duration":"PT30M","range":{"start":"0630","end":"2359"}}},"fulfillment":{"type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"area_code":"560068"}}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"area_code":"560068"}}}},"payment":{"type":"ON-ORDER","@ondc/org/collection_amount":"0"},"@ondc/org/payload_details":{"weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}},"category":"F&B","value":{"currency":"INR","value":"238.0"}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.909Z","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org"},"message":{"catalog":{"bpp/descriptor":{"name":"WITS Project Ref Logistic"},"bpp/providers":[{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320","descriptor":{"name":"WITS Project Ref Logistic","long_desc":"WITS Project Ref Logistic","short_desc":"WITS Project Ref Logistic"},"categories":[{"id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"PT15M"}},"tags":[{"code":"distance","list":[{"code":"motorable_distance_type","value":"kilometer"},{"code":"motorable_distance","value":"0.15"}]}]},{"id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","type":"RTO"}],"items":[{"id":"Standard","parent_item_id":"","category_id":"Immediate Delivery","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P","name":"Immediate Delivery","long_desc":"Upto 60 mins for Delivery","short_desc":"Upto 60 mins for Delivery"},"price":{"currency":"INR","value":"122.38"},"time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}},{"id":"rto","parent_item_id":"Standard","category_id":"Immediate Delivery","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P","name":"RTO quote","short_desc":"RTO quote","long_desc":"RTO quote"},"price":{"currency":"INR","value":"34.82"},"time":{"label":"TAT","duration":"P1D","timestamp":"2023-12-09"}}]}]}}}],"cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","cancellation_reason_id":"010"}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery","descriptor":{"code":"P2P"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:09.356Z","updated_at":"2023-12-08T09:08:09.356Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/settlement_details":[]}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.525Z"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery"}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"tags":[{"code":"rider_check","list":[{"code":"inline_check_for_rider","value":"yes"}]}]}],"quote":{"price":{"currency":"INR","value":"122.38"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}}],"ttl":"PT15M"},"payment":{"type":"ON-ORDER","collected_by":"BAP","@ondc/org/settlement_details":[]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"refund_eligible":true,"reason_required":false,"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}}},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"50"}}},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100"}}},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}}}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.306Z","ttl":"PT30S"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Created","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","price":{"value":"116.00","currency":"INR"},"@ondc/org/title_type":"delivery"},{"@ondc/org/item_id":"Standard","price":{"value":"6.38","currency":"INR"},"@ondc/org/title_type":"tax"}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","tracking":true,"start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}]}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP"},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"unit":"kilogram","value":3}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Accepted","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"tracking":false}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","status":"PAID","@ondc/org/settlement_details":[]},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}},"refund_eligible":true,"reason_required":false},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"50"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}},"refund_eligible":true,"reason_required":true}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}],"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.489Z"}}}],"status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"ref_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"on_track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.763Z"},"message":{"tracking":{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","location":{"gps":"12.958766,77.625282","time":{"timestamp":"2023-12-08T09:08:11.489Z"},"updated_at":"1970-01-01T00:00:00.000Z"},"status":"active"}}}],"on_support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.785Z"},"message":{"phone":"8755555551","email":"accounts@thewitslab.com","uri":"http://t.me/supportBot"}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:39.272Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"In-progress","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tracking":false}],"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","@ondc/org/settlement_details":[]},"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]}}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:34:28.223Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Cancelled","cancellation":{"cancelled_by":"extweb.oyeti.com/ecommerce/ondc","reason":{"id":"010"}},"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}},{"id":"rto","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"159.09","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"rto","price":{"currency":"INR","value":"36.71"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"3.67"}}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"start":{"time":{"duration":"P1D","timestamp":"2023-12-08T09:18:06.524Z"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]},"time":{"timestamp":"2023-12-08T09:19:27.742Z"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","time":{"timestamp":"2023-12-08T09:19:27.742Z"}},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"value":3,"unit":"kilogram"}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}}},"updated_at":"2023-12-08T09:34:28.223Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js index 201216f..d6fef76 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js @@ -628,8 +628,6 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js index 5de61bb..c145f38 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js @@ -549,8 +549,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js index 3a97ae2..f137e4b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js @@ -321,8 +321,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup", "ttl"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js index c687d03..4d202a2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js @@ -568,8 +568,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js index 9a4649c..8e18120 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js @@ -177,7 +177,8 @@ module.exports = { type: "object", properties: { code: { - type: "string" + type: "string", + enum: ["BUYER_TERMS"], }, }, required: ["code"], @@ -191,7 +192,8 @@ module.exports = { type: "object", properties: { code: { - type: "string" + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js index 51e46f8..6844f48 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js @@ -335,7 +335,6 @@ module.exports = { }, additionalProperties: false, isLengthValid:true, - errorMessage:"name + building + locality < 190 chars", required: [ "name", "building", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js index fb38da1..91a0436 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js @@ -202,8 +202,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup"], }, fulfillments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js index fd47ce2..e583451 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js @@ -139,7 +139,6 @@ module.exports = { }, }, isEndTimeGreater: true, - errorMessage: 'The "end" time must be greater than the "start" time. Ref footnote 12 of v1.1 .', required: ["start", "end"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js index 9a9ed5a..2d0b76e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js @@ -55,7 +55,6 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: "name + building + locality < 190 chars", }, }, required: ["gps", "address"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 5f77fae..9b96e2e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -1042,7 +1042,6 @@ module.exports = { }, }, // isFutureDated: true, - // errorMessage: - // "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 7ac6ff0..f63135d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -197,7 +197,7 @@ module.exports = { }, }, isLengthValid:true, - errorMessage:"name + building + locality < 190 chars", + required: [ "name", "building", @@ -275,7 +275,7 @@ module.exports = { }, }, isLengthValid:true, - errorMessage:"name + building + locality < 190 chars", + required: [ "name", "building", @@ -346,7 +346,6 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: "name + building + locality < 190 chars", additionalProperties: false, required: [ "name", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 860fa2d..256cbe1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -195,8 +195,7 @@ module.exports = { }, required: ["price", "breakup"], isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + }, fulfillments: { @@ -340,8 +339,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], @@ -462,8 +460,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], @@ -717,6 +714,6 @@ module.exports = { }, }, // isFutureDated: true, - // errorMessage: "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js index a372264..82bc4e4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -187,8 +187,7 @@ module.exports = { }, required: ["price", "breakup", "ttl"], isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + }, fulfillments: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 348df28..0b7fbf5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -199,8 +199,7 @@ module.exports = { }, required: ["price", "breakup"], isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + }, fulfillments: { type: "array", @@ -340,8 +339,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], @@ -467,8 +465,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js index 3c7def9..a750922 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js @@ -122,8 +122,6 @@ module.exports = { }, }, isEndTimeGreater: true, - errorMessage: - 'The "end" time must be greater than the "start" time', required: ["start", "end"], }, }, From d162983144571a4849f5f622e90a6662a6d6ce8f Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Dec 2023 11:45:10 +0530 Subject: [PATCH 054/228] bug fixes --- .../v1.1/confirmSchema.js | 5 +++++ .../v1.1/onStatusSchema.js | 2 +- .../v1.2/confirmSchema.js | 5 +++++ .../logistics_api_json_schema/v1.2/initSchema.js | 1 + .../v1.2/onUpdateSchema.js | 2 +- .../log-verification-utility/utils/ContextVal.js | 16 +++++++++++++--- .../utils/logistics/logConfirm.js | 2 +- .../utils/logistics/logOnStatus.js | 14 +++++++++----- 8 files changed, 36 insertions(+), 11 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index 55f5a4c..bfe077e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -87,6 +87,11 @@ module.exports = { properties: { id: { type: "string", + not: { + const: { $data: "1/context/transaction_id" }, + }, + errorMessage: + "should be unique (cannot be equal to transaction_id)", }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js index 91a0436..d9c2783 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js @@ -393,7 +393,7 @@ module.exports = { }, }, if: { properties: { type: { const: "Prepaid" } } }, - then: { required: ["type", "state", "tracking"] }, + then: { required: ["type", "state", "tracking","start","end"] }, else: { required: ["type", "state"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 9b96e2e..88416f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -88,6 +88,11 @@ module.exports = { properties: { id: { type: "string", + not: { + const: { $data: "1/context/transaction_id" }, + }, + errorMessage: + "should be unique (cannot be equal to transaction_id)", }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index f63135d..0721b13 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -459,6 +459,7 @@ module.exports = { errorMessage:"should be same as in /search - ${/search/0/message/intent/payment/type}" }, }, + additionalProperties:false, required: ["type"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index aad1d92..ab0a17a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -259,7 +259,7 @@ module.exports = { }, }, - required: ["code", "short_desc"], + required: [], allOf: [ { if: { properties: { code: { const: "1" } } }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 7d0ceb7..11175d7 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -14,9 +14,8 @@ const checkContextVal = (payload, msgIdSet, i) => { let Obj = {}; let data = payload.context; let domain = payload.context.domain; - let maxTimeDiff = 0; - if (domain === "ONDC:RET10") { - maxTimeDiff = 5000; + let maxTimeDiff = 5000; + if (domain === "ONDC:RET10" && payload?.context?.version === "2.0.1") { if (action === "init") { maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); dao.setValue("maxTimeDiff", maxTimeDiff); @@ -25,6 +24,16 @@ const checkContextVal = (payload, msgIdSet, i) => { } } else if (domain === "nic2004:60232") { maxTimeDiff = 1000; + } else if ( + domain === "ONDC:RET10" && + payload?.context?.version === "2.0.2" + ) { + if (action === "select") { + maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); + dao.setValue("maxTimeDiff", maxTimeDiff); + } else if (action === "on_select") { + maxTimeDiff = dao.getValue("maxTimeDiff"); + } } console.log("time difference", maxTimeDiff); @@ -88,6 +97,7 @@ const checkContextVal = (payload, msgIdSet, i) => { } else { if ( action === "on_search" || + action === "on_select" || action === "on_init" || action === "on_confirm" || action === "on_update" diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 72d9b7f..8760879 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -75,7 +75,7 @@ const checkConfirm = (data, msgIdSet) => { let avgPickupTime= fulfillment.start.time.duration; if(avgPickupTime!==dao.getValue("avgPickupTime")){ - cnfrmObj.avgPckupErr=`Average Pickup Time mismatches from the one provided in /on_search` + cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; if (rts === "yes" && !fulfillment?.start?.instructions?.short_desc) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index abda338..a7a9fa1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -74,6 +74,12 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; } } + + if (ffState === "Agent-assigned" || ffState === "Searching-for-Agent") { + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + } if (ffState === "Order-picked-up") { if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; @@ -142,14 +148,12 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } if (fulfillments.length > 1) { - if (!dao.getValue("pickupTime")) { - onStatusObj.msngPickupState = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; - } else if (!fulfillment.start.time.timestamp) { + if (!fulfillment.start.time.timestamp) { onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if(fulfillment.tracking===true){ - onStatusObj.trackErr=`fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled` + if (fulfillment.tracking === true) { + onStatusObj.trackErr = `fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled`; } if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( From 890768e784e40caf15f227d5656afc509bf1ab40 Mon Sep 17 00:00:00 2001 From: Abhijeet Singh Rathor Date: Wed, 20 Dec 2023 17:10:19 +0530 Subject: [PATCH 055/228] feat: added vlookup signature method --- utilities/.DS_Store | Bin 8196 -> 8196 bytes utilities/ondc-crypto-sdk-nodejs/.DS_Store | Bin 0 -> 6148 bytes utilities/ondc-crypto-sdk-nodejs/README.md | 27 +++++++++++++++--- .../ondc-crypto-sdk-nodejs/package-lock.json | 4 +-- utilities/ondc-crypto-sdk-nodejs/package.json | 3 +- utilities/ondc-crypto-sdk-nodejs/src/index.ts | 13 +++++++-- .../ondc-crypto-sdk-nodejs/src/types/index.ts | 17 ++++++++--- .../src/utility/index.ts | 21 ++++++++++++-- 8 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 utilities/ondc-crypto-sdk-nodejs/.DS_Store diff --git a/utilities/.DS_Store b/utilities/.DS_Store index 1fc751e820bb6232bf82fd6a33a560b7478d5e33..7ca357777b900eb8ce454e315c60f096bf3eddf0 100644 GIT binary patch delta 60 zcmZp1XmQwZL1gk`LBYu}0*PGW)zzjJItoUH#*^iR95?rgRx)j7ldxgMlqhEc06iBG AT>t<8 delta 63 zcmZp1XmQwZL1ePGKq-frp@EKqp^5oqc_Hb^j|EgVcZ*gtZDyCSX62TsuEru;!2|$e Ca}rH1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 { @@ -109,7 +110,7 @@ const verifyHeader = async ({ headerParts, body, publicKey }: IVerifyHeader) => return verified; }; -export const isSignatureValid = async ({ header, body, publicKey }: IsSignatureValid) => { +export const isHeaderValid = async ({ header, body, publicKey }: IsHeaderValid) => { try { const headerParts = splitAuthHeader(header); const keyIdSplit = headerParts?.keyId?.split('|'); @@ -122,3 +123,19 @@ export const isSignatureValid = async ({ header, body, publicKey }: IsSignatureV return false; } }; + +export const createVLookupSignature = async ({ + country, + domain, + type, + city, + subscriber_id, + privateKey, +}: CreateVLookupSignature) => { + const stringToSign = `${country}|${domain}|${type}|${city}|${subscriber_id}`; + const signature = await signMessage({ + signingString: stringToSign, + privateKey, + }); + return signature; +}; From b7b29c3ee608a79734ea849c36208864eaa593a7 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Dec 2023 18:05:32 +0530 Subject: [PATCH 056/228] minor fixes --- .../v1.1/confirmSchema.js | 14 +++++--- .../v1.2/confirmSchema.js | 14 +++++--- .../utils/b2b/b2bOnSearch.js | 33 +++++++++++++++++++ .../utils/constants.js | 4 ++- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index bfe077e..ad2ac64 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -87,11 +87,15 @@ module.exports = { properties: { id: { type: "string", - not: { - const: { $data: "1/context/transaction_id" }, - }, - errorMessage: - "should be unique (cannot be equal to transaction_id)", + allOf: [ + { + not: { + const: { $data: "3/context/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + }, + ], }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 88416f6..9311e1f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -88,11 +88,15 @@ module.exports = { properties: { id: { type: "string", - not: { - const: { $data: "1/context/transaction_id" }, - }, - errorMessage: - "should be unique (cannot be equal to transaction_id)", + allOf: [ + { + not: { + const: { $data: "3/context/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + }, + ], }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index a4dd00b..af21a6f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -7,6 +7,7 @@ const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); const checkOnSearch = async (data, msgIdSet) => { const onSrchObj = {}; let onSearch = data; + let domain = onSearch.context.domain; onSearch = onSearch.message.catalog; try { @@ -49,6 +50,38 @@ const checkOnSearch = async (data, msgIdSet) => { } } } + + //checking mandatory attributes for fashion and electronics + + provider.items.forEach((item) => { + let itemTags = item?.tags; + let mandatoryAttr; + + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET14") { + mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + } + itemTags.map(({ descriptor, list }, index) => { + switch (descriptor.code) { + case "attribute": + const encounteredAttr = []; + list.map(({ descriptor, value }) => { + encounteredAttr.push(descriptor.code); + }); + + // Check if all allowedCodes are encountered + const missingAttr = mandatoryAttr.filter( + (code) => !encounteredAttr.includes(code) + ); + if (missingAttr.length > 0) { + onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + } + break; + } + }); + }); } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 5e039d0..8b44c9f 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -167,5 +167,7 @@ module.exports = Object.freeze({ "RTO-Disposed", "Cancelled", ], - CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"] + CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], + FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], + ELECTRONICS_ATTRIBUTES: ["brand","model"] }); From 4bb7f629572e69339881b897f17a580a7e5a321f Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:46:14 +0530 Subject: [PATCH 057/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index ef7f741..13a0cfa 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -4,7 +4,7 @@ ``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging doc (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" ``` From 36c1d32523bfeedd1202e55c36248020a1461b83 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 058/228] Update readme.md From 1fb6653c2a0107bbd3766d3f6439050f4c0ee946 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:49:46 +0530 Subject: [PATCH 059/228] Update README.md --- utilities/signing_and_verification/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index dc9777d..1893bf8 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -23,16 +23,16 @@ python cryptic_utils.py generate_key_pairs ``` Signing_private_key: G0Pme72u8Y1MwxHqvY4iBW+7VPtJ7dsX7SGs6zZ5yvVIzdRAyHR6YkwHG2ufOE+12lsbJRwBF4Hqd7dUEOZZkg== Signing_public_key: SM3UQMh0emJMBxtrnzhPtdpbGyUcAReB6ne3VBDmWZI= - Crypto_Privatekey: MC4CAQAwBQYDK2VuBCIEIKi7NbXeN8QzXjN48XkjOiS/UaR6rumXep8VslMy4fRU - Crypto_Publickey: MCowBQYDK2VuAyEA9CEWxnLJkmwW/67QR739BEam7bbd3NsffjDa5HANf0Q= + Encryption_Privatekey: MC4CAQAwBQYDK2VuBCIEIKi7NbXeN8QzXjN48XkjOiS/UaR6rumXep8VslMy4fRU + Encryption_Publickey: MCowBQYDK2VuAyEA9CEWxnLJkmwW/67QR739BEam7bbd3NsffjDa5HANf0Q= ``` 4. Export private and public keys ``` export PRIVATE_KEY= export PUBLIC_KEY= -export CRYPTO_PRIVATE_KEY= -export CRYPTO_PUBLIC_KEY= +export ENCRYPTION_PRIVATE_KEY= +export ENCRYPTION_PUBLIC_KEY= ``` 5. Create authorisation header From 06f5213c2de74ce7f2ac8df5a192e719ef951e81 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:58:54 +0530 Subject: [PATCH 060/228] Update cryptic_utils.py --- .../signing_and_verification/cryptic_utils.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py index b1ad6fc..cab39c0 100644 --- a/utilities/signing_and_verification/cryptic_utils.py +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -101,7 +101,7 @@ def generate_key_pairs(): #print(private_key) public_key = base64.b64encode(bytes(signing_key.verify_key)).decode() inst_private_key = X25519PrivateKey.generate() - #print(base64.b64encode(bytes(tcrypto_private_key.).decode())) + #print(base64.b64encode(bytes(tencryption_private_key.).decode())) inst_public_key = inst_private_key.public_key() bytes_private_key = inst_private_key.private_bytes( encoding=serialization.Encoding.DER, @@ -112,21 +112,21 @@ def generate_key_pairs(): encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo ) - crypto_private_key = base64.b64encode(bytes_private_key).decode('utf-8') - crypto_public_key = base64.b64encode(bytes_public_key).decode('utf-8') + encryption_private_key = base64.b64encode(bytes_private_key).decode('utf-8') + encryption_public_key = base64.b64encode(bytes_public_key).decode('utf-8') return {"Signing_private_key": private_key, "Signing_public_key": public_key, - "Crypto_Privatekey": crypto_private_key, - "Crypto_Publickey": crypto_public_key} + "Encryption_Privatekey": encryption_private_key, + "Encryption_Publickey": encryption_public_key} -def encrypt(crypto_private_key, crypto_public_key, null): +def encrypt(encryption_private_key, encryption_public_key, null): private_key = serialization.load_der_private_key( - base64.b64decode(crypto_private_key), + base64.b64decode(encryption_private_key), password=None ) public_key = serialization.load_der_public_key( - base64.b64decode(crypto_public_key) + base64.b64decode(encryption_public_key) ) shared_key = private_key.exchange(public_key) cipher = AES.new(shared_key, AES.MODE_ECB) @@ -134,13 +134,13 @@ def encrypt(crypto_private_key, crypto_public_key, null): return base64.b64encode(cipher.encrypt(pad(text,AES.block_size))).decode('utf-8') -def decrypt(crypto_private_key, crypto_public_key, cipherstring): +def decrypt(encryption_private_key, encryption_public_key, cipherstring): private_key = serialization.load_der_private_key( - base64.b64decode(crypto_private_key), + base64.b64decode(encryption_private_key), password=None ) public_key = serialization.load_der_public_key( - base64.b64decode(crypto_public_key) + base64.b64decode(encryption_public_key) ) shared_key = private_key.exchange(public_key) cipher = AES.new(shared_key, AES.MODE_ECB) From 261d138955117f38340a26e41f65a4b82db655ad Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:10:18 +0530 Subject: [PATCH 061/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index 13a0cfa..e1d7433 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -4,7 +4,7 @@ ``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on [Staging](url) [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" ``` From 8d924ef1aef10a75a834fca3460c62a5f5aaa9c0 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:23:05 +0530 Subject: [PATCH 062/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index e1d7433..1884776 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -1,12 +1,12 @@ + # Subscribing to ONDC Registry 1. Add following constants like below. -``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on [Staging](url) [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- PUBLIC_KEY_1 = "Registry's encryption public key as per your environment which is available in NP On-Boarding on [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" -``` + 2. Place the index.js file code into your main file, and this utility will host the on_subscribe endpoint as well as html file. From bef41d87a4c3171e5e6801c45b24a22897b7c54c Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:24:18 +0530 Subject: [PATCH 063/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index 1884776..7120fb6 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -3,8 +3,8 @@ 1. Add following constants like below. -- PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key as per your environment which is available in NP On-Boarding on [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- ENCRYPTION_PRIVATE_KEY = "NP's encryption private key" +- ONDC_PUBLIC_KEY = "Registry's encryption public key as per your environment which is available in NP On-Boarding on [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" From c6b312015e5626120174318e77b3adf44a730394 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:24:52 +0530 Subject: [PATCH 064/228] Update index.js --- utilities/on_subscibe-service/node/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/node/index.js b/utilities/on_subscibe-service/node/index.js index 5b98381..58e384f 100644 --- a/utilities/on_subscibe-service/node/index.js +++ b/utilities/on_subscibe-service/node/index.js @@ -5,9 +5,9 @@ const crypto = require('crypto'); // Node.js crypto module for encryption and de const _sodium = require('libsodium-wrappers'); const port = 3000; // Port on which the server will listen -const PRIVATE_KEY_1 = +const ENCRYPTION_PRIVATE_KEY = 'MC4CAQEwBQYDK2VuBCIEILgcht9h660ZeO36tG+QuHGNcLN9JuAzxHWZl09f57Bh'; -const PUBLIC_KEY_1 = +const ONDC_PUBLIC_KEY = 'MCowBQYDK2VuAyEAlKHWJWiEiHFGlAJ6TE4VMGaeQUYg5DHEpuQdiq6flnQ='; const REQUEST_ID = '6a6abf53-674f-4d6d-a52b-62e3fda55e04'; const SIGNING_PRIVATE_KEY = From f6856eb7366c8fece0685c22fb935bd2a31a6d5d Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 28 Dec 2023 11:51:05 +0530 Subject: [PATCH 065/228] b2b and logistics fixes --- .../log-verification-utility/.gitignore | 2 +- .../log_report.json | 8 + .../log_report.json | 62 ++ .../schema/B2B_json_schema/keywords/onInit.js | 5 +- .../B2B_json_schema/schemaValidator copy1.js | 107 ++ .../schema/B2B_json_schema/schemaValidator.js | 47 +- .../B2B_json_schema/{ => v1}/confirm.js | 0 .../schema/B2B_json_schema/{ => v1}/init.js | 0 .../schema/B2B_json_schema/{ => v1}/master.js | 0 .../B2B_json_schema/{ => v1}/on_confirm.js | 0 .../B2B_json_schema/{ => v1}/on_init.js | 0 .../B2B_json_schema/{ => v1}/on_search.js | 0 .../B2B_json_schema/{ => v1}/on_select.js | 2 +- .../B2B_json_schema/{ => v1}/on_status.js | 0 .../B2B_json_schema/{ => v1}/on_update.js | 1 - .../schema/B2B_json_schema/{ => v1}/search.js | 1 - .../schema/B2B_json_schema/{ => v1}/select.js | 0 .../schema/B2B_json_schema/{ => v1}/status.js | 1 - .../schema/B2B_json_schema/{ => v1}/update.js | 1 - .../schema/B2B_json_schema/v2/confirm.js | 769 ++++++++++++++ .../schema/B2B_json_schema/v2/init.js | 531 ++++++++++ .../schema/B2B_json_schema/v2/master.js | 78 ++ .../schema/B2B_json_schema/v2/on_confirm.js | 833 +++++++++++++++ .../schema/B2B_json_schema/v2/on_init.js | 694 +++++++++++++ .../schema/B2B_json_schema/v2/on_search.js | 966 ++++++++++++++++++ .../schema/B2B_json_schema/v2/on_select.js | 335 ++++++ .../schema/B2B_json_schema/v2/on_status.js | 758 ++++++++++++++ .../schema/B2B_json_schema/v2/on_update.js | 530 ++++++++++ .../schema/B2B_json_schema/v2/search.js | 262 +++++ .../schema/B2B_json_schema/v2/select.js | 432 ++++++++ .../schema/B2B_json_schema/v2/status.js | 107 ++ .../schema/B2B_json_schema/v2/update.js | 333 ++++++ .../v1.1/confirmSchema.js | 2 +- .../v1.1/searchSchema.js | 2 +- .../v1.2/confirmSchema.js | 40 +- .../v1.2/keywords/onInit.js | 2 + .../v1.2/onCancelSchema.js | 4 +- .../v1.2/onInitSchema.js | 2 + .../v1.2/onSearchSchema.js | 47 + .../v1.2/updateSchema.js | 3 +- .../log-verification-utility/schema/main.js | 6 +- .../utils/b2b/b2bInit.js | 21 +- .../utils/b2b/b2bOnSearch.js | 2 +- .../utils/b2b/b2bOnStatus.js | 7 +- .../utils/constants.js | 4 +- .../utils/logistics/logConfirm.js | 4 +- .../utils/logistics/logInit.js | 4 +- .../utils/logistics/logOnCancel.js | 34 +- .../utils/logistics/logOnStatus.js | 6 +- .../utils/logistics/logUpdate.js | 4 + .../log-verification-utility/utils/utils.js | 11 +- 51 files changed, 7003 insertions(+), 67 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/confirm.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/init.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/master.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_confirm.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_init.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_search.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_select.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_status.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_update.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/search.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/select.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/status.js (98%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/update.js (99%) create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore index 5b4e0ec..8c29104 100644 --- a/utilities/logistics-b2b/log-verification-utility/.gitignore +++ b/utilities/logistics-b2b/log-verification-utility/.gitignore @@ -12,4 +12,4 @@ test.js !LICENSE.md logFlow*.json .DS_Store -log_report.json \ No newline at end of file +log_report.md \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json new file mode 100644 index 0000000..f33ebf7 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json @@ -0,0 +1,8 @@ +{ + "Schema": { + "schemaErr0": "/on_init/0/message/order/quote price is not matching with the total breakup price", + "schemaErr1": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'code'", + "schemaErr2": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'short_desc'", + "schemaErr3": "/on_update/0/message/order/fulfillments/0/start must pass \"$merge\" keyword validation" + } +} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json new file mode 100644 index 0000000..fb6d4bf --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json @@ -0,0 +1,62 @@ +{ + "Flow Error": { + "0": "Incorrect Flow as per context/timestamps - (search,on_search,cancel,init,on_init,confirm,on_confirm,status,support,track,on_track,on_support,on_status,on_cancel)" + }, + "Schema": { + "schemaErr0": "/search/0/message/intent/payment @ondc/org/collection_amount is required only for payment/type 'ON-FULFILLMENT'", + "schemaErr1": "/search/0/message/intent/payment must match \"then\" schema", + "schemaErr2": "/confirm/0/message/order/billing/created_at mismatches in /billing in /init and /confirm", + "schemaErr3": "/confirm/0/message/order/billing/updated_at mismatches in /billing in /init and /confirm", + "schemaErr4": "/confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", + "schemaErr5": "/on_confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", + "schemaErr6": "/on_status/0/message/order/fulfillments/0/start/time must have required property 'range'", + "schemaErr7": "/on_status/0/message/order/fulfillments/0/end must have required property 'time'", + "schemaErr8": "/on_status/0/message/order/fulfillments/0 must match \"then\" schema", + "schemaErr9": "/on_cancel/0/message/order must have required property 'created_at'", + "schemaErr10": "/on_cancel/0/message/order/quote price is not matching with the total breakup price", + "schemaErr11": "/on_cancel/0/message/order/fulfillments/0/start/time must have required property 'range'", + "schemaErr12": "/on_cancel/0/message/order/fulfillments/0/end/time must have required property 'range'", + "schemaErr13": "/on_cancel/0/message/order/fulfillments/0 must match \"then\" schema" + }, + "Context": { + "init_0": { + "tmpstmpErr": "Timestamp mismatch for /init " + }, + "status_0": { + "tmpstmpErr": "Timestamp mismatch for /status " + }, + "support_0": { + "tmpstmpErr": "Timestamp mismatch for /support " + }, + "track_0": { + "tmpstmpErr": "Timestamp mismatch for /track " + }, + "on_track_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + }, + "on_support_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + }, + "on_status_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + }, + "on_cancel_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + } + }, + "Message": { + "on_search_0": { + "itemTAT": "For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. 2023-12-08" + }, + "confirm_0": { + "itemDurationErr": "item duration does not match with the one provided in /on_search (LSP can send NACK)", + "avgPckupErr": "Average Pickup Time mismatches from the one provided in /on_search" + }, + "on_confirm_0": { + "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" + }, + "on_status_0": { + "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" + } + } +} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js index d9a2b1d..b31f2e2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js @@ -1,11 +1,14 @@ module.exports = { isQuoteMatching: (data) => { - const quotePrice = parseFloat(data?.price?.value); + let quotePrice = parseFloat(data?.price?.value); const breakupArr = data.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); + }); + totalBreakup= parseFloat(totalBreakup).toFixed(2) + quotePrice=quotePrice.toFixed(2) if (quotePrice != totalBreakup) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js new file mode 100644 index 0000000..51f97d6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js @@ -0,0 +1,107 @@ +const onConfirmSchema = require("./on_confirm"); +const onInitSchema = require("./on_init"); +const onSearchSchema = require("./on_search"); +const selectSchema = require("./select"); +const onSelectSchema = require("./on_select"); +const onUpdateSchema = require("./on_update"); +const searchSchema = require("./search"); +const initSchema = require("./init"); +const masterSchema = require("./master"); +const confirmSchema = require("./confirm"); +const statusSchema = require("./status"); +const updateSchema = require("./update"); +const onStatusSchema = require("./on_status"); +const { isLengthValid } = require("./keywords/init"); +const { isQuoteMatching } = require("./keywords/onInit"); +const { isFutureDated } = require("./keywords/confirm"); +const { isEndTimeGreater } = require("./keywords/search"); + +const fs = require("fs"); +//const async = require("async"); +const path = require("path"); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + + +const validate_schema = (data, schema) => { + const Ajv = require("ajv"); + const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + $data: true, + }); + const addFormats = require("ajv-formats"); + + addFormats(ajv); + require("ajv-errors")(ajv); + let error_list = []; + try { + validate = ajv + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(selectSchema) + .addSchema(onSelectSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema) + .addKeyword("isEndTimeGreater", { + validate: (schema, data) => isEndTimeGreater(data), + }) + .addKeyword("isQuoteMatching", { + validate: (schema, data) => isQuoteMatching(data), + }) + .addKeyword("isFutureDated", { + validate: (schema, data) => isFutureDated(data), + }) + .addKeyword("isLengthValid", { + validate: (schema, data) => isLengthValid(data), + }); + + validate = validate.compile(schema); + + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + } catch (error) { + console.log("ERROR!! validating schema"); + console.trace(error); + } + return error_list; +}; + +const validate_schema_b2b_master = (data) => { + error_list = validate_schema(data, masterSchema); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_b2b_master, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js index 43fb234..66aa4f1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -1,16 +1,4 @@ -const onConfirmSchema = require("./on_confirm"); -const onInitSchema = require("./on_init"); -const onSearchSchema = require("./on_search"); -const selectSchema = require("./select"); -const onSelectSchema = require("./on_select"); -const onUpdateSchema = require("./on_update"); -const searchSchema = require("./search"); -const initSchema = require("./init"); -const masterSchema = require("./master"); -const confirmSchema = require("./confirm"); -const statusSchema = require("./status"); -const updateSchema = require("./update"); -const onStatusSchema = require("./on_status"); + const { isLengthValid } = require("./keywords/init"); const { isQuoteMatching } = require("./keywords/onInit"); const { isFutureDated } = require("./keywords/confirm"); @@ -42,7 +30,33 @@ const formatted_error = (errors) => { return error_json; }; -const validate_schema = (data, schema) => { +const loadSchema = (schemaType, version) => { + try { + return require(`./${version}/${schemaType}.js`); + } catch (error) { + console.log("Error Occurred while importing", error); + } +}; + +const validate_schema = (data, schema,version) => { + const searchSchema = loadSchema("search", version); + const onSearchSchema = loadSchema("on_search", version); + + const selectSchema = loadSchema("select", version); + const onSelectSchema = loadSchema("on_select", version); + + const initSchema = loadSchema("init", version); + const onInitSchema = loadSchema("on_init", version); + + const confirmSchema = loadSchema("confirm", version); + const onConfirmSchema = loadSchema("on_confirm", version); + + const updateSchema = loadSchema("update", version); + const onUpdateSchema = loadSchema("on_update", version); + + const statusSchema = loadSchema("status", version); + const onStatusSchema = loadSchema("on_status", version); + const Ajv = require("ajv"); const ajv = new Ajv({ allErrors: true, @@ -96,8 +110,9 @@ const validate_schema = (data, schema) => { return error_list; }; -const validate_schema_b2b_master = (data) => { - error_list = validate_schema(data, masterSchema); +const validate_schema_b2b_master = (data,version) => { + const masterSchema = loadSchema("master", version); + error_list = validate_schema(data, masterSchema,version); return formatted_error(error_list); }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/master.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/master.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_init.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_init.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js index f137e4b..f2fe7b0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js @@ -220,7 +220,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "Packing charges", "delivery ", "tax", "misc"] + enum: ["item", "discount", "packing", "delivery ", "tax", "misc"] }, price: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_update.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_update.js index d87b56d..8abb301 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_update.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/search.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/search.js index 9c8f6af..5c45d70 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/search.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/status.js similarity index 98% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/status.js index 45afe99..c6bcf70 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/status.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/update.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/update.js index 62e1bd1..24e08c0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/update.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js new file mode 100644 index 0000000..5adfe0d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -0,0 +1,769 @@ +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "confirm", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + enum: ["Created"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + locations: { + type: "array", + const: { $data: "/init/0/message/order/provider/locations" }, + errorMessage:"mismatch from /init", + items: { + type: "object", + properties: { + id: { + type: "string", + + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["person"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + created_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "created_at does not match context timestamp - ${3/context/timestamp}", + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "updated_at does not match context timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties:false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js new file mode 100644 index 0000000..9b9db05 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -0,0 +1,531 @@ +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "init", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/select/0/message/order/provider/locations/0/id", + }, + }, + }, + required: ["id"], + }, + } + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + }, + address: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + }, + email: { + type: "string", + }, + phone: { + type: "string", + }, + created_at: { + type: "string", + }, + updated_at: { + type: "string", + }, + }, + additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "License", + "Badge", + "Permit", + "Certificate", + ], + }, + desc: { + type: "string", + }, + icon: { + type: "string", + }, + url: { + type: "string", + pattern: + "^https://[\\w.-]+(\\.[a-zA-Z]{2,})?(:[0-9]+)?(/\\S*)?$", + }, + }, + required: ["id", "type", "desc", "icon", "url"], + }, + }, + }, + required: ["creds"], + }, + }, + required: ["person"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties: false, + required: [ + "provider", + "items", + "billing", + "fulfillments", + "payments", + "tags", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js new file mode 100644 index 0000000..d01fe98 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js @@ -0,0 +1,78 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + } + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js new file mode 100644 index 0000000..3e87a93 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -0,0 +1,833 @@ +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_confirm", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/confirm/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/provider/id" }, + }, + locations: { + type: "array", + const: { $data: "/confirm/0/message/order/provider/locations" }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + rateable: { + type: "boolean", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "stops", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + const: { $data: "3/context/timestamp" }, + errorMessage: + " should be updated as per context/timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "tags", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js new file mode 100644 index 0000000..d47c1fe --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -0,0 +1,694 @@ +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_init", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/locations/0/id"} + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["BUYER_TERMS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_REQ","PACKAGING_REQ"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "tracking", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties:false, + required: [ + "provider", + "provider_location", + "items", + "billing", + "fulfillments", + "quote", + "payments", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js new file mode 100644 index 0000000..13d05ca --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -0,0 +1,966 @@ +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_search", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup"], + }, + }, + required: ["id", "type"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["id", "type"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "short_desc", "long_desc", "images"], + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + additional_desc: { + type: "object", + properties: { + url: { + type: "string", + }, + content_type: { + type: "string", + }, + }, + required: ["url", "content_type"], + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "code"], + }, + rating: { + type: "string", + }, + ttl: { + type: "string", + format: "duration", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + code: { + type: "string", + }, + name: { + type: "string", + }, + }, + required: ["code", "name"], + }, + state: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + }, + additionalProperties: false, + required: [ + "id", + "gps", + "address", + "city", + "state", + "country", + "area_code", + ], + }, + }, + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["License", "Badge", "Permit", "Certificate"], + }, + desc: { + type: "string", + }, + url: { + type: "string", + format: "uri", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["mimetype", "url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + creator: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + required: ["full"], + }, + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["address", "phone"], + }, + }, + required: ["name", "contact"], + }, + }, + required: ["descriptor"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: ["currency", "value", "maximum_value"], + }, + quantity: { + type: "object", + properties: { + unitized: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["measure"], + }, + available: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, + maximum: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, + }, + required: ["unitized", "available", "maximum"], + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + }, + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: [ + "currency", + "value", + "offered_value", + "maximum_value", + ], + }, + }, + required: ["id", "descriptor", "price"], + }, + }, + cancellation_terms: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + refund_eligible: { + type: "string", + }, + return_policy: { + type: "object", + properties: { + return_eligible: { + type: "string", + }, + return_within: { + type: "string", + }, + fulfillment_managed_by: { + type: "string", + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + required: ["address", "gps"], + }, + }, + required: [ + "return_eligible", + "return_within", + "fulfillment_managed_by", + "return_location", + ], + }, + }, + if: { + properties: { + fulfillment_state: { + properties: { + descriptor: { + properties: { + code: { + const: "Order-delivered", + }, + }, + }, + }, + }, + }, + }, + then: { + required: ["fulfillment_state", "return_policy"], + }, + else: { + required: [ + "fulfillment_state", + "refund_eligible", + ], + }, + }, + }, + replacement_terms: { + type: "array", + items: { + type: "object", + properties: { + replace_within: { + type: "string", + }, + }, + required: ["replace_within"], + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + matched: { + type: "string", + }, + recommended: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + + "descriptor", + "creator", + "price", + "quantity", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "replacement_terms", + + "matched", + "recommended", + ], + }, + }, + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + location_ids: { + type: "array", + items: {}, + }, + category_ids: { + type: "array", + items: {}, + }, + item_ids: { + type: "array", + items: {}, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + }, + required: [ + "id", + "descriptor", + "location_ids", + "category_ids", + "item_ids", + "time", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["contact"], + }, + }, + }, + required: [ + "id", + "descriptor", + "ttl", + "locations", + "tags", + "items", + "fulfillments", + ], + }, + }, + }, + additionalProperties: false, + required: ["fulfillments", "payments", "descriptor", "providers"], + }, + }, + required: ["catalog"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js new file mode 100644 index 0000000..8e8591b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -0,0 +1,335 @@ +module.exports = { + $id: "http://example.com/schema/onSelectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_select", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/select/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + tracking: { + type: "boolean", + }, + "@ondc/org/category": { + type: "string", + }, + "@ondc/org/TAT": { + type: "string", + format: "duration" + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Serviceable", "Non-Serviceable"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "tracking", + "@ondc/org/category", + "@ondc/org/TAT", + "state", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "discount", "packing", "delivery ", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + quantity: { + type: "object", + properties: { + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + }, + required: ["available", "maximum"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["quantity", "price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + format: "duration" + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + }, + required: ["provider", "items", "quote"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js new file mode 100644 index 0000000..487e02a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -0,0 +1,758 @@ +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_status", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress", + "Cancelled", + "Completed", + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + additionalProperties: false, + required: ["selected"], + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + required: ["name"], + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Agent-assigned", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + end: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + agent: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["person", "contact"], + }, + }, + if: { properties: { type: { const: "start" } } }, + then: { + properties: { + location: { required: ["id", "descriptor", "gps"] }, + }, + }, + else: { + properties: { + location: { required: ["address", "gps"] }, + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "type", + "tracking", + "state", + "stops", + ], + anyof: [ + { + properties: { + state: { + const: "Order-picked-up", + }, + stops: { + type: "array", + items: { + properties: { + type: { + const: "start", + }, + time: { + required: ["range", "timestamp"], + }, + }, + }, + }, + }, + }, + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/payments/0/type", + }, + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/collected_by", + }, + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", + }, + }, + required: ["url", "label"], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "order/created_at should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "documents", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js new file mode 100644 index 0000000..55c6645 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -0,0 +1,530 @@ +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_update", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + }, + message_id: { + type: "string", + const: { $data: "/update/0/context/message_id" }, + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress" + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["id", "quantity", "fulfillment_ids"], + }, + }, + payment: { + type: "object", + properties: { + uri: { + type: "string", + }, + tl_method: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum:["BAP","BPP"] + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["Pending","Agent-assigned","Order-picked-up","Out-for-delivery","Delivered"] + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + end: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: [ + "type", + "location", + "time", + "instructions", + "contact", + ], + }, + }, + rateable: { + type: "boolean", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_DETAILS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_ID","COUNT","MEASURE_UNIT","MEASURE_VALUE"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "stops" + ], + }, + }, + }, + + required: ["id", "state", "provider", "items"], + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js new file mode 100644 index 0000000..a10ad82 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -0,0 +1,262 @@ +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "search", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + category: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Delivery and Self-Pickup"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + }, + required: ["type", "location"], + }, + }, + }, + required: ["type", "stops"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + tags: { + type: "array", + minItems: 2, + uniqueItems: true, + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["bap_terms", "buyer_id"], + }, + }, + required:["code"] + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + required:["code"] + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + minItems: 2, + }, + }, + required: ["descriptor", "list"], + if: { + properties: { + descriptor: { + properties: { code: { const: "bap_terms" } }, + }, + }, + }, + then: { + properties: { + list: { + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + enum: ["finder_fee_type", "finder_fee_amount"], + }, + }, + }, + }, + required: ["descriptor"], + }, + }, + }, + errorMessage: + "For 'bap_terms', the 'list' must contain either 'finder_fee_type' or 'finder_fee_amount'.", + }, + else: { + if: { + properties: { + descriptor: { + properties: { code: { const: "buyer_id" } }, + }, + }, + }, + then: { + properties: { + list: { + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + }, + required: ["descriptor"], + }, + }, + }, + errorMessage: + "For 'buyer_id', the 'list' must contain either 'buyer_id_code' or 'buyer_id_no'.", + }, + }, + }, + }, + }, + additionalProperties:false, + required: ["item", "fulfillment", "payment", "tags"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js new file mode 100644 index 0000000..444749f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -0,0 +1,432 @@ +module.exports = { + $id: "http://example.com/schema/selectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "select", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: { $data: "2/message/order/provider/ttl" }, + errorMessage: + "should match provider ttl - ${2/message/order/provider/ttl}", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "location_ids", "quantity"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + }, + required: ["type", "location"], + }, + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "License", + "Badge", + "Permit", + "Certificate", + ], + }, + desc: { + type: "string", + }, + icon: { + type: "string", + }, + url: { + type: "string", + pattern: + "^https://[\\w.-]+(\\.[a-zA-Z]{2,})?(:[0-9]+)?(/\\S*)?$", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + }, + required: ["creds"], + }, + }, + required: ["person"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id", "COMM_CHANNEL"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: [ + "buyer_id_code", + "buyer_id_no", + "chat_url", + ], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties: false, + required: ["provider", "items", "fulfillments", "payments", "tags"], + }, + }, + required: ["order"], + additionalProperties: false, + }, + }, + required: ["context", "message"], + additionalProperties: false, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js new file mode 100644 index 0000000..387a6fe --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js @@ -0,0 +1,107 @@ +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "status", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/on_confirm/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/on_confirm/0/message/order/id" }, + }, + }, + additionalProperties:false, + required: ["order_id"], + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js new file mode 100644 index 0000000..2067cf4 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js @@ -0,0 +1,333 @@ +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "update", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum:["fulfillment","item"] + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: + { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + }, + required: ["id", "quantity"], + }, + + }, + payments: { + type: "array", + items: + { + type: "object", + properties: { + uri: { + type: "string", + }, + tl_method: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: + { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: [ + "settlement_counterparty", + "settlement_type", + ], + }, + + }, + }, + required: [ + "uri", + "tl_method", + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + + }, + }, + additionalProperties:false, + required: ["id", "state", "provider", "items", "payments"], + }, + }, + required: ["update_target", "order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index ad2ac64..5700fdc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -93,7 +93,7 @@ module.exports = { const: { $data: "3/context/transaction_id" }, }, errorMessage: - "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + "should be unique and not be equal to transaction_id: ${3/context/transaction_id}", }, ], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js index e583451..e1a8a1b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js @@ -242,7 +242,7 @@ module.exports = { type: "string", }, }, - required: ["@ondc/org/collection_amount"], + required: [], }, "@ondc/org/payload_details": { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 9311e1f..c2ac4e6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -94,7 +94,7 @@ module.exports = { const: { $data: "3/context/transaction_id" }, }, errorMessage: - "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + "should be unique and not be equal to transaction_id: ${3/context/transaction_id}", }, ], }, @@ -312,7 +312,7 @@ module.exports = { }, duration: { type: "string", - format: "duration" + format: "duration", }, location: { type: "object", @@ -592,7 +592,7 @@ module.exports = { "both 'state' and 'rto_action' tags are required", }, }, - + additionalProperties: false, required: ["id", "type", "start", "end", "tags"], }, }, @@ -1030,8 +1030,40 @@ module.exports = { type: "string", format: "date-time", }, - }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.TERMS, + + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + minItems: 2, + errorMessage: "both 'bpp_terms' and 'bap_terms' tags are required (logistics buyer NP must accept LSP terms. If not accepted, LSP can NACK /confirm with error code 65002)", + }, + }, + additionalProperties: false, required: [ "id", "state", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index 172c10e..5dcead5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -7,6 +7,8 @@ module.exports = { totalBreakup += parseFloat(breakup?.price?.value); }); // console.log(quotePrice,totalBreakup); + totalBreakup= parseFloat(totalBreakup).toFixed(2) + quotePrice=quotePrice.toFixed(2) if (quotePrice != totalBreakup) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 256cbe1..79705df 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -538,14 +538,14 @@ module.exports = { properties: { time: { required: ["range"] }, }, - required: ["time", "person", "location", "contact"], + required: [ "person", "location", "contact"], }, end: { properties: { time: { required: ["range"] }, }, - required: ["time", "person", "location", "contact"], + required: ["person", "location", "contact"], }, }, required: ["id", "type", "state", "start", "end", "tracking"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js index 82bc4e4..7b1e2fc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -355,6 +355,8 @@ module.exports = { type: { type: "string", enum: constants.PAYMENT_TYPE, + const: { $data: "/search/0/message/intent/payment/type" }, + errorMessage:"does not match the intended payment type by the logistics buyer" }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js index 203bb8c..71dd9a7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js @@ -301,6 +301,7 @@ module.exports = { required: ["label", "duration", "timestamp"], }, }, + additionalProperties:false, required: [ "id", "category_id", @@ -322,7 +323,53 @@ module.exports = { type: "string", enum: constants.FULFILLMENT_TYPE, }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + duration: { + type: "string", + }, + }, + required: ["duration"], + }, + }, + required: ["time"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["distance"] + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["motorable_distance_type","motorable_distance"] + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + + required: ["code", "list"], + }, + }, }, + additionalProperties:false, required: ["id", "type"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 34098a6..209fc5f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -326,13 +326,12 @@ module.exports = { format: "date-time", }, }, - + additionalProperties:false, required: ["id", "items", "fulfillments", "updated_at"], }, }, required: ["update_target", "order"], }, }, - required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/main.js b/utilities/logistics-b2b/log-verification-utility/schema/main.js index 3abb175..cc7470e 100755 --- a/utilities/logistics-b2b/log-verification-utility/schema/main.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/main.js @@ -9,13 +9,15 @@ const { const fs = require("fs"); const validate_schema_for_domain_json = (vertical, data, version) => { - version = getVersion(data); + version = getVersion(data,vertical); switch (vertical) { case "logistics": + res = validate_schema_master(data, version); return res; case "b2b": - res = validate_schema_b2b_master(data); + + res = validate_schema_b2b_master(data,version); return res; default: console.log("Invalid Domain!!"); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index d63e0cb..b7cc0ce 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -36,11 +36,14 @@ const checkInit = (data, msgIdSet) => { if (providerLocArr) { providerLocArr.forEach((location, i) => { - providerObj[0]?.locations?.forEach((element) => { - console.log(location.id, element.id); + if (providerObj) { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + } - if (location.id === element.id) providerLocExists = true; - }); if (!providerLocExists) { let itemkey = `providerLocErr${i}`; initObj[ @@ -66,10 +69,12 @@ const checkInit = (data, msgIdSet) => { let itemExists = false; itemsArr.forEach((item, i) => { - onSearchitemsArr.forEach((element) => { - if (item.id === element.id) itemExists = true; - console.log(item.id, element.id); - }); + if (onSearchitemsArr) { + onSearchitemsArr.forEach((element) => { + if (item.id === element.id) itemExists = true; + }); + } + if (!itemExists) { let itemkey = `itemErr${i}`; initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index af21a6f..32ee952 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -71,7 +71,7 @@ const checkOnSearch = async (data, msgIdSet) => { encounteredAttr.push(descriptor.code); }); - // Check if all allowedCodes are encountered + // Check if all mandatory attributes are encountered const missingAttr = mandatoryAttr.filter( (code) => !encounteredAttr.includes(code) ); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 6facef2..30585b6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -107,12 +107,12 @@ const checkOnStatus = (data, msgIdSet) => { fulfillment.stops.forEach((stop) => { if (stop.type === "start") { pickupTime = stop?.time?.timestamp; - dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - fulfillment?.start?.time?.timestamp !== + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; @@ -135,12 +135,11 @@ const checkOnStatus = (data, msgIdSet) => { fulfillment.stops.forEach((stop) => { if (stop.type === "start") { pickupTime = stop?.time?.timestamp; - dao.setValue("pickupTime", pickupTime); if (!pickupTime) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - fulfillment?.start?.time?.timestamp !== + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 8b44c9f..56c887f 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -133,6 +133,7 @@ module.exports = Object.freeze({ "004", "005", "006", + "007", "008", "009", "010", @@ -169,5 +170,6 @@ module.exports = Object.freeze({ ], CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], - ELECTRONICS_ATTRIBUTES: ["brand","model"] + ELECTRONICS_ATTRIBUTES: ["brand","model"], + TERMS:["bap_terms","bpp_terms"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 8760879..5b91a63 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -72,9 +72,9 @@ const checkConfirm = (data, msgIdSet) => { let p2h2p = dao.getValue("p2h2p"); fulfillments.forEach((fulfillment) => { - let avgPickupTime= fulfillment.start.time.duration; + let avgPickupTime= fulfillment?.start?.time?.duration; - if(avgPickupTime!==dao.getValue("avgPickupTime")){ + if(avgPickupTime && avgPickupTime!==dao.getValue("avgPickupTime")){ cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index 4907554..93cdc26 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -77,7 +77,6 @@ const checkInit = (data, msgIdSet) => { } onSearchitemsArr?.forEach((element) => { if (item.id === element.id) itemExists = true; - console.log(item.id, element.id); }); if (!itemExists) { let itemkey = `itemErr${i}`; @@ -86,7 +85,10 @@ const checkInit = (data, msgIdSet) => { let itemObj = onSearchitemsArr.filter( (element) => item.id === element.id ); + itemObj = itemObj[0]; + dao.setValue("selectedItem",itemObj.id) + console.log(itemObj.id); if (item.category_id != itemObj.category_id) { let itemkey = `catIdErr${i}`; initObj[ diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index 731db03..1dbeee1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -9,8 +9,10 @@ const checkOnCancel = (data, msgIdSet) => { let contextTime = on_cancel.context.timestamp; let version = on_cancel.context.core_version; let messageId = on_cancel.context.message_id; + const providerId = on_cancel.message?.provider?.id; on_cancel = on_cancel.message.order; + let onSearchItemsArr = dao.getValue(`${on_cancel?.provider?.id}itemsArr`); let ffState; let orderState = on_cancel.state; let items = on_cancel.items; @@ -42,6 +44,13 @@ const checkOnCancel = (data, msgIdSet) => { } catch (error) { console.log(error); } + if (onSearchItemsArr) { + let selectedItem = onSearchItemsArr.filter( + (element) => element.parent_item_id === dao.getValue("selectedItem") + ); + selectedItem = selectedItem[0]; + } + try { fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; @@ -63,9 +72,7 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if(fulfillment.tracking===true){ - onStatusObj.trackErr=`fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled` - } + if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( !_.isEqual( @@ -76,9 +83,17 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } } - console.log('comparing RTO fulfillment id with /on_search'); + console.log("comparing RTO fulfillment id with /on_search"); //checking RTO id matching with /on_search if (version === "1.2.0") { + if (dao.getValue("rts") === "yes") { + if (!fulfillment?.start?.time) { + onCancelObj.msngStrtTime = `Pickup time range (fulfillments/start/time) is missing`; + } + if (!fulfillment?.end?.time) { + onCancelObj.msngDlvryTime = `Delivery time range (fulfillments/end/time) is missing`; + } + } let fulTags = fulfillment?.tags; let rtoID; fulTags.forEach((tag) => { @@ -87,8 +102,9 @@ const checkOnCancel = (data, msgIdSet) => { lists.forEach((list) => { if (list.code === "rto_id") { rtoID = list.value; - if (rtoID !== dao.getValue("rtoID")) { - onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${dao.getValue("rtoID")}' in /fulfillments`; + + if (rtoID !== selectedItem.fulfillment_id) { + onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; } } }); @@ -100,9 +116,9 @@ const checkOnCancel = (data, msgIdSet) => { if (orderState !== "Cancelled") { onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } - console.log(fulfillment.id,dao.getValue("rtoID")); - if(fulfillment.id!==dao.getValue("rtoID")){ - onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${dao.getValue("rtoID")}' in /fulfillments`; + console.log(fulfillment.id, selectedItem?.fulfillment_id); + if (fulfillment.id !== selectedItem.fulfillment_id) { + onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; } if (ffState === "RTO-Initiated") { RtoPickupTime = fulfillment?.start?.time?.timestamp; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index a7a9fa1..7ec4271 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -62,7 +62,7 @@ const checkOnStatus = (data, msgIdSet) => { ) { if ( categoryId === "Immediate Delivery" && - fulfillment.tracking !== true + fulfillment.tracking !== true && ffState!=='Cancelled' ) { onStatusObj.trckErr = `tracking should be enabled (true) for hyperlocal (Immediate Delivery)`; } @@ -152,9 +152,7 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if (fulfillment.tracking === true) { - onStatusObj.trackErr = `fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled`; - } + if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( !_.isEqual( diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js index a97eec7..d1edb5d 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js @@ -7,12 +7,16 @@ const checkUpdate = (data, msgIdSet) => { let updtObj = {}; let update = data; let version = update.context.core_version; + let contextTimestamp = update.context.timestamp; let p2h2p = dao.getValue("p2h2p"); let awbNo= dao.getValue("awbNo"); dao.setValue("updateApi",true) update = update.message.order; + if (update?.updated_at > contextTimestamp) { + updtObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; + } if (version === "1.1.0") rts = update?.fulfillments[0]?.tags["@ondc/org/order_ready_to_ship"]; else { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 55e29ab..04fd841 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -197,9 +197,16 @@ const timestampCheck = (date) => { } }; -const getVersion = (data) => { - if (data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; +const getVersion = (data,vertical) => { + if(vertical==='logistics'){ + if (data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; else return "v1.2"; + } + if(vertical==='b2b'){ + if (data?.search[0]?.context?.version === "2.0.1") return "v1"; + else return "v2"; + } + }; function compareDates(dateString1, dateString2) { const date1 = new Date(dateString1); From 87fe16e9f8ac60883fa6e5f4c06bb6c968a6836f Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 28 Dec 2023 11:55:34 +0530 Subject: [PATCH 066/228] minor change --- .../schema/logistics_api_json_schema/v1.2/keywords/onInit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index 5dcead5..af5d333 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -1,6 +1,6 @@ module.exports = { isQuoteMatching: (data) => { - const quotePrice = parseFloat(data?.price?.value); + let quotePrice = parseFloat(data?.price?.value); const breakupArr = data.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { From 3207c0ca0c349f6e7cb85e87a66a86746e2888f4 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 28 Dec 2023 11:56:37 +0530 Subject: [PATCH 067/228] updated --- .../B2B_json_schema/schemaValidator copy1.js | 107 ------------------ 1 file changed, 107 deletions(-) delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js deleted file mode 100644 index 51f97d6..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js +++ /dev/null @@ -1,107 +0,0 @@ -const onConfirmSchema = require("./on_confirm"); -const onInitSchema = require("./on_init"); -const onSearchSchema = require("./on_search"); -const selectSchema = require("./select"); -const onSelectSchema = require("./on_select"); -const onUpdateSchema = require("./on_update"); -const searchSchema = require("./search"); -const initSchema = require("./init"); -const masterSchema = require("./master"); -const confirmSchema = require("./confirm"); -const statusSchema = require("./status"); -const updateSchema = require("./update"); -const onStatusSchema = require("./on_status"); -const { isLengthValid } = require("./keywords/init"); -const { isQuoteMatching } = require("./keywords/onInit"); -const { isFutureDated } = require("./keywords/confirm"); -const { isEndTimeGreater } = require("./keywords/search"); - -const fs = require("fs"); -//const async = require("async"); -const path = require("path"); - -const formatted_error = (errors) => { - error_list = []; - let status = ""; - errors.forEach((error) => { - error_dict = { - message: `${error.message}${ - error.params.allowedValues ? ` (${error.params.allowedValues})` : "" - }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ - error.params.additionalProperty - ? ` (${error.params.additionalProperty})` - : "" - }`, - details: error.instancePath, - }; - error_list.push(error_dict); - }); - if (error_list.length === 0) status = "pass"; - else status = "fail"; - error_json = { errors: error_list, status: status }; - return error_json; -}; - - -const validate_schema = (data, schema) => { - const Ajv = require("ajv"); - const ajv = new Ajv({ - allErrors: true, - strict: false, - strictRequired: false, - strictTypes: false, - $data: true, - }); - const addFormats = require("ajv-formats"); - - addFormats(ajv); - require("ajv-errors")(ajv); - let error_list = []; - try { - validate = ajv - .addSchema(searchSchema) - .addSchema(onSearchSchema) - .addSchema(selectSchema) - .addSchema(onSelectSchema) - .addSchema(initSchema) - .addSchema(onInitSchema) - .addSchema(confirmSchema) - .addSchema(onConfirmSchema) - .addSchema(updateSchema) - .addSchema(onUpdateSchema) - .addSchema(statusSchema) - .addSchema(onStatusSchema) - .addKeyword("isEndTimeGreater", { - validate: (schema, data) => isEndTimeGreater(data), - }) - .addKeyword("isQuoteMatching", { - validate: (schema, data) => isQuoteMatching(data), - }) - .addKeyword("isFutureDated", { - validate: (schema, data) => isFutureDated(data), - }) - .addKeyword("isLengthValid", { - validate: (schema, data) => isLengthValid(data), - }); - - validate = validate.compile(schema); - - const valid = validate(data); - if (!valid) { - error_list = validate.errors; - } - } catch (error) { - console.log("ERROR!! validating schema"); - console.trace(error); - } - return error_list; -}; - -const validate_schema_b2b_master = (data) => { - error_list = validate_schema(data, masterSchema); - return formatted_error(error_list); -}; - -module.exports = { - validate_schema_b2b_master, -}; From 92690873ee0dc1a0e691b375ef4bec3bd315beff Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Fri, 29 Dec 2023 15:33:22 +0530 Subject: [PATCH 068/228] ref: Update index.js keys issue resolved --- utilities/on_subscibe-service/node/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/node/index.js b/utilities/on_subscibe-service/node/index.js index 58e384f..458173d 100644 --- a/utilities/on_subscibe-service/node/index.js +++ b/utilities/on_subscibe-service/node/index.js @@ -30,12 +30,12 @@ const htmlFile = ` `; // Pre-defined public and private keys const privateKey = crypto.createPrivateKey({ - key: Buffer.from(PRIVATE_KEY_1, 'base64'), // Decode private key from base64 + key: Buffer.from(ENCRYPTION_PRIVATE_KEY, 'base64'), // Decode private key from base64 format: 'der', // Specify the key format as DER type: 'pkcs8', // Specify the key type as PKCS#8 }); const publicKey = crypto.createPublicKey({ - key: Buffer.from(PUBLIC_KEY_1, 'base64'), // Decode public key from base64 + key: Buffer.from(ONDC_PUBLIC_KEY, 'base64'), // Decode public key from base64 format: 'der', // Specify the key format as DER type: 'spki', // Specify the key type as SubjectPublicKeyInfo (SPKI) }); From c6dd73b57510a1818c7dd5d17cdc3489c6f810bd Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 29 Dec 2023 15:45:59 +0530 Subject: [PATCH 069/228] feedback updated --- .../log-verification-utility/.gitignore | 1 + .../log_report.json | 8 --- .../merged.json | 1 - .../log_report.json | 62 ------------------ .../merged.json | 1 - .../schema/B2B_json_schema/v2/on_status.js | 27 +++++--- .../schema/B2B_json_schema/v2/on_update.js | 63 +++++++++++-------- 7 files changed, 56 insertions(+), 107 deletions(-) delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore index 8c29104..3a79b99 100644 --- a/utilities/logistics-b2b/log-verification-utility/.gitignore +++ b/utilities/logistics-b2b/log-verification-utility/.gitignore @@ -3,6 +3,7 @@ package-lock.json *.env .vscode /public/logs/* +/public/server/* verification-logs /utils/*.json /utils/*.txt diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json deleted file mode 100644 index f33ebf7..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Schema": { - "schemaErr0": "/on_init/0/message/order/quote price is not matching with the total breakup price", - "schemaErr1": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'code'", - "schemaErr2": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'short_desc'", - "schemaErr3": "/on_update/0/message/order/fulfillments/0/start must pass \"$merge\" keyword validation" - } -} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json deleted file mode 100644 index 3e428f9..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json +++ /dev/null @@ -1 +0,0 @@ -{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:32.568Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Express Delivery"},"fulfillment":{"type":"Delivery","end":{"location":{"gps":"28.5080098, 77.0909696","address":{"area_code":"122016"}}},"start":{"location":{"gps":"12.9298689, 77.6848366","address":{"area_code":"560103"}}}},"provider":{"time":{"range":{"start":"0000","end":"2359"},"days":"1,2,3,4,5,6,7","schedule":{"holidays":[]}}},"payment":{"type":"POST-FULFILLMENT"},"@ondc/org/payload_details":{"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}},"value":{"currency":"INR","value":"2000.0"},"category":"Grocery","weight":{"unit":"gram","value":10}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:33.338Z","ttl":"PT30S"},"message":{"catalog":{"bpp/descriptor":{"name":"Ecom Express Private Limited"},"bpp/providers":[{"id":"I1","descriptor":{"name":"Ecom Express Private Limited","short_desc":"Ecom Express Private Limited","long_desc":"Ecom Express Private Limited"},"categories":[{"id":"Express Delivery","time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}],"fulfillments":[{"id":"1","type":"Delivery"},{"id":"2","type":"RTO"}],"items":[{"id":"1","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"1","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}},{"id":"2","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"2","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}]}]}}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.110Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.906Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}}}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.642Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"code":"4","short_desc":"1368","long_desc":"QR code will be attached to package"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:20:59.374Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.973Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"short_desc":"1368","long_desc":"QR code will be attached to package","code":"4"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:39.973Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"889d3a90-9a20-4289-bb83-b05809918520","timestamp":"2023-12-18T13:38:54.815Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","items":[{"id":"1","descriptor":{"code":"P2H2P"},"category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"@ondc/org/awb_no":"110919056165"}],"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:32:39.165Z"},"update_target":"fulfillment"}}],"on_update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"246cb466-8ac5-40b6-a586-08c8bdc1c72b","timestamp":"2023-12-18T13:38:55.288Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Accepted","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:55.288Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11457434-00a2-434d-bc7f-16eff98e3737","timestamp":"2023-12-18T13:39:37.639Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:39:37.639Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"0bf1fd6a-8e8f-4fc1-aad2-79152c0237b4","timestamp":"2023-12-18T13:40:21.368Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Initiated"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:40:21.368Z","created_at":"2023-12-07T14:20:59.374Z"}}},{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"2119685b-9816-4571-b6bd-4f428ee12812","timestamp":"2023-12-18T13:41:34.451Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Delivered"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:41:34.451Z","created_at":"2023-12-07T14:20:59.374Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json deleted file mode 100644 index fb6d4bf..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "Flow Error": { - "0": "Incorrect Flow as per context/timestamps - (search,on_search,cancel,init,on_init,confirm,on_confirm,status,support,track,on_track,on_support,on_status,on_cancel)" - }, - "Schema": { - "schemaErr0": "/search/0/message/intent/payment @ondc/org/collection_amount is required only for payment/type 'ON-FULFILLMENT'", - "schemaErr1": "/search/0/message/intent/payment must match \"then\" schema", - "schemaErr2": "/confirm/0/message/order/billing/created_at mismatches in /billing in /init and /confirm", - "schemaErr3": "/confirm/0/message/order/billing/updated_at mismatches in /billing in /init and /confirm", - "schemaErr4": "/confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", - "schemaErr5": "/on_confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", - "schemaErr6": "/on_status/0/message/order/fulfillments/0/start/time must have required property 'range'", - "schemaErr7": "/on_status/0/message/order/fulfillments/0/end must have required property 'time'", - "schemaErr8": "/on_status/0/message/order/fulfillments/0 must match \"then\" schema", - "schemaErr9": "/on_cancel/0/message/order must have required property 'created_at'", - "schemaErr10": "/on_cancel/0/message/order/quote price is not matching with the total breakup price", - "schemaErr11": "/on_cancel/0/message/order/fulfillments/0/start/time must have required property 'range'", - "schemaErr12": "/on_cancel/0/message/order/fulfillments/0/end/time must have required property 'range'", - "schemaErr13": "/on_cancel/0/message/order/fulfillments/0 must match \"then\" schema" - }, - "Context": { - "init_0": { - "tmpstmpErr": "Timestamp mismatch for /init " - }, - "status_0": { - "tmpstmpErr": "Timestamp mismatch for /status " - }, - "support_0": { - "tmpstmpErr": "Timestamp mismatch for /support " - }, - "track_0": { - "tmpstmpErr": "Timestamp mismatch for /track " - }, - "on_track_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - }, - "on_support_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - }, - "on_status_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - }, - "on_cancel_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - } - }, - "Message": { - "on_search_0": { - "itemTAT": "For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. 2023-12-08" - }, - "confirm_0": { - "itemDurationErr": "item duration does not match with the one provided in /on_search (LSP can send NACK)", - "avgPckupErr": "Average Pickup Time mismatches from the one provided in /on_search" - }, - "on_confirm_0": { - "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" - }, - "on_status_0": { - "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" - } - } -} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json deleted file mode 100644 index bc99584..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json +++ /dev/null @@ -1 +0,0 @@ -{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.783Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Immediate Delivery"},"provider":{"time":{"days":"1,2,3,4,5,6","schedule":{"holidays":[]},"duration":"PT30M","range":{"start":"0630","end":"2359"}}},"fulfillment":{"type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"area_code":"560068"}}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"area_code":"560068"}}}},"payment":{"type":"ON-ORDER","@ondc/org/collection_amount":"0"},"@ondc/org/payload_details":{"weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}},"category":"F&B","value":{"currency":"INR","value":"238.0"}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.909Z","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org"},"message":{"catalog":{"bpp/descriptor":{"name":"WITS Project Ref Logistic"},"bpp/providers":[{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320","descriptor":{"name":"WITS Project Ref Logistic","long_desc":"WITS Project Ref Logistic","short_desc":"WITS Project Ref Logistic"},"categories":[{"id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"PT15M"}},"tags":[{"code":"distance","list":[{"code":"motorable_distance_type","value":"kilometer"},{"code":"motorable_distance","value":"0.15"}]}]},{"id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","type":"RTO"}],"items":[{"id":"Standard","parent_item_id":"","category_id":"Immediate Delivery","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P","name":"Immediate Delivery","long_desc":"Upto 60 mins for Delivery","short_desc":"Upto 60 mins for Delivery"},"price":{"currency":"INR","value":"122.38"},"time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}},{"id":"rto","parent_item_id":"Standard","category_id":"Immediate Delivery","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P","name":"RTO quote","short_desc":"RTO quote","long_desc":"RTO quote"},"price":{"currency":"INR","value":"34.82"},"time":{"label":"TAT","duration":"P1D","timestamp":"2023-12-09"}}]}]}}}],"cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","cancellation_reason_id":"010"}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery","descriptor":{"code":"P2P"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:09.356Z","updated_at":"2023-12-08T09:08:09.356Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/settlement_details":[]}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.525Z"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery"}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"tags":[{"code":"rider_check","list":[{"code":"inline_check_for_rider","value":"yes"}]}]}],"quote":{"price":{"currency":"INR","value":"122.38"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}}],"ttl":"PT15M"},"payment":{"type":"ON-ORDER","collected_by":"BAP","@ondc/org/settlement_details":[]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"refund_eligible":true,"reason_required":false,"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}}},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"50"}}},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100"}}},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}}}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.306Z","ttl":"PT30S"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Created","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","price":{"value":"116.00","currency":"INR"},"@ondc/org/title_type":"delivery"},{"@ondc/org/item_id":"Standard","price":{"value":"6.38","currency":"INR"},"@ondc/org/title_type":"tax"}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","tracking":true,"start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}]}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP"},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"unit":"kilogram","value":3}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Accepted","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"tracking":false}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","status":"PAID","@ondc/org/settlement_details":[]},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}},"refund_eligible":true,"reason_required":false},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"50"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}},"refund_eligible":true,"reason_required":true}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}],"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.489Z"}}}],"status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"ref_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"on_track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.763Z"},"message":{"tracking":{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","location":{"gps":"12.958766,77.625282","time":{"timestamp":"2023-12-08T09:08:11.489Z"},"updated_at":"1970-01-01T00:00:00.000Z"},"status":"active"}}}],"on_support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.785Z"},"message":{"phone":"8755555551","email":"accounts@thewitslab.com","uri":"http://t.me/supportBot"}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:39.272Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"In-progress","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tracking":false}],"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","@ondc/org/settlement_details":[]},"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]}}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:34:28.223Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Cancelled","cancellation":{"cancelled_by":"extweb.oyeti.com/ecommerce/ondc","reason":{"id":"010"}},"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}},{"id":"rto","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"159.09","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"rto","price":{"currency":"INR","value":"36.71"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"3.67"}}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"start":{"time":{"duration":"P1D","timestamp":"2023-12-08T09:18:06.524Z"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]},"time":{"timestamp":"2023-12-08T09:19:27.742Z"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","time":{"timestamp":"2023-12-08T09:19:27.742Z"}},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"value":3,"unit":"kilogram"}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}}},"updated_at":"2023-12-08T09:34:28.223Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 487e02a..ecaf332 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -235,9 +235,10 @@ module.exports = { type: "string", enum: [ "Pending", - "Packed", - "Agent-assigned", + "Out-for-pickup", "Order-picked-up", + "In-transit", + "At-destination-hub", "Out-for-delivery", "Order-delivered", ], @@ -327,21 +328,27 @@ module.exports = { properties: { start: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], }, timestamp: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["range"], @@ -568,7 +575,7 @@ module.exports = { }, }, isQuoteMatching: true, - + required: ["price", "breakup", "ttl"], }, payments: { @@ -753,6 +760,6 @@ module.exports = { required: ["order"], }, }, - + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js index 55c6645..1301497 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -56,18 +56,18 @@ module.exports = { }, transaction_id: { type: "string", - const: { $data: "/select/0/context/transaction_id" }, + const: { $data: "/select/0/context/transaction_id" }, }, message_id: { type: "string", - const: { $data: "/update/0/context/message_id" }, + const: { $data: "/update/0/context/message_id" }, }, timestamp: { type: "string", format: "date-time", }, ttl: { - type: "string" + type: "string", }, }, required: [ @@ -93,22 +93,18 @@ module.exports = { properties: { id: { type: "string", - const: { $data: "/confirm/0/message/order/id" }, + const: { $data: "/confirm/0/message/order/id" }, }, state: { type: "string", - enum: [ - "Created", - "Accepted", - "In-progress" - ], + enum: ["Created", "Accepted", "In-progress"], }, provider: { type: "object", properties: { id: { type: "string", - const: { $data: "/select/0/message/order/provider/id" }, + const: { $data: "/init/0/message/order/provider/id" }, }, }, required: ["id"], @@ -178,7 +174,7 @@ module.exports = { }, collected_by: { type: "string", - enum:["BAP","BPP"] + enum: ["BAP", "BPP"], }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", @@ -255,13 +251,13 @@ module.exports = { }, }, if: { properties: { type: { const: "ON-FULFILLMENT" } } }, - then: { - properties: { - collected_by: { - const: "BPP", - }, + then: { + properties: { + collected_by: { + const: "BPP", }, }, + }, required: [ "params", "status", @@ -290,7 +286,15 @@ module.exports = { properties: { code: { type: "string", - enum:["Pending","Agent-assigned","Order-picked-up","Out-for-delivery","Delivered"] + enum: [ + "Pending", + "Out-for-pickup", + "Order-picked-up", + "In-transit", + "At-destination-hub", + "Out-for-delivery", + "Order-delivered", + ], }, }, required: ["code"], @@ -374,13 +378,17 @@ module.exports = { properties: { start: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], @@ -435,7 +443,7 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_DETAILS"] + enum: ["ITEM_DETAILS"], }, }, required: ["code"], @@ -450,7 +458,12 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_ID","COUNT","MEASURE_UNIT","MEASURE_VALUE"] + enum: [ + "ITEM_ID", + "COUNT", + "MEASURE_UNIT", + "MEASURE_VALUE", + ], }, }, required: ["code"], @@ -472,12 +485,12 @@ module.exports = { "@ondc/org/provider_name", "state", "type", - "stops" + "stops", ], }, }, }, - + required: ["id", "state", "provider", "items"], }, }, From c28859004355236a99f8e274f69d60d8d806b829 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Dec 2023 11:10:22 +0530 Subject: [PATCH 070/228] minor bug fixes --- .../347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json | 1 + .../6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json | 1 + .../schema/B2B_json_schema/on_confirm.js | 2 -- .../schema/B2B_json_schema/on_init.js | 3 +-- .../schema/B2B_json_schema/on_select.js | 3 +-- .../schema/B2B_json_schema/on_status.js | 3 +-- .../schema/B2B_json_schema/select.js | 6 ++++-- .../logistics_api_json_schema/v1.1/initSchema.js | 1 - .../logistics_api_json_schema/v1.1/onStatusSchema.js | 3 +-- .../logistics_api_json_schema/v1.1/searchSchema.js | 1 - .../v1.2/common/commonSchema.js | 1 - .../logistics_api_json_schema/v1.2/confirmSchema.js | 3 +-- .../logistics_api_json_schema/v1.2/initSchema.js | 5 ++--- .../logistics_api_json_schema/v1.2/onCancelSchema.js | 11 ++++------- .../logistics_api_json_schema/v1.2/onInitSchema.js | 3 +-- .../logistics_api_json_schema/v1.2/onStatusSchema.js | 9 +++------ .../logistics_api_json_schema/v1.2/searchSchema.js | 2 -- 17 files changed, 21 insertions(+), 37 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json new file mode 100644 index 0000000..3e428f9 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json @@ -0,0 +1 @@ +{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:32.568Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Express Delivery"},"fulfillment":{"type":"Delivery","end":{"location":{"gps":"28.5080098, 77.0909696","address":{"area_code":"122016"}}},"start":{"location":{"gps":"12.9298689, 77.6848366","address":{"area_code":"560103"}}}},"provider":{"time":{"range":{"start":"0000","end":"2359"},"days":"1,2,3,4,5,6,7","schedule":{"holidays":[]}}},"payment":{"type":"POST-FULFILLMENT"},"@ondc/org/payload_details":{"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}},"value":{"currency":"INR","value":"2000.0"},"category":"Grocery","weight":{"unit":"gram","value":10}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:33.338Z","ttl":"PT30S"},"message":{"catalog":{"bpp/descriptor":{"name":"Ecom Express Private Limited"},"bpp/providers":[{"id":"I1","descriptor":{"name":"Ecom Express Private Limited","short_desc":"Ecom Express Private Limited","long_desc":"Ecom Express Private Limited"},"categories":[{"id":"Express Delivery","time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}],"fulfillments":[{"id":"1","type":"Delivery"},{"id":"2","type":"RTO"}],"items":[{"id":"1","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"1","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}},{"id":"2","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"2","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}]}]}}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.110Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.906Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}}}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.642Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"code":"4","short_desc":"1368","long_desc":"QR code will be attached to package"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:20:59.374Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.973Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"short_desc":"1368","long_desc":"QR code will be attached to package","code":"4"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:39.973Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"889d3a90-9a20-4289-bb83-b05809918520","timestamp":"2023-12-18T13:38:54.815Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","items":[{"id":"1","descriptor":{"code":"P2H2P"},"category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"@ondc/org/awb_no":"110919056165"}],"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:32:39.165Z"},"update_target":"fulfillment"}}],"on_update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"246cb466-8ac5-40b6-a586-08c8bdc1c72b","timestamp":"2023-12-18T13:38:55.288Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Accepted","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:55.288Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11457434-00a2-434d-bc7f-16eff98e3737","timestamp":"2023-12-18T13:39:37.639Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:39:37.639Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"0bf1fd6a-8e8f-4fc1-aad2-79152c0237b4","timestamp":"2023-12-18T13:40:21.368Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Initiated"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:40:21.368Z","created_at":"2023-12-07T14:20:59.374Z"}}},{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"2119685b-9816-4571-b6bd-4f428ee12812","timestamp":"2023-12-18T13:41:34.451Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Delivered"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:41:34.451Z","created_at":"2023-12-07T14:20:59.374Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json new file mode 100644 index 0000000..bc99584 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json @@ -0,0 +1 @@ +{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.783Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Immediate Delivery"},"provider":{"time":{"days":"1,2,3,4,5,6","schedule":{"holidays":[]},"duration":"PT30M","range":{"start":"0630","end":"2359"}}},"fulfillment":{"type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"area_code":"560068"}}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"area_code":"560068"}}}},"payment":{"type":"ON-ORDER","@ondc/org/collection_amount":"0"},"@ondc/org/payload_details":{"weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}},"category":"F&B","value":{"currency":"INR","value":"238.0"}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.909Z","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org"},"message":{"catalog":{"bpp/descriptor":{"name":"WITS Project Ref Logistic"},"bpp/providers":[{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320","descriptor":{"name":"WITS Project Ref Logistic","long_desc":"WITS Project Ref Logistic","short_desc":"WITS Project Ref Logistic"},"categories":[{"id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"PT15M"}},"tags":[{"code":"distance","list":[{"code":"motorable_distance_type","value":"kilometer"},{"code":"motorable_distance","value":"0.15"}]}]},{"id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","type":"RTO"}],"items":[{"id":"Standard","parent_item_id":"","category_id":"Immediate Delivery","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P","name":"Immediate Delivery","long_desc":"Upto 60 mins for Delivery","short_desc":"Upto 60 mins for Delivery"},"price":{"currency":"INR","value":"122.38"},"time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}},{"id":"rto","parent_item_id":"Standard","category_id":"Immediate Delivery","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P","name":"RTO quote","short_desc":"RTO quote","long_desc":"RTO quote"},"price":{"currency":"INR","value":"34.82"},"time":{"label":"TAT","duration":"P1D","timestamp":"2023-12-09"}}]}]}}}],"cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","cancellation_reason_id":"010"}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery","descriptor":{"code":"P2P"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:09.356Z","updated_at":"2023-12-08T09:08:09.356Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/settlement_details":[]}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.525Z"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery"}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"tags":[{"code":"rider_check","list":[{"code":"inline_check_for_rider","value":"yes"}]}]}],"quote":{"price":{"currency":"INR","value":"122.38"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}}],"ttl":"PT15M"},"payment":{"type":"ON-ORDER","collected_by":"BAP","@ondc/org/settlement_details":[]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"refund_eligible":true,"reason_required":false,"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}}},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"50"}}},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100"}}},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}}}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.306Z","ttl":"PT30S"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Created","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","price":{"value":"116.00","currency":"INR"},"@ondc/org/title_type":"delivery"},{"@ondc/org/item_id":"Standard","price":{"value":"6.38","currency":"INR"},"@ondc/org/title_type":"tax"}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","tracking":true,"start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}]}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP"},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"unit":"kilogram","value":3}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Accepted","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"tracking":false}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","status":"PAID","@ondc/org/settlement_details":[]},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}},"refund_eligible":true,"reason_required":false},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"50"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}},"refund_eligible":true,"reason_required":true}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}],"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.489Z"}}}],"status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"ref_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"on_track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.763Z"},"message":{"tracking":{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","location":{"gps":"12.958766,77.625282","time":{"timestamp":"2023-12-08T09:08:11.489Z"},"updated_at":"1970-01-01T00:00:00.000Z"},"status":"active"}}}],"on_support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.785Z"},"message":{"phone":"8755555551","email":"accounts@thewitslab.com","uri":"http://t.me/supportBot"}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:39.272Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"In-progress","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tracking":false}],"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","@ondc/org/settlement_details":[]},"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]}}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:34:28.223Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Cancelled","cancellation":{"cancelled_by":"extweb.oyeti.com/ecommerce/ondc","reason":{"id":"010"}},"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}},{"id":"rto","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"159.09","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"rto","price":{"currency":"INR","value":"36.71"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"3.67"}}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"start":{"time":{"duration":"P1D","timestamp":"2023-12-08T09:18:06.524Z"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]},"time":{"timestamp":"2023-12-08T09:19:27.742Z"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","time":{"timestamp":"2023-12-08T09:19:27.742Z"}},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"value":3,"unit":"kilogram"}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}}},"updated_at":"2023-12-08T09:34:28.223Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js index 201216f..d6fef76 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js @@ -628,8 +628,6 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js index 5de61bb..c145f38 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js @@ -549,8 +549,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js index 3a97ae2..f137e4b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js @@ -321,8 +321,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup", "ttl"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js index c687d03..4d202a2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js @@ -568,8 +568,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup", "ttl"], }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js index 9a4649c..8e18120 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js @@ -177,7 +177,8 @@ module.exports = { type: "object", properties: { code: { - type: "string" + type: "string", + enum: ["BUYER_TERMS"], }, }, required: ["code"], @@ -191,7 +192,8 @@ module.exports = { type: "object", properties: { code: { - type: "string" + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js index 51e46f8..6844f48 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/initSchema.js @@ -335,7 +335,6 @@ module.exports = { }, additionalProperties: false, isLengthValid:true, - errorMessage:"name + building + locality < 190 chars", required: [ "name", "building", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js index fb38da1..91a0436 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js @@ -202,8 +202,7 @@ module.exports = { }, }, isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + required: ["price", "breakup"], }, fulfillments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js index fd47ce2..e583451 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js @@ -139,7 +139,6 @@ module.exports = { }, }, isEndTimeGreater: true, - errorMessage: 'The "end" time must be greater than the "start" time. Ref footnote 12 of v1.1 .', required: ["start", "end"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js index 9a9ed5a..2d0b76e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/common/commonSchema.js @@ -55,7 +55,6 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: "name + building + locality < 190 chars", }, }, required: ["gps", "address"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 5f77fae..9b96e2e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -1042,7 +1042,6 @@ module.exports = { }, }, // isFutureDated: true, - // errorMessage: - // "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 7ac6ff0..f63135d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -197,7 +197,7 @@ module.exports = { }, }, isLengthValid:true, - errorMessage:"name + building + locality < 190 chars", + required: [ "name", "building", @@ -275,7 +275,7 @@ module.exports = { }, }, isLengthValid:true, - errorMessage:"name + building + locality < 190 chars", + required: [ "name", "building", @@ -346,7 +346,6 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: "name + building + locality < 190 chars", additionalProperties: false, required: [ "name", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 860fa2d..256cbe1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -195,8 +195,7 @@ module.exports = { }, required: ["price", "breakup"], isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + }, fulfillments: { @@ -340,8 +339,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], @@ -462,8 +460,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], @@ -717,6 +714,6 @@ module.exports = { }, }, // isFutureDated: true, - // errorMessage: "order/created_at or order/updated_at cannot be future dated w.r.t context/timestamp", + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js index a372264..82bc4e4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -187,8 +187,7 @@ module.exports = { }, required: ["price", "breakup", "ttl"], isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + }, fulfillments: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 348df28..0b7fbf5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -199,8 +199,7 @@ module.exports = { }, required: ["price", "breakup"], isQuoteMatching: true, - errorMessage: - "price is not matching with the total breakup price", + }, fulfillments: { type: "array", @@ -340,8 +339,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], @@ -467,8 +465,7 @@ module.exports = { }, }, isLengthValid: true, - errorMessage: - "name + building + locality < 190 chars", + }, }, required: ["gps", "address"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js index 3c7def9..a750922 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js @@ -122,8 +122,6 @@ module.exports = { }, }, isEndTimeGreater: true, - errorMessage: - 'The "end" time must be greater than the "start" time', required: ["start", "end"], }, }, From 57a5cbf789c089cabf7144b00a00afa14a2dab5f Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Dec 2023 11:45:10 +0530 Subject: [PATCH 071/228] bug fixes --- .../v1.1/confirmSchema.js | 5 +++++ .../v1.1/onStatusSchema.js | 2 +- .../v1.2/confirmSchema.js | 5 +++++ .../logistics_api_json_schema/v1.2/initSchema.js | 1 + .../v1.2/onUpdateSchema.js | 2 +- .../log-verification-utility/utils/ContextVal.js | 16 +++++++++++++--- .../utils/logistics/logConfirm.js | 2 +- .../utils/logistics/logOnStatus.js | 14 +++++++++----- 8 files changed, 36 insertions(+), 11 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index 55f5a4c..bfe077e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -87,6 +87,11 @@ module.exports = { properties: { id: { type: "string", + not: { + const: { $data: "1/context/transaction_id" }, + }, + errorMessage: + "should be unique (cannot be equal to transaction_id)", }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js index 91a0436..d9c2783 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/onStatusSchema.js @@ -393,7 +393,7 @@ module.exports = { }, }, if: { properties: { type: { const: "Prepaid" } } }, - then: { required: ["type", "state", "tracking"] }, + then: { required: ["type", "state", "tracking","start","end"] }, else: { required: ["type", "state"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 9b96e2e..88416f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -88,6 +88,11 @@ module.exports = { properties: { id: { type: "string", + not: { + const: { $data: "1/context/transaction_id" }, + }, + errorMessage: + "should be unique (cannot be equal to transaction_id)", }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index f63135d..0721b13 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -459,6 +459,7 @@ module.exports = { errorMessage:"should be same as in /search - ${/search/0/message/intent/payment/type}" }, }, + additionalProperties:false, required: ["type"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index aad1d92..ab0a17a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -259,7 +259,7 @@ module.exports = { }, }, - required: ["code", "short_desc"], + required: [], allOf: [ { if: { properties: { code: { const: "1" } } }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 7d0ceb7..11175d7 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -14,9 +14,8 @@ const checkContextVal = (payload, msgIdSet, i) => { let Obj = {}; let data = payload.context; let domain = payload.context.domain; - let maxTimeDiff = 0; - if (domain === "ONDC:RET10") { - maxTimeDiff = 5000; + let maxTimeDiff = 5000; + if (domain === "ONDC:RET10" && payload?.context?.version === "2.0.1") { if (action === "init") { maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); dao.setValue("maxTimeDiff", maxTimeDiff); @@ -25,6 +24,16 @@ const checkContextVal = (payload, msgIdSet, i) => { } } else if (domain === "nic2004:60232") { maxTimeDiff = 1000; + } else if ( + domain === "ONDC:RET10" && + payload?.context?.version === "2.0.2" + ) { + if (action === "select") { + maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); + dao.setValue("maxTimeDiff", maxTimeDiff); + } else if (action === "on_select") { + maxTimeDiff = dao.getValue("maxTimeDiff"); + } } console.log("time difference", maxTimeDiff); @@ -88,6 +97,7 @@ const checkContextVal = (payload, msgIdSet, i) => { } else { if ( action === "on_search" || + action === "on_select" || action === "on_init" || action === "on_confirm" || action === "on_update" diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 72d9b7f..8760879 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -75,7 +75,7 @@ const checkConfirm = (data, msgIdSet) => { let avgPickupTime= fulfillment.start.time.duration; if(avgPickupTime!==dao.getValue("avgPickupTime")){ - cnfrmObj.avgPckupErr=`Average Pickup Time mismatches from the one provided in /on_search` + cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; if (rts === "yes" && !fulfillment?.start?.instructions?.short_desc) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index abda338..a7a9fa1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -74,6 +74,12 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; } } + + if (ffState === "Agent-assigned" || ffState === "Searching-for-Agent") { + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + } if (ffState === "Order-picked-up") { if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; @@ -142,14 +148,12 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } if (fulfillments.length > 1) { - if (!dao.getValue("pickupTime")) { - onStatusObj.msngPickupState = `/on_status call for Fulfillment state - 'Order-picked-up' missing`; - } else if (!fulfillment.start.time.timestamp) { + if (!fulfillment.start.time.timestamp) { onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if(fulfillment.tracking===true){ - onStatusObj.trackErr=`fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled` + if (fulfillment.tracking === true) { + onStatusObj.trackErr = `fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled`; } if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( From 20a19a82fe418d7133a77b6d662da21faf8b6e62 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Dec 2023 18:05:32 +0530 Subject: [PATCH 072/228] minor fixes --- .../v1.1/confirmSchema.js | 14 +++++--- .../v1.2/confirmSchema.js | 14 +++++--- .../utils/b2b/b2bOnSearch.js | 33 +++++++++++++++++++ .../utils/constants.js | 4 ++- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index bfe077e..ad2ac64 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -87,11 +87,15 @@ module.exports = { properties: { id: { type: "string", - not: { - const: { $data: "1/context/transaction_id" }, - }, - errorMessage: - "should be unique (cannot be equal to transaction_id)", + allOf: [ + { + not: { + const: { $data: "3/context/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + }, + ], }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 88416f6..9311e1f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -88,11 +88,15 @@ module.exports = { properties: { id: { type: "string", - not: { - const: { $data: "1/context/transaction_id" }, - }, - errorMessage: - "should be unique (cannot be equal to transaction_id)", + allOf: [ + { + not: { + const: { $data: "3/context/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + }, + ], }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index a4dd00b..af21a6f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -7,6 +7,7 @@ const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); const checkOnSearch = async (data, msgIdSet) => { const onSrchObj = {}; let onSearch = data; + let domain = onSearch.context.domain; onSearch = onSearch.message.catalog; try { @@ -49,6 +50,38 @@ const checkOnSearch = async (data, msgIdSet) => { } } } + + //checking mandatory attributes for fashion and electronics + + provider.items.forEach((item) => { + let itemTags = item?.tags; + let mandatoryAttr; + + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET14") { + mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + } + itemTags.map(({ descriptor, list }, index) => { + switch (descriptor.code) { + case "attribute": + const encounteredAttr = []; + list.map(({ descriptor, value }) => { + encounteredAttr.push(descriptor.code); + }); + + // Check if all allowedCodes are encountered + const missingAttr = mandatoryAttr.filter( + (code) => !encounteredAttr.includes(code) + ); + if (missingAttr.length > 0) { + onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + } + break; + } + }); + }); } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 5e039d0..8b44c9f 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -167,5 +167,7 @@ module.exports = Object.freeze({ "RTO-Disposed", "Cancelled", ], - CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"] + CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], + FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], + ELECTRONICS_ATTRIBUTES: ["brand","model"] }); From 57471e1b9213dd074ac0c2b7123dc4a72093c28b Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 28 Dec 2023 11:51:05 +0530 Subject: [PATCH 073/228] b2b and logistics fixes --- .../log-verification-utility/.gitignore | 2 +- .../log_report.json | 8 + .../log_report.json | 62 ++ .../schema/B2B_json_schema/keywords/onInit.js | 5 +- .../B2B_json_schema/schemaValidator copy1.js | 107 ++ .../schema/B2B_json_schema/schemaValidator.js | 47 +- .../B2B_json_schema/{ => v1}/confirm.js | 0 .../schema/B2B_json_schema/{ => v1}/init.js | 0 .../schema/B2B_json_schema/{ => v1}/master.js | 0 .../B2B_json_schema/{ => v1}/on_confirm.js | 0 .../B2B_json_schema/{ => v1}/on_init.js | 0 .../B2B_json_schema/{ => v1}/on_search.js | 0 .../B2B_json_schema/{ => v1}/on_select.js | 2 +- .../B2B_json_schema/{ => v1}/on_status.js | 0 .../B2B_json_schema/{ => v1}/on_update.js | 1 - .../schema/B2B_json_schema/{ => v1}/search.js | 1 - .../schema/B2B_json_schema/{ => v1}/select.js | 0 .../schema/B2B_json_schema/{ => v1}/status.js | 1 - .../schema/B2B_json_schema/{ => v1}/update.js | 1 - .../schema/B2B_json_schema/v2/confirm.js | 769 ++++++++++++++ .../schema/B2B_json_schema/v2/init.js | 531 ++++++++++ .../schema/B2B_json_schema/v2/master.js | 78 ++ .../schema/B2B_json_schema/v2/on_confirm.js | 833 +++++++++++++++ .../schema/B2B_json_schema/v2/on_init.js | 694 +++++++++++++ .../schema/B2B_json_schema/v2/on_search.js | 966 ++++++++++++++++++ .../schema/B2B_json_schema/v2/on_select.js | 335 ++++++ .../schema/B2B_json_schema/v2/on_status.js | 758 ++++++++++++++ .../schema/B2B_json_schema/v2/on_update.js | 530 ++++++++++ .../schema/B2B_json_schema/v2/search.js | 262 +++++ .../schema/B2B_json_schema/v2/select.js | 432 ++++++++ .../schema/B2B_json_schema/v2/status.js | 107 ++ .../schema/B2B_json_schema/v2/update.js | 333 ++++++ .../v1.1/confirmSchema.js | 2 +- .../v1.1/searchSchema.js | 2 +- .../v1.2/confirmSchema.js | 40 +- .../v1.2/keywords/onInit.js | 2 + .../v1.2/onCancelSchema.js | 4 +- .../v1.2/onInitSchema.js | 2 + .../v1.2/onSearchSchema.js | 47 + .../v1.2/updateSchema.js | 3 +- .../log-verification-utility/schema/main.js | 6 +- .../utils/b2b/b2bInit.js | 21 +- .../utils/b2b/b2bOnSearch.js | 2 +- .../utils/b2b/b2bOnStatus.js | 7 +- .../utils/constants.js | 4 +- .../utils/logistics/logConfirm.js | 4 +- .../utils/logistics/logInit.js | 4 +- .../utils/logistics/logOnCancel.js | 34 +- .../utils/logistics/logOnStatus.js | 6 +- .../utils/logistics/logUpdate.js | 4 + .../log-verification-utility/utils/utils.js | 11 +- 51 files changed, 7003 insertions(+), 67 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json create mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/confirm.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/init.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/master.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_confirm.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_init.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_search.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_select.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_status.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/on_update.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/search.js (99%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/select.js (100%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/status.js (98%) rename utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/{ => v1}/update.js (99%) create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore index 5b4e0ec..8c29104 100644 --- a/utilities/logistics-b2b/log-verification-utility/.gitignore +++ b/utilities/logistics-b2b/log-verification-utility/.gitignore @@ -12,4 +12,4 @@ test.js !LICENSE.md logFlow*.json .DS_Store -log_report.json \ No newline at end of file +log_report.md \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json new file mode 100644 index 0000000..f33ebf7 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json @@ -0,0 +1,8 @@ +{ + "Schema": { + "schemaErr0": "/on_init/0/message/order/quote price is not matching with the total breakup price", + "schemaErr1": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'code'", + "schemaErr2": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'short_desc'", + "schemaErr3": "/on_update/0/message/order/fulfillments/0/start must pass \"$merge\" keyword validation" + } +} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json new file mode 100644 index 0000000..fb6d4bf --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json @@ -0,0 +1,62 @@ +{ + "Flow Error": { + "0": "Incorrect Flow as per context/timestamps - (search,on_search,cancel,init,on_init,confirm,on_confirm,status,support,track,on_track,on_support,on_status,on_cancel)" + }, + "Schema": { + "schemaErr0": "/search/0/message/intent/payment @ondc/org/collection_amount is required only for payment/type 'ON-FULFILLMENT'", + "schemaErr1": "/search/0/message/intent/payment must match \"then\" schema", + "schemaErr2": "/confirm/0/message/order/billing/created_at mismatches in /billing in /init and /confirm", + "schemaErr3": "/confirm/0/message/order/billing/updated_at mismatches in /billing in /init and /confirm", + "schemaErr4": "/confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", + "schemaErr5": "/on_confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", + "schemaErr6": "/on_status/0/message/order/fulfillments/0/start/time must have required property 'range'", + "schemaErr7": "/on_status/0/message/order/fulfillments/0/end must have required property 'time'", + "schemaErr8": "/on_status/0/message/order/fulfillments/0 must match \"then\" schema", + "schemaErr9": "/on_cancel/0/message/order must have required property 'created_at'", + "schemaErr10": "/on_cancel/0/message/order/quote price is not matching with the total breakup price", + "schemaErr11": "/on_cancel/0/message/order/fulfillments/0/start/time must have required property 'range'", + "schemaErr12": "/on_cancel/0/message/order/fulfillments/0/end/time must have required property 'range'", + "schemaErr13": "/on_cancel/0/message/order/fulfillments/0 must match \"then\" schema" + }, + "Context": { + "init_0": { + "tmpstmpErr": "Timestamp mismatch for /init " + }, + "status_0": { + "tmpstmpErr": "Timestamp mismatch for /status " + }, + "support_0": { + "tmpstmpErr": "Timestamp mismatch for /support " + }, + "track_0": { + "tmpstmpErr": "Timestamp mismatch for /track " + }, + "on_track_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + }, + "on_support_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + }, + "on_status_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + }, + "on_cancel_0": { + "msgIdErr": "Message Id cannot be same for different sets of APIs" + } + }, + "Message": { + "on_search_0": { + "itemTAT": "For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. 2023-12-08" + }, + "confirm_0": { + "itemDurationErr": "item duration does not match with the one provided in /on_search (LSP can send NACK)", + "avgPckupErr": "Average Pickup Time mismatches from the one provided in /on_search" + }, + "on_confirm_0": { + "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" + }, + "on_status_0": { + "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" + } + } +} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js index d9a2b1d..b31f2e2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js @@ -1,11 +1,14 @@ module.exports = { isQuoteMatching: (data) => { - const quotePrice = parseFloat(data?.price?.value); + let quotePrice = parseFloat(data?.price?.value); const breakupArr = data.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); + }); + totalBreakup= parseFloat(totalBreakup).toFixed(2) + quotePrice=quotePrice.toFixed(2) if (quotePrice != totalBreakup) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js new file mode 100644 index 0000000..51f97d6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js @@ -0,0 +1,107 @@ +const onConfirmSchema = require("./on_confirm"); +const onInitSchema = require("./on_init"); +const onSearchSchema = require("./on_search"); +const selectSchema = require("./select"); +const onSelectSchema = require("./on_select"); +const onUpdateSchema = require("./on_update"); +const searchSchema = require("./search"); +const initSchema = require("./init"); +const masterSchema = require("./master"); +const confirmSchema = require("./confirm"); +const statusSchema = require("./status"); +const updateSchema = require("./update"); +const onStatusSchema = require("./on_status"); +const { isLengthValid } = require("./keywords/init"); +const { isQuoteMatching } = require("./keywords/onInit"); +const { isFutureDated } = require("./keywords/confirm"); +const { isEndTimeGreater } = require("./keywords/search"); + +const fs = require("fs"); +//const async = require("async"); +const path = require("path"); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + + +const validate_schema = (data, schema) => { + const Ajv = require("ajv"); + const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + $data: true, + }); + const addFormats = require("ajv-formats"); + + addFormats(ajv); + require("ajv-errors")(ajv); + let error_list = []; + try { + validate = ajv + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(selectSchema) + .addSchema(onSelectSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema) + .addKeyword("isEndTimeGreater", { + validate: (schema, data) => isEndTimeGreater(data), + }) + .addKeyword("isQuoteMatching", { + validate: (schema, data) => isQuoteMatching(data), + }) + .addKeyword("isFutureDated", { + validate: (schema, data) => isFutureDated(data), + }) + .addKeyword("isLengthValid", { + validate: (schema, data) => isLengthValid(data), + }); + + validate = validate.compile(schema); + + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + } catch (error) { + console.log("ERROR!! validating schema"); + console.trace(error); + } + return error_list; +}; + +const validate_schema_b2b_master = (data) => { + error_list = validate_schema(data, masterSchema); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_b2b_master, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js index 43fb234..66aa4f1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -1,16 +1,4 @@ -const onConfirmSchema = require("./on_confirm"); -const onInitSchema = require("./on_init"); -const onSearchSchema = require("./on_search"); -const selectSchema = require("./select"); -const onSelectSchema = require("./on_select"); -const onUpdateSchema = require("./on_update"); -const searchSchema = require("./search"); -const initSchema = require("./init"); -const masterSchema = require("./master"); -const confirmSchema = require("./confirm"); -const statusSchema = require("./status"); -const updateSchema = require("./update"); -const onStatusSchema = require("./on_status"); + const { isLengthValid } = require("./keywords/init"); const { isQuoteMatching } = require("./keywords/onInit"); const { isFutureDated } = require("./keywords/confirm"); @@ -42,7 +30,33 @@ const formatted_error = (errors) => { return error_json; }; -const validate_schema = (data, schema) => { +const loadSchema = (schemaType, version) => { + try { + return require(`./${version}/${schemaType}.js`); + } catch (error) { + console.log("Error Occurred while importing", error); + } +}; + +const validate_schema = (data, schema,version) => { + const searchSchema = loadSchema("search", version); + const onSearchSchema = loadSchema("on_search", version); + + const selectSchema = loadSchema("select", version); + const onSelectSchema = loadSchema("on_select", version); + + const initSchema = loadSchema("init", version); + const onInitSchema = loadSchema("on_init", version); + + const confirmSchema = loadSchema("confirm", version); + const onConfirmSchema = loadSchema("on_confirm", version); + + const updateSchema = loadSchema("update", version); + const onUpdateSchema = loadSchema("on_update", version); + + const statusSchema = loadSchema("status", version); + const onStatusSchema = loadSchema("on_status", version); + const Ajv = require("ajv"); const ajv = new Ajv({ allErrors: true, @@ -96,8 +110,9 @@ const validate_schema = (data, schema) => { return error_list; }; -const validate_schema_b2b_master = (data) => { - error_list = validate_schema(data, masterSchema); +const validate_schema_b2b_master = (data,version) => { + const masterSchema = loadSchema("master", version); + error_list = validate_schema(data, masterSchema,version); return formatted_error(error_list); }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/confirm.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/init.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/master.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/master.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/master.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_confirm.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_init.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_init.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_init.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_search.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js index f137e4b..f2fe7b0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js @@ -220,7 +220,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "Packing charges", "delivery ", "tax", "misc"] + enum: ["item", "discount", "packing", "delivery ", "tax", "misc"] }, price: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_status.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_update.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_update.js index d87b56d..8abb301 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_update.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/search.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/search.js index 9c8f6af..5c45d70 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/search.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js similarity index 100% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/select.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/status.js similarity index 98% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/status.js index 45afe99..c6bcf70 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/status.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/update.js similarity index 99% rename from utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js rename to utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/update.js index 62e1bd1..24e08c0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/update.js @@ -7,7 +7,6 @@ module.exports = { properties: { domain: { type: "string", - const: "ONDC:RET10", }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js new file mode 100644 index 0000000..5adfe0d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -0,0 +1,769 @@ +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "confirm", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "string", + enum: ["Created"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + locations: { + type: "array", + const: { $data: "/init/0/message/order/provider/locations" }, + errorMessage:"mismatch from /init", + items: { + type: "object", + properties: { + id: { + type: "string", + + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["person"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + created_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "created_at does not match context timestamp - ${3/context/timestamp}", + }, + updated_at: { + type: "string", + const: { $data: "3/context/timestamp" }, + errorMessage: + "updated_at does not match context timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties:false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js new file mode 100644 index 0000000..9b9db05 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -0,0 +1,531 @@ +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "init", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/select/0/message/order/provider/locations/0/id", + }, + }, + }, + required: ["id"], + }, + } + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + minLength: 3, + }, + address: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + }, + email: { + type: "string", + }, + phone: { + type: "string", + }, + created_at: { + type: "string", + }, + updated_at: { + type: "string", + }, + }, + additionalProperties: false, + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "License", + "Badge", + "Permit", + "Certificate", + ], + }, + desc: { + type: "string", + }, + icon: { + type: "string", + }, + url: { + type: "string", + pattern: + "^https://[\\w.-]+(\\.[a-zA-Z]{2,})?(:[0-9]+)?(/\\S*)?$", + }, + }, + required: ["id", "type", "desc", "icon", "url"], + }, + }, + }, + required: ["creds"], + }, + }, + required: ["person"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties: false, + required: [ + "provider", + "items", + "billing", + "fulfillments", + "payments", + "tags", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js new file mode 100644 index 0000000..d01fe98 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js @@ -0,0 +1,78 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + } + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js new file mode 100644 index 0000000..3e87a93 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -0,0 +1,833 @@ +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_confirm", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/confirm/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/provider/id" }, + }, + locations: { + type: "array", + const: { $data: "/confirm/0/message/order/provider/locations" }, + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + rateable: { + type: "boolean", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "stops", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + const: { + $data: "/on_init/0/message/order/quote/price/value", + }, + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + const: { $data: "3/context/timestamp" }, + errorMessage: + " should be updated as per context/timestamp - ${3/context/timestamp}", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "tags", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js new file mode 100644 index 0000000..d47c1fe --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -0,0 +1,694 @@ +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_init", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/init/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + format: "duration" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + provider_location: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/init/0/message/order/provider/locations/0/id"} + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["BUYER_TERMS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_REQ","PACKAGING_REQ"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + } + ] + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "tax_id", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["type", "location", "contact"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + anyOf: [ + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + }, + { + const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, + } + ] + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "type", "tracking", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + required: [ + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties:false, + required: [ + "provider", + "provider_location", + "items", + "billing", + "fulfillments", + "quote", + "payments", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js new file mode 100644 index 0000000..13d05ca --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -0,0 +1,966 @@ +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_search", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["Delivery", "Self-Pickup"], + }, + }, + required: ["id", "type"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["id", "type"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "short_desc", "long_desc", "images"], + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + additional_desc: { + type: "object", + properties: { + url: { + type: "string", + }, + content_type: { + type: "string", + }, + }, + required: ["url", "content_type"], + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "code"], + }, + rating: { + type: "string", + }, + ttl: { + type: "string", + format: "duration", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + code: { + type: "string", + }, + name: { + type: "string", + }, + }, + required: ["code", "name"], + }, + state: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + }, + additionalProperties: false, + required: [ + "id", + "gps", + "address", + "city", + "state", + "country", + "area_code", + ], + }, + }, + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: ["License", "Badge", "Permit", "Certificate"], + }, + desc: { + type: "string", + }, + url: { + type: "string", + format: "uri", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["mimetype", "url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + creator: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + required: ["full"], + }, + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["address", "phone"], + }, + }, + required: ["name", "contact"], + }, + }, + required: ["descriptor"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: ["currency", "value", "maximum_value"], + }, + quantity: { + type: "object", + properties: { + unitized: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["measure"], + }, + available: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, + maximum: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, + }, + required: ["unitized", "available", "maximum"], + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + }, + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: [ + "currency", + "value", + "offered_value", + "maximum_value", + ], + }, + }, + required: ["id", "descriptor", "price"], + }, + }, + cancellation_terms: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + refund_eligible: { + type: "string", + }, + return_policy: { + type: "object", + properties: { + return_eligible: { + type: "string", + }, + return_within: { + type: "string", + }, + fulfillment_managed_by: { + type: "string", + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + required: ["address", "gps"], + }, + }, + required: [ + "return_eligible", + "return_within", + "fulfillment_managed_by", + "return_location", + ], + }, + }, + if: { + properties: { + fulfillment_state: { + properties: { + descriptor: { + properties: { + code: { + const: "Order-delivered", + }, + }, + }, + }, + }, + }, + }, + then: { + required: ["fulfillment_state", "return_policy"], + }, + else: { + required: [ + "fulfillment_state", + "refund_eligible", + ], + }, + }, + }, + replacement_terms: { + type: "array", + items: { + type: "object", + properties: { + replace_within: { + type: "string", + }, + }, + required: ["replace_within"], + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + matched: { + type: "string", + }, + recommended: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + + "descriptor", + "creator", + "price", + "quantity", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "replacement_terms", + + "matched", + "recommended", + ], + }, + }, + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + location_ids: { + type: "array", + items: {}, + }, + category_ids: { + type: "array", + items: {}, + }, + item_ids: { + type: "array", + items: {}, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + }, + required: [ + "id", + "descriptor", + "location_ids", + "category_ids", + "item_ids", + "time", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["contact"], + }, + }, + }, + required: [ + "id", + "descriptor", + "ttl", + "locations", + "tags", + "items", + "fulfillments", + ], + }, + }, + }, + additionalProperties: false, + required: ["fulfillments", "payments", "descriptor", "providers"], + }, + }, + required: ["catalog"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js new file mode 100644 index 0000000..8e8591b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -0,0 +1,335 @@ +module.exports = { + $id: "http://example.com/schema/onSelectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_select", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/select/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ] + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + tracking: { + type: "boolean", + }, + "@ondc/org/category": { + type: "string", + }, + "@ondc/org/TAT": { + type: "string", + format: "duration" + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Serviceable", "Non-Serviceable"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "tracking", + "@ondc/org/category", + "@ondc/org/TAT", + "state", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: ["item", "discount", "packing", "delivery ", "tax", "misc"] + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + quantity: { + type: "object", + properties: { + available: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + maximum: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + }, + required: ["available", "maximum"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["quantity", "price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + format: "duration" + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + }, + required: ["provider", "items", "quote"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js new file mode 100644 index 0000000..487e02a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -0,0 +1,758 @@ +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_status", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress", + "Cancelled", + "Completed", + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + additionalProperties: false, + required: ["selected"], + }, + }, + required: ["id", "fulfillment_ids", "quantity"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + required: ["name"], + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "Pending", + "Packed", + "Agent-assigned", + "Order-picked-up", + "Out-for-delivery", + "Order-delivered", + ], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + end: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + agent: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["person", "contact"], + }, + }, + if: { properties: { type: { const: "start" } } }, + then: { + properties: { + location: { required: ["id", "descriptor", "gps"] }, + }, + }, + else: { + properties: { + location: { required: ["address", "gps"] }, + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "type", + "tracking", + "state", + "stops", + ], + anyof: [ + { + properties: { + state: { + const: "Order-picked-up", + }, + stops: { + type: "array", + items: { + properties: { + type: { + const: "start", + }, + time: { + required: ["range", "timestamp"], + }, + }, + }, + }, + }, + }, + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + if: { + properties: { + "@ondc/org/title_type": { + const: "item", + }, + }, + }, + then: { + required: [ + "@ondc/org/item_id", + "@ondc/org/item_quantity", + "title", + "@ondc/org/title_type", + "price", + "item", + ], + }, + else: { + properties: { + "@ondc/org/title_type": { + enum: [ + "delivery", + "packing", + "tax", + "discount", + "misc", + ], + }, + }, + required: [ + "@ondc/org/item_id", + "title", + "@ondc/org/title_type", + "price", + ], + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + const: { + $data: "/on_confirm/0/message/order/payments/0/type", + }, + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/collected_by", + }, + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + }, + + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", + }, + }, + required: ["url", "label"], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "order/created_at should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "documents", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js new file mode 100644 index 0000000..55c6645 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -0,0 +1,530 @@ +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_update", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + }, + message_id: { + type: "string", + const: { $data: "/update/0/context/message_id" }, + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: [ + "Created", + "Accepted", + "In-progress" + ], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["id", "quantity", "fulfillment_ids"], + }, + }, + payment: { + type: "object", + properties: { + uri: { + type: "string", + }, + tl_method: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum:["BAP","BPP"] + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["Pending","Agent-assigned","Order-picked-up","Out-for-delivery","Delivered"] + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + end: { + type: "string", + pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: [ + "type", + "location", + "time", + "instructions", + "contact", + ], + }, + }, + rateable: { + type: "boolean", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_DETAILS"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["ITEM_ID","COUNT","MEASURE_UNIT","MEASURE_VALUE"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "state", + "type", + "stops" + ], + }, + }, + }, + + required: ["id", "state", "provider", "items"], + }, + }, + required: ["order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js new file mode 100644 index 0000000..a10ad82 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -0,0 +1,262 @@ +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "search", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + category: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: ["Delivery", "Self-Pickup", "Delivery and Self-Pickup"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + }, + required: ["type", "location"], + }, + }, + }, + required: ["type", "stops"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + tags: { + type: "array", + minItems: 2, + uniqueItems: true, + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["bap_terms", "buyer_id"], + }, + }, + required:["code"] + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + required:["code"] + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + minItems: 2, + }, + }, + required: ["descriptor", "list"], + if: { + properties: { + descriptor: { + properties: { code: { const: "bap_terms" } }, + }, + }, + }, + then: { + properties: { + list: { + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + enum: ["finder_fee_type", "finder_fee_amount"], + }, + }, + }, + }, + required: ["descriptor"], + }, + }, + }, + errorMessage: + "For 'bap_terms', the 'list' must contain either 'finder_fee_type' or 'finder_fee_amount'.", + }, + else: { + if: { + properties: { + descriptor: { + properties: { code: { const: "buyer_id" } }, + }, + }, + }, + then: { + properties: { + list: { + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + enum: ["buyer_id_code", "buyer_id_no"], + }, + }, + }, + }, + required: ["descriptor"], + }, + }, + }, + errorMessage: + "For 'buyer_id', the 'list' must contain either 'buyer_id_code' or 'buyer_id_no'.", + }, + }, + }, + }, + }, + additionalProperties:false, + required: ["item", "fulfillment", "payment", "tags"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js new file mode 100644 index 0000000..444749f --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -0,0 +1,432 @@ +module.exports = { + $id: "http://example.com/schema/selectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "select", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: { $data: "2/message/order/provider/ttl" }, + errorMessage: + "should match provider ttl - ${2/message/order/provider/ttl}", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + ttl: { + type: "string", + format: "duration", + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "location_ids", "quantity"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + }, + required: ["type", "location"], + }, + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "License", + "Badge", + "Permit", + "Certificate", + ], + }, + desc: { + type: "string", + }, + icon: { + type: "string", + }, + url: { + type: "string", + pattern: + "^https://[\\w.-]+(\\.[a-zA-Z]{2,})?(:[0-9]+)?(/\\S*)?$", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + }, + required: ["creds"], + }, + }, + required: ["person"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + }, + required: ["type"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: ["buyer_id", "COMM_CHANNEL"], + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: [ + "buyer_id_code", + "buyer_id_no", + "chat_url", + ], + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + additionalProperties: false, + required: ["provider", "items", "fulfillments", "payments", "tags"], + }, + }, + required: ["order"], + additionalProperties: false, + }, + }, + required: ["context", "message"], + additionalProperties: false, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js new file mode 100644 index 0000000..387a6fe --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/status.js @@ -0,0 +1,107 @@ +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "status", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/on_confirm/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/on_confirm/0/message/order/id" }, + }, + }, + additionalProperties:false, + required: ["order_id"], + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js new file mode 100644 index 0000000..2067cf4 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js @@ -0,0 +1,333 @@ +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "update", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum:["fulfillment","item"] + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: + { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + }, + required: ["id", "quantity"], + }, + + }, + payments: { + type: "array", + items: + { + type: "object", + properties: { + uri: { + type: "string", + }, + tl_method: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { + type: "array", + items: + { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + beneficiary_name: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: [ + "settlement_counterparty", + "settlement_type", + ], + }, + + }, + }, + required: [ + "uri", + "tl_method", + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + ], + }, + + }, + }, + additionalProperties:false, + required: ["id", "state", "provider", "items", "payments"], + }, + }, + required: ["update_target", "order"], + }, + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js index ad2ac64..5700fdc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/confirmSchema.js @@ -93,7 +93,7 @@ module.exports = { const: { $data: "3/context/transaction_id" }, }, errorMessage: - "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + "should be unique and not be equal to transaction_id: ${3/context/transaction_id}", }, ], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js index e583451..e1a8a1b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.1/searchSchema.js @@ -242,7 +242,7 @@ module.exports = { type: "string", }, }, - required: ["@ondc/org/collection_amount"], + required: [], }, "@ondc/org/payload_details": { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 9311e1f..c2ac4e6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -94,7 +94,7 @@ module.exports = { const: { $data: "3/context/transaction_id" }, }, errorMessage: - "Message ID should not be equal to transaction_id: ${3/context/transaction_id}", + "should be unique and not be equal to transaction_id: ${3/context/transaction_id}", }, ], }, @@ -312,7 +312,7 @@ module.exports = { }, duration: { type: "string", - format: "duration" + format: "duration", }, location: { type: "object", @@ -592,7 +592,7 @@ module.exports = { "both 'state' and 'rto_action' tags are required", }, }, - + additionalProperties: false, required: ["id", "type", "start", "end", "tags"], }, }, @@ -1030,8 +1030,40 @@ module.exports = { type: "string", format: "date-time", }, - }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.TERMS, + + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + required: ["code", "list"], + }, + minItems: 2, + errorMessage: "both 'bpp_terms' and 'bap_terms' tags are required (logistics buyer NP must accept LSP terms. If not accepted, LSP can NACK /confirm with error code 65002)", + }, + }, + additionalProperties: false, required: [ "id", "state", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index 172c10e..5dcead5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -7,6 +7,8 @@ module.exports = { totalBreakup += parseFloat(breakup?.price?.value); }); // console.log(quotePrice,totalBreakup); + totalBreakup= parseFloat(totalBreakup).toFixed(2) + quotePrice=quotePrice.toFixed(2) if (quotePrice != totalBreakup) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 256cbe1..79705df 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -538,14 +538,14 @@ module.exports = { properties: { time: { required: ["range"] }, }, - required: ["time", "person", "location", "contact"], + required: [ "person", "location", "contact"], }, end: { properties: { time: { required: ["range"] }, }, - required: ["time", "person", "location", "contact"], + required: ["person", "location", "contact"], }, }, required: ["id", "type", "state", "start", "end", "tracking"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js index 82bc4e4..7b1e2fc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -355,6 +355,8 @@ module.exports = { type: { type: "string", enum: constants.PAYMENT_TYPE, + const: { $data: "/search/0/message/intent/payment/type" }, + errorMessage:"does not match the intended payment type by the logistics buyer" }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js index 203bb8c..71dd9a7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js @@ -301,6 +301,7 @@ module.exports = { required: ["label", "duration", "timestamp"], }, }, + additionalProperties:false, required: [ "id", "category_id", @@ -322,7 +323,53 @@ module.exports = { type: "string", enum: constants.FULFILLMENT_TYPE, }, + start: { + type: "object", + properties: { + time: { + type: "object", + properties: { + duration: { + type: "string", + }, + }, + required: ["duration"], + }, + }, + required: ["time"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["distance"] + }, + list: { + type: "array", + items: { + type: "object", + properties: { + code: { + type: "string", + enum: ["motorable_distance_type","motorable_distance"] + }, + value: { + type: "string", + }, + }, + required: ["code", "value"], + }, + }, + }, + + required: ["code", "list"], + }, + }, }, + additionalProperties:false, required: ["id", "type"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 34098a6..209fc5f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -326,13 +326,12 @@ module.exports = { format: "date-time", }, }, - + additionalProperties:false, required: ["id", "items", "fulfillments", "updated_at"], }, }, required: ["update_target", "order"], }, }, - required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/main.js b/utilities/logistics-b2b/log-verification-utility/schema/main.js index 3abb175..cc7470e 100755 --- a/utilities/logistics-b2b/log-verification-utility/schema/main.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/main.js @@ -9,13 +9,15 @@ const { const fs = require("fs"); const validate_schema_for_domain_json = (vertical, data, version) => { - version = getVersion(data); + version = getVersion(data,vertical); switch (vertical) { case "logistics": + res = validate_schema_master(data, version); return res; case "b2b": - res = validate_schema_b2b_master(data); + + res = validate_schema_b2b_master(data,version); return res; default: console.log("Invalid Domain!!"); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index d63e0cb..b7cc0ce 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -36,11 +36,14 @@ const checkInit = (data, msgIdSet) => { if (providerLocArr) { providerLocArr.forEach((location, i) => { - providerObj[0]?.locations?.forEach((element) => { - console.log(location.id, element.id); + if (providerObj) { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + } - if (location.id === element.id) providerLocExists = true; - }); if (!providerLocExists) { let itemkey = `providerLocErr${i}`; initObj[ @@ -66,10 +69,12 @@ const checkInit = (data, msgIdSet) => { let itemExists = false; itemsArr.forEach((item, i) => { - onSearchitemsArr.forEach((element) => { - if (item.id === element.id) itemExists = true; - console.log(item.id, element.id); - }); + if (onSearchitemsArr) { + onSearchitemsArr.forEach((element) => { + if (item.id === element.id) itemExists = true; + }); + } + if (!itemExists) { let itemkey = `itemErr${i}`; initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index af21a6f..32ee952 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -71,7 +71,7 @@ const checkOnSearch = async (data, msgIdSet) => { encounteredAttr.push(descriptor.code); }); - // Check if all allowedCodes are encountered + // Check if all mandatory attributes are encountered const missingAttr = mandatoryAttr.filter( (code) => !encounteredAttr.includes(code) ); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 6facef2..30585b6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -107,12 +107,12 @@ const checkOnStatus = (data, msgIdSet) => { fulfillment.stops.forEach((stop) => { if (stop.type === "start") { pickupTime = stop?.time?.timestamp; - dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - fulfillment?.start?.time?.timestamp !== + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; @@ -135,12 +135,11 @@ const checkOnStatus = (data, msgIdSet) => { fulfillment.stops.forEach((stop) => { if (stop.type === "start") { pickupTime = stop?.time?.timestamp; - dao.setValue("pickupTime", pickupTime); if (!pickupTime) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - fulfillment?.start?.time?.timestamp !== + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 8b44c9f..56c887f 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -133,6 +133,7 @@ module.exports = Object.freeze({ "004", "005", "006", + "007", "008", "009", "010", @@ -169,5 +170,6 @@ module.exports = Object.freeze({ ], CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], - ELECTRONICS_ATTRIBUTES: ["brand","model"] + ELECTRONICS_ATTRIBUTES: ["brand","model"], + TERMS:["bap_terms","bpp_terms"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 8760879..5b91a63 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -72,9 +72,9 @@ const checkConfirm = (data, msgIdSet) => { let p2h2p = dao.getValue("p2h2p"); fulfillments.forEach((fulfillment) => { - let avgPickupTime= fulfillment.start.time.duration; + let avgPickupTime= fulfillment?.start?.time?.duration; - if(avgPickupTime!==dao.getValue("avgPickupTime")){ + if(avgPickupTime && avgPickupTime!==dao.getValue("avgPickupTime")){ cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index 4907554..93cdc26 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -77,7 +77,6 @@ const checkInit = (data, msgIdSet) => { } onSearchitemsArr?.forEach((element) => { if (item.id === element.id) itemExists = true; - console.log(item.id, element.id); }); if (!itemExists) { let itemkey = `itemErr${i}`; @@ -86,7 +85,10 @@ const checkInit = (data, msgIdSet) => { let itemObj = onSearchitemsArr.filter( (element) => item.id === element.id ); + itemObj = itemObj[0]; + dao.setValue("selectedItem",itemObj.id) + console.log(itemObj.id); if (item.category_id != itemObj.category_id) { let itemkey = `catIdErr${i}`; initObj[ diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index 731db03..1dbeee1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -9,8 +9,10 @@ const checkOnCancel = (data, msgIdSet) => { let contextTime = on_cancel.context.timestamp; let version = on_cancel.context.core_version; let messageId = on_cancel.context.message_id; + const providerId = on_cancel.message?.provider?.id; on_cancel = on_cancel.message.order; + let onSearchItemsArr = dao.getValue(`${on_cancel?.provider?.id}itemsArr`); let ffState; let orderState = on_cancel.state; let items = on_cancel.items; @@ -42,6 +44,13 @@ const checkOnCancel = (data, msgIdSet) => { } catch (error) { console.log(error); } + if (onSearchItemsArr) { + let selectedItem = onSearchItemsArr.filter( + (element) => element.parent_item_id === dao.getValue("selectedItem") + ); + selectedItem = selectedItem[0]; + } + try { fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; @@ -63,9 +72,7 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if(fulfillment.tracking===true){ - onStatusObj.trackErr=`fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled` - } + if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( !_.isEqual( @@ -76,9 +83,17 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } } - console.log('comparing RTO fulfillment id with /on_search'); + console.log("comparing RTO fulfillment id with /on_search"); //checking RTO id matching with /on_search if (version === "1.2.0") { + if (dao.getValue("rts") === "yes") { + if (!fulfillment?.start?.time) { + onCancelObj.msngStrtTime = `Pickup time range (fulfillments/start/time) is missing`; + } + if (!fulfillment?.end?.time) { + onCancelObj.msngDlvryTime = `Delivery time range (fulfillments/end/time) is missing`; + } + } let fulTags = fulfillment?.tags; let rtoID; fulTags.forEach((tag) => { @@ -87,8 +102,9 @@ const checkOnCancel = (data, msgIdSet) => { lists.forEach((list) => { if (list.code === "rto_id") { rtoID = list.value; - if (rtoID !== dao.getValue("rtoID")) { - onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${dao.getValue("rtoID")}' in /fulfillments`; + + if (rtoID !== selectedItem.fulfillment_id) { + onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; } } }); @@ -100,9 +116,9 @@ const checkOnCancel = (data, msgIdSet) => { if (orderState !== "Cancelled") { onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } - console.log(fulfillment.id,dao.getValue("rtoID")); - if(fulfillment.id!==dao.getValue("rtoID")){ - onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${dao.getValue("rtoID")}' in /fulfillments`; + console.log(fulfillment.id, selectedItem?.fulfillment_id); + if (fulfillment.id !== selectedItem.fulfillment_id) { + onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; } if (ffState === "RTO-Initiated") { RtoPickupTime = fulfillment?.start?.time?.timestamp; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index a7a9fa1..7ec4271 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -62,7 +62,7 @@ const checkOnStatus = (data, msgIdSet) => { ) { if ( categoryId === "Immediate Delivery" && - fulfillment.tracking !== true + fulfillment.tracking !== true && ffState!=='Cancelled' ) { onStatusObj.trckErr = `tracking should be enabled (true) for hyperlocal (Immediate Delivery)`; } @@ -152,9 +152,7 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if (fulfillment.tracking === true) { - onStatusObj.trackErr = `fulfillment tracking can be disabled (false) after the fulfillment is 'Cancelled`; - } + if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { if ( !_.isEqual( diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js index a97eec7..d1edb5d 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logUpdate.js @@ -7,12 +7,16 @@ const checkUpdate = (data, msgIdSet) => { let updtObj = {}; let update = data; let version = update.context.core_version; + let contextTimestamp = update.context.timestamp; let p2h2p = dao.getValue("p2h2p"); let awbNo= dao.getValue("awbNo"); dao.setValue("updateApi",true) update = update.message.order; + if (update?.updated_at > contextTimestamp) { + updtObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; + } if (version === "1.1.0") rts = update?.fulfillments[0]?.tags["@ondc/org/order_ready_to_ship"]; else { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 55e29ab..04fd841 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -197,9 +197,16 @@ const timestampCheck = (date) => { } }; -const getVersion = (data) => { - if (data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; +const getVersion = (data,vertical) => { + if(vertical==='logistics'){ + if (data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; else return "v1.2"; + } + if(vertical==='b2b'){ + if (data?.search[0]?.context?.version === "2.0.1") return "v1"; + else return "v2"; + } + }; function compareDates(dateString1, dateString2) { const date1 = new Date(dateString1); From c6a5e11477a2a127c57ffbdabe79778d0d681a66 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 28 Dec 2023 11:55:34 +0530 Subject: [PATCH 074/228] minor change --- .../schema/logistics_api_json_schema/v1.2/keywords/onInit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index 5dcead5..af5d333 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -1,6 +1,6 @@ module.exports = { isQuoteMatching: (data) => { - const quotePrice = parseFloat(data?.price?.value); + let quotePrice = parseFloat(data?.price?.value); const breakupArr = data.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { From 5101927303716869cfaf69ea5e4257199b7a1733 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 28 Dec 2023 11:56:37 +0530 Subject: [PATCH 075/228] updated --- .../B2B_json_schema/schemaValidator copy1.js | 107 ------------------ 1 file changed, 107 deletions(-) delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js deleted file mode 100644 index 51f97d6..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator copy1.js +++ /dev/null @@ -1,107 +0,0 @@ -const onConfirmSchema = require("./on_confirm"); -const onInitSchema = require("./on_init"); -const onSearchSchema = require("./on_search"); -const selectSchema = require("./select"); -const onSelectSchema = require("./on_select"); -const onUpdateSchema = require("./on_update"); -const searchSchema = require("./search"); -const initSchema = require("./init"); -const masterSchema = require("./master"); -const confirmSchema = require("./confirm"); -const statusSchema = require("./status"); -const updateSchema = require("./update"); -const onStatusSchema = require("./on_status"); -const { isLengthValid } = require("./keywords/init"); -const { isQuoteMatching } = require("./keywords/onInit"); -const { isFutureDated } = require("./keywords/confirm"); -const { isEndTimeGreater } = require("./keywords/search"); - -const fs = require("fs"); -//const async = require("async"); -const path = require("path"); - -const formatted_error = (errors) => { - error_list = []; - let status = ""; - errors.forEach((error) => { - error_dict = { - message: `${error.message}${ - error.params.allowedValues ? ` (${error.params.allowedValues})` : "" - }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ - error.params.additionalProperty - ? ` (${error.params.additionalProperty})` - : "" - }`, - details: error.instancePath, - }; - error_list.push(error_dict); - }); - if (error_list.length === 0) status = "pass"; - else status = "fail"; - error_json = { errors: error_list, status: status }; - return error_json; -}; - - -const validate_schema = (data, schema) => { - const Ajv = require("ajv"); - const ajv = new Ajv({ - allErrors: true, - strict: false, - strictRequired: false, - strictTypes: false, - $data: true, - }); - const addFormats = require("ajv-formats"); - - addFormats(ajv); - require("ajv-errors")(ajv); - let error_list = []; - try { - validate = ajv - .addSchema(searchSchema) - .addSchema(onSearchSchema) - .addSchema(selectSchema) - .addSchema(onSelectSchema) - .addSchema(initSchema) - .addSchema(onInitSchema) - .addSchema(confirmSchema) - .addSchema(onConfirmSchema) - .addSchema(updateSchema) - .addSchema(onUpdateSchema) - .addSchema(statusSchema) - .addSchema(onStatusSchema) - .addKeyword("isEndTimeGreater", { - validate: (schema, data) => isEndTimeGreater(data), - }) - .addKeyword("isQuoteMatching", { - validate: (schema, data) => isQuoteMatching(data), - }) - .addKeyword("isFutureDated", { - validate: (schema, data) => isFutureDated(data), - }) - .addKeyword("isLengthValid", { - validate: (schema, data) => isLengthValid(data), - }); - - validate = validate.compile(schema); - - const valid = validate(data); - if (!valid) { - error_list = validate.errors; - } - } catch (error) { - console.log("ERROR!! validating schema"); - console.trace(error); - } - return error_list; -}; - -const validate_schema_b2b_master = (data) => { - error_list = validate_schema(data, masterSchema); - return formatted_error(error_list); -}; - -module.exports = { - validate_schema_b2b_master, -}; From e44332fcd2a91cea62837820e1867cfc3854e01c Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 29 Dec 2023 15:45:59 +0530 Subject: [PATCH 076/228] feedback updated --- .../log-verification-utility/.gitignore | 1 + .../log_report.json | 8 --- .../merged.json | 1 - .../log_report.json | 62 ------------------ .../merged.json | 1 - .../schema/B2B_json_schema/v2/on_status.js | 27 +++++--- .../schema/B2B_json_schema/v2/on_update.js | 63 +++++++++++-------- 7 files changed, 56 insertions(+), 107 deletions(-) delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json diff --git a/utilities/logistics-b2b/log-verification-utility/.gitignore b/utilities/logistics-b2b/log-verification-utility/.gitignore index 8c29104..3a79b99 100644 --- a/utilities/logistics-b2b/log-verification-utility/.gitignore +++ b/utilities/logistics-b2b/log-verification-utility/.gitignore @@ -3,6 +3,7 @@ package-lock.json *.env .vscode /public/logs/* +/public/server/* verification-logs /utils/*.json /utils/*.txt diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json deleted file mode 100644 index f33ebf7..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/log_report.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "Schema": { - "schemaErr0": "/on_init/0/message/order/quote price is not matching with the total breakup price", - "schemaErr1": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'code'", - "schemaErr2": "/on_update/0/message/order/fulfillments/0/start/instructions must have required property 'short_desc'", - "schemaErr3": "/on_update/0/message/order/fulfillments/0/start must pass \"$merge\" keyword validation" - } -} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json deleted file mode 100644 index 3e428f9..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/347301e3-ea1d-48d1-9ca5-283b7c18d586/merged.json +++ /dev/null @@ -1 +0,0 @@ -{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:32.568Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Express Delivery"},"fulfillment":{"type":"Delivery","end":{"location":{"gps":"28.5080098, 77.0909696","address":{"area_code":"122016"}}},"start":{"location":{"gps":"12.9298689, 77.6848366","address":{"area_code":"560103"}}}},"provider":{"time":{"range":{"start":"0000","end":"2359"},"days":"1,2,3,4,5,6,7","schedule":{"holidays":[]}}},"payment":{"type":"POST-FULFILLMENT"},"@ondc/org/payload_details":{"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}},"value":{"currency":"INR","value":"2000.0"},"category":"Grocery","weight":{"unit":"gram","value":10}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"b9913991-a295-4d22-ad19-82472d884117","timestamp":"2023-12-18T13:38:33.338Z","ttl":"PT30S"},"message":{"catalog":{"bpp/descriptor":{"name":"Ecom Express Private Limited"},"bpp/providers":[{"id":"I1","descriptor":{"name":"Ecom Express Private Limited","short_desc":"Ecom Express Private Limited","long_desc":"Ecom Express Private Limited"},"categories":[{"id":"Express Delivery","time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}],"fulfillments":[{"id":"1","type":"Delivery"},{"id":"2","type":"RTO"}],"items":[{"id":"1","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"1","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}},{"id":"2","parent_item_id":"EXPP","descriptor":{"name":"Express Plus Delivery","code":"P2H2P","short_desc":"Fast Delivery For Items","long_desc":"Fast Delivery for Items"},"category_id":"Express Delivery","fulfillment_id":"2","price":{"currency":"INR","value":"618.38"},"time":{"label":"TAT","timestamp":"2023-12-18","duration":"P5D"}}]}]}}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.110Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11bdd314-e0d7-4f23-8cea-2d89b730342a","timestamp":"2023-12-18T13:38:36.906Z","ttl":"PT30S"},"message":{"order":{"payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","fulfillment_id":"1","category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","end":{"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"contact":{"phone":"09898767675","email":"abii@gmail.com"},"location":{"gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}}}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.642Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","area_code":"122016","country":"India"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"code":"4","short_desc":"1368","long_desc":"QR code will be attached to package"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103","country":"India"}}}}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","area_code":"600127","country":"India"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:20:59.374Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"f6991386-0c8b-4ef6-ba06-9946297c8bde","timestamp":"2023-12-18T13:38:39.973Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Created","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"short_desc":"1368","long_desc":"QR code will be attached to package","code":"4"},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:39.973Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"889d3a90-9a20-4289-bb83-b05809918520","timestamp":"2023-12-18T13:38:54.815Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","items":[{"id":"1","descriptor":{"code":"P2H2P"},"category_id":"Express Delivery"}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"@ondc/org/awb_no":"110919056165"}],"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-07T14:32:39.165Z"},"update_target":"fulfillment"}}],"on_update":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_update","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"246cb466-8ac5-40b6-a586-08c8bdc1c72b","timestamp":"2023-12-18T13:38:55.288Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Accepted","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"1","type":"Delivery","tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"yes"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Pending"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:38:55.288Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"11457434-00a2-434d-bc7f-16eff98e3737","timestamp":"2023-12-18T13:39:37.639Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:39:37.639Z","created_at":"2023-12-07T14:20:59.374Z"}}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"0bf1fd6a-8e8f-4fc1-aad2-79152c0237b4","timestamp":"2023-12-18T13:40:21.368Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Initiated"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:40:21.368Z","created_at":"2023-12-07T14:20:59.374Z"}}},{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"stage-ondc.ecomexpress.in","bap_uri":"https://1b75-49-249-159-126.ngrok-free.app","bpp_id":"stage-ondc.ecomexpress.in","bpp_uri":"https://stage-ondc.ecomexpress.in","transaction_id":"347301e3-ea1d-48d1-9ca5-283b7c18d586","message_id":"2119685b-9816-4571-b6bd-4f428ee12812","timestamp":"2023-12-18T13:41:34.451Z","ttl":"PT30S"},"message":{"order":{"id":"3Q1QNP3PGX","state":"Cancelled","payment":{"type":"POST-FULFILLMENT","collected_by":"BAP","status":"PAID"},"cancellation":{"reason":{"id":"004"},"cancelled_by":"stage-ondc.ecomexpress.in"},"provider":{"id":"I1"},"quote":{"price":{"currency":"INR","value":"618.38"},"breakup":[{"price":{"currency":"INR","value":"618.38"},"@ondc/org/item_id":"1","@ondc/org/title_type":"delivery"}]},"items":[{"id":"1","quantity":{"count":1},"fulfillment_id":"1","category_id":"Express Delivery","descriptor":{"code":"P2H2P"}}],"fulfillments":[{"id":"2","type":"RTO","tags":[{"code":"rto_event","list":[{"code":"retry_count","value":"3"},{"code":"rto_id","value":"2"},{"code":"cancellation_reason_id","value":"004"},{"code":"cancelled_by","value":"stage-ondc.ecomexpress.in"}]}],"end":{"person":{"name":"Mithun Chakraborty 420"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-23T00:00:00.000Z","end":"2023-12-23T23:59:00.000Z"}},"contact":{"phone":"9999988888","email":"Baba@Elaichi.com"},"location":{"gps":"28.5080098, 77.0909696","address":{"name":"Mithun Chakraborty 420","building":"IHQ ecom express","locality":"Unnamed Road","city":"Gurugram","state":"Haryana","country":"India","area_code":"122016"}}},"start":{"person":{"name":"Abinaya"},"time":{"timestamp":"2023-12-15T08:50:53.670Z","range":{"start":"2023-12-19T00:00:00.000Z","end":"2023-12-19T23:59:00.000Z"}},"contact":{"phone":"09898767675","email":"abii@gmail.com"},"instructions":{"images":["https://stage-ondc.ecomexpress.in/shippingLabel/110919056165"]},"location":{"id":"19753-ONDC-1-3523_location","gps":"12.9298689, 77.6848366","address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","country":"India","area_code":"560103"}}},"state":{"descriptor":{"code":"RTO-Delivered"}},"tracking":false,"@ondc/org/awb_no":"112844922778"}],"billing":{"name":"Gofrugal Technologies Pvt Ltd","tax_number":"33AACCG2423J1ZZ","email":"accounts@gofrugal.com","phone":"9999988888","address":{"name":"KRISP IT Park","building":"942, Kelambakkam - Vandalur Rd","locality":"Kizhakottayur","city":"Chennai","state":"Tamil Nadu","country":"India","area_code":"600127"},"created_at":"2023-12-18T13:38:36.110Z","updated_at":"2023-12-18T13:38:36.110Z"},"@ondc/org/linked_order":{"items":[{"quantity":{"count":1,"measure":{"unit":"gram","value":10}},"price":{"currency":"INR","value":"2000.00"},"category_id":"Grocery","descriptor":{"name":"PLAIN ATTA"}}],"provider":{"descriptor":{"name":"Subbu Zoho ONDC"},"address":{"name":"Subbu Zoho ONDC","building":"block v","locality":"Vannar Pettai","city":"Bangalore","state":"Tamil Nadu","area_code":"560103"}},"order":{"id":"2023-12-07-225813","weight":{"unit":"gram","value":10},"dimensions":{"length":{"unit":"centimeter","value":2},"breadth":{"unit":"centimeter","value":3},"height":{"unit":"centimeter","value":4}}}},"updated_at":"2023-12-18T13:41:34.451Z","created_at":"2023-12-07T14:20:59.374Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json deleted file mode 100644 index fb6d4bf..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/log_report.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "Flow Error": { - "0": "Incorrect Flow as per context/timestamps - (search,on_search,cancel,init,on_init,confirm,on_confirm,status,support,track,on_track,on_support,on_status,on_cancel)" - }, - "Schema": { - "schemaErr0": "/search/0/message/intent/payment @ondc/org/collection_amount is required only for payment/type 'ON-FULFILLMENT'", - "schemaErr1": "/search/0/message/intent/payment must match \"then\" schema", - "schemaErr2": "/confirm/0/message/order/billing/created_at mismatches in /billing in /init and /confirm", - "schemaErr3": "/confirm/0/message/order/billing/updated_at mismatches in /billing in /init and /confirm", - "schemaErr4": "/confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", - "schemaErr5": "/on_confirm/0/message/order/payment/collected_by mismatches in /payment in /on_init and /confirm", - "schemaErr6": "/on_status/0/message/order/fulfillments/0/start/time must have required property 'range'", - "schemaErr7": "/on_status/0/message/order/fulfillments/0/end must have required property 'time'", - "schemaErr8": "/on_status/0/message/order/fulfillments/0 must match \"then\" schema", - "schemaErr9": "/on_cancel/0/message/order must have required property 'created_at'", - "schemaErr10": "/on_cancel/0/message/order/quote price is not matching with the total breakup price", - "schemaErr11": "/on_cancel/0/message/order/fulfillments/0/start/time must have required property 'range'", - "schemaErr12": "/on_cancel/0/message/order/fulfillments/0/end/time must have required property 'range'", - "schemaErr13": "/on_cancel/0/message/order/fulfillments/0 must match \"then\" schema" - }, - "Context": { - "init_0": { - "tmpstmpErr": "Timestamp mismatch for /init " - }, - "status_0": { - "tmpstmpErr": "Timestamp mismatch for /status " - }, - "support_0": { - "tmpstmpErr": "Timestamp mismatch for /support " - }, - "track_0": { - "tmpstmpErr": "Timestamp mismatch for /track " - }, - "on_track_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - }, - "on_support_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - }, - "on_status_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - }, - "on_cancel_0": { - "msgIdErr": "Message Id cannot be same for different sets of APIs" - } - }, - "Message": { - "on_search_0": { - "itemTAT": "For Same Day Delivery/Immediate Delivery, TAT date should be the same date i.e. 2023-12-08" - }, - "confirm_0": { - "itemDurationErr": "item duration does not match with the one provided in /on_search (LSP can send NACK)", - "avgPckupErr": "Average Pickup Time mismatches from the one provided in /on_search" - }, - "on_confirm_0": { - "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" - }, - "on_status_0": { - "trckErr": "tracking should be enabled (true) for hyperlocal (Immediate Delivery)" - } - } -} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json b/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json deleted file mode 100644 index bc99584..0000000 --- a/utilities/logistics-b2b/log-verification-utility/public/server/logistics/6802cbf8-dbb2-4562-abda-3fc2ebef2b75/merged.json +++ /dev/null @@ -1 +0,0 @@ -{"search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.783Z","ttl":"PT30S"},"message":{"intent":{"category":{"id":"Immediate Delivery"},"provider":{"time":{"days":"1,2,3,4,5,6","schedule":{"holidays":[]},"duration":"PT30M","range":{"start":"0630","end":"2359"}}},"fulfillment":{"type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"area_code":"560068"}}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"area_code":"560068"}}}},"payment":{"type":"ON-ORDER","@ondc/org/collection_amount":"0"},"@ondc/org/payload_details":{"weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}},"category":"F&B","value":{"currency":"INR","value":"238.0"}}}}}],"on_search":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_search","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"2f7b0c90-edf2-485f-ae15-665229687122","timestamp":"2023-12-08T09:07:59.909Z","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org"},"message":{"catalog":{"bpp/descriptor":{"name":"WITS Project Ref Logistic"},"bpp/providers":[{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320","descriptor":{"name":"WITS Project Ref Logistic","long_desc":"WITS Project Ref Logistic","short_desc":"WITS Project Ref Logistic"},"categories":[{"id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"PT15M"}},"tags":[{"code":"distance","list":[{"code":"motorable_distance_type","value":"kilometer"},{"code":"motorable_distance","value":"0.15"}]}]},{"id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","type":"RTO"}],"items":[{"id":"Standard","parent_item_id":"","category_id":"Immediate Delivery","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P","name":"Immediate Delivery","long_desc":"Upto 60 mins for Delivery","short_desc":"Upto 60 mins for Delivery"},"price":{"currency":"INR","value":"122.38"},"time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}},{"id":"rto","parent_item_id":"Standard","category_id":"Immediate Delivery","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P","name":"RTO quote","short_desc":"RTO quote","long_desc":"RTO quote"},"price":{"currency":"INR","value":"34.82"},"time":{"label":"TAT","duration":"P1D","timestamp":"2023-12-09"}}]}]}}}],"cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","cancellation_reason_id":"010"}}],"init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.356Z","ttl":"PT30S"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery","descriptor":{"code":"P2P"}}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:09.356Z","updated_at":"2023-12-08T09:08:09.356Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/settlement_details":[]}}}}],"on_init":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_init","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:08:09.525Z"},"message":{"order":{"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery"}],"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"end":{"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"images":[]}},"tags":[{"code":"rider_check","list":[{"code":"inline_check_for_rider","value":"yes"}]}]}],"quote":{"price":{"currency":"INR","value":"122.38"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}}],"ttl":"PT15M"},"payment":{"type":"ON-ORDER","collected_by":"BAP","@ondc/org/settlement_details":[]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"refund_eligible":true,"reason_required":false,"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}}},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"50"}}},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100"}}},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"refund_eligible":true,"reason_required":true,"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}}}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]}}}],"confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"extweb.oyeti.com/ecommerce/ondc","bpp_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.306Z","ttl":"PT30S"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Created","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","price":{"value":"116.00","currency":"INR"},"@ondc/org/title_type":"delivery"},{"@ondc/org/item_id":"Standard","price":{"value":"6.38","currency":"INR"},"@ondc/org/title_type":"tax"}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","tracking":true,"start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","long_desc":"Order Numer Last 6 Digits"}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}]}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"city":"Bengaluru","name":"Naffa Innovations Pvt Ltd","state":"Karnataka","country":"IND","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP"},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"unit":"kilogram","value":3}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}]},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z"}}}],"on_confirm":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_confirm","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Accepted","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tags":[{"code":"state","list":[{"code":"ready_to_ship","value":"no"}]},{"code":"rto_action","list":[{"code":"return_to_origin","value":"yes"}]}],"tracking":false}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","status":"PAID","@ondc/org/settlement_details":[]},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]},"cancellation_terms":[{"fulfillment_state":{"descriptor":{"code":"Pending","short_desc":""}},"cancellation_fee":{"amount":{"currency":"INR","value":"0.0"}},"refund_eligible":true,"reason_required":false},{"fulfillment_state":{"descriptor":{"code":"Agent-assigned","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"50"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Order-picked-up","short_desc":"001,003"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100"}},"refund_eligible":true,"reason_required":true},{"fulfillment_state":{"descriptor":{"code":"Out-for-delivery","short_desc":"011,012,013,014,015"}},"cancellation_fee":{"amount":{"currency":"INR","value":"100.0"}},"refund_eligible":true,"reason_required":true}],"tags":[{"code":"bpp_terms","list":[{"code":"max_liability","value":"2"},{"code":"max_liability_cap","value":"10000"},{"code":"mandatory_arbitration","value":"false"},{"code":"court_jurisdiction","value":"Bengaluru"},{"code":"delay_interest","value":"1000"},{"code":"static_terms","value":"https://github.com/ONDC-Official/protocol-network-extension/discussions/79"}]}],"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.489Z"}}}],"status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"ref_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.489Z","ttl":"PT30S"},"message":{"order_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75"}}],"on_track":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_track","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.763Z"},"message":{"tracking":{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","location":{"gps":"12.958766,77.625282","time":{"timestamp":"2023-12-08T09:08:11.489Z"},"updated_at":"1970-01-01T00:00:00.000Z"},"status":"active"}}}],"on_support":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_support","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:11.785Z"},"message":{"phone":"8755555551","email":"accounts@thewitslab.com","uri":"http://t.me/supportBot"}}],"on_status":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_status","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"47f3f650-4661-425b-b68d-031efaba239b","timestamp":"2023-12-08T09:08:39.272Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"In-progress","provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"descriptor":{"code":"P2P"},"time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"},"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","category_id":"Immediate Delivery"}],"quote":{"price":{"value":"122.38","currency":"INR"},"breakup":[{"price":{"currency":"INR","value":"116.00"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery"},{"price":{"currency":"INR","value":"6.38"},"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax"}]},"fulfillments":[{"state":{"descriptor":{"code":"Pending"}},"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","start":{"time":{"duration":"P1D"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"tracking":false}],"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","@ondc/org/settlement_details":[]},"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"@ondc/org/linked_order":{"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"weight":{"unit":"kilogram","value":3},"id":"2023-12-08-650909","dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}},"items":[{"descriptor":{"name":"Almond Filter Coffee"},"quantity":{"measure":{"value":3,"unit":"kilogram"},"count":2},"price":{"currency":"INR","value":"119.0"},"category_id":"F&B"}]}}}}],"on_cancel":[{"context":{"domain":"nic2004:60232","country":"IND","city":"std:080","action":"on_cancel","core_version":"1.2.0","bap_id":"extweb.oyeti.com/ecommerce/ondc","bap_uri":"https://extweb.oyeti.com/ecommerce/ondc/ecommerce/ondc","bpp_id":"ref-logistics-app-preprod.ondc.org","bpp_uri":"https://ref-logistics-app-preprod.ondc.org","transaction_id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","message_id":"e292631e-2f47-4af4-b767-3f03bf44ef94","timestamp":"2023-12-08T09:34:28.223Z"},"message":{"order":{"id":"6802cbf8-dbb2-4562-abda-3fc2ebef2b75","state":"Cancelled","cancellation":{"cancelled_by":"extweb.oyeti.com/ecommerce/ondc","reason":{"id":"010"}},"provider":{"id":"275b09c9-d0d9-42bb-98f1-2c4153a9d320"},"items":[{"id":"Standard","fulfillment_id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT30M","timestamp":"2023-12-08"}},{"id":"rto","fulfillment_id":"9ad1e641-0ba2-4689-a25a-82f8c74671e1","descriptor":{"code":"P2P"},"category_id":"Immediate Delivery","time":{"label":"TAT","duration":"PT60M","timestamp":"2023-12-08"}}],"quote":{"price":{"value":"159.09","currency":"INR"},"breakup":[{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"delivery","price":{"currency":"INR","value":"116.00"}},{"@ondc/org/item_id":"Standard","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"6.38"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"rto","price":{"currency":"INR","value":"36.71"}},{"@ondc/org/item_id":"rto","@ondc/org/title_type":"tax","price":{"currency":"INR","value":"3.67"}}]},"fulfillments":[{"id":"cc9f3061-29eb-4baf-80dd-4a4b3900c978","type":"Delivery","state":{"descriptor":{"code":"Cancelled"}},"tracking":false,"start":{"time":{"duration":"P1D","timestamp":"2023-12-08T09:18:06.524Z"},"person":{"name":"Nandyal Chefs"},"location":{"gps":"12.9029804, 77.6241936","address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]}},"end":{"person":{"name":"Venkateswara Reddy"},"location":{"gps":"12.903803216971028, 77.62518882751466","address":{"name":"Venkateswara Reddy","building":"Venky House","locality":"9th A Cross Road","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560068"}},"contact":{"phone":"7893847511","email":"venkateshmurapureddy@gmail.com"},"instructions":{"code":"2","short_desc":"650909","images":[]},"time":{"timestamp":"2023-12-08T09:19:27.742Z"}}}],"billing":{"name":"Kumar Abhishek","email":"accounts@tonetag.com","phone":"8197153537","address":{"name":"Naffa Innovations Pvt Ltd","building":"117, The Arcade, Brigade Metropolis, Garudachar Palya","locality":"Mahadevapura","city":"Bengaluru","state":"Karnataka","country":"IND","area_code":"560048"},"created_at":"2023-12-08T09:08:11.306Z","updated_at":"2023-12-08T09:08:11.306Z","tax_number":"29AAECN5025F1ZK"},"payment":{"type":"ON-ORDER","collected_by":"BPP","@ondc/org/collection_amount":"0","status":"PAID","time":{"timestamp":"2023-12-08T09:19:27.742Z"}},"@ondc/org/linked_order":{"items":[{"category_id":"F&B","descriptor":{"name":"Almond Filter Coffee"},"quantity":{"count":2,"measure":{"value":3,"unit":"kilogram"}},"price":{"currency":"INR","value":"119.0"}}],"provider":{"descriptor":{"name":"Nandyal Chefs"},"address":{"name":"Nandyal Chefs","building":"Bommanahalli","locality":"Bengaluru, Bangalore Division, Karnataka, India","city":"Bengaluru","state":"Karnataka","country":"India","area_code":"560068"}},"order":{"id":"2023-12-08-650909","weight":{"unit":"kilogram","value":3},"dimensions":{"length":{"unit":"centimeter","value":15},"breadth":{"unit":"centimeter","value":10},"height":{"unit":"centimeter","value":10}}}},"updated_at":"2023-12-08T09:34:28.223Z"}}}]} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 487e02a..ecaf332 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -235,9 +235,10 @@ module.exports = { type: "string", enum: [ "Pending", - "Packed", - "Agent-assigned", + "Out-for-pickup", "Order-picked-up", + "In-transit", + "At-destination-hub", "Out-for-delivery", "Order-delivered", ], @@ -327,21 +328,27 @@ module.exports = { properties: { start: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], }, timestamp: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["range"], @@ -568,7 +575,7 @@ module.exports = { }, }, isQuoteMatching: true, - + required: ["price", "breakup", "ttl"], }, payments: { @@ -753,6 +760,6 @@ module.exports = { required: ["order"], }, }, - + required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js index 55c6645..1301497 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -56,18 +56,18 @@ module.exports = { }, transaction_id: { type: "string", - const: { $data: "/select/0/context/transaction_id" }, + const: { $data: "/select/0/context/transaction_id" }, }, message_id: { type: "string", - const: { $data: "/update/0/context/message_id" }, + const: { $data: "/update/0/context/message_id" }, }, timestamp: { type: "string", format: "date-time", }, ttl: { - type: "string" + type: "string", }, }, required: [ @@ -93,22 +93,18 @@ module.exports = { properties: { id: { type: "string", - const: { $data: "/confirm/0/message/order/id" }, + const: { $data: "/confirm/0/message/order/id" }, }, state: { type: "string", - enum: [ - "Created", - "Accepted", - "In-progress" - ], + enum: ["Created", "Accepted", "In-progress"], }, provider: { type: "object", properties: { id: { type: "string", - const: { $data: "/select/0/message/order/provider/id" }, + const: { $data: "/init/0/message/order/provider/id" }, }, }, required: ["id"], @@ -178,7 +174,7 @@ module.exports = { }, collected_by: { type: "string", - enum:["BAP","BPP"] + enum: ["BAP", "BPP"], }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", @@ -255,13 +251,13 @@ module.exports = { }, }, if: { properties: { type: { const: "ON-FULFILLMENT" } } }, - then: { - properties: { - collected_by: { - const: "BPP", - }, + then: { + properties: { + collected_by: { + const: "BPP", }, }, + }, required: [ "params", "status", @@ -290,7 +286,15 @@ module.exports = { properties: { code: { type: "string", - enum:["Pending","Agent-assigned","Order-picked-up","Out-for-delivery","Delivered"] + enum: [ + "Pending", + "Out-for-pickup", + "Order-picked-up", + "In-transit", + "At-destination-hub", + "Out-for-delivery", + "Order-delivered", + ], }, }, required: ["code"], @@ -374,13 +378,17 @@ module.exports = { properties: { start: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start", "end"], @@ -435,7 +443,7 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_DETAILS"] + enum: ["ITEM_DETAILS"], }, }, required: ["code"], @@ -450,7 +458,12 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_ID","COUNT","MEASURE_UNIT","MEASURE_VALUE"] + enum: [ + "ITEM_ID", + "COUNT", + "MEASURE_UNIT", + "MEASURE_VALUE", + ], }, }, required: ["code"], @@ -472,12 +485,12 @@ module.exports = { "@ondc/org/provider_name", "state", "type", - "stops" + "stops", ], }, }, }, - + required: ["id", "state", "provider", "items"], }, }, From 3f3a0ef0e1a70d964d74da9b236a3b058db0cc1d Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 4 Jan 2024 12:34:23 +0530 Subject: [PATCH 077/228] fixed bugs and exceptions --- .../schema/B2B_json_schema/keywords/init.js | 2 +- .../schema/B2B_json_schema/keywords/onInit.js | 2 +- .../schema/B2B_json_schema/keywords/search.js | 4 +- .../schema/B2B_json_schema/v2/confirm.js | 2 +- .../schema/B2B_json_schema/v2/init.js | 2 +- .../schema/B2B_json_schema/v2/on_confirm.js | 2 - .../schema/B2B_json_schema/v2/on_init.js | 2 - .../schema/B2B_json_schema/v2/on_search.js | 2 +- .../schema/B2B_json_schema/v2/search.js | 3 ++ .../schema/B2B_json_schema/v2/select.js | 2 +- .../v1.2/confirmSchema.js | 19 ++++++++- .../v1.2/keywords/init.js | 2 +- .../v1.2/keywords/onInit.js | 2 +- .../v1.2/keywords/search.js | 4 +- .../v1.2/onCancelSchema.js | 15 +++++++ .../v1.2/onConfirmSchema.js | 17 +++++++- .../v1.2/onStatusSchema.js | 39 +++++++++++++++++++ .../v1.2/onUpdateSchema.js | 15 +++++++ .../utils/ContextVal.js | 3 +- .../utils/logistics/logInit.js | 6 +-- 20 files changed, 119 insertions(+), 26 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js index 18a4db3..8f448e9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js @@ -1,6 +1,6 @@ module.exports = { isLengthValid: (data) => { - if (data.name.length + data.building.length + data.locality.length > 190) + if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js index b31f2e2..f4081b8 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js @@ -1,7 +1,7 @@ module.exports = { isQuoteMatching: (data) => { let quotePrice = parseFloat(data?.price?.value); - const breakupArr = data.breakup; + const breakupArr = data?.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js index 6588a9e..7a14c5b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js @@ -1,7 +1,7 @@ module.exports = { isEndTimeGreater: (data) => { - const startTime = parseInt(data.start); - const endTime = parseInt(data.end); + const startTime = parseInt(data?.start); + const endTime = parseInt(data?.end); return startTime < endTime; }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 5adfe0d..082d0fc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -308,7 +308,7 @@ module.exports = { gps: { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 9b9db05..336f703 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -287,7 +287,7 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 3e87a93..d6f47d8 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -343,8 +343,6 @@ module.exports = { }, gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index d47c1fe..35dfa68 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -300,8 +300,6 @@ module.exports = { properties: { gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 13d05ca..d8d3584 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -238,7 +238,7 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index a10ad82..79d7f96 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -123,6 +123,9 @@ module.exports = { properties: { gps: { type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, area_code: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 444749f..218b65f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -235,7 +235,7 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, area_code: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index c2ac4e6..1b3b5d0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -172,6 +172,21 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "category_id", "descriptor", "fulfillment_id"], // anyOf: [ @@ -1038,7 +1053,6 @@ module.exports = { code: { type: "string", enum: constants.TERMS, - }, list: { type: "array", @@ -1060,7 +1074,8 @@ module.exports = { required: ["code", "list"], }, minItems: 2, - errorMessage: "both 'bpp_terms' and 'bap_terms' tags are required (logistics buyer NP must accept LSP terms. If not accepted, LSP can NACK /confirm with error code 65002)", + errorMessage: + "both 'bpp_terms' and 'bap_terms' tags are required (logistics buyer NP must accept LSP terms. If not accepted, LSP can NACK /confirm with error code 65002)", }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js index 18a4db3..8f448e9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js @@ -1,6 +1,6 @@ module.exports = { isLengthValid: (data) => { - if (data.name.length + data.building.length + data.locality.length > 190) + if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index af5d333..a0aebf6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -1,7 +1,7 @@ module.exports = { isQuoteMatching: (data) => { let quotePrice = parseFloat(data?.price?.value); - const breakupArr = data.breakup; + const breakupArr = data?.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js index 6588a9e..7a14c5b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js @@ -1,7 +1,7 @@ module.exports = { isEndTimeGreater: (data) => { - const startTime = parseInt(data.start); - const endTime = parseInt(data.end); + const startTime = parseInt(data?.start); + const endTime = parseInt(data?.end); return startTime < endTime; }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 79705df..56701b7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -159,6 +159,21 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "category_id", "descriptor", "fulfillment_id"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index ad3d244..ff7b510 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -198,8 +198,23 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, - required: ["id", "category_id", "descriptor"], + required: ["id", "category_id", "descriptor","time","fulfillment_id"], }, }, quote: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 0b7fbf5..1017c08 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -163,6 +163,21 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "category_id", "descriptor", "fulfillment_id"], }, @@ -625,6 +640,30 @@ module.exports = { }, }, }, + + if: { properties: { type: { const: "ON-ORDER" } } }, + then: { + properties: { + collected_by: { + const: "BAP", + }, + status:{ + const:"PAID" + } + }, + }, + + if: { properties: { type: { const: "POST-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BAP", + }, + status:{ + const:"NOT-PAID" + } + }, + }, required: ["type", "collected_by","status"], }, billing: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index ab0a17a..7aff9a5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -149,6 +149,21 @@ module.exports = { }, }, }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "fulfillment_id", "category_id", "descriptor"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 11175d7..8749ce0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -15,7 +15,7 @@ const checkContextVal = (payload, msgIdSet, i) => { let data = payload.context; let domain = payload.context.domain; let maxTimeDiff = 5000; - if (domain === "ONDC:RET10" && payload?.context?.version === "2.0.1") { + if (payload?.context?.version === "2.0.1") { if (action === "init") { maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); dao.setValue("maxTimeDiff", maxTimeDiff); @@ -25,7 +25,6 @@ const checkContextVal = (payload, msgIdSet, i) => { } else if (domain === "nic2004:60232") { maxTimeDiff = 1000; } else if ( - domain === "ONDC:RET10" && payload?.context?.version === "2.0.2" ) { if (action === "select") { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index 93cdc26..ef36eae 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -6,11 +6,7 @@ const utils = require("../utils"); const checkInit = (data, msgIdSet) => { const billing = data.message.order.billing const billingAdd= billing.address - const len = billingAdd.name.length + billingAdd.building.length +billingAdd.locality.length - console.log(billingAdd.name.length,billingAdd.building.length,billingAdd.locality.length); - console.log("length",len); - if (billingAdd.name.length + billingAdd.building.length +billingAdd.locality.length > 190) return true - else false + const initObj = {}; let init = data; let p2h2p = false; From 6385d9ebc079b8846ddf6280dbba87119b84e5fb Mon Sep 17 00:00:00 2001 From: pratikmazumdar Date: Thu, 11 Jan 2024 14:37:29 +0530 Subject: [PATCH 078/228] fix: python util --- .../on_subscibe-service/python/Readme.md | 10 +- .../on_subscibe-service/python/server.py | 355 ++++++++++-------- 2 files changed, 198 insertions(+), 167 deletions(-) diff --git a/utilities/on_subscibe-service/python/Readme.md b/utilities/on_subscibe-service/python/Readme.md index a2f27c9..84aa97c 100644 --- a/utilities/on_subscibe-service/python/Readme.md +++ b/utilities/on_subscibe-service/python/Readme.md @@ -1,5 +1,9 @@ # Subscribing to ONDC Registry +### Start Server + +``` flask --app server run ``` + 1. Add following environment variables like below. ``` - name: BAP_BASE_URL @@ -19,10 +23,10 @@ curl --location 'https:///subscribe' \ --header 'Content-Type: application/json' \ --data '{ - "/bap/beckn/v1/4b17bd06-ae7e-48e9-85bf-282fb310209c | 60": { + " | ": { "signingPublicKey": "...", "signingPrivateKey": "...", - "ondcPublicKey": "MCowBQYDK2VuAyEAvVEyZY91O2yV8w8/CAwVDAnqIZDJJUPdLUUKwLo3K0M=", + "ondcPublicKey": "MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=", # Change it for pre-prod and prod "encPublicKey": "...", "encPrivateKey": "...", "type": "BAP", @@ -31,7 +35,7 @@ curl --location 'https:///subscribe' \ "/dobpp/beckn/7f7896dd-787e-4a0b-8675-e9e6fe93bb8f | 50": { "signingPublicKey": "HUVYp98+DBp/LIbs7LoeSec3NwQcojLZhsa/tQdqbP4=", "signingPrivateKey": "...", - "ondcPublicKey": "MCowBQYDK2VuAyEAvVEyZY91O2yV8w8/CAwVDAnqIZDJJUPdLUUKwLo3K0M=", + "ondcPublicKey": "MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=", "encPublicKey": "...", "encPrivateKey": "...", "type": "BPP", diff --git a/utilities/on_subscibe-service/python/server.py b/utilities/on_subscibe-service/python/server.py index feec8e2..ff61bfe 100644 --- a/utilities/on_subscibe-service/python/server.py +++ b/utilities/on_subscibe-service/python/server.py @@ -4,13 +4,13 @@ import base64 import datetime import json -import nacl.encoding +from nacl.bindings import crypto_sign_ed25519_sk_to_seed import nacl.hash from nacl.signing import SigningKey from cryptography.hazmat.primitives import serialization from Cryptodome.Cipher import AES from Cryptodome.Util.Padding import unpad -from flask import Flask, request +from flask import Flask, request, render_template import requests import uuid import multiprocessing @@ -26,110 +26,113 @@ subscribers_uniquekey_store = {} bapSubscribeBody = { - "context": { - "operation": { - "ops_no": 1 + "context": { + "operation": { + "ops_no": 1 + }, }, - }, - "message": { - "request_id": "", - "timestamp": "", - "entity": { - "gst": { - "legal_entity_name": "...", - "business_address": "...", - "city_code": [ - "std:080" - ], - "gst_no": "..." - }, - "pan": { - "name_as_per_pan": "...", - "pan_no": "...", - "date_of_incorporation": "..." - }, - "name_of_authorised_signatory": "...", - "email_id": "email@domain.in", - "mobile_no": ..., - "country": "IND", - "subscriber_id": "", - "unique_key_id": "", - "callback_url": "/", - "key_pair": { - "signing_public_key": "", - "encryption_public_key": "", - "valid_from": "", - "valid_until": "2030-06-19T11:57:54.101Z" - } - }, - "network_participant": [ - { - "subscriber_url": "/", - "domain": "ONDC:TRV10", - "type": "buyerApp", - "msn": False, - "city_code": [] - } - ] - } + "message": { + "request_id": "", + "timestamp": "", + "entity": { + "gst": { + "legal_entity_name": "...", + "business_address": "...", + "city_code": [ + "std:080" + ], + "gst_no": "..." + }, + "pan": { + "name_as_per_pan": "...", + "pan_no": "...", + "date_of_incorporation": "..." + }, + "name_of_authorised_signatory": "...", + "email_id": "email@domain.in", + "mobile_no": ..., + "country": "IND", + "subscriber_id": "", + "unique_key_id": "", + "callback_url": "/", + "key_pair": { + "signing_public_key": "", + "encryption_public_key": "", + "valid_from": "", + "valid_until": "2030-06-19T11:57:54.101Z" + } + }, + "network_participant": [ + { + "subscriber_url": "/", + "domain": "ONDC:TRV10", + "type": "buyerApp", + "msn": False, + "city_code": [] + } + ] + } } bppSubscribeBody = { - "context": { - "operation": { - "ops_no": 2 - } - }, - "message": { - "request_id": "", - "timestamp": "", - "entity": { - "gst": { - "legal_entity_name": "...", - "business_address": "...", - "city_code": [ - "std:080" - ], - "gst_no": "..." - }, - "pan": { - "name_as_per_pan": "...", - "pan_no": "...", - "date_of_incorporation": "..." - }, - "name_of_authorised_signatory": "...", - "email_id": "email@domain.in", - "mobile_no": ..., - "country": "IND", - "subscriber_id": "", - "unique_key_id": "", - "callback_url": "/", - "key_pair": { - "signing_public_key": "", - "encryption_public_key": "", - "valid_from": "", - "valid_until": "2030-06-19T11:57:54.101Z" - } + "context": { + "operation": { + "ops_no": 2 + } }, - "network_participant": [ - { - "subscriber_url": "/", - "domain": "ONDC:TRV10", - "type": "sellerApp", - "msn": False, - "city_code": [] - } - ] - } + "message": { + "request_id": "", + "timestamp": "", + "entity": { + "gst": { + "legal_entity_name": "...", + "business_address": "...", + "city_code": [ + "std:080" + ], + "gst_no": "..." + }, + "pan": { + "name_as_per_pan": "...", + "pan_no": "...", + "date_of_incorporation": "..." + }, + "name_of_authorised_signatory": "...", + "email_id": "email@domain.in", + "mobile_no": ..., + "country": "IND", + "subscriber_id": "", + "unique_key_id": "", + "callback_url": "/", + "key_pair": { + "signing_public_key": "", + "encryption_public_key": "", + "valid_from": "", + "valid_until": "2030-06-19T11:57:54.101Z" + } + }, + "network_participant": [ + { + "subscriber_url": "/", + "domain": "ONDC:TRV10", + "type": "sellerApp", + "msn": False, + "city_code": [] + } + ] + } } -def sign(signing_key, signing_private_key): - signing_private_key64 = base64.b64decode(signing_private_key) - signer = SigningKey(signing_private_key64, encoder=nacl.encoding.RawEncoder) + +def sign(signing_key, private_key): + private_key64 = base64.b64decode(private_key) + seed = crypto_sign_ed25519_sk_to_seed(private_key64) + signer = SigningKey(seed) signed = signer.sign(bytes(signing_key, encoding='utf8')) signature = base64.b64encode(signed.signature).decode() return signature + def decrypt(enc_public_key, enc_private_key, cipherstring): private_key = serialization.load_der_private_key( base64.b64decode(enc_private_key), @@ -143,12 +146,13 @@ def decrypt(enc_public_key, enc_private_key, cipherstring): ciphertxt = base64.b64decode(cipherstring) return unpad(cipher.decrypt(ciphertxt), AES.block_size).decode('utf-8') -def createHtml(request_id, subscriber, subscriber_id): - signature = sign(request_id, subscriber['signingPrivateKey']) + +def createHtml(subscriber, subscriber_id): + signature = sign(subscriber['requestId'], subscriber['signingPrivateKey']) htmlFile = f''' - + ONDC Site Verification Page @@ -156,87 +160,103 @@ def createHtml(request_id, subscriber, subscriber_id): ''' if subscriber['type'] == "BAP": - if not os.path.exists(f'ondc-verification/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}'): - os.makedirs(f'ondc-verification/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}') - with open(f"ondc-verification/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}/ondc-site-verification.html", "w+") as file: + if not os.path.exists(f'templates/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}'): + os.makedirs( + f'templates/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}') + with open(f"templates/{subscriber_id[slice(len(bapBaseUrl) + 1, len(subscriber_id))]}/ondc-site-verification.html", "w+") as file: file.write(htmlFile) elif subscriber['type'] == "BPP": - if not os.path.exists(f'ondc-verification/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}'): - os.makedirs(f'ondc-verification/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}') - with open(f"ondc-verification/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}/ondc-site-verification.html", "w+") as file: + if not os.path.exists(f'templates/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}'): + os.makedirs( + f'templates/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}') + with open(f"templates/{subscriber_id[slice(len(bppBaseUrl) + 1, len(subscriber_id))]}/ondc-site-verification.html", "w+") as file: file.write(htmlFile) + app = Flask(__name__) -@app.route('/subscribe/on_subscribe', methods=['POST']) + +@app.route('/on_subscribe', methods=['POST']) def onsubscribe(): data = request.get_json() - print(f"/subscribe/on_subscribe called :: Request -> {data}") + print(f"/on_subscribe called :: Request -> {data}") subscriber_id = data['subscriber_id'] unique_key_id = subscribers_uniquekey_store[subscriber_id] subscriber = subscribers[f"{subscriber_id} | {unique_key_id}"] - return { - "answer" : decrypt(subscriber['ondcPublicKey'], subscriber['encPrivateKey'], data['challenge']) + print(subscriber) + return { + "answer": decrypt(subscriber['ondcPublicKey'], subscriber['encPrivateKey'], data['challenge']) } + def serve_file(): - os.system(f'python -m http.server {static_file_port} --directory ondc-verification') + os.system( + f'python -m http.server {static_file_port} --directory ondc-verification') + def subscribe_helper(): if subscribers != None: - global subscribers_uniquekey_store - for subscriber_uk_id, subscriber in subscribers.items(): - [subscriber_id, unique_key_id] = subscriber_uk_id.split(' | ') - subscribers_uniquekey_store[subscriber_id] = unique_key_id - request_id = str(uuid.uuid4()) - subscribers[subscriber_uk_id]['requestId'] = request_id - createHtml(request_id, subscriber, subscriber_id) - process = multiprocessing.Process(target=serve_file) - process.start() - time.sleep(5) - for subscriber_uk_id, subscriber in subscribers.items(): - [subscriber_id, unique_key_id] = subscriber_uk_id.split(' | ') - request_id = subscriber['requestId'] - current_datetime = datetime.datetime.now().astimezone(pytz.timezone('Asia/Kolkata')) - current_datetime_iso8601 = current_datetime.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z" - - if subscriber['type'] == 'BAP': - bapSubscribeBody['message']['request_id'] = request_id - bapSubscribeBody['message']['timestamp'] = current_datetime_iso8601 - bapSubscribeBody['message']['entity']['subscriber_id'] = subscriber_id - bapSubscribeBody['message']['entity']['unique_key_id'] = unique_key_id - bapSubscribeBody['message']['entity']['key_pair']['signing_public_key'] = subscriber['signingPublicKey'] - bapSubscribeBody['message']['entity']['key_pair']['encryption_public_key'] = subscriber['encPublicKey'] - bapSubscribeBody['message']['entity']['key_pair']['valid_from'] = current_datetime_iso8601 - bapSubscribeBody['message']['network_participant'][0]['city_code'] = [subscriber['city']] - - print(json.dumps(bapSubscribeBody)) - - response = requests.post(registry_url, json=bapSubscribeBody) - if response.status_code == 200: - print(f"/subscribe for {subscriber_uk_id} request successful :: {response.json()}") - else: - print(f"/subscribe for {subscriber_uk_id} request failed :: {response.json()}") - elif subscriber['type'] == 'BPP': - bppSubscribeBody['message']['request_id'] = request_id - bppSubscribeBody['message']['timestamp'] = current_datetime_iso8601 - bppSubscribeBody['message']['entity']['subscriber_id'] = subscriber_id - bppSubscribeBody['message']['entity']['unique_key_id'] = unique_key_id - bppSubscribeBody['message']['entity']['key_pair']['signing_public_key'] = subscriber['signingPublicKey'] - bppSubscribeBody['message']['entity']['key_pair']['encryption_public_key'] = subscriber['encPublicKey'] - bppSubscribeBody['message']['entity']['key_pair']['valid_from'] = current_datetime_iso8601 - bppSubscribeBody['message']['network_participant'][0]['city_code'] = [subscriber['city']] - - print(json.dumps(bppSubscribeBody)) - - response = requests.post(registry_url, json=bppSubscribeBody) - if response.status_code == 200: - print(f"/subscribe for {subscriber_uk_id} request successful :: {response.json()}") - else: - print(f"/subscribe for {subscriber_uk_id} request failed :: {response.json()}") - time.sleep(300) - process.terminate() - process.join() + global subscribers_uniquekey_store + for subscriber_uk_id, subscriber in subscribers.items(): + [subscriber_id, unique_key_id] = subscriber_uk_id.split(' | ') + subscribers_uniquekey_store[subscriber_id] = unique_key_id + request_id = str(uuid.uuid4()) + subscribers[subscriber_uk_id]['requestId'] = request_id + createHtml(subscriber, subscriber_id) + process = multiprocessing.Process(target=serve_file) + process.start() + time.sleep(5) + for subscriber_uk_id, subscriber in subscribers.items(): + [subscriber_id, unique_key_id] = subscriber_uk_id.split(' | ') + request_id = subscriber['requestId'] + current_datetime = datetime.datetime.now().astimezone(pytz.timezone('Asia/Kolkata')) + current_datetime_iso8601 = current_datetime.strftime( + "%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z" + + if subscriber['type'] == 'BAP': + bapSubscribeBody['message']['request_id'] = request_id + bapSubscribeBody['message']['timestamp'] = current_datetime_iso8601 + bapSubscribeBody['message']['entity']['subscriber_id'] = subscriber_id + bapSubscribeBody['message']['entity']['unique_key_id'] = unique_key_id + bapSubscribeBody['message']['entity']['key_pair']['signing_public_key'] = subscriber['signingPublicKey'] + bapSubscribeBody['message']['entity']['key_pair']['encryption_public_key'] = subscriber['encPublicKey'] + bapSubscribeBody['message']['entity']['key_pair']['valid_from'] = current_datetime_iso8601 + bapSubscribeBody['message']['network_participant'][0]['city_code'] = [ + subscriber['city']] + + print(json.dumps(bapSubscribeBody)) + + response = requests.post(registry_url, json=bapSubscribeBody) + if response.status_code == 200: + print( + f"/subscribe for {subscriber_uk_id} request successful :: {response.json()}") + else: + print( + f"/subscribe for {subscriber_uk_id} request failed :: {response.json()}") + elif subscriber['type'] == 'BPP': + bppSubscribeBody['message']['request_id'] = request_id + bppSubscribeBody['message']['timestamp'] = current_datetime_iso8601 + bppSubscribeBody['message']['entity']['subscriber_id'] = subscriber_id + bppSubscribeBody['message']['entity']['unique_key_id'] = unique_key_id + bppSubscribeBody['message']['entity']['key_pair']['signing_public_key'] = subscriber['signingPublicKey'] + bppSubscribeBody['message']['entity']['key_pair']['encryption_public_key'] = subscriber['encPublicKey'] + bppSubscribeBody['message']['entity']['key_pair']['valid_from'] = current_datetime_iso8601 + bppSubscribeBody['message']['network_participant'][0]['city_code'] = [ + subscriber['city']] + + print(json.dumps(bppSubscribeBody)) + + response = requests.post(registry_url, json=bppSubscribeBody) + if response.status_code == 200: + print( + f"/subscribe for {subscriber_uk_id} request successful :: {response.json()}") + else: + print( + f"/subscribe for {subscriber_uk_id} request failed :: {response.json()}") + time.sleep(300) + process.terminate() + process.join() + @app.route('/subscribe', methods=['POST']) def subscribe(): @@ -245,10 +265,17 @@ def subscribe(): print(f"/subscribe called :: Request -> {subscribers}") thread1 = threading.Thread(target=subscribe_helper) thread1.start() - return { "success" : "ACK" } + return {"success": "ACK"} + + +@app.route('/ondc-site-verification.html', methods=['GET']) +def verify_html(): + return render_template('ondc-site-verification.html') + def start_flask_app(): app.run(port=app_port, host="0.0.0.0") + if __name__ == '__main__': - start_flask_app(); \ No newline at end of file + start_flask_app() From c83bd58f16bd39dad6e288767033d5dcbec5ccd3 Mon Sep 17 00:00:00 2001 From: Sahil Sharma <123928721+sahilsharma9@users.noreply.github.com> Date: Tue, 19 Dec 2023 15:01:03 +0530 Subject: [PATCH 079/228] feat: node.js lookup service --- utilities/vlookup/node.js/README.md | 65 ++++++++++++ utilities/vlookup/node.js/index.js | 147 ++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+) create mode 100644 utilities/vlookup/node.js/README.md create mode 100644 utilities/vlookup/node.js/index.js diff --git a/utilities/vlookup/node.js/README.md b/utilities/vlookup/node.js/README.md new file mode 100644 index 0000000..b93686d --- /dev/null +++ b/utilities/vlookup/node.js/README.md @@ -0,0 +1,65 @@ +# ONDC VLookup Service + +This repository contains a simple Express.js server that facilitates the ONDC (Open Network for Digital Commerce) VLookup service. The VLookup service allows you to perform lookups in the ONDC registry and obtain relevant information based on specified parameters. + +## Getting Started + +### Prerequisites + +- Node.js installed on your machine + +### Installation + +1. Clone this repository to your local machine. +2. Navigate to the project directory in the terminal. +3. Run `npm install` to install the required dependencies. + +### Usage + +1. Start the server by running `node index.js` in the terminal. +2. The server will run on http://localhost:9900. + +## Routes + +### VLookup + +Perform a VLookup operation by sending a POST request to `http://localhost:9900/vlookup`. The payload should be in the following format: + +```json +{ + "senderSubscriberId": "your_subscriber_id", + "privateKey": "your_private_key", + + //search parameters of the NP whose details need to be fetched from registry + + "domain": "ONDC:RET10", + "subscriberId": "subscriber_id", // subscriber_id you want to lookup + "country": "IND", // country + "type": "buyerApp", //buyerApp, sellerApp, gateway + "city": "std:022", // city code + "env": "staging" //staging,preprod,prod +} +``` + +## Signature + +Sign your data by sending a POST request to [http://localhost:9900/vlookup/sign](http://localhost:9900/vlookup/sign). The payload should be the same as for the VLookup route. The response will include a signature. + +## Important Note + +Make sure to replace the sample private key with your actual private key. + +## Dependencies + +- Express.js +- sodium-native +- crypto +- axios + +## Contributing + +Feel free to contribute to the development of this project by submitting pull requests. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. diff --git a/utilities/vlookup/node.js/index.js b/utilities/vlookup/node.js/index.js new file mode 100644 index 0000000..9b831cc --- /dev/null +++ b/utilities/vlookup/node.js/index.js @@ -0,0 +1,147 @@ +const express = require("express"); +const sodium = require("sodium-native"); +const crypto = require("crypto"); +const axios = require("axios"); +const app = express(); +const port = 9900; + +const createSigningString = (data) => { + const { country, domain, type, city, subscriberId } = data; + return [country, domain, type, city, subscriberId].join("|"); +}; + +const getEnvDetails = (env) => { + let envLink = ""; + if (env === "preprod") { + envLink = "https://preprod.registry.ondc.org/ondc/vlookup"; + } else if (env === "prod") { + envLink = "https://prod.registry.ondc.org/vlookup"; + } else if (env === "staging") { + envLink = "https://staging.registry.ondc.org/vlookup"; + } else { + throw new Error("Unsupported environment"); + } + return envLink; +}; + +const fetchRegistryResponse = async ( + requestId, + timestamp, + signature, + searchParameters, + senderSubscriberId, + envLink +) => { + try { + const response = await axios.post(envLink, { + sender_subscriber_id: senderSubscriberId, + request_id: requestId, + timestamp, + search_parameters: searchParameters, + signature, + }); + return response; + } catch (error) { + return error; + } +}; + +const getVLookUpData = async (signature, data) => { + try { + const requestId = crypto.randomUUID(); + const timestamp = new Date().toISOString(); + const { country, domain, type, city, subscriberId } = data; + const searchParameters = { + country, + domain, + type, + city, + subscriber_id: subscriberId, + }; + const senderSubscriberId = data.senderSubscriberId; + const envLink = getEnvDetails(data.env); + + const res = await fetchRegistryResponse( + requestId, + timestamp, + signature, + searchParameters, + senderSubscriberId, + envLink + ); + return res; + } catch (error) { + logError("getVLookUpData", error); + throw error; + } +}; + +const signData = (message, privateKey) => { + const signature = new Uint8Array(sodium.crypto_sign_BYTES); + sodium.crypto_sign_detached(signature, message, privateKey); + return signature; +}; + +const sign = (signingString, privateKey) => { + let privateKeyBytes = Buffer.from(privateKey, "base64"); + const message = Buffer.from(signingString); + + if (privateKeyBytes.length !== sodium.crypto_sign_SECRETKEYBYTES) { + return "Invalid private key length"; + } + privateKey = new Uint8Array(privateKeyBytes); + + const signature = signData(message, privateKey); + + signatureBase64 = Buffer.from(signature).toString("base64"); + + return signatureBase64; +}; + +const vLookUp = async (data) => { + try { + const signingString = createSigningString(data); + const signature = sign(signingString, data.privateKey); + let res = await getVLookUpData(signature, data); + res = res.data; + return res; + } catch (error) { + logError("vLookUp", error); + throw error; + } +}; + +const logError = (location, error) => { + console.error(`Error in ${location}:`, error); +}; + +app.use(express.json()); + +// Route for signing your data +app.post("/vlookup/sign", (req, res) => { + try { + const data = req.body; + const signingString = createSigningString(data); + const signature = sign(signingString, data.privateKey); + res.status(200).send({ success: true, signature }); + } catch (error) { + logError("/vlookup/sign", error); + res.status(400).send({ success: false, response: error.message }); + } +}); + +// Route for vlookup +app.post("/vlookup", async (req, res) => { + try { + const response = await vLookUp(req.body); + res.status(200).send({ success: true, response }); + } catch (error) { + logError("/vlookup", error); + res.status(400).send({ success: false, response: error.message }); + } +}); + +// Start the server +app.listen(port, () => { + console.log(`Server is running on http://localhost:${port}`); +}); From 834f8315b47d0933a37e6839f073415023241525 Mon Sep 17 00:00:00 2001 From: Sahil Sharma <123928721+sahilsharma9@users.noreply.github.com> Date: Tue, 19 Dec 2023 16:28:35 +0530 Subject: [PATCH 080/228] ref: added package.json and .gitignore --- utilities/vlookup/node.js/.gitignore | 2 ++ utilities/vlookup/node.js/README.md | 2 +- utilities/vlookup/node.js/package.json | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 utilities/vlookup/node.js/.gitignore create mode 100644 utilities/vlookup/node.js/package.json diff --git a/utilities/vlookup/node.js/.gitignore b/utilities/vlookup/node.js/.gitignore new file mode 100644 index 0000000..49e0fc6 --- /dev/null +++ b/utilities/vlookup/node.js/.gitignore @@ -0,0 +1,2 @@ +/node_modules +/package-lock.json \ No newline at end of file diff --git a/utilities/vlookup/node.js/README.md b/utilities/vlookup/node.js/README.md index b93686d..9e13889 100644 --- a/utilities/vlookup/node.js/README.md +++ b/utilities/vlookup/node.js/README.md @@ -16,7 +16,7 @@ This repository contains a simple Express.js server that facilitates the ONDC (O ### Usage -1. Start the server by running `node index.js` in the terminal. +1. Start the server by running `npm start` in the terminal. 2. The server will run on http://localhost:9900. ## Routes diff --git a/utilities/vlookup/node.js/package.json b/utilities/vlookup/node.js/package.json new file mode 100644 index 0000000..8a69f84 --- /dev/null +++ b/utilities/vlookup/node.js/package.json @@ -0,0 +1,18 @@ +{ + "name": "vlookup-service", + "version": "1.0.0", + "description": "This repository contains a simple Express.js server that facilitates the ONDC (Open Network for Digital Commerce) VLookup service. The VLookup service allows you to perform lookups in the ONDC registry and obtain relevant information based on specified parameters.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "start": "node index.js" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^1.6.2", + "crypto": "^1.0.1", + "express": "^4.18.2", + "sodium-native": "^4.0.4" + } +} From e3c979dfd6596c6ffdffc731c67f03f8a4f596ec Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:46:14 +0530 Subject: [PATCH 081/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index ef7f741..13a0cfa 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -4,7 +4,7 @@ ``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging doc (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" ``` From b3cbbc588b8a3e557eb8340ecc3446684e843b24 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 082/228] Update readme.md From d0cf079ed2d09c35395d8c85faec9146fc94d9f7 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:49:46 +0530 Subject: [PATCH 083/228] Update README.md --- utilities/signing_and_verification/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utilities/signing_and_verification/README.md b/utilities/signing_and_verification/README.md index dc9777d..1893bf8 100644 --- a/utilities/signing_and_verification/README.md +++ b/utilities/signing_and_verification/README.md @@ -23,16 +23,16 @@ python cryptic_utils.py generate_key_pairs ``` Signing_private_key: G0Pme72u8Y1MwxHqvY4iBW+7VPtJ7dsX7SGs6zZ5yvVIzdRAyHR6YkwHG2ufOE+12lsbJRwBF4Hqd7dUEOZZkg== Signing_public_key: SM3UQMh0emJMBxtrnzhPtdpbGyUcAReB6ne3VBDmWZI= - Crypto_Privatekey: MC4CAQAwBQYDK2VuBCIEIKi7NbXeN8QzXjN48XkjOiS/UaR6rumXep8VslMy4fRU - Crypto_Publickey: MCowBQYDK2VuAyEA9CEWxnLJkmwW/67QR739BEam7bbd3NsffjDa5HANf0Q= + Encryption_Privatekey: MC4CAQAwBQYDK2VuBCIEIKi7NbXeN8QzXjN48XkjOiS/UaR6rumXep8VslMy4fRU + Encryption_Publickey: MCowBQYDK2VuAyEA9CEWxnLJkmwW/67QR739BEam7bbd3NsffjDa5HANf0Q= ``` 4. Export private and public keys ``` export PRIVATE_KEY= export PUBLIC_KEY= -export CRYPTO_PRIVATE_KEY= -export CRYPTO_PUBLIC_KEY= +export ENCRYPTION_PRIVATE_KEY= +export ENCRYPTION_PUBLIC_KEY= ``` 5. Create authorisation header From 460012ac957ad8c0cb68d682b62f5e98f7ffd9b5 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:58:54 +0530 Subject: [PATCH 084/228] Update cryptic_utils.py --- .../signing_and_verification/cryptic_utils.py | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/utilities/signing_and_verification/cryptic_utils.py b/utilities/signing_and_verification/cryptic_utils.py index b1ad6fc..cab39c0 100644 --- a/utilities/signing_and_verification/cryptic_utils.py +++ b/utilities/signing_and_verification/cryptic_utils.py @@ -101,7 +101,7 @@ def generate_key_pairs(): #print(private_key) public_key = base64.b64encode(bytes(signing_key.verify_key)).decode() inst_private_key = X25519PrivateKey.generate() - #print(base64.b64encode(bytes(tcrypto_private_key.).decode())) + #print(base64.b64encode(bytes(tencryption_private_key.).decode())) inst_public_key = inst_private_key.public_key() bytes_private_key = inst_private_key.private_bytes( encoding=serialization.Encoding.DER, @@ -112,21 +112,21 @@ def generate_key_pairs(): encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo ) - crypto_private_key = base64.b64encode(bytes_private_key).decode('utf-8') - crypto_public_key = base64.b64encode(bytes_public_key).decode('utf-8') + encryption_private_key = base64.b64encode(bytes_private_key).decode('utf-8') + encryption_public_key = base64.b64encode(bytes_public_key).decode('utf-8') return {"Signing_private_key": private_key, "Signing_public_key": public_key, - "Crypto_Privatekey": crypto_private_key, - "Crypto_Publickey": crypto_public_key} + "Encryption_Privatekey": encryption_private_key, + "Encryption_Publickey": encryption_public_key} -def encrypt(crypto_private_key, crypto_public_key, null): +def encrypt(encryption_private_key, encryption_public_key, null): private_key = serialization.load_der_private_key( - base64.b64decode(crypto_private_key), + base64.b64decode(encryption_private_key), password=None ) public_key = serialization.load_der_public_key( - base64.b64decode(crypto_public_key) + base64.b64decode(encryption_public_key) ) shared_key = private_key.exchange(public_key) cipher = AES.new(shared_key, AES.MODE_ECB) @@ -134,13 +134,13 @@ def encrypt(crypto_private_key, crypto_public_key, null): return base64.b64encode(cipher.encrypt(pad(text,AES.block_size))).decode('utf-8') -def decrypt(crypto_private_key, crypto_public_key, cipherstring): +def decrypt(encryption_private_key, encryption_public_key, cipherstring): private_key = serialization.load_der_private_key( - base64.b64decode(crypto_private_key), + base64.b64decode(encryption_private_key), password=None ) public_key = serialization.load_der_public_key( - base64.b64decode(crypto_public_key) + base64.b64decode(encryption_public_key) ) shared_key = private_key.exchange(public_key) cipher = AES.new(shared_key, AES.MODE_ECB) From 22172ce41366ec4dc9461ed99c835d3aa7d7ba9d Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:10:18 +0530 Subject: [PATCH 085/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index 13a0cfa..e1d7433 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -4,7 +4,7 @@ ``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on Staging [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on [Staging](url) [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" ``` From 5bf2adae9ba3915990b1e40dd19d45fd804e5cb9 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:23:05 +0530 Subject: [PATCH 086/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index e1d7433..1884776 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -1,12 +1,12 @@ + # Subscribing to ONDC Registry 1. Add following constants like below. -``` - PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key which is available in NP On-Boarding on [Staging](url) [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- PUBLIC_KEY_1 = "Registry's encryption public key as per your environment which is available in NP On-Boarding on [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" -``` + 2. Place the index.js file code into your main file, and this utility will host the on_subscribe endpoint as well as html file. From 9ed419f264b15639a1e5b2133596f75ade9760d5 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:24:18 +0530 Subject: [PATCH 087/228] Update readme.md --- utilities/on_subscibe-service/node/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/node/readme.md b/utilities/on_subscibe-service/node/readme.md index 1884776..7120fb6 100644 --- a/utilities/on_subscibe-service/node/readme.md +++ b/utilities/on_subscibe-service/node/readme.md @@ -3,8 +3,8 @@ 1. Add following constants like below. -- PRIVATE_KEY_1 = "NP's encryption private key" -- PUBLIC_KEY_1 = "Registry's encryption public key as per your environment which is available in NP On-Boarding on [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" +- ENCRYPTION_PRIVATE_KEY = "NP's encryption private key" +- ONDC_PUBLIC_KEY = "Registry's encryption public key as per your environment which is available in NP On-Boarding on [document](https://github.com/ONDC-Official/developer-docs/blob/main/registry/Onboarding%20of%20Participants.md) (staging key: MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=)" - REQUEST_ID = "request_id which is sent in /subscribe" - SIGNING_PRIVATE_KEY = "NP's signing private key" From f4911efd617ad1c469c6140f021c6d5d588ced2b Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 16:24:52 +0530 Subject: [PATCH 088/228] Update index.js --- utilities/on_subscibe-service/node/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/node/index.js b/utilities/on_subscibe-service/node/index.js index 5b98381..58e384f 100644 --- a/utilities/on_subscibe-service/node/index.js +++ b/utilities/on_subscibe-service/node/index.js @@ -5,9 +5,9 @@ const crypto = require('crypto'); // Node.js crypto module for encryption and de const _sodium = require('libsodium-wrappers'); const port = 3000; // Port on which the server will listen -const PRIVATE_KEY_1 = +const ENCRYPTION_PRIVATE_KEY = 'MC4CAQEwBQYDK2VuBCIEILgcht9h660ZeO36tG+QuHGNcLN9JuAzxHWZl09f57Bh'; -const PUBLIC_KEY_1 = +const ONDC_PUBLIC_KEY = 'MCowBQYDK2VuAyEAlKHWJWiEiHFGlAJ6TE4VMGaeQUYg5DHEpuQdiq6flnQ='; const REQUEST_ID = '6a6abf53-674f-4d6d-a52b-62e3fda55e04'; const SIGNING_PRIVATE_KEY = From 06cbfeb5680df66fc8d5a890ad63420b2967b8ac Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Fri, 29 Dec 2023 15:33:22 +0530 Subject: [PATCH 089/228] ref: Update index.js keys issue resolved --- utilities/on_subscibe-service/node/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/node/index.js b/utilities/on_subscibe-service/node/index.js index 58e384f..458173d 100644 --- a/utilities/on_subscibe-service/node/index.js +++ b/utilities/on_subscibe-service/node/index.js @@ -30,12 +30,12 @@ const htmlFile = ` `; // Pre-defined public and private keys const privateKey = crypto.createPrivateKey({ - key: Buffer.from(PRIVATE_KEY_1, 'base64'), // Decode private key from base64 + key: Buffer.from(ENCRYPTION_PRIVATE_KEY, 'base64'), // Decode private key from base64 format: 'der', // Specify the key format as DER type: 'pkcs8', // Specify the key type as PKCS#8 }); const publicKey = crypto.createPublicKey({ - key: Buffer.from(PUBLIC_KEY_1, 'base64'), // Decode public key from base64 + key: Buffer.from(ONDC_PUBLIC_KEY, 'base64'), // Decode public key from base64 format: 'der', // Specify the key format as DER type: 'spki', // Specify the key type as SubjectPublicKeyInfo (SPKI) }); From b541d7f1915f6a4d185627fc9f4d0965345aebb5 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 15:47:30 +0530 Subject: [PATCH 090/228] QR code update --- .../deep-links/qr_code_generator/__init__.py | 1 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 323 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 3705 bytes .../deep-links/qr_code_generator/core.py | 80 ++++++++++++++++++ .../deep-links/qr_code_generator/logo.png | Bin 0 -> 47774 bytes utilities/deep-links/qr_generate.py | 56 +++--------- 6 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 utilities/deep-links/qr_code_generator/__init__.py create mode 100644 utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc create mode 100644 utilities/deep-links/qr_code_generator/__pycache__/core.cpython-311.pyc create mode 100644 utilities/deep-links/qr_code_generator/core.py create mode 100644 utilities/deep-links/qr_code_generator/logo.png diff --git a/utilities/deep-links/qr_code_generator/__init__.py b/utilities/deep-links/qr_code_generator/__init__.py new file mode 100644 index 0000000..751f3de --- /dev/null +++ b/utilities/deep-links/qr_code_generator/__init__.py @@ -0,0 +1 @@ +from .core import generate_deep_link, generate_qr_code \ No newline at end of file diff --git a/utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc b/utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03e3ab7466373f13646a04ffd6281eb2ee261e98 GIT binary patch literal 323 zcmZ`!Jxc>Y5Z&DisDVJRuokSYh})$S8&k(ZY|<>t?I=t32L1=RTB*?>#83$5dkaO!V$qM+Y++fqr6RkNoE~3+H0eA zkc-%K9zss?dbzkd?Xq41vhZjDY&cP)fk&yCEIwSb5IOp$d{`SA)0rB?2gy$4a}Oo@%68BO$F+@xf1(idI7TsCw@B5gUTk zJ2U4#&f}hQ=G=4cmtL<6LHlRhZ?VK7^bazrH(PD+It+siBqEVYpeX5W2`Xue+NkQ9 zJ!-dbbddNKT3Ij4v*yG<-`N65^U9r%YDGf)Zbd*YvSE2A~_h*Di`Er#0b9u<~wu0!z;t z%Q-4bmFfmIR>>fXo&f)|h72&0D%o2|Y7^0R4}lbVFI?+xXrb#WR@9Itq;3mIK@@~kXk3o3Bymbp zLzkz=$M_XZN=TZ7)sTYcu!2)@d_qd56PVBlB3lSwO5N;A1nN3TxAu1CV)GInWIQ07&WO$&+uB%b9JtlW;N8c@#H z-KcnBH*?>+mMA@d@WZF(0OZjNZ_nSo{NKF1?(H+Yefh}>?fS)~yO-7nbvj_sfifMa zbnM?a`|xbllCLNK68>ZO57U2|hPi%d%mCOiZgh<2!!K#)FMm>Y4Z>UWRC}F1X3)pV z^syJd{blztc#DUsJ*+82jU9LGrwpZ2^YP}>!UC2A#p{C*{Ts;Ha{d+@(YN;rYd)(@ zw0oX04U$s5wVnZydIB0fYiQMaiWZ56R@1BmR~;`pYKv&GAy>4C_AUAe?Eb8wLC&7F zmz;Il=KkI60F+HT?9z(N7Tc;Zg@Cr{q&LwzL~hIZmOXTqE;Z$XCTdr!+#I8kz^S!G zUwxFdy+y}n+5b}_E4p)ztV26emj!u|U2Ln*L{FeTd@EaKz`h)(^*7Myy)wM-lhMM# zwc3z@Y}UGxbAnamyuZ`3j;wRerXAcxERsBEwYPlDW|_UMd!N-A_~)W81JT#Q*<@1- zXVdyF=bSC)$}*+Sx=zh~md(1dY-?0P{4k}iW~%x)OSSq0YF7JI)Q_|e>l6qLAf*%P zMre0M^jmrVttg?;U8H@qO9g!0Id=gIY6e%}-bqR=VepLpBW# z^Vb&eE*r1OJd_$DS4#03plaI;)!65x1dgRZW;44rm**^cLO`Ub!cFLR1@IENpbYWj zcurVJXuPEIeN9=hZ>Xwp1Zyiws-f+)oWj=587?8u%OrokB3a@Uxhz1PXv2yklY*xx zxO&IoX60KkRmxzKos|_4E7#z5WS^5XlbKBj@gzWEz0!=mj6OqW}NNntKBr-8} zEq1}=1W}AZ=@d*lDJ)^rMPSVGsp$Z|n^@5ll6Os7PGcyoa|v0{Oxp5I4g8@z+TQ;mp-QWbKA-IT>nA<{!Ku^w(UVq_XGEu zd;Ox$^%`7nnd_}^t_O}a$NG4|p>qL)3zWIQ_rA6V$+cu@_4%1XQumD+zOjP6(%!kz z^RTD*W4(RAXdfuBuxVS@{Y){a`v(mFK!L9KJ04`$vc*Z=-*5Q)3-mVV-d%8#uJ;RE z8h?CoQ+OQKdrum@C-u&g1@1*#$8W9|Pd)m$H1p`3-gVsQI{sDH=B=kkwvOmsXZ5yW zqiwjr5V?2O?i4SUR?0mmzFOJJ>HZPJKVogrbM(;%CE?M~=BcfZzn3II=mQb0LEZ zmAO!Lz12(LD0ttzbRXJAHpaILUU1&B@6=`h0K7VP+Tc!?xziQS`@-G1OJm) z+1CfJ&h;Byf0^qC+BeX)84wJ;+6@tKcZ!?xpl>~c7hLvlf6#G(v46)fFb-16AwUOR z3dz={{mR8~?Tjp{5NmezwyJyp807!~?F5hufE8H^xwcrhH!J>jxN}KaTuI>b$_yY# zPEhXv*tSy?RYBgo^;A$-x%I6eciws`$d$LA3UcPH=X-Y`&w=}xuJwg&yKSE>@7wmU T)bVZ90G($j@ZNiXrQH7j)68Rj literal 0 HcmV?d00001 diff --git a/utilities/deep-links/qr_code_generator/core.py b/utilities/deep-links/qr_code_generator/core.py new file mode 100644 index 0000000..10f3b62 --- /dev/null +++ b/utilities/deep-links/qr_code_generator/core.py @@ -0,0 +1,80 @@ +import qrcode +from PIL import Image +import json +import sys +import os + +BASE_URL = "beckn://ondc" + +DEFAULT_PARAMS = { + "context.action": "search" +} + + +# Generate deep link +def generate_deep_link(**kwargs): + params = DEFAULT_PARAMS.copy() + params.update(kwargs) + query_string = '&'.join([f"{k}={v}" for k, v in params.items()]) + # fallback_url = "https://google.com" + print(f"{BASE_URL}?{query_string}") + return f"{BASE_URL}?{query_string}" + +# Generate QR code with deep link embedded + +def generate_qr_code(deep_link, file_name="qr_code.png"): + """ + Generate a QR code from a given deep link. + + Parameters: + - deep_link (str): The deep link to encode in the QR code. + - file_name (str): The name of the file to save the QR code image. Default is "qr_code.png". + + Returns: + - None + """ + try: + + # load ONDC logo + logo_path = os.path.join(os.path.dirname(__file__), "logo.png") + + # Create QR code with deep link embedded + qr = qrcode.QRCode( + # version=1, + error_correction=qrcode.constants.ERROR_CORRECT_H, + box_size=10, + border=4, + ) + qr.add_data(deep_link) + qr.make(fit=True) + + img = qr.make_image(fill_color="black", back_color="white") + qr_img = img.convert("RGBA") + + # # Load the logo image + logo = Image.open(logo_path) + logo = logo.convert("RGBA") + + # taking base width + basewidth = 400 + + # adjust image size + wpercent = (basewidth/float(logo.size[0])) + hsize = int((float(logo.size[1])*float(wpercent))) + logo = logo.resize((basewidth, hsize), Image.LANCZOS) + + # # Calculate the position to center the logo on the QR code + logo_position = ((qr_img.size[0] - logo.size[0]) // 2, (qr_img.size[1] - logo.size[1]) // 2) + + # # Paste the logo onto the QR code + qr_img.paste(logo, logo_position, logo) + + + qr_img.save(file_name) + + except FileNotFoundError: + print(f"Logo file not found at: {logo_path}") + raise + except Exception as e: + print(f"Exception at: {e}") + raise \ No newline at end of file diff --git a/utilities/deep-links/qr_code_generator/logo.png b/utilities/deep-links/qr_code_generator/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5f98a832f3f2d3eda417d0cd07e59eb5c4cef896 GIT binary patch literal 47774 zcmb@t^+VI&7e78gK~%t(h)Ro;NGZtZRyq`@Lk+5C}x3sPI+;1R`n!fe7jD5Carp z!)|X7C;+7RR{Eod(H5G-!(g)Z=<{)qDg`N11Pcq(LcF)5g3KKz0vUxn3m?Z6UKBGb zK0A1PCwcKZSy#jSOjp7lh9nN`Psupk__`CV2iCI4l zdz*PI3vpLkxpv8)N~%$-y2jm14={Qgj47<)nK}!eB7!W}CfelN-p+R{9+@kxeT&tC zd)N4t9@@jB=8Z*f*rkGEdaC|hk2mQP$b2Y&o?`^SQJ(=Qf~!)86ygIzM6L&#H=-d~d$+jHs?nD}a4*N7)ZlRpD7iMg63ykT%CG+ix) zxGSzSs8gB;9KD=QEj<*3yKH3%--zFMNTVx1#e6FcJ{?EGB<2w}$*z0mZYx30rtV&(2s@m4Dbx zgt8TBp10;7*1T2ICpvh8thvfPv^ck-1xBP83#Cm1rjBdmp!AWd52YxquD zw=n;)%YnD?b;_ z%rd*?xiM8iO2mV)*ez~qY9>ZJKwGc)kRKj+gnJ4M1vnHC9S+;J6s_94`av?n&F!?W?yWBUA%R zw^7qHw$~0f3$pP{u4fEA$O; zMutgSE^GaYYwMSUXrw6WK480#a5vjwgnjdmNA^^0N92%{W1aqU|35S)sQ*E&C6hda z1d1+7m@-MepDn07+GGUHzDxz?fDS|~|CAoG!^@JTUk9|Z>S5WButYb)pc?_l-4K$p zz*hmS{dCMeF_(~==p5*Zw22!-RXacPf+qCy+%hlc{zrZ)l6_e-rSdhM@ewGpP#YRM z)xACa5SZ}HbQ5&+2EJY^Ll#yK8fng+8iy3lA-I7dsg4l>?0Yz}wvYC{6+!ml0QQTg zIJG5e3K#>Sl}L(F(|tBVezyZ){S!@deuFoPn$pQthQ}dRWV!^|x!j{?KQ3u*0c2MZ z`Y(~uJ)gan!puH`Hr}kA{0XlKn?oo9V^W19?d!uKt3#kB^`@zWBPb<695H2ahUB`J z1-<~eCWS(*<`G&qtZADdmoGr-2@Eq+2W`OC+nt z#nrOu6Dfi=io0wwtWi^dQ`u4D(tlSWjZ=UA19>%Z!TYzS#Q^35X^~fS#RA$`>tH5k z&;i5R;kFh$<_P)>7(2T|f8S4@Gj~Y{m;zUU<7N?|0D0rLD@e!ydmG*qW+n^TI2^Fs zeG32Y2+9nMc~R3J_^NW|FL?l)h;Coxgz8-2W`SBl$d4SR?&<|gfi_ABA=krxa3G>m z6l^i$w1f4;exQIa!VvaZM8=JLQ`h(It#8481fVyAc6U5lFK?<|0D}yPOZ^??OoHtE z0qiRL2+9HQK1_a_D8^es3t|f0ksgI>n8v~IOMT1=K_xbW>Ogv z==H-yF(N7X;?bsVKlp9H1i>+axjXR2sWvju$m;=~QT7=`%Z(AAL|&YSOgTU+h(Q~= z$QlV#6fv+6+21!zwq)Qk&}e{6w|00me+0crq#`Ng9p%#{4nklekSkyHa0lb|v^hX` zC8YNtoA4TWGa& z0Xqo=ZsnJ$K%x%-kF`%)KrE)R?}4J9ia{i+jFG^Cjwp!~omFc`2+R*zikpAb}p{(547Mu(28524a09Wt(M1t-~b6(5?Rb7{tX>7 z0m!TPC4fL9fINcTe72#%jS>(76go)5Ikz%zs8G_SC!jMv83525v?06qK+kRwfdUrQ zNJNuvMjlAt^gS(c4*-xv+^+F6Ilg}b5#>85P(Z+A7FVHNe+=fXxWij z0wImygI`y90~&y2(%z>B(Ie{y?5gQCg{#lB0Cr^0Z$4Xn1oxf#a~l+Jq%bBjxN{SC zv>XY0XYG`JFaSQ04mS7_3XB70w$Q8 z4I{P|fsHk??Z42at31S7AvxsfIXy-p=1@_w17PZB2FGXG%A1_abga~U_hvx>xk3Ww_r-Zo5GUu zvmEp?5Z-^ACQHna)2U~K0Dy}Wu(>b!QTOL0W(P=s*-;~bZ7oL|fL%sgVB`}(y@V7A0cNVCQXX*n;1d&ke>?LIkPKhj zUoqG6!KHx!_)0ecPCEi?(-IH9n%)`(9PsTiM+yS7jTF+ZRw44+F*mdUifsm9VZHvd zKVr98onZ!OXW0g(96;05k_0~c3OgnNWmBY?90MpAxn~`B9fLk30BtM}FiA^Rc(VZ} zx7Rdg{dD_fdj`}+XX}x#FdU#&JRW>x1FHvi=b=%(H#@)5B{p zEMa(?c4`AT)s6%BA}nkoYP>lBPNtd|_4-tx`diQGB9m^|q|#1)Khzro@+YM0U=TMe z4#0@zmHlFH&5^z;J+R!oiqHzQJ^-Ddu`XXE8mOvL-_fSW+5l7nYHYIdwJhA70nMKh zAdI!%0N4~>%~fD(kV1ftTEQ)b8r z^p-(rZ$O;jNWq0TQW;1ryR~y4 z*vNytTSmZVQvi5L8d40i0!A~~-U)F7WzJBYcGq~j{Duq7xSe_P83V>p*5J1yZ@wEw zPQ6D80y@-wMjZPgX>YW-l%mrBOV~#WyqglccYXnm^*@3Ffd|%m!(`4Ws~&li0-dib z|3{IUvy&{QsuBGkEdf$E-$HX!P3&tlw|8z_9CU#pZVZ=7+j>&-Z)@m=7NM7L_!(&h zXoHOri~hE40(6{5)O+6qjN~ibIc=TjO%!2FrjMTjeR*z#TMgPCu&KkNeFqKjlGPMv z=B(C>0^O9tQzM{OF#y#AqDcF18I}YffOMSz84d{797?0`NK*1DN`9)TVw0JVL# z-lxk;un_nNK;{HC>kFWYE*v~8IfH%#?6Ic+)^7kA1RjFJ*a0iVyIvye0YO4FHkpp@ z9{|nE7g6YCU}L|dU1LE8-=KEg4cQH_Je}iGpTy78-^dX%f>UlA0XgAk&4)!xcXeQ% z8QT2V3-}x+MP1gC&t(9O+<~t5mLI@$CQNYRjD+6E!Vx0Zi9jRkHo-pgJIO$ly3=fr zeE^m>_K{g5C6%IVKuGrpfiAR#5y%h9w9C1$`kUR~h1y!A07+%#seZ1|4n%VRE+b;> zj{SkDEcV|}6-X9fqFXC83P>6oE+K;m;NzaeBqU3rr+ z!oVG<8T5Yu4I(&W224AN0hwn*pk@?pj%B^BFOynS+3)M? z^i$-a=G2%?==aZUGNVHTW>W32JGbn?-F=5sJ@06O!Z**!=(3pn^^Ko< zw$dcZlUj zv3@48=rUAZ6644{;6k|1j_HfjI-OJ#BKB$^gkK%a-1wLSGfGYjPl(?%QLm>JnX6i(Y?J?55d=8m+x%MGh+03*wuUE zP2;LpHZ$`7-eX_8rm)W6->$rII1ya;WLu2{ME`r>sKC1ekDrn`#eQSP2fqtn#fLWH z5oGW9?2U^l!BK28jloA$BrCD3om&&V~HB#kKSzrF90-w@ip&+wu&(UG@j5|qxNQ~n|*)`XtmX-m7d z_Z9%ns65r}eOM9@Arnit{YwFSeS*CC%*G|(ZvLh76t>uTbj$U$@8FH_W`g-9Li*%~ z4!KYvjZ&Ur+<3q2kf%S1dQbdyY8tgTlMU!Cw<1ELC&LzqnA z{bv|tfz7yVEqneQy$Z@^p0LHIrTmML&W+2*C@bPai%Bf}3e@|8Ylp~t-5r4&B4gzQ zKVF9Dd+X+kkWjt5_L54+MMdQaqTr;yuax{N@ucDA&bA3B&`5^kQ_oH}{B9&4H6N2K zv3evO(U$s%S$ZJ2Vd(!;>fO2H1RD8ofLKS}k#`hCr-v8gt{t1b->*eolEC?dF)@&L zCy7@@Eg>PCXmF?sMz#N@AkSmPOp`y|Fq_xdRk!XjG3!TK|6|+z>p7=i?CZmlTXcdK z#VNB@61;!tuJ0c_9N&I@(*s34kKfc&hLV<`R9y~VZas7`1HvQx3gzVDw0 z3xKjj1-NqvD@e<$$4XW-`JK(%eyLCkbI4vbm+RJ9-zmR8EnGdn)|jeHx#FG}w!)5k z(vz*I=iITvb&73z-YZb3suX=qF+xza^*^28z}4!rXflw9QubPr7?Pil$PU~LN!40S zH=cggO>$lWUF9vkXR)hHveIm0Q+1~B>6Xbpoja9IKO&K;=Sy$OO%Bp5R2__Ua7c5lFP%BXUP1 z$ZEjl*VRS*ah&P9(8&E3m|mv2c1YgKkJ$7x>x(+V(}}z{o01}WJn0!c#jBH_lb*P< z?x(93wZPs5@?)Wi{QlOEL?3Ify8F~wI|IbPe|0`bgLJ~{@J@V+aHI3jMKDr=VzS=f zcj-U9)a|%zmu4sTYsUccV|{Nfpd>`)MA!wPX8~lT zQCg5|o(Ne&e|5>qSYwJae#U&=<4+(jeKY|?_RR^oKeyIdlw!g-JALdq_=z&?om)Lu zFgQ(@H6e5*)#5Z}SM;^!m6bzebK0^CxRq~72>Ft0od3cZefIEluutYRr4@%bz=x?) z@kw?T5=i`djoR2gnlrm;=Wp46vQje7)dX#P6iB@*xN^Fh84-%lFD6;Nr#ZHguE>GU zy)Ep#fA;+Jq~`u+VfzX5vc}3N_dDlb)3s^xDZ9w}H!Ra|E~muT6f{{(>%2nG9j&~W z3njjJVr+faKlw*g?`g#tX@8tn)T_|$sGQd)YDv=j$-skibc%c#B3`vEVKQ751Nmlo$HCf^k8M2D%>zdg=#@z59JKke1+jlE5=TnKNdawFDRfQ#K*VYRnqTHHAY$Z3J9<9CC$`PSP zB2*;AIkbo)6=O8J3VX+q{TV5fmMGlXdSkg-srElxXgc3?+I8C(*-YEh%Ws6jHb28K zpEvO-)U$ZCI*f4m=X;EV-KMP}1?gG$TsUH;U!JeC)}_}Y87VK>cHs&y)aT4@+RjXH zMGH(`_AeiiG^MUgt=q#p(~4Sd@JHvJv8BPs16A3Y=XZUpP;IpJ8sB|l^=P8Y@Y(yX zSp#XT*cY?O@q=Tk{P!#+`_ zi}QC2Q)!Y(+S*(C84qH=p1Msk672m;_~hHtTT&A9MqQU&drIk>5u1*6O21ITPe;)r zOw#?!WFP;C`0#(}nCpKc`wcPOf|#Kb%m>#%vZG|6xeF;6#D4sG!NfrNg0DGhAn2sC zR-=TdjgJ1l!$5ItK1u)TAo?BtU!qu}uT6mgzdg$5y4KLScuIKKEZ{3>;LYI(}*q#d_)*x6_7Jxa}$M*B70MHu6#TgJ}9%lUWzZCQs?zCkL z*C_6FDRkH&v3b0exp6Lsxz=m(`E0z*hl4H-H~LDcjYj+Kr~2r*%%1Q^zd|!jGX(e2{|Hq(Mt)%#SH5;YL?m>I9vSn$b8Cm z-6{Q>>Pm~V{p2Nh%8VIlZdLp!LKd<-%Mxf1$CPSDlT--1mb5xmH-lazC``w6-Mb zG*Z0o=4pk^a#R0~`G%3@A47(s7{l9sDOE__@{ANNoz_<6)`N+)vk_a{Um2VkZO}fl zHhYf!%C*;W*1s41@#xak{V2!yQX>qv;IMMc?_P^oBW>=*e?2_)FsF^XmW{^|`xJc@ z=hMBO!ww1E+UAOxh2Cljad%WeSIbof)c7C7v+VA2eFpvx$Cb*O!*cyC^!jXNtre)# zv1j`Jn;#FFgxztL_ z4w3!MIHM%xI*+==4^~pGMZFtuSldsPl2|rL@cFD3>0>8XcX5)z?0or8MlY4tX-I#I zY+5d|vR<;`$+ug^)drVEE7lu^35@an+a17RM_@F(LET6>c342VX?@E!=G7rvG554RS4zmV@UBWyu#I7@4;5;J0;<=6x9QgyyzOpo zAI7=_#(|abvb?ajd@n}hbNuLJWzl_X^Rs922uy}9Z9 z`$FY(@q(+-xz|)LR&O;VVcCy%Fb9s>6Gm)pJkY7Zj=1GJ#gK7fq5z8R#n;n>7qaARiD!7 zd-CLQ-)4RKTU zqT?={d{DAQ)Xl|`?p#CcmReZ38L|0VL+x{8-Nb@~etH@o$?F+5vJ6i12I67L`PbF+ zqi%mQI4v4d?59N5V_W5w-$r0M6o6HyeWE_8S(bZ_=kCZuslBF86F&cej({U_`{krMbi=VW85V=(x zK%QX!zc4Gz)r3JOXEN?*45z#+7X3%p*|he)aiL}-+Q)7}jv6-a%x*Hb#6N1AOnd-T zi8%fpeP(|z&UaGdy*Fvrud>A5LdE#b31;K!3MFna9wsR| zEkE5;yDY92)~+ZK!{4J}#vqKBCvWqe)YfzXKvp>sFr6`w!_gK^qa>~?nyU~pd}3?S zfy5MO=49NvNQ7L0<*k*V1P1Ci!*`p2)Z9`-R3WZB|F=ql$LNd1j#*m$I}8I^MO6RG=^Pd&=)GT@ zsms=!<%gj;U7hgdvr^A-FPoyA4`23r3_rPGyIXX*!{8D_eX8Z@ z*|?=L$5gN0tjFW2E4$l(>RSq0=&9_4Ed6jhJCTh06Dyiu&LxYJJleBdUr%yR=-XVT zP`aKjqXu5uLbeNm=|qq7`~OT+^j;4Q#x!mk72lb1?PL5R^3BsB^Pfmc24(DbZBO%P zWTTed?=WN0M@Z>LG=UIXTixdCPcjH!)Z%drE5qqB7_s$&Otf%KX#uAYwOb|Lb#t1w z?wm6R&`4gbII;K~wIC#_sMhFRTkYCVA8K4baJ_xtta%PZ} zs+WTCGE+tGwGpB8zIlXs@Fd>3@3x?0irtf)@<5-Ehz}5HX^a$xQ zZb$Bet3OQ5j`Od6rO$W%MJsG6F`7Jk%zOp$bjnhfI8&a;JlE~Q5}unyz}Yy0TEt0a&~r_>%0af0=FVD5j-HjsuyPP zXaUSLXp){8xZ{6O49735`EcxpdZRzL8!`l#S@~ccagvW===XH&3w3!rvj$v~Qz5>p z_8GSxW0H38p5HqezE8AW^@_RWY*ythzT5IAfe+wr=<;2eU+I^?U`o82xc-Y z*EeMGR+c5Ly{MBzJtjH0KI?`j@VOfCOHadR^o#`$zyd@IiJ*lgDzeVXK!~INj(Aja z>|>`P`t&dU$r}WH+nP#{KAi|^shX$CJb-yB>m!hbCqbvha|VZ1!U zxs*8EU@`W%hB5NCg6I92%uF68Z!VgW9PTjSN8}pK-qq2)z>5Z!)LTCYKm!|)F5vhV zY1`3uva?_dpM|5>>d-+`Hz-XCJ8)N@zfG0>cE zEM|w=i>KNdAX9B7Z#Pq+CclLSPyl~q+&bWKoUP+T78 zZ{)=XQY|V$-CC!LW{6({%kb<($%hSlz>;ra#_SK|dD+e7WSkC!mX_l9R^4fWDB{x$ z`>~Q*^{<7+6gzPUu&22~GwU#{vAX@}bDP6%1X}=)6J^$L%71l>1@)3mznFRR zh*_qs5{u@InQGeDw<~WVCrdji09%*oer?8{Mci6{{G@+6>-<^Oim;m0*0#masP|uV z>B?Un_nwYCjdkc4gBr*vdM(7T`e62!G0?CmQ~IE>4j`E9?ru1^$I+6tH*DZ8Y0W;+ zF#lwG+yb}Ts@|G7R+6onk4uM}GhTWx5!@YS?Eb{sosvrsgaoSY zfZ68dbU8=jNA-peyErAbt^AKuJvhO%U0U|7E>6LfruO3o0wJ|K+g0C4kz|Qd^T(Tq zjjQ<0e1?>`O?NOzw$#u*N&qOXPv?plszslOL<+CDw-Cb-VvW6eM+?&(2wETc)a8ua zX%xR@c$oqs`e;iLC{1KE0jk*o)opCMsTRXAW&zB!CXMymd^k}VUS2-(x1A1Qb~t8`zsS6c=(mxeA07A)u)Q~C{- zRnYq^-!?ghUD`x1yt0$QRZ7j9$j!8%ipRRYJqdt1*9%YwTp!>WS%kS8N4XHDt%%Uj z(Ae16=lQI^H4N#UgQ`3+J}uV~q2m_&<%19J$`6y$-Bl1;H6+EZm);|xO{Zvh>#ufI zLU0nYmMDd^KxL(D*LFJk-WiI|@$y8^eNsf+ci-GAT;r$To9vOS*XirM_cvr=S<4O- zN!GCkZnu4;f-IsLyy!w9t_h>=8*hy6Vw0MsG7f&`vNX-lOeiZE0);$YL-;5ND_p}f{s`GGc!M{TsYJOtKxhjglC3FsP#6l!TqMihx z^GDbgn$k=fMP<9;;oyJW_R&jceiUUrG3oe#kO7YOkZac_!(7l-qPJKDJxnzvo7Njm z-lUo!PP7$jb~r` zSGTzxh51{+`>*ut>|&;kvYu%c4n`kh1r=awgAr6ggRk4&?Ku(%jn~s<=Pe~<15w%z=nt%&i!UAM zoYG2XKy=>5%~ioRNm_4KroxT(4I*zFYqDKr*3B$$c^T4~KiPoI{ohU5w>1=cG`htZ zE)Lusj!Fw3?sTVJ){~RA76e=%}1G>o-!vF7}d$@ z&r{(&!S*Vgiz8B02FWx--U8b^_p#P!YA!JjR=RA39S#4Sjo;ZLlAyk_3_M8Fni2ZL zfcWI@4X!t{3IOtlBY5)Xx69-@A0HI~;dAJs5mO;IzQ@=5a)^`oT$YV7I1p&cJ%Jz{X3ZdAF06cp0OY za^oT=pTc!CpRX<+D><(m%}kh4d7o2Z?N!lF3jHqC>P|YztXu|(b=s+-zB$gRvo?6w z(ZM6O=F(HsUh0T>RbE^*Ld_3{5;W-Vf=`4x(`jrry>a~mdM+%?ocghv8mpJ9oQFqt zWS#dc=8xz#3=Fv1|Gm#$4l&D*4`0E*3%B^wAluymr}aQD`(lA3$R28R7R?q#P^a99 z7v`^CxwLaEWC*rpIBhXN`MCP!95~va2&{(bpFcG@mN-8#77URi+6%bNKz&gsA7-1f z>=4d7;mpIV921VcWZzh=xJ@`XA zN#nQ8`*7}`tM>qK{Z>Cte29W|%bbVU{xkQqE%rI=9pt;HqsnO7OrZ3t4MW!%$k}>a zZUkdjT%zpbmAmYc(w-FbYC>HsIugZFngukL1+3LxF{=r$ z(}Paz>VQ8~sKxhP_?GrIParsFx@9>-sFyHQwU_vftZkWNW&Ot@$Fe(>;=Ala{&94EFUT%@aRy+u1nYLuZpVFd??+s%A*%qW#6qP?7Z^j zqJCqf+(+lGIM@+qZz6#H$y}E8iS5h!jcn?D;7L zH>hkfARgqgrE}2NfPuhNv|eV)MC%~3oZz(t;Xqhk7}_OCt4~0`*%@P$C6@LudU}kA z4?OtseHX*G385BT=p&R^4TfFN;jnL7Tf49LJ9E27Mc6b!gk=&sTmL`G5Hrl;D-gwG zn{PJ*8LIs#E0c^Y-7yMy^9x9B*?u*w%)w1 zkWi+Ih%TI_PwZ#giF0AVykJhJUaA{5K@y-t7SGnv_TNj#sJ=MXK~8a#m;bHoCdhVC7?^mjz_-biJ74Zl2H z@t^7y7(eR0Pu3z#LpQh%Mt0R%-LdNOXM5@`pkgoaH_m&pKN=xkpYQk8HFte1h);St z#K;A0(3B%s7q)T9jzOte?(mGYja6MsH&dHXdZ|8u?R@76b$H|)rFki5|1IRthnNRG zKaH+O^~24ftr)$Z=qjrz@wrCEB_$wGRa4(UmrE#8rvN0H*n)EF|LQT#>p{tN&rOz$Fd98zw ztb=MOOnZ+IAxdeVxvof)ikn*=2RVRgt0jqmpVS;B1D%;eA(?GDx^e_;2}*!GjQ%d~ z7-yQ%fZf-lu#YxYn`2hiP;z@V+sO2L;MaoWVDVDT=Uj6(0D#P;4O0{ zb|%tz0OZKnaGq#ohE}OHo~-5ctD>R?-L;`Kc3MG)$63Sdw?p6YnN889@Ewxron4(* zxnm@(PF>){oZh6aWdVM^1E*fsn3rT7{CpM_r1h17_3h3Z8~2@*qpl-3`0t5X%Y+%A z3Ka0Z0`&O(_4F%6Sqx6HD3-|uK8s1YJ%$_9<_fQ~3dlV^oStVEIPtU53l*!xaFTG! zz(s!La33XT_lJB$7*sWBNL1yCd6iYr`V1bL)vJ&0dUrc8(i*vyfBwIbZ~R~6>!(P7 zyWxs??KgLWwz>Jwy}pHYeFvVb0%mwXIPcbMNCADVTS&L z5VTo9MnuKVx6G@JMTHb>Wq)?Ya^T_Xtoh{iTe!7f_u68}DxRl(YMiDGU09AMMeT4^ zAnE4fXAQ7vK!5#J^ezhq8p&OorFsn21eHq?3wd3JUWz{lO;1dGk#x&Hu{7pgB-Q!i ze$G`4E`0aR&#alogd%Sz={2tT1uu`6T&DlI;%uvbDL;{&%r41%ooJdVy>Ki$E!ZK( zX5322(y|~#hTAyEF?m?K-1u0STHIN8GfLGeKYozmm>;$(; zBy;SA$0Ed9^yF%mlV?3FI&e0}WwFNU7+!4EOV$TFnI@kS{nxa^R#qeASJHSL;{K~g zxPlj}vK;MZ2|Q+6pje`c#zkw61H;nQ=E8a*rfT6m!rkceX%W-fTIDRDdwR1AE&&qJ zMKSQCu=YD&KG#UCe}MJZ$0R1}6Y`b(C~;m8t$b-|9-B?hiRGnQv*wk$Pg<9vy=P)I ze+}}x%L}?#lV{JaHctIAqQ-IhetxY3Y4uW5<@3+JKSpt41?`-`zim0!(=k+&_>J`w_z98H?g*!BC-edP)y{;L4&6 zxG3K6C8}w?@N4{`cuyhbD$}+5bM2buSw}6OsOXC%L}~2Oe*eEt#O%AXETj)`Emwbw zmOIw+f7M%iE}hs`AnT2jfn~NKby^^_57HM0Y3vG=NpO~rW91912K zr!6@Uyxd;Y7p1f6u7JSLugihz)2Xf1BYHtzVta%Y-e=4% z7YKTwCy5BUIY@2oX3GoqJFXQfHnFc#(L^nhaA~A~lMJ$13V>P{< zzWz>_j+gLz?9WLCJuj9Qt&w6TjS&NOr-9#SPA4r9KMdZp$sTy7?xt<7CS!O$U6s6P zWAFw*XkYW%cWy`9TD*F1V)17H<(+x&xo1eVX%qL(AX(=IzKI>ZtVr`J8Q8np3-gZ5 zWd_{V&{Znda%vjb2ohJ*Esn`4^ix=!AM>oNS3SZ;X%Bfp6s?lZ_bXE1wVn3LH}`Bm ziGl9K15(wTq_=t@-A1m9&Z#Fc*{6y;w-~-=8RJX<01bavJ+N&dIt>Wu_PIleP0#Swwr6 zo4B*hkk`UrSh1ZPx_Wwe7k^C65BbBIYG3h)S^-~rx2kdc!re%Ox|17IlaQf*0*wfT3^HJL1*Hpg} z!=HjACe=UcdW_fYdMqu`_G?f^e1h^}IW=$XE8Sa%5v!wlq$H;|aurYdJH>Ex z-D4Gtv^b$BldS+sz!rj|`n*~ci=`u?W51XhCWa5^5NOm8nMZI-UIKuo72T>HEG z;Jt^sURhHuYN6xPZxi3ir{uSVN6{r#RaKc$Jm|bIg?_G6FZU5tHxhlnl-^V*fH8Dw z=oqs@T;Q5Jhj@k}WbE(tk+rC$%&%z#AJj~gunough^?)=sFbLyCDQ}B;*b4yanwSp z{@T{jMgB48%JzauS|+7e3wEm#_=yr)j&@w~f1sf@wJ(srIzP2{mLb`?64SumB10wp zSme=n8LUz{=VxQ!U#{k;S85gak`H!aM6O>8Sd^!ILlc~N5O|#ULRZddN{%0&Y^m!E z-}*x<07^?S7ToRHA+!&lmphCuju@SLFiRjpV@Df`UY-D5o-jq($D}1%_6_+UCTjL| z$Lef9gJ9scD&V!@U%V_vAh6`sX)DC@eJ4(yEl&|O%HfPI>9ACnxA1f9Xb+gsT2V0c zgyqQ)>_5g{Ms{81hBiVAiMJhjMV=E0IQgv&(xqhn`)nDq-0U4UP}#K4?~C6|ndQqS zW16{TQuveBRG2^)hdR6LSibsP#IfiEH>l|w-)%geRVCYZFC081GwJi0PJjL7qkhGV`dnmh^V`nL0_M|dQK%z^ zuHhH=3IQG&{J*f_gcZv4r_AOOIx09oqG1aW*$@cZi_Ef|y))|b{FfdVWZ4ftr0}v_ zr)K@VW$4b)033mq{q=#QtIxb+%z3SwzLUN$#NbX^qldRkluDa5rZk_gB1jZHhgt@2 zo6M)uh}h=(?9IaYuBE=7sJySra%H#m21RNUatDHq1u5S!&S|r;qY__Ub{F*SRu<#` zX7a6L=coo;UXV}p4bm#F#B-$ZNd>RZI=g9Jvml2iUMcF zYCTfk6!Nh=;qCcq_l=5u1FQu*al?ji%;Faa97~5t?K<#9c>(Fo*$4j*Q(qa-))s6X z+^x7qJ zK3V#1UH`O923OJi*g4&!RBHx%v1iXr*EqxS+$=`=$vH&i7CJ7zYGa;Z?#0xQm7czq zYfMMj{#z+xec=V*e+8vIne5J~YXn(v{5a|27geyi{%&AQVjt^2_kUIES5{9Xkd<}N zdaGNb0gqMNPrQdymAyz2#3hVQE54;M*i{&Qr}P^8km?k-b+Xyx4MK)BKHUW8*-_S; zW~3u?EdM`n&~hAy5ghR|s#jCUz!{~BULhIY-g531dUili7t;BihB7^k-uzZ8lHWnu z)*?viI!m2;*{kWBaVO^MiUCuJVjNkF-#)3p)%>z9mzpzHB%2%sADu!+?R(>WYosIV zNb~gFxXlUhuxzn({B~ogle#66u{D$fD{qNauzZU?x(_0Y9#l7E(5|={qVjsEN9lGH zxLt(bYO!=3f$pg!@*gJ567L~DoBw|pF}11Z?~T0~Dq`H5*w?0AX?a>s=LGsC3)gd2 zPj9s_aONMTD?PZHfzyodUJoc9kF#FyD7Z<5mYKXx- zAcmRve3S70F9A1}!BQsElMEDM8IQ)aM5hR6t?lp_$mjZ;rzS33X>DdJv106t^7 zda(E0!W#icgEH_Uz<(hu^lI&l3&XE+HEhHZHbX$HT2~Gmz4UEHUsbW1;l7qy|171~PknRM_-(YUj)V#!k1Wz7w+2(aL{$Eao4AYXnOF@&73 zh4U>Yw2|p;dLBKOTkgce9=w-dtp$(?+$0L2oftL!%+lSI-+Z=u8xAd*1VMckQ1-nkFYk z5{s7U9r*8glrnONf2go>4xXkooN36q992jcanaGfds%4;FrF%TyZXOW$R8S4mSf-L zRXA9Jax$5ES6UwH{n}5=?XeVolk%w?+0egVe|CyM2L@RF@!o2q+ozJQdGFudRSqR`Q!HbnbWa0L#@?)&@*7D@ zR=Yh#6rtHE`*=ykq#ee^% z0fAM^Zxm#wB4izLlei$Bt+QOAHeM53`T0Y86f1Rqv`a1yuG&xu!NiN;es`8@FD_Km zC5Yd_Dyhm^?a39=!*xi>Fh$Wk_TAcR@xbQUq*C@fbI;gI0bTU}Zb|jY9H$c*dcZ-l z<}hLI3QMoE^XAn7F3+C;@R!CqzTVmWFM%|ip*ySsnq2oy_%|hDT&7LD(7w2?!9l={ zc~y2Y3;ve@1?_dfNyIV%<)i(4mnumxA%&|amSJn9AZE$CA!ZuDBn6suzUy^A#N#c(L%wSSEc^8-E*Gz8Aj2oQ0 zdEf&3xzpwF6t%005hDRhaob+NiBpK>*NtM> z8iCV9(SguMf3^Ak%=Y|2F0nkglS?RW8Y+{{411)=dXIE_}?YRy$|Cn+L zjq&ccMRoG3iWF!MiMH3tczP?VlNF^C5WS-lzvM%- zlQ%DDJ8lBK#?MF-_uE)Yb|=42F1n9}dH{C3@gQHPtCfE?My(>%1_4U<4UB-R-^H&u z*JB}K*P4pfUX{Js0>IiYK~X^FYYK{`T#-02uw3KC&+NOuhgC$D5UbKe_P4i-tP|gr zd;$-CudTESGGZ+VZhKwCJVJ*j21|w&{6_jnt+`7V%BC5vpEghhTwEXFE}97r1cbyB z{C8{GGmhL+8rl*pIy5HF*ix}-bC!PS~T2* z)1c=sN2T=ZmmJSYCLasU`1)Q)=k3|g*Y{-x#81_G6Ia&OyXB8Gq$UF5OJqn6Uk%F@ z)5r@v779r%0;(2Y@ZzBT*!h`*G}n|5vevS^hmtdvk87p@pOBK4m9__{B}bnicpUvAM;WbaztinkfnLsr7K?FO3fuGG zTZPwD%ppL)8VvLR9*plgi?gVvBy{&HSW4!oP;9C)QTnnDFJBz>;;QYHW*4bV510o! znqqXR*m98balQ#AwAK=U0kYG`XhB08?m%I=HS z^^b0D+?`5ui`w3AH#eUuxUqN9Zi)Ur1fvAw5VlP+e@~H5CsCJ?c7-@tb^|)a?`M|8 zvSfUMzTk)ECORkJ7j0Sd@;YXvML#tFh2=A3$FD{V_b+~iq1eI_n_jcq(CLJTOq0g4 zG0v_8KFqF&2d6(i_J0y$xc^ifc=3=!2NG)15j-WUTVA8c6ZfXiYP%;+9VbrF=oy9! zz#|}Ax0P3*vo4^i+#K$+r=?DnVG0AS(FXf7?**p+LvR*9t7cV3Dw~+mH^$A(Oge@H zpav*xq!Yx3lkq}4dv!_x}N*)zLuC|)g1Z-VXaD$B% zs=mV-$6Y_Ju1vZN;eMZ-5TSwN`JKbbtsPif@G-^W(L%meC9tl&EB%2t(KusZ?dI~a<3afgI^^{Ph~!VY>~RY` znz374<-cw1i}H&}`aSSKCe*b1UU}#4no!8aKy*;o@3gU5p}a}DylEv_OYcVhhE3J* zht|)x(b92tC%`*ISa_5Wc)9F5QNrI_7iIw1x5xz9uPU%k67_=g|U&2)$GC|Pt%V| zI&Xm<{EU^wnw$NRh%N1JVk*GP&DBGPu|ENrTrdRi7kvUp&ag^>hh&ED8jssJltT7s zKf^7ry-f$%t@SV$!xDYao3LSZ(u<0ovoM z0SO4W8`by9jNEa&PE8su%>2Sn61JX>*wfdh4ZBzZq#VsuFd20kV3Uj8k6k43Eq+s1 zj?^tE7|sfwS^&T<)f*6Y%uvOes?veIWSKyAhHZ+jdst*<21-KD^HIJe zN0p=@(MzBkc&-h(?tl8iW%d=C_2DYS>O`E(U zEov?dGnB7iYbU>6JA!NDmbtd)MVRYBCFh!L2M?#O+X@`}UVcq+9WD(LzA1yK(?XuW z8VrQ1o8NKLJU(vJA{~v9Im#6!Z}c~}du6b3I1c3DL~6@_44`}wR7Re5(N};Tl~wcg zwkEC|vcqH&(9km%dR}g#xjy_RoMU{W&3`T^0SJ0A5ddm0kZ|}3_g$WS=Yvc|$&kQJ zRA(xq0YkZRbPhhiy38GPQQsSK;!y8#JXj`(@gR|<>J{r8y zZ%i1E$g{zNv_3o(rc?EtXN%f@j`*gT195-e_dha9yk~D!TU7W6Q;l>#{}L|7yiF1d zKwJt)Yz*ya;7+Bd7D(X~Y5?CG-65MNBS2&l7>HvR@>z&05;%Yh30zR?BXeeL~TTO;|TJDf!xrC(nKXg@B=>lN0s# zh_KX?NNA_v<$xj{&&uCy3;WYZ&4kmN(y7zUSoqVOx$g?urM0I*B>)M8A>L0ASjb|U zJd@)sWmQG!ji40p$Fd=KWF8Sx(pv=1PSR`;Zj2h~uQU0|X|m4HM1YE8fA);=HW-+T z0`rszm)y|#_JTK*OB%mvI#(PZIfjZOY^9wngsw-}8n6T>OIo@lT65jEmMmO)Cr$(n zV)~s(#6x~xw0`)6%F3jU&i&SeJdFOc+`t@)pc@+2j!#T|1E3?d9UCTn18}Bf3(vM? zGtyEfVAQEwR?Ua2HYYV~gS0Pi^B3 zV@3Ys)f-L!;K94)dlHgnLD_hiiF!nKDUS=FLgOho9Bz-t%CMs$NI+A`dXyZvZzS{n zu?(Fw;Ndf!(wc_UUF6Nn4;__Cac{?7lmYqI{wlR=#VK)Q6I*BuaoZS9jjAye?w-5r+!K#V%}RZz^P=m(zuWXV)gvZt2nYeAA_d!-_d*bFa~eFfqnl8 z$@48ucmXzP+LiUuiFXE1xfd);8e3o-{UBh{g`qct=E!bk7&g}>-uDfQ;nuA!1(wr0 zSRI(|yR$|;$h|!N{s||ed$nI*)tjz}%PyUWNll^#)Tja1hZn&B&r?=Ck9z7qUumdO zOvVsc4&X2o096DB5N_3F9xF?N=L;R%PupW@vUfLlXi9pi%m^3DGb!JC65~wdX%vgX z9zxG`lVo2>)TJ$1_a!hWra?UfkXYGO)?Y3#b2QAh^mlO;N~Gt|c7q({PC#zNMGumoL-p!U4~1dR_c+$@A43)cIg zpQ}^7I97uykfk7ge;|2E(rpKro(GpMA4rFA;Q*aBrFl;T6Z=+26t)F1%dzF2U7d_^~3GUjZFn`Y1rx%0!Ztr>}HKcwOBYvVd2P()2QNIF+S= zHIK2mM=Ge_(Q#d*LU|;e^V7CangI*_>mLVm0RvB+FI?ixm&XBEI8Sy3Lhula{7ufT zXN6#oQe)~V!HczA7Q5mg;ZGlNYYg`gB8VmPL^ceYyTXxg!z3STqef>fZvT8j)&ulj zGjoeFll}%&*`5AWah^zly*G|e`7P1~ktg{W!Fy*1r=*iaI|yTpJ-E8LYGT}xeReZ; z^Vn0gRjkI;;4!mF##BWjn_OdZ|P z-u4N3iv_X@l>VW%xnYg$o`h{RY4FQ40fs;e5oTr3>#0_tK8oIn=?AR0QZetZI{p5a zAh)Uv`l`v2gp=w#IJ)@AaPdd{E(+7t)I04!iV#4KTX{N#=t>g&sO;9QQ55HAwxB zk8VdUkhl0JQ%5ep6{5H&B(nNI(#=|p6+-4yhikhi#L32pObpi$%|oe!#Y3@4RTu3+ z_WE2lPc)Nc-CVTbn;dK#$M$Nrz*>h3$-IE@^AGSG@0<_wCLP9;R=q!a(2MvKXK|5a zU+D!Kh1m4imn@xCIWRxZZaN3jOH#9TIC@xnob9$< z0D=yr=;AgF6paP-7zYh9@k~E~=z^)eC2_irxG(SW4fh(}&J%F_StEyayhhy$Bo^-4 zIZxej(3m>eTpi;G)G7Lp+lv0W4G!k1GMQ1dfDbPe5U2>Xdq;jqbYx&YKlCIU(Kf;l zQfQ(?*Bf%*Z{LjMZGmjE^=41lctb)=K<&@Q*Noet<4ay-6K?hz9lpzTFb+fTcK#-H z*y$tx{*(wa*I|wqH%Lq+dAiKL(Y>W0{EFq&oue~--?*{_%XzrOPs>W~{Jh$%ymUlm zz-p{zHT4^U^@!e~q)@cY*or^oZZ=uN;u!f}B=Ry$9x1?1yH-)^W_`AiEB3wG51uxV zx!AS7d@d?5Ehaf=nHX251$V79+>PSKz65v%Ur@_{V@oq#MuaG{t)`r+deh8 zsV$ZH1bfULy!3k;g-NtY7O>CYQ3oH;En+@m+t4DTOf-8=u_qAvd^aO57FWwL=Ds|x zjbi4K$pRp~PJC6>YElc4nNq3vH>_frMm7 zK~|DN>C!B{F{CE~rMP#KNrZN`YZ=0=LFS@B|I+xAG?JkNwa}6mER-Af^98e3FLmm1 zx!N${)4317utO-9%La-1oNHj0>?HuN4=?h9pJwPOTkqj=9hp669#wSw4`46{r~*aI zgDKzJ<pFnwo|e91`%rglz9? zR0DDxXaY@0@ z>NL|q-cq4_SE6oN2{R~6+u-jPh21si_uV9JS(kY2y$M~Q2<-g}ZQPHQNH>Dv6*Cza zzZ+3xC}{Ockxf&bPX7(3Eml3BmguwWeP%n!+Q*XI!fN(T8ST-`8^c%|D!Zy5DZt+7Z|!a{lP(ExIV|wt2enPeVFIAz0OM{>HW9lk+EbNS-+6x4xKgF)5{;9B zC`3EG`i`)``vT!}>w$-Nu{c*@*}U{47l}?)-E~P7SVoRyVw-7VCxApKkP)wnUgVBN|GM(bEaHMz(Q}N;b`w9Gk zho%--XWX2AG6kW4J1K-X-6Vyg+bskRn>UX>yLxaU?foKjGa|=fQ|mfXcTSAOE@||( z9#sZ>Mv_5~7uc-Nx;zeF>y5^>gx>58sPGdgN0F2oC zUE%QrW;#F09h0|TIF|T#M{U>8Ttq|ozcEsy(Aw z(gz@szzOTjQVrKwdk4&}?<`sffBuc|xh600s*=qYV#X>`Bl`7BHqE^d|U0}M;Y zHM9o$;dBV%ek;(jAZHv`TH=Bfg6zkK+jWoTT%&Wl=f+oNOSo^w!evUiqTSHPN`EzI-y#Tm;6--1gjG+lIb1vRSiJPedRo%JzJ>y;67RQ zf@T6Zx2OdsDW^6~O$ZBBPTCdEr;j&O*Mxs(BInw5Gd7y-rl~536Ak#4HGugEpt7VV z@#<5R68$Z?CBb~y!J*_lw|?qAl%8gB4Bd1RXcW^)nNT~^B42XYpa~Tr-uBBo?l~hj?Nh|8u~N|3JeSD{OJRwi9heqg56L6$!Y#Hp!ehf_Qd(HU-P2?1*=olS@eTqNma&8J#)|JJVwR^2>e_hzTwqJYZc17_Yl6_sKa;jnRZ;>KA(UX zvGP0$O6L0^BNxHc&myQX#-8-!w*GLauJfnlE_0Ly=?w zeiAvBOZ6@H7+(PcX)9dzLc9$g!xnPCi#a>Uqo&t_&c8JRGov%I-0N!6bCiA+$?``E z>LjnP_D}_XCACe#gbb!-7;R4mpqQxR!rn)%7d6mU>&7>qqj}pCS_^@;&8d~cEy&;; zuzNOvHihWr_8Lz{oH*Nt|8eB?UxgzszRGDONsr$I20c^olq|sClxw~r_T=yz)n`|d zZ1DZsTgop&2o$Ec+vV`poVX1cu!r4?Z$Rtiyfc0!xCAi5=QDX@aAc^K<7|+H4dDz3 z!5i}y>5DDotyKz`lS@Em2CPk|5MYwqL*wqAMJD@S)l*-hIm-`o2LBoAyK|JE+ z%-1Ii+PG6@^p)Min+~lW?I@GWyC__xhRUDWS(0v}9JC3|;QxcD@xKtoGj$m|-Z=G# za0k?J2!|FLK}Zyo%J3s$2~%w36a*@kCLB2wO)5<|%O?H^@axGFq0yo5eRCY-eu*DF zY|nMW6Gs3OOUvBkIaM#w{_?QGlTKy-3E^|_#R1gFS?O``)R7`dyjTzJ+(nuD_{w+{sv>0f2B>5Hwg)Zu2zI0~53PZ)K&lEN&63Wx>-l zyJ(haV^9ODGYY8ee0|Uq!f$j(00!+>S>uK?;BR)!-NYf$+Us7&WQbZyPjGoD_y*w`#>H@AFG| zG0*m>+aK?va3#3KIb{E%wAKG(M%H%^XyU$Wsq(>n=G{2xJVH&n_>(VGPpdg_uJ({g0I)fo{p=Jm5I0xqa}F8+Y&HWGBh<}fJ!;&& z+6H07y!)_sP9`;e*LNtAqCI7Mlj1j{8_GCZ^>HZuXX)zyEFB(AYW8SU6Kq{gKjhNh zns=HIU?=|Ov`v$ldmtWu>Mq>ta6QHnJXL{KN8#>5Iy6@Ifff$}cb#PGC!Y*v$;7Du z$fRATwG4~)c>P8(K^RainQtCeoX(#r0m$qyBO52R1o@$CCEJFw2U~*bW#O4;7j=y} znBYI#%Q8F%l`z}x6w@$zA~6M;CY-aDC@NfRPezlK$B6oJMM~-9Fedn?FhbdQtpq&# zkVCRt+E*RC{j(k2|D=M>1?c8*=fJ$zOV948z4F!R$uqrE5mVXJ^-8MJYzSNHCPx(v z`xMPuGqtGoa|&MdrIh;-Gl`m^~A1%M=f` zayEDNj5av&WCU6(z3t!{g>}3@m6ZWlKcbo#!Y9DOoM3zWrtX!;avGeI&bW`eQgnvL zAq&ACxC{JT9N|E2=qlLs$>tPP+$rYFONr#57>FMWxNXn%ZHU557AUPulIGY=E&0zj ze^!J-@6?y(s<8#}PN6hfT+>nuEx6jp;$s;BvuvSQYVzIoB?WG58Efo+kb;=rsYXQr$^mU_MkyPCd*7tYF zn=a?y;p}K81YL>niPQ`Vv12MXux$L| zU6}as4nH0YnPW2FVNG~PP;L5~V*~MV1!25~mex}I{1uo$^)&Ha>;F*O7dhx%fBC{$ zMhq>FHdZou_KGgT#CxfV6Y-7@Lj~$~`LaF`))hA<1vYYro&`LRDdiBemk5L?v4U2S~KiZ?5^rTU>DbB}Nobg7N& zA9nHqoq9e28RzME9Xd$5Vl46NV~Bu{8_6ojx{Yh^xAoW}8csPphf(h%>6nfQUD)=G z<~d~!u1fiLW~GA{-ZvEh3U2;k1Aw2y9LiRa?}9b&i&q*$Hwgli;&dG_uYy9`6l~Wb zavlPcr%n?9w-FLCHe@KE;@x`c1n6kj1^Bktc(M&Q|h0h0N^+8G286XSk zw!zi1bCEieSKfFw$gCrhh<|(3nV4O^_N;!XUi20<+uC~n;(xYCz{kJN3RR{X=m~VY z!4M$OA*_S$kTB}{tGmU`pG(4MjqpT-LQ5u_2dEjKulh58++|(c>)z$!0qfUj-oHPu zeq=8eQX94S*l>TAnqrt_R>dBI(`7{MK;ti4iR3K+U#$x7*OQq{#fJkl(og5Thb2;{ zIPB3T-iOtymi-18c;2LvnjZku`+Cbp9U64D`baxb!s;ylR+0ukhWVDcx?}!UW+Gb$ zUo(4Vcn@(jv%k>bk(ezIy{Sw&qz86Fi3Kln9L_4_T3re3smG1KDpZ=AIvpI`gML}Q{}g_wP1xQ_y`~#w z@}#*vmDJy)Wn6|nGD}_uh}gOblOmPA01-kZKAU75h#|H6<~SI?lO^~OK{z`~(~;-Y zl~$y7mNrnS9oTxq7#ufRAP>TQ96hwT>}u~smC`1A=P@IzqVq>XM$~N4A>FAM+F~;= zs044hFhB3up=DRtl?>cE9c|9z38qPkjL(QOyXqaH)$(Of^|QCnVRt!Yde6x_TXf+H zgN=^b!jS&Q`{*bIs&&Vec(XxMiA=VxGpU;`@^=xo@^9C_k&}d6`yD&a%*5=uw-qOo zg}&dyB)5c~9?#zR@Jf&@k2UU&W`t~P$#g<&h1VsIcf7M`b5@!l90YBPZFXcz^rv_N ziHd6gXG))8m)^ppOowq;!H|(vRXH)$cuegySV4{wQCkUn2;81CBB2la!fA(bxJse% z70gdL+HOQw51)H4cu1)2z{9zMeMa^jaEsqzlz8Za<$P>Cu>w-z*MFB^6{=_8g?Qty z)#N!-_QVG{h~e{n`i*@D9I?ea(ek|yi!+*ZANmaHX2F#t_uUNr%abC|r#bMCS@F3! zs7RWMegnIZ^%oEv-YfbV^*3#bF&Iq{wzHImI4w4-W-|N3R_TM0N2Lz}r^C4*hdE>r z(31tVKf8Bt8+8b^|2ZKnkp$sxKr*y1s*h~yUmRn^yN6>0)zt?9F^dVEIUiQ5G!e3; z`7B^6RylHzev5$#x=KZMgOV>aX>+CY{|-ncXQ%Oa^Ic@!Ca75dT9-SfXy9BDt++3v*Da%t!g)@*a}o?p;P_y^jV zay^eiG8?#BLh49YONX}$7Cd7++h~PaTl1@t)X%f4oa{V3)s)}B5u9Pwzp%vI{j{Vt4vXT4Mo0s9c%+Q+7pskTEtyVG`DzVm9>yXO-gB%lgiAL{OWAn&2AkvEel)gBFflQ z1fz^|Y1)_2siCD1dPvU6E=BCEdNHlhJe4<5b-{&%WlyUa~K=RBJM z!_VU&pGx75kN%eE;b)`11F!VR+hi)625w1eBd63JA0F|#+>(IMh^?lgh@&tOz)&lr z1~1bF&T|<;&lAy@2UCB3jx?bQzSKq@#n9DSNwO~t@EH#rQ+~WU6*<534fbrRNRB6H zoQhww@@1Hp7ZWs;PH)u{fx*d?xK9|_qUZg_KljPm>e45VP6TTW%!Ir3&e6WiEb;Vx-+h@H}BNQ zM5taw1&>4U206UrYW>Rwu{WN&V$nobryR?4khUj|fZ6~*DGnoO{1Fy^H&OEDO%!ba zaaFcxv5I`i$NmK9OkCSN<$VE?3U}F2m@o#a`}O2{)Y_9_#s1W(=_cqZ7wK7K4uf0m zYi!}M4d@73)%chc#*tjjkN4XcYmP7aw1V)FU^R=%Nb*9ywjBL@o(tEMG}Z^9N)bQIFZn+~ME+ATV9fvH|` zvxcJghu6~l#-#lYZ5D(Qwzsln;!hCVuA>_u415h9FzsyU`UR%;?ATi2=Y605NIv!t zz-{dHy!81mf-d=i-DHg*Uc7eh7s=NZ{=_JJ0Qh@TF6_V38o%5C9*lsVxPJgF#cr6zli6koOv)OVZx;z6pzV>AsFMPNAHX zFb?Q`1i4~0jgdwzYO=hT+I?XP(iJ4!Foq+Q#{$iIrc*RL>deiO-D4MZ~Vc$AwNxoVy)rIu0C5*g^x z5g(noj?zVgFyU!y&+vR_DWnueNR+b)6E2pZD7kPXtGr~RTNRqI!m08ZUZn^0N9DiP zPy&n0da%Oe%xdFa%$#V}AJr+j*wKhxy_Zr^rXp>6|cyc?j3_fe}P=N_i7S)45VD2I(0aUKpuB|GT^tWLB+ zuYGm%B5mY67qU7rrs2|chnN)@;H*WnwENuuh|MK>Y{e8Du0)XgyyMTBjC>jM)jAQ; zkHz-z=WF|%ViFcqp=$d8XiKP-iHq1D#0I3T;RLe2pxT4iG`^`R1WkH2UllpchIb5W050d38^Os;B~Np*nL(TMrqT`u{8&j(nT|Is6s7* zoK?!z=~F1ufJfZULQOy@CUr=R1Djsf%m*x}a3bdsV~~8g3_{R4|5^x$AcpojNKeRd zPaewOn8-nePQ+bcM+N&V0<`tC5bjuGb#c#h`FJtG1qrANpCMTt=8X*_$jWJHQik;2 z5ct-lA~(g;;5Y~qOdd-rffrr)R_kSotG8-2off_JMrVOgtv&48RCPl^v5_qKgs#2Z3X3~N_fW`LP9w?f@&X@J>qM8 z)g<0@!8kOangkZH!ohQ#fo1W?Rj+Zawo*v%XtU*0mES3?wiyftNP z_D(em7HzCX#}w(>)poSwA9&jrp(gEL0u*3a`oM*4@`pFa1Wb;HKPNs5+<$2~^yg&A7xY=I zF2qAJGYANQNgCpmnYmJTSZ*pcB(G@Hv7Ok>t|V{Gi5k35vk8f!YOVTa2m5P*fgQ0- zr`sw=y|C}!e>zS(;LWc~?r1Furl)yGMvYqFmc-JAaj*hP)uM*;d3)d7<)_KJ?%h23 zrflDQfUn{34j6QNm#0GZE3X$}d~S`iy<}B<_(THTX~@1vrJrXy%tpnvVtNaP5BcGa zylLvh9choR?HBM-xwC$j8~DEHP5{c9iL8cjFy_>N{bn?wCpxIp9)it@f$en36uIOo zcO7`LcS?8od6Kr+?Mz_e9xW7;!uwN82^KNo1DfYf)#gKYW!gq}cMN&!8Ck%j(%FsR zr={!lx54+9}?O>u$H0SO9&y>uG6JH)Ssfbu`u^ssz7>e~}`C)HWI+TkBaC38eJ zjL(Tol%9@umfo}J`1k{ZM0T1N?~QBy-D+C^1FpNq+}HlMUkr=Dp=oxlMhBQa6ay=Z zXd{tz8#WFlxkh!fNb&kM4j*91K=t_?=03iiIsQMRL`hc_ovoYH3hNb=k@~~pH2>o) zk;-NrMTxl2ta-Pxg+0@M2^fbZY-s4xAojpNMVV_6~VK@9Hr|5J5FVN9+{H z8**&9XtOdb!BpEgYEH`H4ujr(jNeHwv6#Eg3QOdUile@CQm{PC3l@zI<6N>TF!seksUuhRtm9vbLL?6BB~xj9I}vhs*7TLV?^I|)y@YM5dVx=Qm8sG z#mCsh)*v;fPH87-&8#>GB@ag;1NS4u-nscG5LS-5O*QXi9(I`XiEWtdF6kM@Vx}BE za)sI5ksPch4IPJa^7%rnn6s-7^Q;K{0+7BCf<^x&M*;<3Al84~j3q%uO3o&jxhXYC zK3tT*`msQcy-%LA0&V6a$s1$pC*q)au6BO<-x=@8d*0`W0`Iw=*#uK3BF$~=j>+67 z382$WU+gP8Dq}X`?r!3xe`RCfWvVc)tzi z?s7#GLptAiKe`Bv90PTjip=|oIo5vg16)zVg%vKHrqJ*PXWd{*0jM(D3uG4>10@?X z#)B(1?Qc>K1SJX~^GP$su$TZ>j%SUjF%{-F*Q>FZg zL_EUvjp;|n00mQz)vRoYKh7Q$SiF9X&{(E1Hm3A`DlwW9gw=l2vgI~R=e z%f-Ur$>V^36R4{c9Ixuq`s_6&OrF^O$x-n@lQK2E1NbQlmNASnCyK+ui-yVYC-lQ& z7q?}L9ASbg>EtR{ldT_e2`qhg{nJ^@lM2-*L`a7_-lA=N`J#@H=vTiXCnlh&oTSy- zn^#hym=Fw@IF|c1p9;`|T}(sJ>)`h17{L}agVNf&*sz5*cC4EIp1sYw|N zXi3}GIs7nS4Xehb7(m`2!hv`5@rstTe{-iSA0SjYWK&!{sC$@bPLSb^CoxAQfz;b> zWPJS`E3zh~p1?D0oMT&j;JkFGBgd@S;2yoHeFv6-%Z|xHL1ywQ+c@~At~dQ+^HcsN zC5G5{%C9R;$xoJWkMI5ACts20gIjmV(G?y9v?k??>~`(jcQj{vU~{B!U;$hCC6+uz zHwR}%7-QAdFME&6lrk+<$~b^OJg`+rJ*8-EK^ap!m1Xx6m{u3?70H{fp7j(w({JZ% zrcR)wi!<<6#}ub4<4*eyaBPJhH(+dj??z<`%lfS*fq-juKY8klC}Mk#dqy0sAb{=E!Yx%#hdJC_sfFrt^|I4#JCPaB!F(BZE^ z$zyK%MX9+6izTP?Q$?Id->08(qCpEXn<_TNzk2wX>^$Y1s}%){33G^9?7$s}|CBhS zQj#9x&Mj%%2<`aTZ?(QE(2wb58i-F)4(A)63>Q=b{jx<{sG=zRlp=QoF2TWIJTx3; z_>(_`yO0J(_S;zQK$8IAe@`G!6 zJ~mLs!I2G89k9&fbSrIZZY-DQQcXW|+G3Lp{jo`1IVo|C_o`UCMk<&q18Ch(*P$&I zZqUBfZ~G5KHc9Va8f}%p52rp7fW=Rlv-Y`ml(U2F85U~ls#kQJ!}V{?F$;bZlWHuNVWQ;PMcedQIyqo3B!0w9J|{lnt}2XH=a z9C*kDZ9PcQ^80P%lB801I{%+#`8#s^g0J!X)3`k^w-w2OKh`AJ*PMzlB)}VWzkhWv zOOvl(+-{s&TYUWe^N#l)uw0@dDSHRpGmBscjftbLt_YScttcO$Rl4&4a~6y$i(6{x zz-_e9hrub8f`J&#hi%7B)0>qaFYPz6Z?ir44=J?_OJ0`}#V5(x^Pq!?(}J~?xVmxf zrE6@r)8d}fiG8A9)n(tzGLMUB%fC*Rk&4jA(`h{JL-cuGC5Rh6!73MV1fQ)`k&w_% z8rUagCIWqf*);_~ZPRq%8@T?S3w{GFyQ{@M%w!bxAjuk=H0-8neDF>09{BF-C`f;h z>5%y``cRfL87y|`0bZ!2j~;1Ib$4Mlta4GajEOm^ViPzExL+ggMS3#&5WHgO^=o8W zTKibYMn#pmlG&zES{DxeYUL$?a=am9vCWgk4#tItVx7B9Hoe1xVZMya zvph{7e;{ZHlAi#YvBq^#NCFV6LHJpT#xHU5`<;uqAGP3g1$y{o2a z*rkh)ME^kH2{y)p91y|$Z`eklBzl=}YxC>NyYpvm(U_e=iYZ^E+owpX=WxQ9Ts?=k<=C%@+T2fh!E4^S>q# zOn;6eTqtO^`uClHEj&KCbNzoLvKkp4qgvmXfxmyC&my7t=7#)TMTAHJjGw0S^uL#e zn0(nN`S;QZHeD~`&eLfxv-9&xxBFIhHorB3Zh-m)EE{dLOw< zjk3#_qcVes2a=IjL+I?8jeX&5e0+@&+`5@LIXPR4qqcSG%Vl23Zr4M9$2iN>P5ua( zO}0rFr@0WhX_a=6yH||;%Cd5{Vg4d-$Lfk%$<>u>S!pSb7HiWyL82@77}d4Pe-@mn zc;+HJ2Kd}!pkZL3c)VC$a**Q}Z#9u6=Vp{H$=-ee%WCjDm}_SCSAD(u>q;bS55b`K zPM@3$%S-r&RBV*NX?JvI337sD}IXUN6R?33b*zJyw4!62Pd8{YM zd@qYq-w6ol8e4uUt*$OHZ1b9adbqaTX!ij++@367QM_YfD!9FkH`?s=Nc{HggLCII zpQWYc@K?s?qMDj-DJ;4Y=fJxh|KA)-JiNTqU*M1=nD`gUtEy7&x)pYWx0|=-wT+7o zXG>;}t2<@n_$xnun67Aq+#l3FRCrFlq+WaMT8*xfha>{#tb z7XA)a!CO8yE!14ia_#9^6)`13b|bQBnkClYn4d$#!{dqP<6WE-qW)?76WIzF7#NU2 zYB*}sX8ya;N4~i{HqWySxz#4eq(lH*zg^>WrgI15se=OxopGzwjp?u5PrrV>BQ(3i z@IA=(dbjV6o-OLOV(;B)wkPlVu$RgRxxlI8<@c+`&FbW~o*0^Rb-R8t66^k!o2$ZY zHI@eg*-*luSJ(7zBkTP_gsU<~K7;xRsnL*3*F_Emcyp^?msPuCu(!9TYG=n}X>C3F zXudy2?EYuS^bo@;4QGfK$o@}E(;`lPW1Z9IqklgYRb5_Pazn~D)sBGnj+Zqq3t0ib zfQbCEiH{)}t-Ho$S7!OLx}su=pVO?XHsuH2?DeGB|7+|k$j zN{4`el(dvccf-;R5)x9q~QPR_xE{TKl^I$iJ7_QoS8Fc z&dgjs#hd$0t=WN(-vZICgiC#4(BPM}cqDYJ8tIyU{ARK0w_51tUkzvS90yS2k0(Ih z95EUg8Y1>rB?y(@M5Q-1>At&$o9+aAOXTa$($-GAEF$O78Xp!iFaJ`?dZ@sV!B8;O z)FepLBL%@ogn%A)6W?c17r*YC|M>C+`?Z4u&A3dWrE34$KmsQl8(Za-i?g>X-%YWS z>(DaxZ(_zhTJJE&;gxgd&kqaPGEZWze>6LuUZLvso;(S=ZOpO@B;+yc$UxSb zaCG~ykd^?q-&{jjQp&0jzKO1&H?_RVs&xGa+S!)q@P<1pF8C{G5AN4(k!GP#z`V_^ z$O41t&F{V0U*yO4E32!&%hEr7wp?NT^3_c=TF^<{6irbLz=ac5A#>t$Au}p-#l^)N zvkvPDn9(#CE5#wIhZ_GRVyygQyO~qUjfY0<(ta;$RK2x~X75-HZHb0qyF}J3Nl)IKz@<_5{>wMr_ ztkq(JT+Qf7^Nt|3Xfx|QR{2*vea~E`w9U-&PfIVcu3sOzT}mql*^yrh#Ou`%*3$`| zWoBmLbG>CAt*LV()-m9Yz6jqUADkS2mCD?}hmp9y+O;Y+A{}+$w#@!PpZ@%vu;Z(b z5Y1}(XDaYWn@VzTIwlJ0Eke{TGtu?HtoQG?wh%O5ik_)nT{4X16?o5oWH1PatC7ZT zx(}qv($Qn+gleSq7QG8>l1U3`-Z>j;31S9xV2S-{xDxjYjMjpFfo<{v;eH zkFN3zZ?ZCpioy}Z?912eIuB!H5vdd6R_R`o6jOP-#z$69bH4nj&T8RYc-m&b`d&+}3tgO&zJ~Q? zZxK!9nz`(E)smMaJ(ay~Yg{&0Fz6%`0~3=ZHC(%X;eN~h)kIN>U$2~2Kr8yDw4#Fi z&V<_y{O%*3`uC@&Uh(lixFvs1mUpvuBRhQ$)96e?=?qzBMHMmA&KEkoHSWAOjKWvu z_&&Qz#0t&L-4_&?4aXte-pr~99KJp1JdE#XTh)9OdG(_^u$6-D;x~e$Fr%0-E~|m) zI{Hn#G=qjp3cc_>9x?VQl(CNC?U$`@Q;&Z%SYa7QsbX$l7!rgv_#T=Yf2MZ5UQ6H` z`eFfTgk-`;1?eB!*xRdx5itpc_6Fsgz8Wi#)`ek{!DgwXqQqPg@*BCDG&sFk>4tJ# zhIJW(Hx;rsaRtF=#+P(mF``DcSuUjBnGc7K&eB?KkycWVVG_D6whmopAaY!w>DZ#V$I^_)pLcIO_+khqGD^I}XPS>jg0B6QqeN;v`C?{j`ZPm+LNye}Ee;YBh8#o}5sI)94pW7@ zppdm|^Z`orBnRYEck8?t^j_y)&_{C8`((rgN?q!vb+x*sto8KXgbTp^+At?#_7*+2 zM&F*x4*6RC38|(;e>nIvs+C2t**2LR%Fz~n{1qqiAv^^z-9O!?~L z1R3vO7j0fVIA`4TTQAo<7BdgnQMwd|motbpSja%-zeJKw^-gmcZXEKTB{>o;_bVVA zIcGN7oVphhEeue>_O;yg{E*d@(B)J&WU^r6tGKlw(7a+L_rQtlsTcqxw{`N$w zgoUs%p{ca2y&^$A=7BsRU0}`i_3|HcEn2L4&1f;1Aly|qWBfs-1j;*Bi;_<$hvEbJ z8;kU6uLjnvc{ zPcv7as06(%rjS+b$;i!RL5ZlC>OpvpzAQb}MEe}A3Mh5U^Sdm3N*yhf7pjG8HZ-+N0&M%FEV z7xTV6@#Lc-qWw`3V}@4O((wlnA@Z$@$6t;!+0)7_w-(@ zXHtyNtVRL2^zSwC9=e164~ItSlKyri?&3W zgoM&toaY}Mk_1tmlN9Su1;@-d4#*HQ$gsu;S_bkO;tg1c@tsE;?NKlhHS*MiqRx1B zjF&sS39Vk&pSkaDbBtk-UVADd-A@;aOczJfk|MV4-q>7E8SPie{L)uJ=)`BfOYr;CY+|3b$B6I##f3) z(q7VTP35=Gm?>vqtz9?In3v3cw6~>ckm)L$mBq$Vbd7;Pb|o(s3V~>jps|9*;{__p zdwN+vYXys2B0TYQuqTpds_Er4&7{9sh*<;_kQ!9i5e6mmTi{d0o)c@gJ?{Dzc)p+R zo&IQ-Y9`G+FpN4D=<(WVqDXuDR(d_$(eZWZb|j=%Tn8PaifdZpcL6;q%*f!5B7*t3 z;XC9>>d!os#UA-(t+MGIDFEBePTW+Cw!{B0{lPG>-$&o9h~CXSv*%+*%{S>HbSfFF zvV=t?CH~4U;?5UP`^DW1@71`^7s-9lY9i_yaOiHD)y6?W;2wu34fjlm;Sf9Y1H!9@ zpUJ)sq>c}Zu{CLReMqoFqTlwC1#(3+%_EMm*L$87uCJ0F zI0r??;(N;?r>BSTq(P;h>^z}t=2B^@?~G1zv;DD5X-Ckdp!E6P#|$?CbD0GX?~bm) z1c_ePA46}sDpjZWx-NIKbqZ?sxZg?Ji_T{xXY%pw!pMlnU;-#2R^Ax7caR z9=aYu2Isp-^?Q1#@Skd_`1m!|X=XCPh#U@oPpc>Rg^xk=uw5%Ec>ASHIEif-qY~W4>jJ>0k;h-v>}^w{OMti~Q1ZSfFJ6C58Sbb^U>Rv^-s551 z69ZG)x>r;>-15?batMqbNP$oX03Te{hYne!>tnTKBDL>-F>@HO1hEEOh6 zYiR%Z<-mChjH2navs)(u8HljJ%MP;ppf^7A?r(S!t;~G-mRe21zG+wXO1Czo5$Z`; zWb>PNSCIWDh4XA%uPYgMPxgA@qsItnq$J*o@MK-|(fmJBo)S9#!B$FbC zlLZzMs6K=FkiNldtcNPVZ3FQN$J?wwFlkvlFHrH(wk0(_ed21!^Xmv-8m4a#BSMHt zwUWLPD}KsO`qLU8c;3EMn10guL89p~va^Jdh=iD;t^B1{VUc0f_F(_Rn`{~e-ko5) zf7@tdZ1g@`cbPRNIWb0;{g}D4v#$!ZRfv%Nw_;jOLt73=zR4b;`EYn2^9@%MH@@w_ zh3uy06FdgY3(X1t8Og%g@^3#_`!NMv9WCUEP+1wL_?A$?CmFIQdqQ54`z;lDJ($#k zSUN`wo?|(7!^+}1xcGvhnAG%^bU}PFw_Q((qLKw*zAK1+Kg7EHb89DF`3Li6(t|O_ za;kO4od(fZ9}WisrJRoPcEldketJEv{-eb?SM)gLasZPbrTk)W%LLvP1EgAc+3l!)LZ9KR2J{& ztE!e*4V6JV%4V>~?eD1f*lrfa?;DA`vJM)nuPRuhF7&je*~kZ~4pr2F^%q~B0f}*j zpUIUOhklL!G&OYsk1yBkJa*;8F-O`>u2KZ&XgSU5#%-TUvrtz zOVYdZ9B7cApZZ}R(L3+cV@MGe|9p`Gz}uv~hy={ZnW^%h*y0aH0nu_IcUH_geGsFa z>ilIe5hf@VUx;3E@ZN{@7_^3Z02snIMhgG7X4J4Ohe=&jbJRyYoOC!P`uO`Q%b?9e zcQAOMP~n*ZzvcBECoFU3cD}~oAamnsp@XTV-8be!UVi$2Xy(HK<(qd&G%k*wW zfO6%LYv{E}lW6Cl(jyEa?UK2xF#J}Ke9+`Y#mT}l`H9!IK$V>v&bN^j&#>LUFP{+&V&gwGK9b&HR!uN z?F2`3znAi4f`2>*u?EH&#;E1pDq_pR*bd9cx-IuBAF%=__qJYaTBp{9&Ois z>OYDv04@@K#o0#d!2lYmf};herLMRaQcL6D_2ieQ7Id;T7P@O((8jLH2DxZ~my+Ar z*W|Du16Y$ z)vVo%fDVdc=Y8oVM(!9uS!H(QWJ4QZvAJheZifcE;nuUjt~l zL1&Zo-n&wfsz@BBJA5Ukg>E;@tfJB7aVHkK@kFqLCSpY(qOMM>y1FXW_~Yu$7c`!v z|88l`dPQN#6)!1_m;oc`Y-9(_QItSH(2dRCSG?M+v?hGBG)2|*bT(kM^3*wk#e0|row!Z<>CT%Oz@U# zGME_rul297o%)))UuO{{74e4~13%6l%b8qRxD= z%@zY)kk@X?gXFV2?a!!dF{!;N$UR>u<5|AoonotVwMkT#XP2skzUnoy)klWmTXKJ> zsd;mP!vL9i5??9ggy$W3O=xuz+T|z(OC^Q1okQ5dUfsRvQE>sL(kJ6${N=t?OOekfl@9>i{`CTn{0fu#FMey#?CK$7 z7dhG|@#rv#VLo*Y}P_NO#RCL7yf{%Er^<#H<~X(2I!Eg&i=6qmp_H*I?z^ zX9A;jZeg;GI_sPbim~f4f0pmzVq^1GiB4GLERjJ`g$5mZ<&`KFO~yISley%1_|hU6 z3}53~db`F*fzjnXXh4Ix$UBNN6lP-q!4@2DkkEO;pN7pZ;{S6bu!&bgUA=o4v{~BO zE7@0QL>J4Sz9eG*nFY_#1mTEr(zA9uZP?r99{Wob-!irhjY8@q zbSoV=dJ(P^IK(9~iqjpiMD}puGDCk!#+^(rEvN{Yl)x z(RI=O{=ZRr1W8&5>E5&+(V@4DB}wE$t5~Ne*^T6JO24R1ug2ytrpAfj8ibxO9jgo61n=S!|CIG*OFm2DF=_*JGOCoPQ1OG zUi{-R4jGK&uhy8vlrhp{qHn@S{(iA-Q*xgSDjM*f-g2Q6k`FPxMGm$I#GKB{AN?>{ zwC>ZVe1-3IbA|ng@YJ6Zx>!i!i;-7Y$d^K}DMX&_=N8-Hoi%1=2u3Rtafq{khR&m% z!q%4N;hWXA?ny@BDTKt=VNVNd<)h%p`SmtGA~(6@-C&%5I+Jj0^g&j@@L+btC|UWf zQJWj7^N*$^Zjt3nYk?LXrC6gxF2xul42;BNuC9oypv>(yE1B;!LiS(9Lov>x{H>QE z#p2TahTC#`$_z5xFH@*fQss#nm{ScXBF{;taRGZ zVAw_nJ{F&#VROtKDUKSffq8iKth)b3*N19WIaGBc2T<~j7OW73CSIwBmI|kl)A1)=a#Pc4yJ-deD@}4JOe1OnKpSWvlku?rq3DfFUHv8D&*72JSEenHSJ@Fh z?=fdzdnY{3J1=MdpiQ^V1K*WB87X`yAdcW7ayJLp6Z@`9k(BcKxtr4tXcz10U`{p( z#>1p030|0Fyflwc;DI(0$updYp_ZSRy<8OcT=;zNb!ZqUp=b_rr8|9dWHu_RYcf2G zEIK?8fqX`}+{a7Wl-{*j7&A0K87SPg{C&_>EhgdXHkXfT4w!2F@97Zvr%3`jms z0&Zwy^5PPA6t_g4I$$jhe^URVSsfp~DbILs*rVikb~Ns!L=jfJdx@3;-o0f7Oo7Nj zdMU4GT5luPGmE}QkM;yg$L!^OX2j-&U+!AU=88C%`kyR#-bK;b8-J$!K#@i(;*?Rq znMa;S5@}JAo)|EKKxBGHp|965aF2d2lMPCNA1&G$UoDZxKBIhT=jFXjif(=3q9JQo zIqWRyt7;V=!}>Kb$wT3bC9!43_37NlC4Vro7n-`_wA|AzNLDnPuBb{=4(nA2Yh4P- zJw86^wjFR`g#Ln-7Z=;BKMD%D9MXT$bV}E*$y(9Z0K{@T5r*H}6kgK?B0QK(Tb+IF zuX!GFzd=JC6>4Kn+Y!a&{vHfck)=4tk0z$y zTM@nTto6n_X>veYx_NU*`XB^zDNt`Kdn z03J#U*N0~b`+1U79Ld)0HIwPZUBnY%!r{j(Q&jYiBcG$*lLs9v`2XNjq-;{k4SV)F zHcvEa)_*<8|2POnnGjrO{?Q=$+`uYJ9l$#V6tMSZyA@<2p%*$Uf>5X`1t!T1;jW(l z$nUT*_d4IhrF|CsRQ-`7^PIpH&bQW6$so#lEr2nBzJ)fc1wYWhPub;^9Iye?y8?bg@Iq@9HF9K!gT!2^NeZ%q5P_POT=(>+KPj1VJQNz` zqaR^(qSte<%EeD@rKT^I14?8_>FE*yc%!^gzee(voODs0d&)WnL~7hG<;b%8cWo{4 zWy7YX`_i+qS-!f)*5we5OaWP0ZF560;^#c{g51U(iph=BtvGe&-H*mJ8ZgCp&uW6c zM#tU_4$k^}TKL-F!VYzJmfL1046ClQ&ueXJ^7z44M|(fGvPtO=z679!$Tfw<1@X8zvza%ND6-x*%>W zgFkRVxK;K3{W!-Cao6+_WABNrflp0tdM?*MRSrx^XRRnso=*Z z+fyw19_n5f{^a@nFi(zP-Qm@VNJE-)OnQpdkY2QfkrAtO0Yv>##{Ez6Cs4s`e|(Hx zyuv53OkY|m+e&8?B1T=#w>UXxY@~bZ2v-vv+T4;?y_LU&W3EAFJRimlH_)eXtp=GT zrksyT2Fl0QY7`$ZQcgcMyE=Dcum>;E@wgt+j@oCPJ*HgPW8I^d7Omc4P0m#rXISq{uQha`l zuez4p_Scw@n;$rji+}?z#X!r4@@Bzw-acqkF0p7Z%lTM8J8RQ%$dn^pUi#x-^WHy4 z9CYec${68T4WOoXNm~_RJs|9j-o3Z8KhPZQ=5G_NJhwnF@ze(nH9VEU{C6^uP>eWd zvg+w}g7a-l6_H0JODKll`FJ9lNeY^Gi2Oo-nfW~*uZmc0p7RB+UR@B;c{wp$_ll{9 z(uu`l_zgUjNkf&aJ0f$0u~6%Ni8LnP-k@^44#GP3wEXj`_imBG#Y6EO0_4PS?-7{2 zm{u#~_@<7u#-5u6?w%_x_iSsy!XJM7+EAgR-7z#TyUn|p4ai6>Gob-&ajF1Zz36XreHpTAMvl%j?>;6FRM7ytt zaW|_={I~4c`^&+1bN;{qf6a?_Txdtgz2gV%nDvMCON+Mdgbp{J{xT8^IpglZYxSR( zmAO%aUw7{2l@R&izcRpu6TUv-L;r82)fG#q>V+epLa=u~ z(FojG2_xH+$ypIVa?TvCV7SNs`kLG7BogeWqp#00_`OdG4tfPl_uAT3>R_K*3Sm`y<IK?wbzv~Aml4a-5R%{o_&j-6aLE*KW8{K{}MEc=R8jU zQ^$~(oD=+~g0b9(6>jq|3%RWz`eq0F`Y@{^uWO7LO&m?XZ@e2R*ht|ZuAo~+vgjAm6{B7~G?#bgw z>nQ!5T9&^R{3Xc&R_o{<;P1nNek|NAXGvc0KQfF;&N2S$qVPD@V#-AIFFGq_I*aLR z;BO00L+1Mf8Ub90fA}g_qnFNv!158Zgjdv|MXecs+w>>izcqBdrum0i>2YHE*Zc?n zoCUKdl+qhG1Lnv6cJ>u6b~mkQ&Hk^4Una^~<{v%iSlr{1zK&Ca^uL(1Nr&mI3a93S z{?T!e%6w6}Hswg5rsVs@Br~ zU{MoqJ4^nhmp=q@cWe1g;4bz*Qk3Z}Cg*+r{l#RwKQMGur!Bev8ig?5N5=I%LL>jHVX82grRd(b`-c>Wg`<_a2mZtJHKzzHM$^NomoMS^j<$jvEL=lDIciDo z=wd24Y1weq9yR(+cym8iiMWf;szeF#pU<*bo^M#^&Isa4VEd)IkXtzANx2a z{uvect$i$5h`IKf_h{ey3KJmrwfAt#p9Wy~wzCBm9Q**kyR4!8V}So9O`ArVruQ8z zfZWr><5~U$0He0qE->Q|0Qd#?>Oax|)FnjADAZ$I0Dhq7&5i|FXJY*BMKU3nY$QNd#g*mC|~Mm5Li_2t zJHXRMqC=ADIAUOL0xqG40p-lX=n?UMujLI`w$iKjbdEj;EOBjO|H$X>0WcRcQ+rN; zUqNuBzIKuh@Qc@G*Vui41K6oXUkZHt7>2R3BbE2S!u}z^A0aqpVZtE|G)(d#=Lmq2 z2BPznX$KPE6Y8BtA;x%Af37TC#(4` z0DExpDnAa88!H1I6gcsg0l?MXfsH0u1bd)L;AeiU$cYDxtC*weD}LC+@Y)}R1 z_`t{AB^$GRcL2~%{qClWD#!wh?2fvZsb=PIfd&&!5~>+x3_xflO=1!N&K|O@-8Ab1 zFp6upd|LnrWK(+S@1ej+1@I@yi0?HBj-!$t1sE%rt7^i<* z#$6yAH-)ugY7PfzSk~noRcp!mjsYY%sCby?8v_6yH=A{^Gd<7{D>7w_1MmxS($YF! z15hP5@21jGP5_#!HYX<5-kt%DO{pfLTA~C1lzGe6w>Ro^l>tk#1I^^xj|70Fldg=` z(*wRTYyj?{;o*_51_0JsWF7&>wYpk>#EULpbj z*m=t~glhvSS%Ad;v6(q6py8FSR!DctJ%Bo_6`2D*Z|myv*4N?y#4v_wV=RFGp6>HZ zRzu_&CUCvVg7_}s2ms~ELqkm)>t$a6SWg?Tv5q|v0Gm>CFn;@6gHs4-5OvWsn3=-_ z_?vajiM3rg%W#2$(ejO02|ci@IVy7{SEC&Rdidp-5EyC6$mxH_Mh&g7zr+Eqij2cC zW~GPufN{QWWJEAM;}8sJ$m>i?z^CyyCUAq~?gc)b&DnuXe?Iw$jWr?!Hs!Z?(TctN zT%8oS`B$N*KEAurp_>eBSJ0*@pt!+BOv|ajm6k%}%L)YitWSIEjSB!H`5DD!h>|8kxwC41i@_8DnjIEdey=>?{C@1spkZYEZG8I7VPvmOE+iR@+MffRg%TJEElQ zDF#0+z4qt_dr1K3Og;8eZYs-o1eDJ!AX1P*bO2OZHBN%Fy&{7PD4#S;*FzZ-12A*- zoB)Gk*M2%eDCfz*hB%rC53pn?dtR$0^J0h+m|T6gF&^LpPC(&{^O}`q-ZDbyfVaQL zGwF{Q;M`Eup5#g@VsW?h<`?i)fg zn>oc>3J?I0XskZVgn;Xg0@NuV()H1x*t87S{koLq#HVx@Ix(B-q?$Q(LIp0tH!shQ zZHAxOVy(zYXLL0cv;zQlQ^qHI(Pcth>bGO;98(`D0Vro`Q;XDPgzg$JD|)DAfCQx< zlrv+^$K_a#(+iO5#!Elh&A9`>GBn}>4LnZVTCpreWzwZ83P8y)5{on=ySXmgz~J9Y zNxz3C!U5%7*=+u#DcRj;cX|D9s{-u6RkN;poUGyUXp_X!eDU1_i!pTo2q^XjW5F_| z#22tIe!`I(`H15HWlUgPfit9nt@W<2Jap+gWuqPa6dQQIrHg6EeyHAZ_gn$GG`G}2 zi%G9LCJ%tJ=g#U5A}gkoSmj&qg}|@R;wBs! zBYqa$A>a=@P&a=uCI$f1Y2PmrH?Yc{VvfX}&&HR$22g zK>(QLs_oP}joxT1dPl%7U7#BBp}k)S07~Ax^q2S8ciX}?@|xjTHW>q#rI;n>yL$Bl zUK|R`?+2P82TB-2LF?pBt$Y;b(3K@O4NtgB!xq(1lr1fC)`J_VEmAV+JYN=se_akc@| z&WPb%8cYBXVk`4;@Oa`e^K234)qcT7-^Tj@AF%0&datyYzh{$e@jJA6=77-*<=ioH*TfaCr zTP;+rb6G6Q=RYh^y_FEJxOCwIfKxrx0pkr9qL#1~Bbz)oO;p6!0~df^e(%`2L&BT7 z)a9lCEufL&b#jY4L7=4pZ~%+A@haF3ReK(Pl7Kl~sUMGm+|o=8t_Z!%=tGSVmdk~4 zb&SdV6GZez>D4<>K+cwMlMixau@{=RIlwY5W;VVd2++-hV2|Y{8>x@pqT?OB{$8t; znB>Ps9>FLV8*iuJByfo&nr5a%q-U`nzFy4twlc-d5+QLx`uKRL2J?WmPoGn!HzO_) zG3lMY`@9Wf2Wq$6{@zV>JxGwqa&?qTsc_pG>?$3VIGB`I-tT#%In#aY+;1|COkY@5XNiKZW zU+7g`p5C(hD|i?*mEUTD;IiLy+o95^IO;W*mO4}f7vC(TIynY$%$uAadMcpkrM-+n z_8m+s+5Id4wiaR}TogbMzBun%LnE$D&M)%$SS?&{9$$3#Wd9CEg)FzS%I4;!J}~){ z^cOa{@tu^X1^He4;*#y}y+yr#yy>dnzj}UIZgUczh$8>l%ke3fYU5`MYVt>~d?%B? z9x7zCcP!8j6>{5*_60`_+W2abZ7#yr%Sy{(@%$B@Z&%$PXS1775cvP+50-arG5We_ UBu_mZ Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 091/228] Update readme.md From 744b6638c16fae10b7262382403dcd4f85558f14 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 15:47:30 +0530 Subject: [PATCH 092/228] QR code update --- .../deep-links/qr_code_generator/__init__.py | 1 + .../__pycache__/__init__.cpython-311.pyc | Bin 0 -> 323 bytes .../__pycache__/core.cpython-311.pyc | Bin 0 -> 3705 bytes .../deep-links/qr_code_generator/core.py | 80 ++++++++++++++++++ .../deep-links/qr_code_generator/logo.png | Bin 0 -> 47774 bytes utilities/deep-links/qr_generate.py | 56 +++--------- 6 files changed, 94 insertions(+), 43 deletions(-) create mode 100644 utilities/deep-links/qr_code_generator/__init__.py create mode 100644 utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc create mode 100644 utilities/deep-links/qr_code_generator/__pycache__/core.cpython-311.pyc create mode 100644 utilities/deep-links/qr_code_generator/core.py create mode 100644 utilities/deep-links/qr_code_generator/logo.png diff --git a/utilities/deep-links/qr_code_generator/__init__.py b/utilities/deep-links/qr_code_generator/__init__.py new file mode 100644 index 0000000..751f3de --- /dev/null +++ b/utilities/deep-links/qr_code_generator/__init__.py @@ -0,0 +1 @@ +from .core import generate_deep_link, generate_qr_code \ No newline at end of file diff --git a/utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc b/utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..03e3ab7466373f13646a04ffd6281eb2ee261e98 GIT binary patch literal 323 zcmZ`!Jxc>Y5Z&DisDVJRuokSYh})$S8&k(ZY|<>t?I=t32L1=RTB*?>#83$5dkaO!V$qM+Y++fqr6RkNoE~3+H0eA zkc-%K9zss?dbzkd?Xq41vhZjDY&cP)fk&yCEIwSb5IOp$d{`SA)0rB?2gy$4a}Oo@%68BO$F+@xf1(idI7TsCw@B5gUTk zJ2U4#&f}hQ=G=4cmtL<6LHlRhZ?VK7^bazrH(PD+It+siBqEVYpeX5W2`Xue+NkQ9 zJ!-dbbddNKT3Ij4v*yG<-`N65^U9r%YDGf)Zbd*YvSE2A~_h*Di`Er#0b9u<~wu0!z;t z%Q-4bmFfmIR>>fXo&f)|h72&0D%o2|Y7^0R4}lbVFI?+xXrb#WR@9Itq;3mIK@@~kXk3o3Bymbp zLzkz=$M_XZN=TZ7)sTYcu!2)@d_qd56PVBlB3lSwO5N;A1nN3TxAu1CV)GInWIQ07&WO$&+uB%b9JtlW;N8c@#H z-KcnBH*?>+mMA@d@WZF(0OZjNZ_nSo{NKF1?(H+Yefh}>?fS)~yO-7nbvj_sfifMa zbnM?a`|xbllCLNK68>ZO57U2|hPi%d%mCOiZgh<2!!K#)FMm>Y4Z>UWRC}F1X3)pV z^syJd{blztc#DUsJ*+82jU9LGrwpZ2^YP}>!UC2A#p{C*{Ts;Ha{d+@(YN;rYd)(@ zw0oX04U$s5wVnZydIB0fYiQMaiWZ56R@1BmR~;`pYKv&GAy>4C_AUAe?Eb8wLC&7F zmz;Il=KkI60F+HT?9z(N7Tc;Zg@Cr{q&LwzL~hIZmOXTqE;Z$XCTdr!+#I8kz^S!G zUwxFdy+y}n+5b}_E4p)ztV26emj!u|U2Ln*L{FeTd@EaKz`h)(^*7Myy)wM-lhMM# zwc3z@Y}UGxbAnamyuZ`3j;wRerXAcxERsBEwYPlDW|_UMd!N-A_~)W81JT#Q*<@1- zXVdyF=bSC)$}*+Sx=zh~md(1dY-?0P{4k}iW~%x)OSSq0YF7JI)Q_|e>l6qLAf*%P zMre0M^jmrVttg?;U8H@qO9g!0Id=gIY6e%}-bqR=VepLpBW# z^Vb&eE*r1OJd_$DS4#03plaI;)!65x1dgRZW;44rm**^cLO`Ub!cFLR1@IENpbYWj zcurVJXuPEIeN9=hZ>Xwp1Zyiws-f+)oWj=587?8u%OrokB3a@Uxhz1PXv2yklY*xx zxO&IoX60KkRmxzKos|_4E7#z5WS^5XlbKBj@gzWEz0!=mj6OqW}NNntKBr-8} zEq1}=1W}AZ=@d*lDJ)^rMPSVGsp$Z|n^@5ll6Os7PGcyoa|v0{Oxp5I4g8@z+TQ;mp-QWbKA-IT>nA<{!Ku^w(UVq_XGEu zd;Ox$^%`7nnd_}^t_O}a$NG4|p>qL)3zWIQ_rA6V$+cu@_4%1XQumD+zOjP6(%!kz z^RTD*W4(RAXdfuBuxVS@{Y){a`v(mFK!L9KJ04`$vc*Z=-*5Q)3-mVV-d%8#uJ;RE z8h?CoQ+OQKdrum@C-u&g1@1*#$8W9|Pd)m$H1p`3-gVsQI{sDH=B=kkwvOmsXZ5yW zqiwjr5V?2O?i4SUR?0mmzFOJJ>HZPJKVogrbM(;%CE?M~=BcfZzn3II=mQb0LEZ zmAO!Lz12(LD0ttzbRXJAHpaILUU1&B@6=`h0K7VP+Tc!?xziQS`@-G1OJm) z+1CfJ&h;Byf0^qC+BeX)84wJ;+6@tKcZ!?xpl>~c7hLvlf6#G(v46)fFb-16AwUOR z3dz={{mR8~?Tjp{5NmezwyJyp807!~?F5hufE8H^xwcrhH!J>jxN}KaTuI>b$_yY# zPEhXv*tSy?RYBgo^;A$-x%I6eciws`$d$LA3UcPH=X-Y`&w=}xuJwg&yKSE>@7wmU T)bVZ90G($j@ZNiXrQH7j)68Rj literal 0 HcmV?d00001 diff --git a/utilities/deep-links/qr_code_generator/core.py b/utilities/deep-links/qr_code_generator/core.py new file mode 100644 index 0000000..10f3b62 --- /dev/null +++ b/utilities/deep-links/qr_code_generator/core.py @@ -0,0 +1,80 @@ +import qrcode +from PIL import Image +import json +import sys +import os + +BASE_URL = "beckn://ondc" + +DEFAULT_PARAMS = { + "context.action": "search" +} + + +# Generate deep link +def generate_deep_link(**kwargs): + params = DEFAULT_PARAMS.copy() + params.update(kwargs) + query_string = '&'.join([f"{k}={v}" for k, v in params.items()]) + # fallback_url = "https://google.com" + print(f"{BASE_URL}?{query_string}") + return f"{BASE_URL}?{query_string}" + +# Generate QR code with deep link embedded + +def generate_qr_code(deep_link, file_name="qr_code.png"): + """ + Generate a QR code from a given deep link. + + Parameters: + - deep_link (str): The deep link to encode in the QR code. + - file_name (str): The name of the file to save the QR code image. Default is "qr_code.png". + + Returns: + - None + """ + try: + + # load ONDC logo + logo_path = os.path.join(os.path.dirname(__file__), "logo.png") + + # Create QR code with deep link embedded + qr = qrcode.QRCode( + # version=1, + error_correction=qrcode.constants.ERROR_CORRECT_H, + box_size=10, + border=4, + ) + qr.add_data(deep_link) + qr.make(fit=True) + + img = qr.make_image(fill_color="black", back_color="white") + qr_img = img.convert("RGBA") + + # # Load the logo image + logo = Image.open(logo_path) + logo = logo.convert("RGBA") + + # taking base width + basewidth = 400 + + # adjust image size + wpercent = (basewidth/float(logo.size[0])) + hsize = int((float(logo.size[1])*float(wpercent))) + logo = logo.resize((basewidth, hsize), Image.LANCZOS) + + # # Calculate the position to center the logo on the QR code + logo_position = ((qr_img.size[0] - logo.size[0]) // 2, (qr_img.size[1] - logo.size[1]) // 2) + + # # Paste the logo onto the QR code + qr_img.paste(logo, logo_position, logo) + + + qr_img.save(file_name) + + except FileNotFoundError: + print(f"Logo file not found at: {logo_path}") + raise + except Exception as e: + print(f"Exception at: {e}") + raise \ No newline at end of file diff --git a/utilities/deep-links/qr_code_generator/logo.png b/utilities/deep-links/qr_code_generator/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5f98a832f3f2d3eda417d0cd07e59eb5c4cef896 GIT binary patch literal 47774 zcmb@t^+VI&7e78gK~%t(h)Ro;NGZtZRyq`@Lk+5C}x3sPI+;1R`n!fe7jD5Carp z!)|X7C;+7RR{Eod(H5G-!(g)Z=<{)qDg`N11Pcq(LcF)5g3KKz0vUxn3m?Z6UKBGb zK0A1PCwcKZSy#jSOjp7lh9nN`Psupk__`CV2iCI4l zdz*PI3vpLkxpv8)N~%$-y2jm14={Qgj47<)nK}!eB7!W}CfelN-p+R{9+@kxeT&tC zd)N4t9@@jB=8Z*f*rkGEdaC|hk2mQP$b2Y&o?`^SQJ(=Qf~!)86ygIzM6L&#H=-d~d$+jHs?nD}a4*N7)ZlRpD7iMg63ykT%CG+ix) zxGSzSs8gB;9KD=QEj<*3yKH3%--zFMNTVx1#e6FcJ{?EGB<2w}$*z0mZYx30rtV&(2s@m4Dbx zgt8TBp10;7*1T2ICpvh8thvfPv^ck-1xBP83#Cm1rjBdmp!AWd52YxquD zw=n;)%YnD?b;_ z%rd*?xiM8iO2mV)*ez~qY9>ZJKwGc)kRKj+gnJ4M1vnHC9S+;J6s_94`av?n&F!?W?yWBUA%R zw^7qHw$~0f3$pP{u4fEA$O; zMutgSE^GaYYwMSUXrw6WK480#a5vjwgnjdmNA^^0N92%{W1aqU|35S)sQ*E&C6hda z1d1+7m@-MepDn07+GGUHzDxz?fDS|~|CAoG!^@JTUk9|Z>S5WButYb)pc?_l-4K$p zz*hmS{dCMeF_(~==p5*Zw22!-RXacPf+qCy+%hlc{zrZ)l6_e-rSdhM@ewGpP#YRM z)xACa5SZ}HbQ5&+2EJY^Ll#yK8fng+8iy3lA-I7dsg4l>?0Yz}wvYC{6+!ml0QQTg zIJG5e3K#>Sl}L(F(|tBVezyZ){S!@deuFoPn$pQthQ}dRWV!^|x!j{?KQ3u*0c2MZ z`Y(~uJ)gan!puH`Hr}kA{0XlKn?oo9V^W19?d!uKt3#kB^`@zWBPb<695H2ahUB`J z1-<~eCWS(*<`G&qtZADdmoGr-2@Eq+2W`OC+nt z#nrOu6Dfi=io0wwtWi^dQ`u4D(tlSWjZ=UA19>%Z!TYzS#Q^35X^~fS#RA$`>tH5k z&;i5R;kFh$<_P)>7(2T|f8S4@Gj~Y{m;zUU<7N?|0D0rLD@e!ydmG*qW+n^TI2^Fs zeG32Y2+9nMc~R3J_^NW|FL?l)h;Coxgz8-2W`SBl$d4SR?&<|gfi_ABA=krxa3G>m z6l^i$w1f4;exQIa!VvaZM8=JLQ`h(It#8481fVyAc6U5lFK?<|0D}yPOZ^??OoHtE z0qiRL2+9HQK1_a_D8^es3t|f0ksgI>n8v~IOMT1=K_xbW>Ogv z==H-yF(N7X;?bsVKlp9H1i>+axjXR2sWvju$m;=~QT7=`%Z(AAL|&YSOgTU+h(Q~= z$QlV#6fv+6+21!zwq)Qk&}e{6w|00me+0crq#`Ng9p%#{4nklekSkyHa0lb|v^hX` zC8YNtoA4TWGa& z0Xqo=ZsnJ$K%x%-kF`%)KrE)R?}4J9ia{i+jFG^Cjwp!~omFc`2+R*zikpAb}p{(547Mu(28524a09Wt(M1t-~b6(5?Rb7{tX>7 z0m!TPC4fL9fINcTe72#%jS>(76go)5Ikz%zs8G_SC!jMv83525v?06qK+kRwfdUrQ zNJNuvMjlAt^gS(c4*-xv+^+F6Ilg}b5#>85P(Z+A7FVHNe+=fXxWij z0wImygI`y90~&y2(%z>B(Ie{y?5gQCg{#lB0Cr^0Z$4Xn1oxf#a~l+Jq%bBjxN{SC zv>XY0XYG`JFaSQ04mS7_3XB70w$Q8 z4I{P|fsHk??Z42at31S7AvxsfIXy-p=1@_w17PZB2FGXG%A1_abga~U_hvx>xk3Ww_r-Zo5GUu zvmEp?5Z-^ACQHna)2U~K0Dy}Wu(>b!QTOL0W(P=s*-;~bZ7oL|fL%sgVB`}(y@V7A0cNVCQXX*n;1d&ke>?LIkPKhj zUoqG6!KHx!_)0ecPCEi?(-IH9n%)`(9PsTiM+yS7jTF+ZRw44+F*mdUifsm9VZHvd zKVr98onZ!OXW0g(96;05k_0~c3OgnNWmBY?90MpAxn~`B9fLk30BtM}FiA^Rc(VZ} zx7Rdg{dD_fdj`}+XX}x#FdU#&JRW>x1FHvi=b=%(H#@)5B{p zEMa(?c4`AT)s6%BA}nkoYP>lBPNtd|_4-tx`diQGB9m^|q|#1)Khzro@+YM0U=TMe z4#0@zmHlFH&5^z;J+R!oiqHzQJ^-Ddu`XXE8mOvL-_fSW+5l7nYHYIdwJhA70nMKh zAdI!%0N4~>%~fD(kV1ftTEQ)b8r z^p-(rZ$O;jNWq0TQW;1ryR~y4 z*vNytTSmZVQvi5L8d40i0!A~~-U)F7WzJBYcGq~j{Duq7xSe_P83V>p*5J1yZ@wEw zPQ6D80y@-wMjZPgX>YW-l%mrBOV~#WyqglccYXnm^*@3Ffd|%m!(`4Ws~&li0-dib z|3{IUvy&{QsuBGkEdf$E-$HX!P3&tlw|8z_9CU#pZVZ=7+j>&-Z)@m=7NM7L_!(&h zXoHOri~hE40(6{5)O+6qjN~ibIc=TjO%!2FrjMTjeR*z#TMgPCu&KkNeFqKjlGPMv z=B(C>0^O9tQzM{OF#y#AqDcF18I}YffOMSz84d{797?0`NK*1DN`9)TVw0JVL# z-lxk;un_nNK;{HC>kFWYE*v~8IfH%#?6Ic+)^7kA1RjFJ*a0iVyIvye0YO4FHkpp@ z9{|nE7g6YCU}L|dU1LE8-=KEg4cQH_Je}iGpTy78-^dX%f>UlA0XgAk&4)!xcXeQ% z8QT2V3-}x+MP1gC&t(9O+<~t5mLI@$CQNYRjD+6E!Vx0Zi9jRkHo-pgJIO$ly3=fr zeE^m>_K{g5C6%IVKuGrpfiAR#5y%h9w9C1$`kUR~h1y!A07+%#seZ1|4n%VRE+b;> zj{SkDEcV|}6-X9fqFXC83P>6oE+K;m;NzaeBqU3rr+ z!oVG<8T5Yu4I(&W224AN0hwn*pk@?pj%B^BFOynS+3)M? z^i$-a=G2%?==aZUGNVHTW>W32JGbn?-F=5sJ@06O!Z**!=(3pn^^Ko< zw$dcZlUj zv3@48=rUAZ6644{;6k|1j_HfjI-OJ#BKB$^gkK%a-1wLSGfGYjPl(?%QLm>JnX6i(Y?J?55d=8m+x%MGh+03*wuUE zP2;LpHZ$`7-eX_8rm)W6->$rII1ya;WLu2{ME`r>sKC1ekDrn`#eQSP2fqtn#fLWH z5oGW9?2U^l!BK28jloA$BrCD3om&&V~HB#kKSzrF90-w@ip&+wu&(UG@j5|qxNQ~n|*)`XtmX-m7d z_Z9%ns65r}eOM9@Arnit{YwFSeS*CC%*G|(ZvLh76t>uTbj$U$@8FH_W`g-9Li*%~ z4!KYvjZ&Ur+<3q2kf%S1dQbdyY8tgTlMU!Cw<1ELC&LzqnA z{bv|tfz7yVEqneQy$Z@^p0LHIrTmML&W+2*C@bPai%Bf}3e@|8Ylp~t-5r4&B4gzQ zKVF9Dd+X+kkWjt5_L54+MMdQaqTr;yuax{N@ucDA&bA3B&`5^kQ_oH}{B9&4H6N2K zv3evO(U$s%S$ZJ2Vd(!;>fO2H1RD8ofLKS}k#`hCr-v8gt{t1b->*eolEC?dF)@&L zCy7@@Eg>PCXmF?sMz#N@AkSmPOp`y|Fq_xdRk!XjG3!TK|6|+z>p7=i?CZmlTXcdK z#VNB@61;!tuJ0c_9N&I@(*s34kKfc&hLV<`R9y~VZas7`1HvQx3gzVDw0 z3xKjj1-NqvD@e<$$4XW-`JK(%eyLCkbI4vbm+RJ9-zmR8EnGdn)|jeHx#FG}w!)5k z(vz*I=iITvb&73z-YZb3suX=qF+xza^*^28z}4!rXflw9QubPr7?Pil$PU~LN!40S zH=cggO>$lWUF9vkXR)hHveIm0Q+1~B>6Xbpoja9IKO&K;=Sy$OO%Bp5R2__Ua7c5lFP%BXUP1 z$ZEjl*VRS*ah&P9(8&E3m|mv2c1YgKkJ$7x>x(+V(}}z{o01}WJn0!c#jBH_lb*P< z?x(93wZPs5@?)Wi{QlOEL?3Ify8F~wI|IbPe|0`bgLJ~{@J@V+aHI3jMKDr=VzS=f zcj-U9)a|%zmu4sTYsUccV|{Nfpd>`)MA!wPX8~lT zQCg5|o(Ne&e|5>qSYwJae#U&=<4+(jeKY|?_RR^oKeyIdlw!g-JALdq_=z&?om)Lu zFgQ(@H6e5*)#5Z}SM;^!m6bzebK0^CxRq~72>Ft0od3cZefIEluutYRr4@%bz=x?) z@kw?T5=i`djoR2gnlrm;=Wp46vQje7)dX#P6iB@*xN^Fh84-%lFD6;Nr#ZHguE>GU zy)Ep#fA;+Jq~`u+VfzX5vc}3N_dDlb)3s^xDZ9w}H!Ra|E~muT6f{{(>%2nG9j&~W z3njjJVr+faKlw*g?`g#tX@8tn)T_|$sGQd)YDv=j$-skibc%c#B3`vEVKQ751Nmlo$HCf^k8M2D%>zdg=#@z59JKke1+jlE5=TnKNdawFDRfQ#K*VYRnqTHHAY$Z3J9<9CC$`PSP zB2*;AIkbo)6=O8J3VX+q{TV5fmMGlXdSkg-srElxXgc3?+I8C(*-YEh%Ws6jHb28K zpEvO-)U$ZCI*f4m=X;EV-KMP}1?gG$TsUH;U!JeC)}_}Y87VK>cHs&y)aT4@+RjXH zMGH(`_AeiiG^MUgt=q#p(~4Sd@JHvJv8BPs16A3Y=XZUpP;IpJ8sB|l^=P8Y@Y(yX zSp#XT*cY?O@q=Tk{P!#+`_ zi}QC2Q)!Y(+S*(C84qH=p1Msk672m;_~hHtTT&A9MqQU&drIk>5u1*6O21ITPe;)r zOw#?!WFP;C`0#(}nCpKc`wcPOf|#Kb%m>#%vZG|6xeF;6#D4sG!NfrNg0DGhAn2sC zR-=TdjgJ1l!$5ItK1u)TAo?BtU!qu}uT6mgzdg$5y4KLScuIKKEZ{3>;LYI(}*q#d_)*x6_7Jxa}$M*B70MHu6#TgJ}9%lUWzZCQs?zCkL z*C_6FDRkH&v3b0exp6Lsxz=m(`E0z*hl4H-H~LDcjYj+Kr~2r*%%1Q^zd|!jGX(e2{|Hq(Mt)%#SH5;YL?m>I9vSn$b8Cm z-6{Q>>Pm~V{p2Nh%8VIlZdLp!LKd<-%Mxf1$CPSDlT--1mb5xmH-lazC``w6-Mb zG*Z0o=4pk^a#R0~`G%3@A47(s7{l9sDOE__@{ANNoz_<6)`N+)vk_a{Um2VkZO}fl zHhYf!%C*;W*1s41@#xak{V2!yQX>qv;IMMc?_P^oBW>=*e?2_)FsF^XmW{^|`xJc@ z=hMBO!ww1E+UAOxh2Cljad%WeSIbof)c7C7v+VA2eFpvx$Cb*O!*cyC^!jXNtre)# zv1j`Jn;#FFgxztL_ z4w3!MIHM%xI*+==4^~pGMZFtuSldsPl2|rL@cFD3>0>8XcX5)z?0or8MlY4tX-I#I zY+5d|vR<;`$+ug^)drVEE7lu^35@an+a17RM_@F(LET6>c342VX?@E!=G7rvG554RS4zmV@UBWyu#I7@4;5;J0;<=6x9QgyyzOpo zAI7=_#(|abvb?ajd@n}hbNuLJWzl_X^Rs922uy}9Z9 z`$FY(@q(+-xz|)LR&O;VVcCy%Fb9s>6Gm)pJkY7Zj=1GJ#gK7fq5z8R#n;n>7qaARiD!7 zd-CLQ-)4RKTU zqT?={d{DAQ)Xl|`?p#CcmReZ38L|0VL+x{8-Nb@~etH@o$?F+5vJ6i12I67L`PbF+ zqi%mQI4v4d?59N5V_W5w-$r0M6o6HyeWE_8S(bZ_=kCZuslBF86F&cej({U_`{krMbi=VW85V=(x zK%QX!zc4Gz)r3JOXEN?*45z#+7X3%p*|he)aiL}-+Q)7}jv6-a%x*Hb#6N1AOnd-T zi8%fpeP(|z&UaGdy*Fvrud>A5LdE#b31;K!3MFna9wsR| zEkE5;yDY92)~+ZK!{4J}#vqKBCvWqe)YfzXKvp>sFr6`w!_gK^qa>~?nyU~pd}3?S zfy5MO=49NvNQ7L0<*k*V1P1Ci!*`p2)Z9`-R3WZB|F=ql$LNd1j#*m$I}8I^MO6RG=^Pd&=)GT@ zsms=!<%gj;U7hgdvr^A-FPoyA4`23r3_rPGyIXX*!{8D_eX8Z@ z*|?=L$5gN0tjFW2E4$l(>RSq0=&9_4Ed6jhJCTh06Dyiu&LxYJJleBdUr%yR=-XVT zP`aKjqXu5uLbeNm=|qq7`~OT+^j;4Q#x!mk72lb1?PL5R^3BsB^Pfmc24(DbZBO%P zWTTed?=WN0M@Z>LG=UIXTixdCPcjH!)Z%drE5qqB7_s$&Otf%KX#uAYwOb|Lb#t1w z?wm6R&`4gbII;K~wIC#_sMhFRTkYCVA8K4baJ_xtta%PZ} zs+WTCGE+tGwGpB8zIlXs@Fd>3@3x?0irtf)@<5-Ehz}5HX^a$xQ zZb$Bet3OQ5j`Od6rO$W%MJsG6F`7Jk%zOp$bjnhfI8&a;JlE~Q5}unyz}Yy0TEt0a&~r_>%0af0=FVD5j-HjsuyPP zXaUSLXp){8xZ{6O49735`EcxpdZRzL8!`l#S@~ccagvW===XH&3w3!rvj$v~Qz5>p z_8GSxW0H38p5HqezE8AW^@_RWY*ythzT5IAfe+wr=<;2eU+I^?U`o82xc-Y z*EeMGR+c5Ly{MBzJtjH0KI?`j@VOfCOHadR^o#`$zyd@IiJ*lgDzeVXK!~INj(Aja z>|>`P`t&dU$r}WH+nP#{KAi|^shX$CJb-yB>m!hbCqbvha|VZ1!U zxs*8EU@`W%hB5NCg6I92%uF68Z!VgW9PTjSN8}pK-qq2)z>5Z!)LTCYKm!|)F5vhV zY1`3uva?_dpM|5>>d-+`Hz-XCJ8)N@zfG0>cE zEM|w=i>KNdAX9B7Z#Pq+CclLSPyl~q+&bWKoUP+T78 zZ{)=XQY|V$-CC!LW{6({%kb<($%hSlz>;ra#_SK|dD+e7WSkC!mX_l9R^4fWDB{x$ z`>~Q*^{<7+6gzPUu&22~GwU#{vAX@}bDP6%1X}=)6J^$L%71l>1@)3mznFRR zh*_qs5{u@InQGeDw<~WVCrdji09%*oer?8{Mci6{{G@+6>-<^Oim;m0*0#masP|uV z>B?Un_nwYCjdkc4gBr*vdM(7T`e62!G0?CmQ~IE>4j`E9?ru1^$I+6tH*DZ8Y0W;+ zF#lwG+yb}Ts@|G7R+6onk4uM}GhTWx5!@YS?Eb{sosvrsgaoSY zfZ68dbU8=jNA-peyErAbt^AKuJvhO%U0U|7E>6LfruO3o0wJ|K+g0C4kz|Qd^T(Tq zjjQ<0e1?>`O?NOzw$#u*N&qOXPv?plszslOL<+CDw-Cb-VvW6eM+?&(2wETc)a8ua zX%xR@c$oqs`e;iLC{1KE0jk*o)opCMsTRXAW&zB!CXMymd^k}VUS2-(x1A1Qb~t8`zsS6c=(mxeA07A)u)Q~C{- zRnYq^-!?ghUD`x1yt0$QRZ7j9$j!8%ipRRYJqdt1*9%YwTp!>WS%kS8N4XHDt%%Uj z(Ae16=lQI^H4N#UgQ`3+J}uV~q2m_&<%19J$`6y$-Bl1;H6+EZm);|xO{Zvh>#ufI zLU0nYmMDd^KxL(D*LFJk-WiI|@$y8^eNsf+ci-GAT;r$To9vOS*XirM_cvr=S<4O- zN!GCkZnu4;f-IsLyy!w9t_h>=8*hy6Vw0MsG7f&`vNX-lOeiZE0);$YL-;5ND_p}f{s`GGc!M{TsYJOtKxhjglC3FsP#6l!TqMihx z^GDbgn$k=fMP<9;;oyJW_R&jceiUUrG3oe#kO7YOkZac_!(7l-qPJKDJxnzvo7Njm z-lUo!PP7$jb~r` zSGTzxh51{+`>*ut>|&;kvYu%c4n`kh1r=awgAr6ggRk4&?Ku(%jn~s<=Pe~<15w%z=nt%&i!UAM zoYG2XKy=>5%~ioRNm_4KroxT(4I*zFYqDKr*3B$$c^T4~KiPoI{ohU5w>1=cG`htZ zE)Lusj!Fw3?sTVJ){~RA76e=%}1G>o-!vF7}d$@ z&r{(&!S*Vgiz8B02FWx--U8b^_p#P!YA!JjR=RA39S#4Sjo;ZLlAyk_3_M8Fni2ZL zfcWI@4X!t{3IOtlBY5)Xx69-@A0HI~;dAJs5mO;IzQ@=5a)^`oT$YV7I1p&cJ%Jz{X3ZdAF06cp0OY za^oT=pTc!CpRX<+D><(m%}kh4d7o2Z?N!lF3jHqC>P|YztXu|(b=s+-zB$gRvo?6w z(ZM6O=F(HsUh0T>RbE^*Ld_3{5;W-Vf=`4x(`jrry>a~mdM+%?ocghv8mpJ9oQFqt zWS#dc=8xz#3=Fv1|Gm#$4l&D*4`0E*3%B^wAluymr}aQD`(lA3$R28R7R?q#P^a99 z7v`^CxwLaEWC*rpIBhXN`MCP!95~va2&{(bpFcG@mN-8#77URi+6%bNKz&gsA7-1f z>=4d7;mpIV921VcWZzh=xJ@`XA zN#nQ8`*7}`tM>qK{Z>Cte29W|%bbVU{xkQqE%rI=9pt;HqsnO7OrZ3t4MW!%$k}>a zZUkdjT%zpbmAmYc(w-FbYC>HsIugZFngukL1+3LxF{=r$ z(}Paz>VQ8~sKxhP_?GrIParsFx@9>-sFyHQwU_vftZkWNW&Ot@$Fe(>;=Ala{&94EFUT%@aRy+u1nYLuZpVFd??+s%A*%qW#6qP?7Z^j zqJCqf+(+lGIM@+qZz6#H$y}E8iS5h!jcn?D;7L zH>hkfARgqgrE}2NfPuhNv|eV)MC%~3oZz(t;Xqhk7}_OCt4~0`*%@P$C6@LudU}kA z4?OtseHX*G385BT=p&R^4TfFN;jnL7Tf49LJ9E27Mc6b!gk=&sTmL`G5Hrl;D-gwG zn{PJ*8LIs#E0c^Y-7yMy^9x9B*?u*w%)w1 zkWi+Ih%TI_PwZ#giF0AVykJhJUaA{5K@y-t7SGnv_TNj#sJ=MXK~8a#m;bHoCdhVC7?^mjz_-biJ74Zl2H z@t^7y7(eR0Pu3z#LpQh%Mt0R%-LdNOXM5@`pkgoaH_m&pKN=xkpYQk8HFte1h);St z#K;A0(3B%s7q)T9jzOte?(mGYja6MsH&dHXdZ|8u?R@76b$H|)rFki5|1IRthnNRG zKaH+O^~24ftr)$Z=qjrz@wrCEB_$wGRa4(UmrE#8rvN0H*n)EF|LQT#>p{tN&rOz$Fd98zw ztb=MOOnZ+IAxdeVxvof)ikn*=2RVRgt0jqmpVS;B1D%;eA(?GDx^e_;2}*!GjQ%d~ z7-yQ%fZf-lu#YxYn`2hiP;z@V+sO2L;MaoWVDVDT=Uj6(0D#P;4O0{ zb|%tz0OZKnaGq#ohE}OHo~-5ctD>R?-L;`Kc3MG)$63Sdw?p6YnN889@Ewxron4(* zxnm@(PF>){oZh6aWdVM^1E*fsn3rT7{CpM_r1h17_3h3Z8~2@*qpl-3`0t5X%Y+%A z3Ka0Z0`&O(_4F%6Sqx6HD3-|uK8s1YJ%$_9<_fQ~3dlV^oStVEIPtU53l*!xaFTG! zz(s!La33XT_lJB$7*sWBNL1yCd6iYr`V1bL)vJ&0dUrc8(i*vyfBwIbZ~R~6>!(P7 zyWxs??KgLWwz>Jwy}pHYeFvVb0%mwXIPcbMNCADVTS&L z5VTo9MnuKVx6G@JMTHb>Wq)?Ya^T_Xtoh{iTe!7f_u68}DxRl(YMiDGU09AMMeT4^ zAnE4fXAQ7vK!5#J^ezhq8p&OorFsn21eHq?3wd3JUWz{lO;1dGk#x&Hu{7pgB-Q!i ze$G`4E`0aR&#alogd%Sz={2tT1uu`6T&DlI;%uvbDL;{&%r41%ooJdVy>Ki$E!ZK( zX5322(y|~#hTAyEF?m?K-1u0STHIN8GfLGeKYozmm>;$(; zBy;SA$0Ed9^yF%mlV?3FI&e0}WwFNU7+!4EOV$TFnI@kS{nxa^R#qeASJHSL;{K~g zxPlj}vK;MZ2|Q+6pje`c#zkw61H;nQ=E8a*rfT6m!rkceX%W-fTIDRDdwR1AE&&qJ zMKSQCu=YD&KG#UCe}MJZ$0R1}6Y`b(C~;m8t$b-|9-B?hiRGnQv*wk$Pg<9vy=P)I ze+}}x%L}?#lV{JaHctIAqQ-IhetxY3Y4uW5<@3+JKSpt41?`-`zim0!(=k+&_>J`w_z98H?g*!BC-edP)y{;L4&6 zxG3K6C8}w?@N4{`cuyhbD$}+5bM2buSw}6OsOXC%L}~2Oe*eEt#O%AXETj)`Emwbw zmOIw+f7M%iE}hs`AnT2jfn~NKby^^_57HM0Y3vG=NpO~rW91912K zr!6@Uyxd;Y7p1f6u7JSLugihz)2Xf1BYHtzVta%Y-e=4% z7YKTwCy5BUIY@2oX3GoqJFXQfHnFc#(L^nhaA~A~lMJ$13V>P{< zzWz>_j+gLz?9WLCJuj9Qt&w6TjS&NOr-9#SPA4r9KMdZp$sTy7?xt<7CS!O$U6s6P zWAFw*XkYW%cWy`9TD*F1V)17H<(+x&xo1eVX%qL(AX(=IzKI>ZtVr`J8Q8np3-gZ5 zWd_{V&{Znda%vjb2ohJ*Esn`4^ix=!AM>oNS3SZ;X%Bfp6s?lZ_bXE1wVn3LH}`Bm ziGl9K15(wTq_=t@-A1m9&Z#Fc*{6y;w-~-=8RJX<01bavJ+N&dIt>Wu_PIleP0#Swwr6 zo4B*hkk`UrSh1ZPx_Wwe7k^C65BbBIYG3h)S^-~rx2kdc!re%Ox|17IlaQf*0*wfT3^HJL1*Hpg} z!=HjACe=UcdW_fYdMqu`_G?f^e1h^}IW=$XE8Sa%5v!wlq$H;|aurYdJH>Ex z-D4Gtv^b$BldS+sz!rj|`n*~ci=`u?W51XhCWa5^5NOm8nMZI-UIKuo72T>HEG z;Jt^sURhHuYN6xPZxi3ir{uSVN6{r#RaKc$Jm|bIg?_G6FZU5tHxhlnl-^V*fH8Dw z=oqs@T;Q5Jhj@k}WbE(tk+rC$%&%z#AJj~gunough^?)=sFbLyCDQ}B;*b4yanwSp z{@T{jMgB48%JzauS|+7e3wEm#_=yr)j&@w~f1sf@wJ(srIzP2{mLb`?64SumB10wp zSme=n8LUz{=VxQ!U#{k;S85gak`H!aM6O>8Sd^!ILlc~N5O|#ULRZddN{%0&Y^m!E z-}*x<07^?S7ToRHA+!&lmphCuju@SLFiRjpV@Df`UY-D5o-jq($D}1%_6_+UCTjL| z$Lef9gJ9scD&V!@U%V_vAh6`sX)DC@eJ4(yEl&|O%HfPI>9ACnxA1f9Xb+gsT2V0c zgyqQ)>_5g{Ms{81hBiVAiMJhjMV=E0IQgv&(xqhn`)nDq-0U4UP}#K4?~C6|ndQqS zW16{TQuveBRG2^)hdR6LSibsP#IfiEH>l|w-)%geRVCYZFC081GwJi0PJjL7qkhGV`dnmh^V`nL0_M|dQK%z^ zuHhH=3IQG&{J*f_gcZv4r_AOOIx09oqG1aW*$@cZi_Ef|y))|b{FfdVWZ4ftr0}v_ zr)K@VW$4b)033mq{q=#QtIxb+%z3SwzLUN$#NbX^qldRkluDa5rZk_gB1jZHhgt@2 zo6M)uh}h=(?9IaYuBE=7sJySra%H#m21RNUatDHq1u5S!&S|r;qY__Ub{F*SRu<#` zX7a6L=coo;UXV}p4bm#F#B-$ZNd>RZI=g9Jvml2iUMcF zYCTfk6!Nh=;qCcq_l=5u1FQu*al?ji%;Faa97~5t?K<#9c>(Fo*$4j*Q(qa-))s6X z+^x7qJ zK3V#1UH`O923OJi*g4&!RBHx%v1iXr*EqxS+$=`=$vH&i7CJ7zYGa;Z?#0xQm7czq zYfMMj{#z+xec=V*e+8vIne5J~YXn(v{5a|27geyi{%&AQVjt^2_kUIES5{9Xkd<}N zdaGNb0gqMNPrQdymAyz2#3hVQE54;M*i{&Qr}P^8km?k-b+Xyx4MK)BKHUW8*-_S; zW~3u?EdM`n&~hAy5ghR|s#jCUz!{~BULhIY-g531dUili7t;BihB7^k-uzZ8lHWnu z)*?viI!m2;*{kWBaVO^MiUCuJVjNkF-#)3p)%>z9mzpzHB%2%sADu!+?R(>WYosIV zNb~gFxXlUhuxzn({B~ogle#66u{D$fD{qNauzZU?x(_0Y9#l7E(5|={qVjsEN9lGH zxLt(bYO!=3f$pg!@*gJ567L~DoBw|pF}11Z?~T0~Dq`H5*w?0AX?a>s=LGsC3)gd2 zPj9s_aONMTD?PZHfzyodUJoc9kF#FyD7Z<5mYKXx- zAcmRve3S70F9A1}!BQsElMEDM8IQ)aM5hR6t?lp_$mjZ;rzS33X>DdJv106t^7 zda(E0!W#icgEH_Uz<(hu^lI&l3&XE+HEhHZHbX$HT2~Gmz4UEHUsbW1;l7qy|171~PknRM_-(YUj)V#!k1Wz7w+2(aL{$Eao4AYXnOF@&73 zh4U>Yw2|p;dLBKOTkgce9=w-dtp$(?+$0L2oftL!%+lSI-+Z=u8xAd*1VMckQ1-nkFYk z5{s7U9r*8glrnONf2go>4xXkooN36q992jcanaGfds%4;FrF%TyZXOW$R8S4mSf-L zRXA9Jax$5ES6UwH{n}5=?XeVolk%w?+0egVe|CyM2L@RF@!o2q+ozJQdGFudRSqR`Q!HbnbWa0L#@?)&@*7D@ zR=Yh#6rtHE`*=ykq#ee^% z0fAM^Zxm#wB4izLlei$Bt+QOAHeM53`T0Y86f1Rqv`a1yuG&xu!NiN;es`8@FD_Km zC5Yd_Dyhm^?a39=!*xi>Fh$Wk_TAcR@xbQUq*C@fbI;gI0bTU}Zb|jY9H$c*dcZ-l z<}hLI3QMoE^XAn7F3+C;@R!CqzTVmWFM%|ip*ySsnq2oy_%|hDT&7LD(7w2?!9l={ zc~y2Y3;ve@1?_dfNyIV%<)i(4mnumxA%&|amSJn9AZE$CA!ZuDBn6suzUy^A#N#c(L%wSSEc^8-E*Gz8Aj2oQ0 zdEf&3xzpwF6t%005hDRhaob+NiBpK>*NtM> z8iCV9(SguMf3^Ak%=Y|2F0nkglS?RW8Y+{{411)=dXIE_}?YRy$|Cn+L zjq&ccMRoG3iWF!MiMH3tczP?VlNF^C5WS-lzvM%- zlQ%DDJ8lBK#?MF-_uE)Yb|=42F1n9}dH{C3@gQHPtCfE?My(>%1_4U<4UB-R-^H&u z*JB}K*P4pfUX{Js0>IiYK~X^FYYK{`T#-02uw3KC&+NOuhgC$D5UbKe_P4i-tP|gr zd;$-CudTESGGZ+VZhKwCJVJ*j21|w&{6_jnt+`7V%BC5vpEghhTwEXFE}97r1cbyB z{C8{GGmhL+8rl*pIy5HF*ix}-bC!PS~T2* z)1c=sN2T=ZmmJSYCLasU`1)Q)=k3|g*Y{-x#81_G6Ia&OyXB8Gq$UF5OJqn6Uk%F@ z)5r@v779r%0;(2Y@ZzBT*!h`*G}n|5vevS^hmtdvk87p@pOBK4m9__{B}bnicpUvAM;WbaztinkfnLsr7K?FO3fuGG zTZPwD%ppL)8VvLR9*plgi?gVvBy{&HSW4!oP;9C)QTnnDFJBz>;;QYHW*4bV510o! znqqXR*m98balQ#AwAK=U0kYG`XhB08?m%I=HS z^^b0D+?`5ui`w3AH#eUuxUqN9Zi)Ur1fvAw5VlP+e@~H5CsCJ?c7-@tb^|)a?`M|8 zvSfUMzTk)ECORkJ7j0Sd@;YXvML#tFh2=A3$FD{V_b+~iq1eI_n_jcq(CLJTOq0g4 zG0v_8KFqF&2d6(i_J0y$xc^ifc=3=!2NG)15j-WUTVA8c6ZfXiYP%;+9VbrF=oy9! zz#|}Ax0P3*vo4^i+#K$+r=?DnVG0AS(FXf7?**p+LvR*9t7cV3Dw~+mH^$A(Oge@H zpav*xq!Yx3lkq}4dv!_x}N*)zLuC|)g1Z-VXaD$B% zs=mV-$6Y_Ju1vZN;eMZ-5TSwN`JKbbtsPif@G-^W(L%meC9tl&EB%2t(KusZ?dI~a<3afgI^^{Ph~!VY>~RY` znz374<-cw1i}H&}`aSSKCe*b1UU}#4no!8aKy*;o@3gU5p}a}DylEv_OYcVhhE3J* zht|)x(b92tC%`*ISa_5Wc)9F5QNrI_7iIw1x5xz9uPU%k67_=g|U&2)$GC|Pt%V| zI&Xm<{EU^wnw$NRh%N1JVk*GP&DBGPu|ENrTrdRi7kvUp&ag^>hh&ED8jssJltT7s zKf^7ry-f$%t@SV$!xDYao3LSZ(u<0ovoM z0SO4W8`by9jNEa&PE8su%>2Sn61JX>*wfdh4ZBzZq#VsuFd20kV3Uj8k6k43Eq+s1 zj?^tE7|sfwS^&T<)f*6Y%uvOes?veIWSKyAhHZ+jdst*<21-KD^HIJe zN0p=@(MzBkc&-h(?tl8iW%d=C_2DYS>O`E(U zEov?dGnB7iYbU>6JA!NDmbtd)MVRYBCFh!L2M?#O+X@`}UVcq+9WD(LzA1yK(?XuW z8VrQ1o8NKLJU(vJA{~v9Im#6!Z}c~}du6b3I1c3DL~6@_44`}wR7Re5(N};Tl~wcg zwkEC|vcqH&(9km%dR}g#xjy_RoMU{W&3`T^0SJ0A5ddm0kZ|}3_g$WS=Yvc|$&kQJ zRA(xq0YkZRbPhhiy38GPQQsSK;!y8#JXj`(@gR|<>J{r8y zZ%i1E$g{zNv_3o(rc?EtXN%f@j`*gT195-e_dha9yk~D!TU7W6Q;l>#{}L|7yiF1d zKwJt)Yz*ya;7+Bd7D(X~Y5?CG-65MNBS2&l7>HvR@>z&05;%Yh30zR?BXeeL~TTO;|TJDf!xrC(nKXg@B=>lN0s# zh_KX?NNA_v<$xj{&&uCy3;WYZ&4kmN(y7zUSoqVOx$g?urM0I*B>)M8A>L0ASjb|U zJd@)sWmQG!ji40p$Fd=KWF8Sx(pv=1PSR`;Zj2h~uQU0|X|m4HM1YE8fA);=HW-+T z0`rszm)y|#_JTK*OB%mvI#(PZIfjZOY^9wngsw-}8n6T>OIo@lT65jEmMmO)Cr$(n zV)~s(#6x~xw0`)6%F3jU&i&SeJdFOc+`t@)pc@+2j!#T|1E3?d9UCTn18}Bf3(vM? zGtyEfVAQEwR?Ua2HYYV~gS0Pi^B3 zV@3Ys)f-L!;K94)dlHgnLD_hiiF!nKDUS=FLgOho9Bz-t%CMs$NI+A`dXyZvZzS{n zu?(Fw;Ndf!(wc_UUF6Nn4;__Cac{?7lmYqI{wlR=#VK)Q6I*BuaoZS9jjAye?w-5r+!K#V%}RZz^P=m(zuWXV)gvZt2nYeAA_d!-_d*bFa~eFfqnl8 z$@48ucmXzP+LiUuiFXE1xfd);8e3o-{UBh{g`qct=E!bk7&g}>-uDfQ;nuA!1(wr0 zSRI(|yR$|;$h|!N{s||ed$nI*)tjz}%PyUWNll^#)Tja1hZn&B&r?=Ck9z7qUumdO zOvVsc4&X2o096DB5N_3F9xF?N=L;R%PupW@vUfLlXi9pi%m^3DGb!JC65~wdX%vgX z9zxG`lVo2>)TJ$1_a!hWra?UfkXYGO)?Y3#b2QAh^mlO;N~Gt|c7q({PC#zNMGumoL-p!U4~1dR_c+$@A43)cIg zpQ}^7I97uykfk7ge;|2E(rpKro(GpMA4rFA;Q*aBrFl;T6Z=+26t)F1%dzF2U7d_^~3GUjZFn`Y1rx%0!Ztr>}HKcwOBYvVd2P()2QNIF+S= zHIK2mM=Ge_(Q#d*LU|;e^V7CangI*_>mLVm0RvB+FI?ixm&XBEI8Sy3Lhula{7ufT zXN6#oQe)~V!HczA7Q5mg;ZGlNYYg`gB8VmPL^ceYyTXxg!z3STqef>fZvT8j)&ulj zGjoeFll}%&*`5AWah^zly*G|e`7P1~ktg{W!Fy*1r=*iaI|yTpJ-E8LYGT}xeReZ; z^Vn0gRjkI;;4!mF##BWjn_OdZ|P z-u4N3iv_X@l>VW%xnYg$o`h{RY4FQ40fs;e5oTr3>#0_tK8oIn=?AR0QZetZI{p5a zAh)Uv`l`v2gp=w#IJ)@AaPdd{E(+7t)I04!iV#4KTX{N#=t>g&sO;9QQ55HAwxB zk8VdUkhl0JQ%5ep6{5H&B(nNI(#=|p6+-4yhikhi#L32pObpi$%|oe!#Y3@4RTu3+ z_WE2lPc)Nc-CVTbn;dK#$M$Nrz*>h3$-IE@^AGSG@0<_wCLP9;R=q!a(2MvKXK|5a zU+D!Kh1m4imn@xCIWRxZZaN3jOH#9TIC@xnob9$< z0D=yr=;AgF6paP-7zYh9@k~E~=z^)eC2_irxG(SW4fh(}&J%F_StEyayhhy$Bo^-4 zIZxej(3m>eTpi;G)G7Lp+lv0W4G!k1GMQ1dfDbPe5U2>Xdq;jqbYx&YKlCIU(Kf;l zQfQ(?*Bf%*Z{LjMZGmjE^=41lctb)=K<&@Q*Noet<4ay-6K?hz9lpzTFb+fTcK#-H z*y$tx{*(wa*I|wqH%Lq+dAiKL(Y>W0{EFq&oue~--?*{_%XzrOPs>W~{Jh$%ymUlm zz-p{zHT4^U^@!e~q)@cY*or^oZZ=uN;u!f}B=Ry$9x1?1yH-)^W_`AiEB3wG51uxV zx!AS7d@d?5Ehaf=nHX251$V79+>PSKz65v%Ur@_{V@oq#MuaG{t)`r+deh8 zsV$ZH1bfULy!3k;g-NtY7O>CYQ3oH;En+@m+t4DTOf-8=u_qAvd^aO57FWwL=Ds|x zjbi4K$pRp~PJC6>YElc4nNq3vH>_frMm7 zK~|DN>C!B{F{CE~rMP#KNrZN`YZ=0=LFS@B|I+xAG?JkNwa}6mER-Af^98e3FLmm1 zx!N${)4317utO-9%La-1oNHj0>?HuN4=?h9pJwPOTkqj=9hp669#wSw4`46{r~*aI zgDKzJ<pFnwo|e91`%rglz9? zR0DDxXaY@0@ z>NL|q-cq4_SE6oN2{R~6+u-jPh21si_uV9JS(kY2y$M~Q2<-g}ZQPHQNH>Dv6*Cza zzZ+3xC}{Ockxf&bPX7(3Eml3BmguwWeP%n!+Q*XI!fN(T8ST-`8^c%|D!Zy5DZt+7Z|!a{lP(ExIV|wt2enPeVFIAz0OM{>HW9lk+EbNS-+6x4xKgF)5{;9B zC`3EG`i`)``vT!}>w$-Nu{c*@*}U{47l}?)-E~P7SVoRyVw-7VCxApKkP)wnUgVBN|GM(bEaHMz(Q}N;b`w9Gk zho%--XWX2AG6kW4J1K-X-6Vyg+bskRn>UX>yLxaU?foKjGa|=fQ|mfXcTSAOE@||( z9#sZ>Mv_5~7uc-Nx;zeF>y5^>gx>58sPGdgN0F2oC zUE%QrW;#F09h0|TIF|T#M{U>8Ttq|ozcEsy(Aw z(gz@szzOTjQVrKwdk4&}?<`sffBuc|xh600s*=qYV#X>`Bl`7BHqE^d|U0}M;Y zHM9o$;dBV%ek;(jAZHv`TH=Bfg6zkK+jWoTT%&Wl=f+oNOSo^w!evUiqTSHPN`EzI-y#Tm;6--1gjG+lIb1vRSiJPedRo%JzJ>y;67RQ zf@T6Zx2OdsDW^6~O$ZBBPTCdEr;j&O*Mxs(BInw5Gd7y-rl~536Ak#4HGugEpt7VV z@#<5R68$Z?CBb~y!J*_lw|?qAl%8gB4Bd1RXcW^)nNT~^B42XYpa~Tr-uBBo?l~hj?Nh|8u~N|3JeSD{OJRwi9heqg56L6$!Y#Hp!ehf_Qd(HU-P2?1*=olS@eTqNma&8J#)|JJVwR^2>e_hzTwqJYZc17_Yl6_sKa;jnRZ;>KA(UX zvGP0$O6L0^BNxHc&myQX#-8-!w*GLauJfnlE_0Ly=?w zeiAvBOZ6@H7+(PcX)9dzLc9$g!xnPCi#a>Uqo&t_&c8JRGov%I-0N!6bCiA+$?``E z>LjnP_D}_XCACe#gbb!-7;R4mpqQxR!rn)%7d6mU>&7>qqj}pCS_^@;&8d~cEy&;; zuzNOvHihWr_8Lz{oH*Nt|8eB?UxgzszRGDONsr$I20c^olq|sClxw~r_T=yz)n`|d zZ1DZsTgop&2o$Ec+vV`poVX1cu!r4?Z$Rtiyfc0!xCAi5=QDX@aAc^K<7|+H4dDz3 z!5i}y>5DDotyKz`lS@Em2CPk|5MYwqL*wqAMJD@S)l*-hIm-`o2LBoAyK|JE+ z%-1Ii+PG6@^p)Min+~lW?I@GWyC__xhRUDWS(0v}9JC3|;QxcD@xKtoGj$m|-Z=G# za0k?J2!|FLK}Zyo%J3s$2~%w36a*@kCLB2wO)5<|%O?H^@axGFq0yo5eRCY-eu*DF zY|nMW6Gs3OOUvBkIaM#w{_?QGlTKy-3E^|_#R1gFS?O``)R7`dyjTzJ+(nuD_{w+{sv>0f2B>5Hwg)Zu2zI0~53PZ)K&lEN&63Wx>-l zyJ(haV^9ODGYY8ee0|Uq!f$j(00!+>S>uK?;BR)!-NYf$+Us7&WQbZyPjGoD_y*w`#>H@AFG| zG0*m>+aK?va3#3KIb{E%wAKG(M%H%^XyU$Wsq(>n=G{2xJVH&n_>(VGPpdg_uJ({g0I)fo{p=Jm5I0xqa}F8+Y&HWGBh<}fJ!;&& z+6H07y!)_sP9`;e*LNtAqCI7Mlj1j{8_GCZ^>HZuXX)zyEFB(AYW8SU6Kq{gKjhNh zns=HIU?=|Ov`v$ldmtWu>Mq>ta6QHnJXL{KN8#>5Iy6@Ifff$}cb#PGC!Y*v$;7Du z$fRATwG4~)c>P8(K^RainQtCeoX(#r0m$qyBO52R1o@$CCEJFw2U~*bW#O4;7j=y} znBYI#%Q8F%l`z}x6w@$zA~6M;CY-aDC@NfRPezlK$B6oJMM~-9Fedn?FhbdQtpq&# zkVCRt+E*RC{j(k2|D=M>1?c8*=fJ$zOV948z4F!R$uqrE5mVXJ^-8MJYzSNHCPx(v z`xMPuGqtGoa|&MdrIh;-Gl`m^~A1%M=f` zayEDNj5av&WCU6(z3t!{g>}3@m6ZWlKcbo#!Y9DOoM3zWrtX!;avGeI&bW`eQgnvL zAq&ACxC{JT9N|E2=qlLs$>tPP+$rYFONr#57>FMWxNXn%ZHU557AUPulIGY=E&0zj ze^!J-@6?y(s<8#}PN6hfT+>nuEx6jp;$s;BvuvSQYVzIoB?WG58Efo+kb;=rsYXQr$^mU_MkyPCd*7tYF zn=a?y;p}K81YL>niPQ`Vv12MXux$L| zU6}as4nH0YnPW2FVNG~PP;L5~V*~MV1!25~mex}I{1uo$^)&Ha>;F*O7dhx%fBC{$ zMhq>FHdZou_KGgT#CxfV6Y-7@Lj~$~`LaF`))hA<1vYYro&`LRDdiBemk5L?v4U2S~KiZ?5^rTU>DbB}Nobg7N& zA9nHqoq9e28RzME9Xd$5Vl46NV~Bu{8_6ojx{Yh^xAoW}8csPphf(h%>6nfQUD)=G z<~d~!u1fiLW~GA{-ZvEh3U2;k1Aw2y9LiRa?}9b&i&q*$Hwgli;&dG_uYy9`6l~Wb zavlPcr%n?9w-FLCHe@KE;@x`c1n6kj1^Bktc(M&Q|h0h0N^+8G286XSk zw!zi1bCEieSKfFw$gCrhh<|(3nV4O^_N;!XUi20<+uC~n;(xYCz{kJN3RR{X=m~VY z!4M$OA*_S$kTB}{tGmU`pG(4MjqpT-LQ5u_2dEjKulh58++|(c>)z$!0qfUj-oHPu zeq=8eQX94S*l>TAnqrt_R>dBI(`7{MK;ti4iR3K+U#$x7*OQq{#fJkl(og5Thb2;{ zIPB3T-iOtymi-18c;2LvnjZku`+Cbp9U64D`baxb!s;ylR+0ukhWVDcx?}!UW+Gb$ zUo(4Vcn@(jv%k>bk(ezIy{Sw&qz86Fi3Kln9L_4_T3re3smG1KDpZ=AIvpI`gML}Q{}g_wP1xQ_y`~#w z@}#*vmDJy)Wn6|nGD}_uh}gOblOmPA01-kZKAU75h#|H6<~SI?lO^~OK{z`~(~;-Y zl~$y7mNrnS9oTxq7#ufRAP>TQ96hwT>}u~smC`1A=P@IzqVq>XM$~N4A>FAM+F~;= zs044hFhB3up=DRtl?>cE9c|9z38qPkjL(QOyXqaH)$(Of^|QCnVRt!Yde6x_TXf+H zgN=^b!jS&Q`{*bIs&&Vec(XxMiA=VxGpU;`@^=xo@^9C_k&}d6`yD&a%*5=uw-qOo zg}&dyB)5c~9?#zR@Jf&@k2UU&W`t~P$#g<&h1VsIcf7M`b5@!l90YBPZFXcz^rv_N ziHd6gXG))8m)^ppOowq;!H|(vRXH)$cuegySV4{wQCkUn2;81CBB2la!fA(bxJse% z70gdL+HOQw51)H4cu1)2z{9zMeMa^jaEsqzlz8Za<$P>Cu>w-z*MFB^6{=_8g?Qty z)#N!-_QVG{h~e{n`i*@D9I?ea(ek|yi!+*ZANmaHX2F#t_uUNr%abC|r#bMCS@F3! zs7RWMegnIZ^%oEv-YfbV^*3#bF&Iq{wzHImI4w4-W-|N3R_TM0N2Lz}r^C4*hdE>r z(31tVKf8Bt8+8b^|2ZKnkp$sxKr*y1s*h~yUmRn^yN6>0)zt?9F^dVEIUiQ5G!e3; z`7B^6RylHzev5$#x=KZMgOV>aX>+CY{|-ncXQ%Oa^Ic@!Ca75dT9-SfXy9BDt++3v*Da%t!g)@*a}o?p;P_y^jV zay^eiG8?#BLh49YONX}$7Cd7++h~PaTl1@t)X%f4oa{V3)s)}B5u9Pwzp%vI{j{Vt4vXT4Mo0s9c%+Q+7pskTEtyVG`DzVm9>yXO-gB%lgiAL{OWAn&2AkvEel)gBFflQ z1fz^|Y1)_2siCD1dPvU6E=BCEdNHlhJe4<5b-{&%WlyUa~K=RBJM z!_VU&pGx75kN%eE;b)`11F!VR+hi)625w1eBd63JA0F|#+>(IMh^?lgh@&tOz)&lr z1~1bF&T|<;&lAy@2UCB3jx?bQzSKq@#n9DSNwO~t@EH#rQ+~WU6*<534fbrRNRB6H zoQhww@@1Hp7ZWs;PH)u{fx*d?xK9|_qUZg_KljPm>e45VP6TTW%!Ir3&e6WiEb;Vx-+h@H}BNQ zM5taw1&>4U206UrYW>Rwu{WN&V$nobryR?4khUj|fZ6~*DGnoO{1Fy^H&OEDO%!ba zaaFcxv5I`i$NmK9OkCSN<$VE?3U}F2m@o#a`}O2{)Y_9_#s1W(=_cqZ7wK7K4uf0m zYi!}M4d@73)%chc#*tjjkN4XcYmP7aw1V)FU^R=%Nb*9ywjBL@o(tEMG}Z^9N)bQIFZn+~ME+ATV9fvH|` zvxcJghu6~l#-#lYZ5D(Qwzsln;!hCVuA>_u415h9FzsyU`UR%;?ATi2=Y605NIv!t zz-{dHy!81mf-d=i-DHg*Uc7eh7s=NZ{=_JJ0Qh@TF6_V38o%5C9*lsVxPJgF#cr6zli6koOv)OVZx;z6pzV>AsFMPNAHX zFb?Q`1i4~0jgdwzYO=hT+I?XP(iJ4!Foq+Q#{$iIrc*RL>deiO-D4MZ~Vc$AwNxoVy)rIu0C5*g^x z5g(noj?zVgFyU!y&+vR_DWnueNR+b)6E2pZD7kPXtGr~RTNRqI!m08ZUZn^0N9DiP zPy&n0da%Oe%xdFa%$#V}AJr+j*wKhxy_Zr^rXp>6|cyc?j3_fe}P=N_i7S)45VD2I(0aUKpuB|GT^tWLB+ zuYGm%B5mY67qU7rrs2|chnN)@;H*WnwENuuh|MK>Y{e8Du0)XgyyMTBjC>jM)jAQ; zkHz-z=WF|%ViFcqp=$d8XiKP-iHq1D#0I3T;RLe2pxT4iG`^`R1WkH2UllpchIb5W050d38^Os;B~Np*nL(TMrqT`u{8&j(nT|Is6s7* zoK?!z=~F1ufJfZULQOy@CUr=R1Djsf%m*x}a3bdsV~~8g3_{R4|5^x$AcpojNKeRd zPaewOn8-nePQ+bcM+N&V0<`tC5bjuGb#c#h`FJtG1qrANpCMTt=8X*_$jWJHQik;2 z5ct-lA~(g;;5Y~qOdd-rffrr)R_kSotG8-2off_JMrVOgtv&48RCPl^v5_qKgs#2Z3X3~N_fW`LP9w?f@&X@J>qM8 z)g<0@!8kOangkZH!ohQ#fo1W?Rj+Zawo*v%XtU*0mES3?wiyftNP z_D(em7HzCX#}w(>)poSwA9&jrp(gEL0u*3a`oM*4@`pFa1Wb;HKPNs5+<$2~^yg&A7xY=I zF2qAJGYANQNgCpmnYmJTSZ*pcB(G@Hv7Ok>t|V{Gi5k35vk8f!YOVTa2m5P*fgQ0- zr`sw=y|C}!e>zS(;LWc~?r1Furl)yGMvYqFmc-JAaj*hP)uM*;d3)d7<)_KJ?%h23 zrflDQfUn{34j6QNm#0GZE3X$}d~S`iy<}B<_(THTX~@1vrJrXy%tpnvVtNaP5BcGa zylLvh9choR?HBM-xwC$j8~DEHP5{c9iL8cjFy_>N{bn?wCpxIp9)it@f$en36uIOo zcO7`LcS?8od6Kr+?Mz_e9xW7;!uwN82^KNo1DfYf)#gKYW!gq}cMN&!8Ck%j(%FsR zr={!lx54+9}?O>u$H0SO9&y>uG6JH)Ssfbu`u^ssz7>e~}`C)HWI+TkBaC38eJ zjL(Tol%9@umfo}J`1k{ZM0T1N?~QBy-D+C^1FpNq+}HlMUkr=Dp=oxlMhBQa6ay=Z zXd{tz8#WFlxkh!fNb&kM4j*91K=t_?=03iiIsQMRL`hc_ovoYH3hNb=k@~~pH2>o) zk;-NrMTxl2ta-Pxg+0@M2^fbZY-s4xAojpNMVV_6~VK@9Hr|5J5FVN9+{H z8**&9XtOdb!BpEgYEH`H4ujr(jNeHwv6#Eg3QOdUile@CQm{PC3l@zI<6N>TF!seksUuhRtm9vbLL?6BB~xj9I}vhs*7TLV?^I|)y@YM5dVx=Qm8sG z#mCsh)*v;fPH87-&8#>GB@ag;1NS4u-nscG5LS-5O*QXi9(I`XiEWtdF6kM@Vx}BE za)sI5ksPch4IPJa^7%rnn6s-7^Q;K{0+7BCf<^x&M*;<3Al84~j3q%uO3o&jxhXYC zK3tT*`msQcy-%LA0&V6a$s1$pC*q)au6BO<-x=@8d*0`W0`Iw=*#uK3BF$~=j>+67 z382$WU+gP8Dq}X`?r!3xe`RCfWvVc)tzi z?s7#GLptAiKe`Bv90PTjip=|oIo5vg16)zVg%vKHrqJ*PXWd{*0jM(D3uG4>10@?X z#)B(1?Qc>K1SJX~^GP$su$TZ>j%SUjF%{-F*Q>FZg zL_EUvjp;|n00mQz)vRoYKh7Q$SiF9X&{(E1Hm3A`DlwW9gw=l2vgI~R=e z%f-Ur$>V^36R4{c9Ixuq`s_6&OrF^O$x-n@lQK2E1NbQlmNASnCyK+ui-yVYC-lQ& z7q?}L9ASbg>EtR{ldT_e2`qhg{nJ^@lM2-*L`a7_-lA=N`J#@H=vTiXCnlh&oTSy- zn^#hym=Fw@IF|c1p9;`|T}(sJ>)`h17{L}agVNf&*sz5*cC4EIp1sYw|N zXi3}GIs7nS4Xehb7(m`2!hv`5@rstTe{-iSA0SjYWK&!{sC$@bPLSb^CoxAQfz;b> zWPJS`E3zh~p1?D0oMT&j;JkFGBgd@S;2yoHeFv6-%Z|xHL1ywQ+c@~At~dQ+^HcsN zC5G5{%C9R;$xoJWkMI5ACts20gIjmV(G?y9v?k??>~`(jcQj{vU~{B!U;$hCC6+uz zHwR}%7-QAdFME&6lrk+<$~b^OJg`+rJ*8-EK^ap!m1Xx6m{u3?70H{fp7j(w({JZ% zrcR)wi!<<6#}ub4<4*eyaBPJhH(+dj??z<`%lfS*fq-juKY8klC}Mk#dqy0sAb{=E!Yx%#hdJC_sfFrt^|I4#JCPaB!F(BZE^ z$zyK%MX9+6izTP?Q$?Id->08(qCpEXn<_TNzk2wX>^$Y1s}%){33G^9?7$s}|CBhS zQj#9x&Mj%%2<`aTZ?(QE(2wb58i-F)4(A)63>Q=b{jx<{sG=zRlp=QoF2TWIJTx3; z_>(_`yO0J(_S;zQK$8IAe@`G!6 zJ~mLs!I2G89k9&fbSrIZZY-DQQcXW|+G3Lp{jo`1IVo|C_o`UCMk<&q18Ch(*P$&I zZqUBfZ~G5KHc9Va8f}%p52rp7fW=Rlv-Y`ml(U2F85U~ls#kQJ!}V{?F$;bZlWHuNVWQ;PMcedQIyqo3B!0w9J|{lnt}2XH=a z9C*kDZ9PcQ^80P%lB801I{%+#`8#s^g0J!X)3`k^w-w2OKh`AJ*PMzlB)}VWzkhWv zOOvl(+-{s&TYUWe^N#l)uw0@dDSHRpGmBscjftbLt_YScttcO$Rl4&4a~6y$i(6{x zz-_e9hrub8f`J&#hi%7B)0>qaFYPz6Z?ir44=J?_OJ0`}#V5(x^Pq!?(}J~?xVmxf zrE6@r)8d}fiG8A9)n(tzGLMUB%fC*Rk&4jA(`h{JL-cuGC5Rh6!73MV1fQ)`k&w_% z8rUagCIWqf*);_~ZPRq%8@T?S3w{GFyQ{@M%w!bxAjuk=H0-8neDF>09{BF-C`f;h z>5%y``cRfL87y|`0bZ!2j~;1Ib$4Mlta4GajEOm^ViPzExL+ggMS3#&5WHgO^=o8W zTKibYMn#pmlG&zES{DxeYUL$?a=am9vCWgk4#tItVx7B9Hoe1xVZMya zvph{7e;{ZHlAi#YvBq^#NCFV6LHJpT#xHU5`<;uqAGP3g1$y{o2a z*rkh)ME^kH2{y)p91y|$Z`eklBzl=}YxC>NyYpvm(U_e=iYZ^E+owpX=WxQ9Ts?=k<=C%@+T2fh!E4^S>q# zOn;6eTqtO^`uClHEj&KCbNzoLvKkp4qgvmXfxmyC&my7t=7#)TMTAHJjGw0S^uL#e zn0(nN`S;QZHeD~`&eLfxv-9&xxBFIhHorB3Zh-m)EE{dLOw< zjk3#_qcVes2a=IjL+I?8jeX&5e0+@&+`5@LIXPR4qqcSG%Vl23Zr4M9$2iN>P5ua( zO}0rFr@0WhX_a=6yH||;%Cd5{Vg4d-$Lfk%$<>u>S!pSb7HiWyL82@77}d4Pe-@mn zc;+HJ2Kd}!pkZL3c)VC$a**Q}Z#9u6=Vp{H$=-ee%WCjDm}_SCSAD(u>q;bS55b`K zPM@3$%S-r&RBV*NX?JvI337sD}IXUN6R?33b*zJyw4!62Pd8{YM zd@qYq-w6ol8e4uUt*$OHZ1b9adbqaTX!ij++@367QM_YfD!9FkH`?s=Nc{HggLCII zpQWYc@K?s?qMDj-DJ;4Y=fJxh|KA)-JiNTqU*M1=nD`gUtEy7&x)pYWx0|=-wT+7o zXG>;}t2<@n_$xnun67Aq+#l3FRCrFlq+WaMT8*xfha>{#tb z7XA)a!CO8yE!14ia_#9^6)`13b|bQBnkClYn4d$#!{dqP<6WE-qW)?76WIzF7#NU2 zYB*}sX8ya;N4~i{HqWySxz#4eq(lH*zg^>WrgI15se=OxopGzwjp?u5PrrV>BQ(3i z@IA=(dbjV6o-OLOV(;B)wkPlVu$RgRxxlI8<@c+`&FbW~o*0^Rb-R8t66^k!o2$ZY zHI@eg*-*luSJ(7zBkTP_gsU<~K7;xRsnL*3*F_Emcyp^?msPuCu(!9TYG=n}X>C3F zXudy2?EYuS^bo@;4QGfK$o@}E(;`lPW1Z9IqklgYRb5_Pazn~D)sBGnj+Zqq3t0ib zfQbCEiH{)}t-Ho$S7!OLx}su=pVO?XHsuH2?DeGB|7+|k$j zN{4`el(dvccf-;R5)x9q~QPR_xE{TKl^I$iJ7_QoS8Fc z&dgjs#hd$0t=WN(-vZICgiC#4(BPM}cqDYJ8tIyU{ARK0w_51tUkzvS90yS2k0(Ih z95EUg8Y1>rB?y(@M5Q-1>At&$o9+aAOXTa$($-GAEF$O78Xp!iFaJ`?dZ@sV!B8;O z)FepLBL%@ogn%A)6W?c17r*YC|M>C+`?Z4u&A3dWrE34$KmsQl8(Za-i?g>X-%YWS z>(DaxZ(_zhTJJE&;gxgd&kqaPGEZWze>6LuUZLvso;(S=ZOpO@B;+yc$UxSb zaCG~ykd^?q-&{jjQp&0jzKO1&H?_RVs&xGa+S!)q@P<1pF8C{G5AN4(k!GP#z`V_^ z$O41t&F{V0U*yO4E32!&%hEr7wp?NT^3_c=TF^<{6irbLz=ac5A#>t$Au}p-#l^)N zvkvPDn9(#CE5#wIhZ_GRVyygQyO~qUjfY0<(ta;$RK2x~X75-HZHb0qyF}J3Nl)IKz@<_5{>wMr_ ztkq(JT+Qf7^Nt|3Xfx|QR{2*vea~E`w9U-&PfIVcu3sOzT}mql*^yrh#Ou`%*3$`| zWoBmLbG>CAt*LV()-m9Yz6jqUADkS2mCD?}hmp9y+O;Y+A{}+$w#@!PpZ@%vu;Z(b z5Y1}(XDaYWn@VzTIwlJ0Eke{TGtu?HtoQG?wh%O5ik_)nT{4X16?o5oWH1PatC7ZT zx(}qv($Qn+gleSq7QG8>l1U3`-Z>j;31S9xV2S-{xDxjYjMjpFfo<{v;eH zkFN3zZ?ZCpioy}Z?912eIuB!H5vdd6R_R`o6jOP-#z$69bH4nj&T8RYc-m&b`d&+}3tgO&zJ~Q? zZxK!9nz`(E)smMaJ(ay~Yg{&0Fz6%`0~3=ZHC(%X;eN~h)kIN>U$2~2Kr8yDw4#Fi z&V<_y{O%*3`uC@&Uh(lixFvs1mUpvuBRhQ$)96e?=?qzBMHMmA&KEkoHSWAOjKWvu z_&&Qz#0t&L-4_&?4aXte-pr~99KJp1JdE#XTh)9OdG(_^u$6-D;x~e$Fr%0-E~|m) zI{Hn#G=qjp3cc_>9x?VQl(CNC?U$`@Q;&Z%SYa7QsbX$l7!rgv_#T=Yf2MZ5UQ6H` z`eFfTgk-`;1?eB!*xRdx5itpc_6Fsgz8Wi#)`ek{!DgwXqQqPg@*BCDG&sFk>4tJ# zhIJW(Hx;rsaRtF=#+P(mF``DcSuUjBnGc7K&eB?KkycWVVG_D6whmopAaY!w>DZ#V$I^_)pLcIO_+khqGD^I}XPS>jg0B6QqeN;v`C?{j`ZPm+LNye}Ee;YBh8#o}5sI)94pW7@ zppdm|^Z`orBnRYEck8?t^j_y)&_{C8`((rgN?q!vb+x*sto8KXgbTp^+At?#_7*+2 zM&F*x4*6RC38|(;e>nIvs+C2t**2LR%Fz~n{1qqiAv^^z-9O!?~L z1R3vO7j0fVIA`4TTQAo<7BdgnQMwd|motbpSja%-zeJKw^-gmcZXEKTB{>o;_bVVA zIcGN7oVphhEeue>_O;yg{E*d@(B)J&WU^r6tGKlw(7a+L_rQtlsTcqxw{`N$w zgoUs%p{ca2y&^$A=7BsRU0}`i_3|HcEn2L4&1f;1Aly|qWBfs-1j;*Bi;_<$hvEbJ z8;kU6uLjnvc{ zPcv7as06(%rjS+b$;i!RL5ZlC>OpvpzAQb}MEe}A3Mh5U^Sdm3N*yhf7pjG8HZ-+N0&M%FEV z7xTV6@#Lc-qWw`3V}@4O((wlnA@Z$@$6t;!+0)7_w-(@ zXHtyNtVRL2^zSwC9=e164~ItSlKyri?&3W zgoM&toaY}Mk_1tmlN9Su1;@-d4#*HQ$gsu;S_bkO;tg1c@tsE;?NKlhHS*MiqRx1B zjF&sS39Vk&pSkaDbBtk-UVADd-A@;aOczJfk|MV4-q>7E8SPie{L)uJ=)`BfOYr;CY+|3b$B6I##f3) z(q7VTP35=Gm?>vqtz9?In3v3cw6~>ckm)L$mBq$Vbd7;Pb|o(s3V~>jps|9*;{__p zdwN+vYXys2B0TYQuqTpds_Er4&7{9sh*<;_kQ!9i5e6mmTi{d0o)c@gJ?{Dzc)p+R zo&IQ-Y9`G+FpN4D=<(WVqDXuDR(d_$(eZWZb|j=%Tn8PaifdZpcL6;q%*f!5B7*t3 z;XC9>>d!os#UA-(t+MGIDFEBePTW+Cw!{B0{lPG>-$&o9h~CXSv*%+*%{S>HbSfFF zvV=t?CH~4U;?5UP`^DW1@71`^7s-9lY9i_yaOiHD)y6?W;2wu34fjlm;Sf9Y1H!9@ zpUJ)sq>c}Zu{CLReMqoFqTlwC1#(3+%_EMm*L$87uCJ0F zI0r??;(N;?r>BSTq(P;h>^z}t=2B^@?~G1zv;DD5X-Ckdp!E6P#|$?CbD0GX?~bm) z1c_ePA46}sDpjZWx-NIKbqZ?sxZg?Ji_T{xXY%pw!pMlnU;-#2R^Ax7caR z9=aYu2Isp-^?Q1#@Skd_`1m!|X=XCPh#U@oPpc>Rg^xk=uw5%Ec>ASHIEif-qY~W4>jJ>0k;h-v>}^w{OMti~Q1ZSfFJ6C58Sbb^U>Rv^-s551 z69ZG)x>r;>-15?batMqbNP$oX03Te{hYne!>tnTKBDL>-F>@HO1hEEOh6 zYiR%Z<-mChjH2navs)(u8HljJ%MP;ppf^7A?r(S!t;~G-mRe21zG+wXO1Czo5$Z`; zWb>PNSCIWDh4XA%uPYgMPxgA@qsItnq$J*o@MK-|(fmJBo)S9#!B$FbC zlLZzMs6K=FkiNldtcNPVZ3FQN$J?wwFlkvlFHrH(wk0(_ed21!^Xmv-8m4a#BSMHt zwUWLPD}KsO`qLU8c;3EMn10guL89p~va^Jdh=iD;t^B1{VUc0f_F(_Rn`{~e-ko5) zf7@tdZ1g@`cbPRNIWb0;{g}D4v#$!ZRfv%Nw_;jOLt73=zR4b;`EYn2^9@%MH@@w_ zh3uy06FdgY3(X1t8Og%g@^3#_`!NMv9WCUEP+1wL_?A$?CmFIQdqQ54`z;lDJ($#k zSUN`wo?|(7!^+}1xcGvhnAG%^bU}PFw_Q((qLKw*zAK1+Kg7EHb89DF`3Li6(t|O_ za;kO4od(fZ9}WisrJRoPcEldketJEv{-eb?SM)gLasZPbrTk)W%LLvP1EgAc+3l!)LZ9KR2J{& ztE!e*4V6JV%4V>~?eD1f*lrfa?;DA`vJM)nuPRuhF7&je*~kZ~4pr2F^%q~B0f}*j zpUIUOhklL!G&OYsk1yBkJa*;8F-O`>u2KZ&XgSU5#%-TUvrtz zOVYdZ9B7cApZZ}R(L3+cV@MGe|9p`Gz}uv~hy={ZnW^%h*y0aH0nu_IcUH_geGsFa z>ilIe5hf@VUx;3E@ZN{@7_^3Z02snIMhgG7X4J4Ohe=&jbJRyYoOC!P`uO`Q%b?9e zcQAOMP~n*ZzvcBECoFU3cD}~oAamnsp@XTV-8be!UVi$2Xy(HK<(qd&G%k*wW zfO6%LYv{E}lW6Cl(jyEa?UK2xF#J}Ke9+`Y#mT}l`H9!IK$V>v&bN^j&#>LUFP{+&V&gwGK9b&HR!uN z?F2`3znAi4f`2>*u?EH&#;E1pDq_pR*bd9cx-IuBAF%=__qJYaTBp{9&Ois z>OYDv04@@K#o0#d!2lYmf};herLMRaQcL6D_2ieQ7Id;T7P@O((8jLH2DxZ~my+Ar z*W|Du16Y$ z)vVo%fDVdc=Y8oVM(!9uS!H(QWJ4QZvAJheZifcE;nuUjt~l zL1&Zo-n&wfsz@BBJA5Ukg>E;@tfJB7aVHkK@kFqLCSpY(qOMM>y1FXW_~Yu$7c`!v z|88l`dPQN#6)!1_m;oc`Y-9(_QItSH(2dRCSG?M+v?hGBG)2|*bT(kM^3*wk#e0|row!Z<>CT%Oz@U# zGME_rul297o%)))UuO{{74e4~13%6l%b8qRxD= z%@zY)kk@X?gXFV2?a!!dF{!;N$UR>u<5|AoonotVwMkT#XP2skzUnoy)klWmTXKJ> zsd;mP!vL9i5??9ggy$W3O=xuz+T|z(OC^Q1okQ5dUfsRvQE>sL(kJ6${N=t?OOekfl@9>i{`CTn{0fu#FMey#?CK$7 z7dhG|@#rv#VLo*Y}P_NO#RCL7yf{%Er^<#H<~X(2I!Eg&i=6qmp_H*I?z^ zX9A;jZeg;GI_sPbim~f4f0pmzVq^1GiB4GLERjJ`g$5mZ<&`KFO~yISley%1_|hU6 z3}53~db`F*fzjnXXh4Ix$UBNN6lP-q!4@2DkkEO;pN7pZ;{S6bu!&bgUA=o4v{~BO zE7@0QL>J4Sz9eG*nFY_#1mTEr(zA9uZP?r99{Wob-!irhjY8@q zbSoV=dJ(P^IK(9~iqjpiMD}puGDCk!#+^(rEvN{Yl)x z(RI=O{=ZRr1W8&5>E5&+(V@4DB}wE$t5~Ne*^T6JO24R1ug2ytrpAfj8ibxO9jgo61n=S!|CIG*OFm2DF=_*JGOCoPQ1OG zUi{-R4jGK&uhy8vlrhp{qHn@S{(iA-Q*xgSDjM*f-g2Q6k`FPxMGm$I#GKB{AN?>{ zwC>ZVe1-3IbA|ng@YJ6Zx>!i!i;-7Y$d^K}DMX&_=N8-Hoi%1=2u3Rtafq{khR&m% z!q%4N;hWXA?ny@BDTKt=VNVNd<)h%p`SmtGA~(6@-C&%5I+Jj0^g&j@@L+btC|UWf zQJWj7^N*$^Zjt3nYk?LXrC6gxF2xul42;BNuC9oypv>(yE1B;!LiS(9Lov>x{H>QE z#p2TahTC#`$_z5xFH@*fQss#nm{ScXBF{;taRGZ zVAw_nJ{F&#VROtKDUKSffq8iKth)b3*N19WIaGBc2T<~j7OW73CSIwBmI|kl)A1)=a#Pc4yJ-deD@}4JOe1OnKpSWvlku?rq3DfFUHv8D&*72JSEenHSJ@Fh z?=fdzdnY{3J1=MdpiQ^V1K*WB87X`yAdcW7ayJLp6Z@`9k(BcKxtr4tXcz10U`{p( z#>1p030|0Fyflwc;DI(0$updYp_ZSRy<8OcT=;zNb!ZqUp=b_rr8|9dWHu_RYcf2G zEIK?8fqX`}+{a7Wl-{*j7&A0K87SPg{C&_>EhgdXHkXfT4w!2F@97Zvr%3`jms z0&Zwy^5PPA6t_g4I$$jhe^URVSsfp~DbILs*rVikb~Ns!L=jfJdx@3;-o0f7Oo7Nj zdMU4GT5luPGmE}QkM;yg$L!^OX2j-&U+!AU=88C%`kyR#-bK;b8-J$!K#@i(;*?Rq znMa;S5@}JAo)|EKKxBGHp|965aF2d2lMPCNA1&G$UoDZxKBIhT=jFXjif(=3q9JQo zIqWRyt7;V=!}>Kb$wT3bC9!43_37NlC4Vro7n-`_wA|AzNLDnPuBb{=4(nA2Yh4P- zJw86^wjFR`g#Ln-7Z=;BKMD%D9MXT$bV}E*$y(9Z0K{@T5r*H}6kgK?B0QK(Tb+IF zuX!GFzd=JC6>4Kn+Y!a&{vHfck)=4tk0z$y zTM@nTto6n_X>veYx_NU*`XB^zDNt`Kdn z03J#U*N0~b`+1U79Ld)0HIwPZUBnY%!r{j(Q&jYiBcG$*lLs9v`2XNjq-;{k4SV)F zHcvEa)_*<8|2POnnGjrO{?Q=$+`uYJ9l$#V6tMSZyA@<2p%*$Uf>5X`1t!T1;jW(l z$nUT*_d4IhrF|CsRQ-`7^PIpH&bQW6$so#lEr2nBzJ)fc1wYWhPub;^9Iye?y8?bg@Iq@9HF9K!gT!2^NeZ%q5P_POT=(>+KPj1VJQNz` zqaR^(qSte<%EeD@rKT^I14?8_>FE*yc%!^gzee(voODs0d&)WnL~7hG<;b%8cWo{4 zWy7YX`_i+qS-!f)*5we5OaWP0ZF560;^#c{g51U(iph=BtvGe&-H*mJ8ZgCp&uW6c zM#tU_4$k^}TKL-F!VYzJmfL1046ClQ&ueXJ^7z44M|(fGvPtO=z679!$Tfw<1@X8zvza%ND6-x*%>W zgFkRVxK;K3{W!-Cao6+_WABNrflp0tdM?*MRSrx^XRRnso=*Z z+fyw19_n5f{^a@nFi(zP-Qm@VNJE-)OnQpdkY2QfkrAtO0Yv>##{Ez6Cs4s`e|(Hx zyuv53OkY|m+e&8?B1T=#w>UXxY@~bZ2v-vv+T4;?y_LU&W3EAFJRimlH_)eXtp=GT zrksyT2Fl0QY7`$ZQcgcMyE=Dcum>;E@wgt+j@oCPJ*HgPW8I^d7Omc4P0m#rXISq{uQha`l zuez4p_Scw@n;$rji+}?z#X!r4@@Bzw-acqkF0p7Z%lTM8J8RQ%$dn^pUi#x-^WHy4 z9CYec${68T4WOoXNm~_RJs|9j-o3Z8KhPZQ=5G_NJhwnF@ze(nH9VEU{C6^uP>eWd zvg+w}g7a-l6_H0JODKll`FJ9lNeY^Gi2Oo-nfW~*uZmc0p7RB+UR@B;c{wp$_ll{9 z(uu`l_zgUjNkf&aJ0f$0u~6%Ni8LnP-k@^44#GP3wEXj`_imBG#Y6EO0_4PS?-7{2 zm{u#~_@<7u#-5u6?w%_x_iSsy!XJM7+EAgR-7z#TyUn|p4ai6>Gob-&ajF1Zz36XreHpTAMvl%j?>;6FRM7ytt zaW|_={I~4c`^&+1bN;{qf6a?_Txdtgz2gV%nDvMCON+Mdgbp{J{xT8^IpglZYxSR( zmAO%aUw7{2l@R&izcRpu6TUv-L;r82)fG#q>V+epLa=u~ z(FojG2_xH+$ypIVa?TvCV7SNs`kLG7BogeWqp#00_`OdG4tfPl_uAT3>R_K*3Sm`y<IK?wbzv~Aml4a-5R%{o_&j-6aLE*KW8{K{}MEc=R8jU zQ^$~(oD=+~g0b9(6>jq|3%RWz`eq0F`Y@{^uWO7LO&m?XZ@e2R*ht|ZuAo~+vgjAm6{B7~G?#bgw z>nQ!5T9&^R{3Xc&R_o{<;P1nNek|NAXGvc0KQfF;&N2S$qVPD@V#-AIFFGq_I*aLR z;BO00L+1Mf8Ub90fA}g_qnFNv!158Zgjdv|MXecs+w>>izcqBdrum0i>2YHE*Zc?n zoCUKdl+qhG1Lnv6cJ>u6b~mkQ&Hk^4Una^~<{v%iSlr{1zK&Ca^uL(1Nr&mI3a93S z{?T!e%6w6}Hswg5rsVs@Br~ zU{MoqJ4^nhmp=q@cWe1g;4bz*Qk3Z}Cg*+r{l#RwKQMGur!Bev8ig?5N5=I%LL>jHVX82grRd(b`-c>Wg`<_a2mZtJHKzzHM$^NomoMS^j<$jvEL=lDIciDo z=wd24Y1weq9yR(+cym8iiMWf;szeF#pU<*bo^M#^&Isa4VEd)IkXtzANx2a z{uvect$i$5h`IKf_h{ey3KJmrwfAt#p9Wy~wzCBm9Q**kyR4!8V}So9O`ArVruQ8z zfZWr><5~U$0He0qE->Q|0Qd#?>Oax|)FnjADAZ$I0Dhq7&5i|FXJY*BMKU3nY$QNd#g*mC|~Mm5Li_2t zJHXRMqC=ADIAUOL0xqG40p-lX=n?UMujLI`w$iKjbdEj;EOBjO|H$X>0WcRcQ+rN; zUqNuBzIKuh@Qc@G*Vui41K6oXUkZHt7>2R3BbE2S!u}z^A0aqpVZtE|G)(d#=Lmq2 z2BPznX$KPE6Y8BtA;x%Af37TC#(4` z0DExpDnAa88!H1I6gcsg0l?MXfsH0u1bd)L;AeiU$cYDxtC*weD}LC+@Y)}R1 z_`t{AB^$GRcL2~%{qClWD#!wh?2fvZsb=PIfd&&!5~>+x3_xflO=1!N&K|O@-8Ab1 zFp6upd|LnrWK(+S@1ej+1@I@yi0?HBj-!$t1sE%rt7^i<* z#$6yAH-)ugY7PfzSk~noRcp!mjsYY%sCby?8v_6yH=A{^Gd<7{D>7w_1MmxS($YF! z15hP5@21jGP5_#!HYX<5-kt%DO{pfLTA~C1lzGe6w>Ro^l>tk#1I^^xj|70Fldg=` z(*wRTYyj?{;o*_51_0JsWF7&>wYpk>#EULpbj z*m=t~glhvSS%Ad;v6(q6py8FSR!DctJ%Bo_6`2D*Z|myv*4N?y#4v_wV=RFGp6>HZ zRzu_&CUCvVg7_}s2ms~ELqkm)>t$a6SWg?Tv5q|v0Gm>CFn;@6gHs4-5OvWsn3=-_ z_?vajiM3rg%W#2$(ejO02|ci@IVy7{SEC&Rdidp-5EyC6$mxH_Mh&g7zr+Eqij2cC zW~GPufN{QWWJEAM;}8sJ$m>i?z^CyyCUAq~?gc)b&DnuXe?Iw$jWr?!Hs!Z?(TctN zT%8oS`B$N*KEAurp_>eBSJ0*@pt!+BOv|ajm6k%}%L)YitWSIEjSB!H`5DD!h>|8kxwC41i@_8DnjIEdey=>?{C@1spkZYEZG8I7VPvmOE+iR@+MffRg%TJEElQ zDF#0+z4qt_dr1K3Og;8eZYs-o1eDJ!AX1P*bO2OZHBN%Fy&{7PD4#S;*FzZ-12A*- zoB)Gk*M2%eDCfz*hB%rC53pn?dtR$0^J0h+m|T6gF&^LpPC(&{^O}`q-ZDbyfVaQL zGwF{Q;M`Eup5#g@VsW?h<`?i)fg zn>oc>3J?I0XskZVgn;Xg0@NuV()H1x*t87S{koLq#HVx@Ix(B-q?$Q(LIp0tH!shQ zZHAxOVy(zYXLL0cv;zQlQ^qHI(Pcth>bGO;98(`D0Vro`Q;XDPgzg$JD|)DAfCQx< zlrv+^$K_a#(+iO5#!Elh&A9`>GBn}>4LnZVTCpreWzwZ83P8y)5{on=ySXmgz~J9Y zNxz3C!U5%7*=+u#DcRj;cX|D9s{-u6RkN;poUGyUXp_X!eDU1_i!pTo2q^XjW5F_| z#22tIe!`I(`H15HWlUgPfit9nt@W<2Jap+gWuqPa6dQQIrHg6EeyHAZ_gn$GG`G}2 zi%G9LCJ%tJ=g#U5A}gkoSmj&qg}|@R;wBs! zBYqa$A>a=@P&a=uCI$f1Y2PmrH?Yc{VvfX}&&HR$22g zK>(QLs_oP}joxT1dPl%7U7#BBp}k)S07~Ax^q2S8ciX}?@|xjTHW>q#rI;n>yL$Bl zUK|R`?+2P82TB-2LF?pBt$Y;b(3K@O4NtgB!xq(1lr1fC)`J_VEmAV+JYN=se_akc@| z&WPb%8cYBXVk`4;@Oa`e^K234)qcT7-^Tj@AF%0&datyYzh{$e@jJA6=77-*<=ioH*TfaCr zTP;+rb6G6Q=RYh^y_FEJxOCwIfKxrx0pkr9qL#1~Bbz)oO;p6!0~df^e(%`2L&BT7 z)a9lCEufL&b#jY4L7=4pZ~%+A@haF3ReK(Pl7Kl~sUMGm+|o=8t_Z!%=tGSVmdk~4 zb&SdV6GZez>D4<>K+cwMlMixau@{=RIlwY5W;VVd2++-hV2|Y{8>x@pqT?OB{$8t; znB>Ps9>FLV8*iuJByfo&nr5a%q-U`nzFy4twlc-d5+QLx`uKRL2J?WmPoGn!HzO_) zG3lMY`@9Wf2Wq$6{@zV>JxGwqa&?qTsc_pG>?$3VIGB`I-tT#%In#aY+;1|COkY@5XNiKZW zU+7g`p5C(hD|i?*mEUTD;IiLy+o95^IO;W*mO4}f7vC(TIynY$%$uAadMcpkrM-+n z_8m+s+5Id4wiaR}TogbMzBun%LnE$D&M)%$SS?&{9$$3#Wd9CEg)FzS%I4;!J}~){ z^cOa{@tu^X1^He4;*#y}y+yr#yy>dnzj}UIZgUczh$8>l%ke3fYU5`MYVt>~d?%B? z9x7zCcP!8j6>{5*_60`_+W2abZ7#yr%Sy{(@%$B@Z&%$PXS1775cvP+50-arG5We_ UBu_mZ Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 093/228] Update readme.md From 90b0f6c17873d14ea6a5ec8ffde621ab9f17a3c3 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 094/228] Update readme.md From 4b23c15de24cc8f6dd0b0ef4b03952145bbee05b Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 15:52:04 +0530 Subject: [PATCH 095/228] readme updated --- utilities/deep-links/readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md index efb87e3..2aaefdd 100644 --- a/utilities/deep-links/readme.md +++ b/utilities/deep-links/readme.md @@ -43,10 +43,18 @@ query_string = { ### Run this utility +Option 1: + +** Pass the query_string as a string as an argument ** + ``` python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' ``` +Option 2: + +** Define the query_string in qr_generate.py ** + ## Buyer App Platform Integration Different platforms have different handling mechanisms, for example, Android uses Intent Filters and iOS uses URL schemes or Universal links to identify which apps can handle which URI schemes or use fallback URLs to redirect the consumer to a fallback web URL, usually prompting them to download the relevant app. If multiple apps have registered the same URI scheme, it will either redirect to the default app or prompt the user to select the app they would like to use. Please refer [detailed guide](https://docs.google.com/document/d/1pmwQvF9G37_KwcFViub7m_qYDUjbGLrwvgkv1XZEc08/edit?usp=sharing) on implementation. \ No newline at end of file From fb978f309e98b2693b64257839f603803f69998d Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 15:54:07 +0530 Subject: [PATCH 096/228] readme updated --- utilities/deep-links/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md index 2aaefdd..a0a0087 100644 --- a/utilities/deep-links/readme.md +++ b/utilities/deep-links/readme.md @@ -45,7 +45,7 @@ query_string = { Option 1: -** Pass the query_string as a string as an argument ** +**Pass the query_string as a string as an argument** ``` python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' @@ -53,7 +53,7 @@ python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.prov Option 2: -** Define the query_string in qr_generate.py ** +**Define the query_string in qr_generate.py** ## Buyer App Platform Integration From e1235060a61311ffde22fc5d1fd6e57ecd0a195b Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 16:07:00 +0530 Subject: [PATCH 097/228] readme updated --- utilities/deep-links/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md index a0a0087..e5ac5bc 100644 --- a/utilities/deep-links/readme.md +++ b/utilities/deep-links/readme.md @@ -45,7 +45,7 @@ query_string = { Option 1: -**Pass the query_string as a string as an argument** +**Pass the query_string data as an argument** ``` python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' From f45f51d0d375095f41c98a02bd46a169ac140533 Mon Sep 17 00:00:00 2001 From: Sahil Sharma <123928721+sahilsharma9@users.noreply.github.com> Date: Sun, 14 Jan 2024 19:08:24 +0530 Subject: [PATCH 098/228] feat: signing keys generation using node-js --- .DS_Store | Bin 8196 -> 8196 bytes .../signing_and_verification/node/index.js | 31 +++++++++++ .../node/package.json | 15 ++++++ .../signing_and_verification/node/readme.md | 50 ++++++++++++++++++ .../{ => python}/README.md | 0 .../auth_header_signing_and_verification.md | 0 .../{ => python}/cryptic_utils.py | 0 .../{ => python}/cryptkey.py | 0 .../{ => python}/request_body_raw_text.txt | 0 .../{ => python}/requirements.txt | 0 .../{ => python}/scratch.py | 0 11 files changed, 96 insertions(+) create mode 100644 utilities/signing_and_verification/node/index.js create mode 100644 utilities/signing_and_verification/node/package.json create mode 100644 utilities/signing_and_verification/node/readme.md rename utilities/signing_and_verification/{ => python}/README.md (100%) rename utilities/signing_and_verification/{ => python}/auth_header_signing_and_verification.md (100%) rename utilities/signing_and_verification/{ => python}/cryptic_utils.py (100%) rename utilities/signing_and_verification/{ => python}/cryptkey.py (100%) rename utilities/signing_and_verification/{ => python}/request_body_raw_text.txt (100%) rename utilities/signing_and_verification/{ => python}/requirements.txt (100%) rename utilities/signing_and_verification/{ => python}/scratch.py (100%) diff --git a/.DS_Store b/.DS_Store index 73041bce0f7b779fffdac2a0cc6a3e00e0d4d12f..2428609d3145ccc800b318fe537a46663547dda1 100644 GIT binary patch delta 55 zcmZp1XmQwZSZK1hK&gn4xv7qVv8iRPjzYDik%5kaiJ8gdD+0!oO+ngmO2VX zCPuY73e}cI2099+rWUoeoE)Oc`qn}5**Up+`JIzvgyk8#CKm{aZJs1t%CebF;ycUc Ie Date: Mon, 15 Jan 2024 13:22:55 +0530 Subject: [PATCH 099/228] updated b2b schema --- .../schema/B2B_json_schema/v2/confirm.js | 111 +++++++++++++----- .../schema/B2B_json_schema/v2/init.js | 27 ++++- .../schema/B2B_json_schema/v2/on_confirm.js | 11 +- .../schema/B2B_json_schema/v2/on_init.js | 110 +++++++++++++---- .../schema/B2B_json_schema/v2/on_search.js | 32 ++++- .../schema/B2B_json_schema/v2/on_select.js | 25 +++- .../schema/B2B_json_schema/v2/on_status.js | 3 + .../schema/B2B_json_schema/v2/search.js | 2 +- .../schema/B2B_json_schema/v2/select.js | 86 +++----------- .../v1.2/onConfirmSchema.js | 2 +- .../v1.2/onStatusSchema.js | 2 +- .../utils/b2b/b2bOnSearch.js | 14 ++- .../utils/b2b/b2bSearch.js | 59 +++++----- .../utils/logistics/logOnInit.js | 17 +-- 14 files changed, 328 insertions(+), 173 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 082d0fc..409f3ef 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -70,7 +70,7 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", @@ -119,13 +119,12 @@ module.exports = { locations: { type: "array", const: { $data: "/init/0/message/order/provider/locations" }, - errorMessage:"mismatch from /init", + errorMessage: "mismatch from /init", items: { type: "object", properties: { id: { type: "string", - }, }, required: ["id"], @@ -209,12 +208,22 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/0/value", + }, + errorMessage: + "Buyer terms should be same as provided in /select", }, { - const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/1/value", + }, + errorMessage: + "Buyer terms should be same as provided in /select", + }, + ], }, }, required: ["descriptor", "value"], @@ -276,7 +285,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -307,8 +316,10 @@ module.exports = { properties: { gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", @@ -421,12 +432,18 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/0/value", + }, }, { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/1/value", + }, + }, + ], }, }, if: { @@ -501,7 +518,14 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + ], }, price: { type: "object", @@ -602,6 +626,7 @@ module.exports = { type: "string", enum: ["PAID", "NOT-PAID"], }, + type: { type: "string", enum: [ @@ -612,6 +637,7 @@ module.exports = { }, collected_by: { type: "string", + enum: ["BAP", "BPP"], }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", @@ -619,6 +645,16 @@ module.exports = { "@ondc/org/buyer_app_finder_fee_amount": { type: "string", }, + "@ondc/org/settlement_basis": { + type: "string", + }, + "@ondc/org/settlement_window": { + type: "string", + }, + "@ondc/org/withholding_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { type: "array", items: { @@ -687,14 +723,34 @@ module.exports = { }, }, }, - required: [ - "params", - "status", - "type", - "collected_by", - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - ], + if: { properties: { collected_by: { const: "BPP" } } }, + then: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + "@ondc/org/settlement_details", + ], + }, + else: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + ], + }, }, }, tags: { @@ -738,16 +794,16 @@ module.exports = { type: "string", const: { $data: "3/context/timestamp" }, errorMessage: - "created_at does not match context timestamp - ${3/context/timestamp}", + "does not match context timestamp - ${3/context/timestamp}", }, updated_at: { type: "string", const: { $data: "3/context/timestamp" }, errorMessage: - "updated_at does not match context timestamp - ${3/context/timestamp}", + "does not match context timestamp - ${3/context/timestamp}", }, }, - additionalProperties:false, + additionalProperties: false, required: [ "id", "state", @@ -765,5 +821,6 @@ module.exports = { required: ["order"], }, }, + isFutureDated: true, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 336f703..47ab2d3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -127,6 +127,7 @@ module.exports = { } }, required: ["id", "locations"], + additionalProperties:false }, items: { type: "array", @@ -201,6 +202,22 @@ module.exports = { }, value: { type: "string", + anyOf: [ + { + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/0/value", + }, + errorMessage:"Buyer terms should be same as provided in /select" + }, + { + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/1/value", + }, + errorMessage:"Buyer terms should be same as provided in /select" + }, + ], }, }, required: ["descriptor", "value"], @@ -211,7 +228,7 @@ module.exports = { }, }, }, - required: ["id", "quantity"], + required: ["id", "fulfillment_ids","quantity","tags",], }, }, billing: { @@ -471,8 +488,12 @@ module.exports = { "POST-FULFILLMENT", ], }, + collected_by:{ + type:"string", + enum:["BAP","BPP"] + } }, - required: ["type"], + required: ["type","collected_by"], }, }, tags: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index d6f47d8..9851d51 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -215,13 +215,15 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + const: { $data: "/select/0/message/order/items/0/tags/0/list/0/value" }, + errorMessage:"Buyer terms should be same as provided in /select" }, { - const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + const: { $data: "/select/0/message/order/items/0/tags/0/list/1/value" }, + errorMessage:"Buyer terms should be same as provided in /select" } ] - }, + } }, required: ["descriptor", "value"], }, @@ -803,9 +805,6 @@ module.exports = { updated_at: { type: "string", format: "date-time", - const: { $data: "3/context/timestamp" }, - errorMessage: - " should be updated as per context/timestamp - ${3/context/timestamp}", }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 35dfa68..6c72c5a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -75,7 +75,7 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", @@ -83,7 +83,7 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, }, required: [ @@ -122,7 +122,9 @@ module.exports = { properties: { id: { type: "string", - const: { $data: "/init/0/message/order/provider/locations/0/id"} + const: { + $data: "/init/0/message/order/provider/locations/0/id", + }, }, }, required: ["id"], @@ -178,7 +180,7 @@ module.exports = { properties: { code: { type: "string", - enum:["BUYER_TERMS"] + enum: ["BUYER_TERMS"], }, }, required: ["code"], @@ -193,7 +195,7 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_REQ","PACKAGING_REQ"] + enum: ["ITEM_REQ", "PACKAGING_REQ"], }, }, required: ["code"], @@ -202,12 +204,18 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + const: { + $data: + "/init/0/message/order/items/0/tags/0/list/0/value", + }, }, { - const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/init/0/message/order/items/0/tags/0/list/1/value", + }, + }, + ], }, }, required: ["descriptor", "value"], @@ -269,7 +277,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -394,12 +402,18 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/0/value", + }, }, { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/1/value", + }, + }, + ], }, }, if: { @@ -471,7 +485,14 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + ], }, price: { type: "object", @@ -547,7 +568,7 @@ module.exports = { }, }, isQuoteMatching: true, - + required: ["price", "breakup", "ttl"], }, payments: { @@ -555,12 +576,33 @@ module.exports = { items: { type: "object", properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", }, + "@ondc/org/settlement_basis": { + type: "string", + }, + "@ondc/org/settlement_window": { + type: "string", + }, + "@ondc/org/withholding_amount": { + type: "string", + }, "@ondc/org/settlement_details": { type: "array", items: { @@ -629,10 +671,34 @@ module.exports = { }, }, }, - required: [ - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - ], + if: { properties: { collected_by: { const: "BAP" } } }, + then: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + "@ondc/org/settlement_details", + ], + }, + else: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + ], + }, }, }, tags: { @@ -673,7 +739,7 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: [ "provider", "provider_location", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index d8d3584..4fbe8f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -556,8 +556,38 @@ module.exports = { }, required: ["measure", "count"], }, + minimum: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, }, - required: ["unitized", "available", "maximum"], + required: ["unitized", "available"], }, category_ids: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 8e8591b..d10a53e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -220,7 +220,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery ", "tax", "misc"] + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] }, price: { type: "object", @@ -324,8 +324,29 @@ module.exports = { required: ["price", "breakup", "ttl"], }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by:{ + type:"string", + enum:["BAP","BPP"] + } + }, + required: ["type","collected_by"], + }, + }, }, - required: ["provider", "items", "quote"], + required: ["provider", "items", "quote","payments","fulfillments"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index ecaf332..be80d41 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -235,12 +235,15 @@ module.exports = { type: "string", enum: [ "Pending", + "Packed", + "Agent-assigned", "Out-for-pickup", "Order-picked-up", "In-transit", "At-destination-hub", "Out-for-delivery", "Order-delivered", + "Cancelled" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index 79d7f96..160bdd1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -255,7 +255,7 @@ module.exports = { }, }, additionalProperties:false, - required: ["item", "fulfillment", "payment", "tags"], + required: ["fulfillment", "payment", "tags"], }, }, required: ["intent"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 218b65f..4cc3b84 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -56,9 +56,6 @@ module.exports = { }, transaction_id: { type: "string", - const: { $data: "/search/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -127,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations"], + required: ["id", "locations","ttl"], }, items: { type: "array", @@ -143,6 +140,12 @@ module.exports = { type: "string", }, }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, quantity: { type: "object", properties: { @@ -212,7 +215,7 @@ module.exports = { }, }, }, - required: ["id", "location_ids", "quantity"], + required: ["id", "location_ids", "quantity","tags","fulfillment_ids"], }, }, fulfillments: { @@ -220,6 +223,12 @@ module.exports = { items: { type: "object", properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, stops: { type: "array", items: { @@ -291,73 +300,8 @@ module.exports = { }, required: ["person"], }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: ["DELIVERY_TERMS"], - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: [ - "INCOTERMS", - "NAMED_PLACE_OF_DELIVERY", - ], - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - if: { - properties: { - descriptor: { - properties: { code: { const: "INCOTERMS" } }, - }, - }, - }, - then: { - properties: { - value: { - enum: [ - "DPU", - "CIF", - "EXW", - "FOB", - "DAP", - "DDP", - ], - }, - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, }, - required: ["stops"], + required: ["id","type","stops"], }, }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index ff7b510..952d783 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -214,7 +214,7 @@ module.exports = { required: ["label", "duration", "timestamp"], }, }, - required: ["id", "category_id", "descriptor","time","fulfillment_id"], + required: ["id", "category_id", "descriptor","fulfillment_id"], }, }, quote: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 1017c08..8591436 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -795,7 +795,7 @@ module.exports = { const: { $data: "/confirm/0/message/order/created_at", }, - errorMessage: "mismatches in /confirm and /on_update", + errorMessage: "mismatches in /confirm and /on_status", }, updated_at: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 32ee952..cc4f494 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -43,7 +43,7 @@ const checkOnSearch = async (data, msgIdSet) => { if (!match) { onSrchObj[ "bpp/provider:location:" + id + ":RGC" - ] = `Reverse Geocoding for location ID ${id} failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + ] = `Reverse Geocoding for location ID ${id} failed for provider with id '${provider?.id}'. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; } } catch (error) { console.log("bpp/providers error: ", error); @@ -56,6 +56,7 @@ const checkOnSearch = async (data, msgIdSet) => { provider.items.forEach((item) => { let itemTags = item?.tags; let mandatoryAttr; + let attrPresent = false; if (domain === "ONDC:RET12") { mandatoryAttr = constants.FASHION_ATTRIBUTES; @@ -64,11 +65,12 @@ const checkOnSearch = async (data, msgIdSet) => { mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; } itemTags.map(({ descriptor, list }, index) => { - switch (descriptor.code) { + switch (descriptor?.code) { case "attribute": + attrPresent = true; const encounteredAttr = []; list.map(({ descriptor, value }) => { - encounteredAttr.push(descriptor.code); + encounteredAttr.push(descriptor?.code); }); // Check if all mandatory attributes are encountered @@ -81,6 +83,12 @@ const checkOnSearch = async (data, msgIdSet) => { break; } }); + + if ( + (domain === "ONDC:RET12" || domain === "ONDC:RET14") && + !attrPresent + ) + onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; }); } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js index 726d5fa..a8c8112 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js @@ -16,42 +16,45 @@ const checkSearch = async (data, msgIdSet) => { let startLocation, endLocation; stops.forEach((stop) => { if (stop.type === "start") { - startLocation = stop.location; + startLocation = stop?.location; } if (stop.type === "end") { - endLocation = stop.location; + endLocation = stop?.location; } }); - console.log("Checking Reverse Geocoding for `end` location in `fullfilment`"); - try { - const [lat, long] = endLocation.gps.split(","); - const area_code = endLocation.area_code; - const match = await reverseGeoCodingCheck(lat, long, area_code); - if (!match) - srchObj[ - "RGC-end-Err" - ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; - } catch (error) { - console.log("Error in end location", error); - } - - // check for context cityCode and fulfillment end location - try { - const pinToStd = JSON.parse( - fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + if (endLocation) { + console.log( + "Checking Reverse Geocoding for `end` location in `fullfilment`" ); - const stdCode = data.context?.location?.city?.code.split(":")[1]; - const area_code = endLocation?.area_code; - if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { - srchObj[ - "CityCode-Err" - ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + try { + const [lat, long] = endLocation?.gps.split(","); + const area_code = endLocation?.area_code; + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) + srchObj[ + "RGC-end-Err" + ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } catch (error) { + console.log("Error in end location", error); } - } catch (err) { - console.error("Error in city code check: ", err.message); - } + // check for context cityCode and fulfillment end location + try { + const pinToStd = JSON.parse( + fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + ); + const stdCode = data.context?.location?.city?.code.split(":")[1]; + const area_code = endLocation?.area_code; + if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { + srchObj[ + "CityCode-Err" + ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + } + } catch (err) { + console.error("Error in city code check: ", err.message); + } + } dao.setValue("searchObj", search); return srchObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js index d53e7f6..7f94086 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js @@ -14,9 +14,9 @@ const checkOnInit = (data, msgIdSet) => { let onSearchProvArr = dao.getValue("providersArr"); - console.log(dao.getValue("providerLoc"),on_init.provider_location); - if(dao.getValue("providerLoc")===false && on_init.provider_location){ - onInitObj.prvdrLocErr=`Provider location should be provided only if returned in /on_search, also it is used where the shipment has to be dropped at LSP location` + console.log(dao.getValue("providerLoc"), on_init.provider_location); + if (dao.getValue("providerLoc") === false && on_init.provider_location) { + onInitObj.prvdrLocErr = `Provider location should be provided only if returned in /on_search, also it is used where the shipment has to be dropped at LSP location`; } try { @@ -28,6 +28,7 @@ const checkOnInit = (data, msgIdSet) => { onInitObj.qteDecimalErr = `Quote price value should not have more than 2 decimal places`; } let totalBreakup = 0; + let tax_present = false; on_init.quote.breakup.forEach((breakup, i) => { if (!utils.hasTwoOrLessDecimalPlaces(breakup.price.value)) { let itemkey = `itemPriceErr${i}`; @@ -36,8 +37,8 @@ const checkOnInit = (data, msgIdSet) => { itemkey ] = `Price value for '${breakup["@ondc/org/title_type"]}' should not have more than 2 decimal places`; } - totalBreakup += parseFloat(breakup.price.value); - + totalBreakup += parseFloat(breakup?.price?.value); + if (breakup["@ondc/org/title_type"] === "tax") tax_present = true; onSearchProvArr?.forEach((provider) => { if (provider.id === provId) { provider?.items.forEach((item, i) => { @@ -51,7 +52,7 @@ const checkOnInit = (data, msgIdSet) => { ) { let itemKey = `priceArr${i}`; onInitObj[itemKey] = `Quote price ${parseFloat( - on_init.quote.price.value + on_init?.quote?.price?.value )} for item id '${ breakup["@ondc/org/item_id"] }' does not match item price ${ @@ -64,7 +65,9 @@ const checkOnInit = (data, msgIdSet) => { }); }); - if (parseFloat(on_init.quote.price.value) !== totalBreakup) + if (!tax_present) + onInitObj.taxErr = `fulfillment charges will have separate quote line item for taxes`; + if (parseFloat(on_init?.quote?.price?.value) !== totalBreakup) onInitObj.quotePriceErr = `Quote price ${parseFloat( on_init.quote.price.value )} does not match the breakup total ${totalBreakup} in ${ From 6eadb8ae1056d3c8e601fb990a0a9834a70e122a Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 17 Jan 2024 14:14:32 +0530 Subject: [PATCH 100/228] added b2b validations --- .../schema/B2B_json_schema/v1/on_select.js | 2 +- .../schema/B2B_json_schema/v2/confirm.js | 1 + .../schema/B2B_json_schema/v2/init.js | 1 + .../schema/B2B_json_schema/v2/on_confirm.js | 3 + .../schema/B2B_json_schema/v2/on_init.js | 6 +- .../schema/B2B_json_schema/v2/on_select.js | 50 +++++++------- .../schema/B2B_json_schema/v2/on_status.js | 2 + .../schema/B2B_json_schema/v2/select.js | 2 + .../utils/ContextVal.js | 1 - .../utils/b2b/b2bConfirm.js | 35 ++++++++++ .../utils/b2b/b2bOnInit.js | 35 ++++++++++ .../utils/b2b/b2bOnSelect.js | 66 +++++++++++++++++++ .../utils/b2b/b2bOnStatus.js | 37 +++++++---- .../utils/b2b/b2bSearch.js | 17 +++++ .../utils/b2b/msgValidator.js | 14 ++-- 15 files changed, 222 insertions(+), 50 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js index f2fe7b0..41d3d59 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js @@ -164,7 +164,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["Serviceable", "Non-Serviceable"], + enum: ["Serviceable", "Non-serviceable"], }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 409f3ef..11543ea 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -634,6 +634,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 47ab2d3..6f969ba 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -487,6 +487,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by:{ type:"string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 9851d51..e083acc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -661,6 +661,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by: { type: "string", @@ -668,9 +669,11 @@ module.exports = { }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type" }, }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, }, "@ondc/org/settlement_details": { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 6c72c5a..311aa99 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -583,6 +583,8 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, + }, collected_by: { type: "string", @@ -674,8 +676,6 @@ module.exports = { if: { properties: { collected_by: { const: "BAP" } } }, then: { required: [ - "params", - "status", "type", "collected_by", "@ondc/org/buyer_app_finder_fee_type", @@ -688,8 +688,6 @@ module.exports = { }, else: { required: [ - "params", - "status", "type", "collected_by", "@ondc/org/buyer_app_finder_fee_type", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index d10a53e..f63f43a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -112,10 +112,27 @@ module.exports = { id: { type: "string", const: { $data: "/select/0/message/order/provider/id" }, - }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/select/0/message/order/provider/locations/0/id", + }, + }, + }, + additionalProperties:false, + required: ["id"], + }, + } }, - required: ["id"], + additionalProperties:false, + required: ["id","locations"], }, items: { type: "array", @@ -164,7 +181,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["Serviceable", "Non-Serviceable"], + enum: ["Serviceable", "Non-serviceable"], }, }, required: ["code"], @@ -237,30 +254,6 @@ module.exports = { item: { type: "object", properties: { - quantity: { - type: "object", - properties: { - available: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - maximum: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - }, - required: ["available", "maximum"], - }, price: { type: "object", properties: { @@ -274,7 +267,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["quantity", "price"], + required: ["price"], }, }, if: { @@ -336,6 +329,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by:{ type:"string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index be80d41..24ad2b9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -626,9 +626,11 @@ module.exports = { }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type" }, }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, }, "@ondc/org/settlement_details": { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 4cc3b84..1ed6d8f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -301,6 +301,7 @@ module.exports = { required: ["person"], }, }, + additionalProperties:false, required: ["id","type","stops"], }, }, @@ -316,6 +317,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 8749ce0..8c7731d 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -95,7 +95,6 @@ const checkContextVal = (payload, msgIdSet, i) => { Obj.tmpstmpErr = `Timestamp mismatch for /${action} `; } else { if ( - action === "on_search" || action === "on_select" || action === "on_init" || action === "on_confirm" || diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index e69de29..d078f84 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -0,0 +1,35 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkConfirm = async (data, msgIdSet) => { + const cnfrmObj = {}; + let confirm = data; + confirm = confirm.message.order; + let payments = confirm?.payments; + + try { + console.log(`Checking payment object in /confirm api`); + payments.forEach(payment => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + + if(feeType!=dao.getValue("BuyerFinderFeeType")){ + cnfrmObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` + } + if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ + cnfrmObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` + } + + }); + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return cnfrmObj; +}; +module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index e69de29..c94f90e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -0,0 +1,35 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnInit = async (data, msgIdSet) => { + const onInitObj = {}; + let onInit = data; + onInit = onInit.message.order; + let payments = onInit?.payments; + + try { + console.log(`Checking payment object in /on_init api`); + payments.forEach(payment => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + + if(feeType!=dao.getValue("BuyerFinderFeeType")){ + onInitObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` + } + if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ + onInitObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` + } + + }); + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return onInitObj; +}; +module.exports = checkOnInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js new file mode 100644 index 0000000..1cb2b9e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -0,0 +1,66 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnSelect = async (data, msgIdSet) => { + const onSelectObj = {}; + let onSelect = data; + onSelect = onSelect.message.order; + let quote = onSelect?.quote; + let fulfillments = onSelect?.fulfillments; + let ffState, ffId; + let deliveryQuoteItem = false; + try { + console.log("Checking fulfillment object in /on_select"); + if (fulfillments) { + fulfillments.forEach((fulfillment) => { + ffId = fulfillment?.id; + ffState = fulfillment?.state?.descriptor?.code; + }); + } + } catch (error) { + console.log(error); + } + + try { + console.log(`Checking quote object in /on_select api`); + quote?.breakup.forEach((breakup) => { + let itemPrice = parseFloat(breakup?.item?.price?.value); + let quantity = breakup["@ondc/org/item_quantity"]; + + if ( + breakup["@ondc/org/title_type"] === "delivery" && + breakup["@ondc/org/item_id"] === ffId + ) { + deliveryQuoteItem = true; + } + if ( + breakup["@ondc/org/title_type"] === "item" && + quantity && + parseFloat(breakup.price.value) != itemPrice * quantity?.count + ) { + onSelectObj.quoteErr = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + } + }); + + if (!deliveryQuoteItem && ffState === "Serviceable") { + onSelectObj.deliveryQuoteErr = `Delivery charges should be provided in quote/breakup when fulfillment is 'Serviceable'`; + } + if (deliveryQuoteItem && ffState === "Non-serviceable") { + onSelectObj.deliveryQuoteErr = `Delivery charges are not required in quote/breakup when fulfillment is 'Non-serviceable'`; + } + + if (ffState === "Non-serviceable" && !data.error) { + onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; + } + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return onSelectObj; +}; +module.exports = checkOnSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 30585b6..9d12cef 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -15,6 +15,28 @@ const checkOnStatus = (data, msgIdSet) => { let items = on_status.items; let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; + let payments = on_status?.payments; + + try { + console.log(`Checking payment object in /on_status`); + payments.forEach((payment) => { + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let params = payment?.params; + + if (paymentStatus === "PAID" && !params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if(paymentType==='ON-FULFILLMENT' && orderState!='Completed' && paymentStatus==='PAID'){ + onStatusObj.pymntstsErr= `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'` + } + }); + } catch (error) { + console.log(error); + } // try { // console.log( @@ -98,7 +120,6 @@ const checkOnStatus = (data, msgIdSet) => { }); } - //Out-for-delivery if (ffState === "Out-for-delivery") { if (orderState !== "In-progress") { @@ -107,13 +128,12 @@ const checkOnStatus = (data, msgIdSet) => { fulfillment.stops.forEach((stop) => { if (stop.type === "start") { pickupTime = stop?.time?.timestamp; - + if (!pickupTime) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - pickupTime !== - dao.getValue("pickupTime") + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } @@ -139,8 +159,7 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - pickupTime !== - dao.getValue("pickupTime") + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } @@ -149,7 +168,7 @@ const checkOnStatus = (data, msgIdSet) => { if (stop.type === "end") { deliveryTime = stop?.time?.timestamp; dao.setValue("deliveryTime", deliveryTime); - + if (!deliveryTime) { onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; } @@ -162,10 +181,6 @@ const checkOnStatus = (data, msgIdSet) => { } }); } - - - - } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js index a8c8112..a171cde 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js @@ -12,6 +12,23 @@ const checkSearch = async (data, msgIdSet) => { let contextTime = search.context.timestamp; search = search.message.intent; + try { + console.log("Checking buyer app finder fee in /search"); + + search.tags.forEach((tag) => { + if (tag?.descriptor?.code === "bap_terms" && tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "finder_fee_type") { + dao.setValue("buyerFinderFeeType", val?.value); + } + if (val?.descriptor?.code === "finder_fee_amount") { + dao.setValue("buyerFinderFeeAmount", val?.value); + } + }); + } + }); + } catch (error) {} + const stops = data?.message?.intent?.fulfillment?.stops; let startLocation, endLocation; stops.forEach((stop) => { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index e15deca..ae9f2dc 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -1,7 +1,8 @@ const checkConfirm = require("./b2bConfirm"); const checkInit = require("./b2bInit"); -const checkOnConfirm = require("./b2bOnConfirm"); const checkOnInit = require("./b2bOnInit"); +const checkOnConfirm = require("./b2bOnConfirm"); +const checkOnSelect = require("./b2bOnSelect"); const checkOnSearch = require("./b2bOnSearch"); const checkOnUpdate = require("./b2bOnUpdate"); const checkUpdate = require("./b2bUpdate"); @@ -18,14 +19,17 @@ const b2bVal = (element, action, msgIdSet) => { case "on_search": return checkOnSearch(element, msgIdSet); + case "on_select": + return checkOnSelect(element, msgIdSet); + case "init": return checkInit(element, msgIdSet); - // case "on_init": - // return checkOnInit(element, msgIdSet); + case "on_init": + return checkOnInit(element, msgIdSet); - // case "confirm": - // return checkConfirm(element, msgIdSet); + case "confirm": + return checkConfirm(element, msgIdSet); // case "on_confirm": // return checkOnConfirm(element, msgIdSet); From 4aa0f6727d42269062d187981e307af22a37092f Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 18 Jan 2024 10:25:19 +0530 Subject: [PATCH 101/228] bug fix --- .../utils/b2b/b2bConfirm.js | 21 +++++++++---------- .../utils/b2b/b2bOnInit.js | 21 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index d078f84..74c9580 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -11,18 +11,17 @@ const checkConfirm = async (data, msgIdSet) => { try { console.log(`Checking payment object in /confirm api`); - payments.forEach(payment => { - let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] - let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + payments.forEach((payment) => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; - if(feeType!=dao.getValue("BuyerFinderFeeType")){ - cnfrmObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` - } - if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ - cnfrmObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` - } - - }); + if (feeType != dao.getValue("buyerFinderFeeType")) { + onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); } catch (error) { console.log( `!!Error while checking providers array in /on_search api`, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index c94f90e..16f3439 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -11,18 +11,17 @@ const checkOnInit = async (data, msgIdSet) => { try { console.log(`Checking payment object in /on_init api`); - payments.forEach(payment => { - let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] - let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + payments.forEach((payment) => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; - if(feeType!=dao.getValue("BuyerFinderFeeType")){ - onInitObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` - } - if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ - onInitObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` - } - - }); + if (feeType != dao.getValue("buyerFinderFeeType")) { + onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); } catch (error) { console.log( `!!Error while checking providers array in /on_search api`, From bd3441fce138406fee1a331f5e1a232b93094893 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 22 Jan 2024 13:23:16 +0530 Subject: [PATCH 102/228] added b2b val --- .../B2B_json_schema/keywords/confirm.js | 1 - .../schema/B2B_json_schema/v2/confirm.js | 9 +- .../schema/B2B_json_schema/v2/init.js | 4 +- .../schema/B2B_json_schema/v2/on_confirm.js | 3 +- .../schema/B2B_json_schema/v2/on_init.js | 21 ++- .../schema/B2B_json_schema/v2/on_select.js | 117 +++++++++++--- .../schema/B2B_json_schema/v2/on_status.js | 19 ++- .../schema/B2B_json_schema/v2/select.js | 5 +- .../utils/b2b/b2bConfirm.js | 4 +- .../utils/b2b/b2bOnInit.js | 4 +- .../utils/b2b/b2bOnSearch.js | 69 ++++----- .../utils/b2b/b2bOnSelect.js | 17 ++- .../utils/b2b/b2bSelect.js | 144 ++++++++++++++++++ .../utils/b2b/msgValidator.js | 4 + 14 files changed, 335 insertions(+), 86 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js index 239d106..5e7963a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js @@ -3,7 +3,6 @@ module.exports = { const contextTime = data?.context?.timestamp; const created_at = data?.message?.order?.created_at; const updated_at = data?.message?.order?.updated_at; - console.log(contextTime,updated_at); if ( (created_at && created_at > contextTime) || (updated_at && updated_at > contextTime) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 11543ea..ceb53cb 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -634,7 +634,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { type: "string", @@ -793,15 +793,12 @@ module.exports = { }, created_at: { type: "string", - const: { $data: "3/context/timestamp" }, - errorMessage: - "does not match context timestamp - ${3/context/timestamp}", }, updated_at: { type: "string", - const: { $data: "3/context/timestamp" }, + const: { $data: "1/created_at" }, errorMessage: - "does not match context timestamp - ${3/context/timestamp}", + "does not match created_at timestamp - ${1/created_at}", }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 6f969ba..24c21ce 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -228,7 +228,7 @@ module.exports = { }, }, }, - required: ["id", "fulfillment_ids","quantity","tags",], + required: ["id", "fulfillment_ids","quantity"], }, }, billing: { @@ -487,7 +487,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by:{ type:"string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index e083acc..21b1007 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -661,7 +661,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { type: "string", @@ -829,5 +829,6 @@ module.exports = { required: ["order"], }, }, + isFutureDated: true, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 311aa99..6c7d5fc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -287,13 +287,28 @@ module.exports = { properties: { id: { type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/id" }, }, type: { type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/type" }, + }, + "@ondc/org/provider_name": { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1provider_name" }, }, tracking: { type: "boolean", }, + "@ondc/org/category": { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1category" }, + }, + "@ondc/org/TAT": { + type: "string", + format: "duration", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1TAT" }, + }, stops: { type: "array", items: { @@ -459,6 +474,7 @@ module.exports = { }, value: { type: "string", + const: { $data: "/on_select/0/message/order/quote/price/value" }, }, }, required: ["currency", "value"], @@ -583,7 +599,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { @@ -680,9 +696,6 @@ module.exports = { "collected_by", "@ondc/org/buyer_app_finder_fee_type", "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_basis", - "@ondc/org/settlement_window", - "@ondc/org/withholding_amount", "@ondc/org/settlement_details", ], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index f63f43a..8729009 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -75,14 +75,14 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", format: "date-time", }, ttl: { - type: "string" + type: "string", }, }, required: [ @@ -126,30 +126,98 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: ["id"], }, - } + }, }, - additionalProperties:false, - required: ["id","locations"], + additionalProperties: false, + required: ["id", "locations"], }, items: { type: "array", items: { type: "object", properties: { + id: { + type: "string", + }, fulfillment_ids: { type: "array", items: { type: "string", }, }, - id: { - type: "string", + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, }, }, - required: ["id"], + required: ["id", "quantity", "fulfillment_ids"], }, }, fulfillments: { @@ -171,7 +239,7 @@ module.exports = { }, "@ondc/org/TAT": { type: "string", - format: "duration" + format: "duration", }, state: { type: "object", @@ -237,7 +305,14 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + ], }, price: { type: "object", @@ -310,11 +385,11 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, }, isQuoteMatching: true, - + required: ["price", "breakup", "ttl"], }, payments: { @@ -329,18 +404,18 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], }, - collected_by:{ - type:"string", - enum:["BAP","BPP"] - } }, - required: ["type","collected_by"], + required: ["type", "collected_by"], }, }, }, - required: ["provider", "items", "quote","payments","fulfillments"], + required: ["provider", "items", "quote", "payments", "fulfillments"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 24ad2b9..2f37c00 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -243,7 +243,7 @@ module.exports = { "At-destination-hub", "Out-for-delivery", "Order-delivered", - "Cancelled" + "Cancelled", ], }, }, @@ -607,14 +607,15 @@ module.exports = { }, type: { type: "string", - const: { - $data: "/on_confirm/0/message/order/payments/0/type", - }, enum: [ "PRE-FULFILLMENT", "ON-FULFILLMENT", "POST-FULFILLMENT", ], + + const: { + $data: "/on_confirm/0/message/order/payments/0/type", + }, }, collected_by: { type: "string", @@ -626,11 +627,17 @@ module.exports = { }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", - const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type" }, + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type", + }, }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", - const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount", + }, }, "@ondc/org/settlement_details": { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 1ed6d8f..dae5330 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations","ttl"], + required: ["id", "locations"], }, items: { type: "array", @@ -215,7 +215,7 @@ module.exports = { }, }, }, - required: ["id", "location_ids", "quantity","tags","fulfillment_ids"], + required: ["id", "location_ids", "quantity","fulfillment_ids"], }, }, fulfillments: { @@ -317,7 +317,6 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index 74c9580..eafad54 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -18,13 +18,13 @@ const checkConfirm = async (data, msgIdSet) => { if (feeType != dao.getValue("buyerFinderFeeType")) { onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; } }); } catch (error) { console.log( - `!!Error while checking providers array in /on_search api`, + `!!Error while checking providers array in /confirm api`, error ); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index 16f3439..635c8f9 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -18,13 +18,13 @@ const checkOnInit = async (data, msgIdSet) => { if (feeType != dao.getValue("buyerFinderFeeType")) { onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; } }); } catch (error) { console.log( - `!!Error while checking providers array in /on_search api`, + `!!Error while checking providers array in /on_init api`, error ); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index cc4f494..a6bfe43 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -52,44 +52,45 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics + if (domain === "ONDC:RET12" || domain === "ONDC:RET14") { + provider.items.forEach((item) => { + let itemTags = item?.tags; + let mandatoryAttr; + let attrPresent = false; - provider.items.forEach((item) => { - let itemTags = item?.tags; - let mandatoryAttr; - let attrPresent = false; + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET14") { + mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + } + itemTags.map(({ descriptor, list }, index) => { + switch (descriptor?.code) { + case "attribute": + attrPresent = true; + const encounteredAttr = []; + list.map(({ descriptor, value }) => { + encounteredAttr.push(descriptor?.code); + }); - if (domain === "ONDC:RET12") { - mandatoryAttr = constants.FASHION_ATTRIBUTES; - } - if (domain === "ONDC:RET14") { - mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; - } - itemTags.map(({ descriptor, list }, index) => { - switch (descriptor?.code) { - case "attribute": - attrPresent = true; - const encounteredAttr = []; - list.map(({ descriptor, value }) => { - encounteredAttr.push(descriptor?.code); - }); + // Check if all mandatory attributes are encountered + const missingAttr = mandatoryAttr.filter( + (code) => !encounteredAttr.includes(code) + ); + if (missingAttr.length > 0) { + onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + } + break; + } + }); - // Check if all mandatory attributes are encountered - const missingAttr = mandatoryAttr.filter( - (code) => !encounteredAttr.includes(code) - ); - if (missingAttr.length > 0) { - onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; - } - break; - } + if ( + (domain === "ONDC:RET12" || domain === "ONDC:RET14") && + !attrPresent + ) + onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; }); - - if ( - (domain === "ONDC:RET12" || domain === "ONDC:RET14") && - !attrPresent - ) - onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; - }); + } } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 1cb2b9e..b7f7717 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -25,10 +25,12 @@ const checkOnSelect = async (data, msgIdSet) => { try { console.log(`Checking quote object in /on_select api`); - quote?.breakup.forEach((breakup) => { + quote?.breakup.forEach((breakup,i) => { let itemPrice = parseFloat(breakup?.item?.price?.value); + let available = Number(breakup?.item?.quantity?.available?.count) let quantity = breakup["@ondc/org/item_quantity"]; + if ( breakup["@ondc/org/title_type"] === "delivery" && breakup["@ondc/org/item_id"] === ffId @@ -38,9 +40,16 @@ const checkOnSelect = async (data, msgIdSet) => { if ( breakup["@ondc/org/title_type"] === "item" && quantity && - parseFloat(breakup.price.value) != itemPrice * quantity?.count + parseFloat(breakup.price.value).toFixed(2) != parseFloat(itemPrice * quantity?.count).toFixed(2) ) { - onSelectObj.quoteErr = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + let item = `quoteErr${i}` + onSelectObj[item] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + } + + if( breakup["@ondc/org/title_type"] === "item" && + quantity && quantity?.count>available){ + let item = `quoteErr${i}` + onSelectObj[item] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; } }); @@ -56,7 +65,7 @@ const checkOnSelect = async (data, msgIdSet) => { } } catch (error) { console.log( - `!!Error while checking providers array in /on_search api`, + `!!Error while checking providers array in /on_select api`, error ); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index e69de29..9fbfd6a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -0,0 +1,144 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkSelect = async (data, msgIdSet) => { + const selectObj = {}; + let select = data; + select = select.message.order; + let itemIdList; + let fulfillments = select?.fulfillments; + + fulfillments.forEach(fulfillment => { + + const fulId= fulfillment?.id + const fulType = fulfillment?.type + + console.log("Checking if the fulfillment id and type in /select present in /on_search") + + + }); + + + //provider check + // try { + // console.log(`Comparing provider object in /select and /on_search`); + // if (select.provider) { + // onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); + // let providerObj = providersArr?.filter( + // (prov) => prov.id === select.provider.id + // ); + // if (!providerObj || providerObj?.length < 1) { + // selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; + // } else { + // if ( + // (!select?.provider?.locations || + // select?.provider?.locations?.length < 1) && + // providerObj[0]?.locations?.length > 1 + // ) { + // selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + // } else if (select?.provider?.locations) { + // let providerLocArr = select.provider.locations; + // let providerLocExists = false; + // providerLocArr.forEach((location, i) => { + // providerObj[0]?.locations?.forEach((element) => { + // console.log(location.id, element.id); + + // if (location.id === element.id) providerLocExists = true; + // }); + + // if (!providerLocExists) { + // let itemkey = `providerLocErr${i}`; + // selectObj[ + // itemkey + // ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + // } + // providerLocExists = false; + // }); + // } + // } + // } + // } catch (error) { + // console.log( + // `!!Error while checking provider object in /${constants.LOG_select}`, + // error + // ); + // } + + // //item check + // try { + // console.log(`Comparing item object in /select and /on_search`); + // let itemExists = false; + + // itemsArr?.forEach((item, i) => { + // if (item.descriptor.code === "P2H2P") { + // p2h2p = true; + // } + // onSearchitemsArr?.forEach((element) => { + // if (item.id === element.id) itemExists = true; + // }); + // if (!itemExists) { + // let itemkey = `itemErr${i}`; + // selectObj[ + // itemkey + // ] = `Item Id '${item.id}' does not exist in /on_search`; + // } else { + // let itemObj = onSearchitemsArr.filter( + // (element) => item.id === element.id + // ); + + // itemObj = itemObj[0]; + // dao.setValue("selectedItem", itemObj.id); + // console.log(itemObj.id); + // if (item.category_id != itemObj.category_id) { + // let itemkey = `catIdErr${i}`; + // selectObj[ + // itemkey + // ] = `Category id '${item.category_id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + // } + // if (item.descriptor.code != itemObj.descriptor.code) { + // let itemkey = `codeErr${i}`; + // selectObj[ + // itemkey + // ] = `Descriptor code '${item.descriptor.code}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + // } + // fulfillmentsArr.forEach((fulfillment, i) => { + // if (fulfillment.id !== itemObj.fulfillment_id) { + // let itemkey = `flfillmentErr${i}`; + // selectObj[ + // itemkey + // ] = `Fulfillment id '${fulfillment.id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + // } else { + // let bppfulfillment = bppFulfillmentsArr?.find( + // (element) => element.id === fulfillment.id + // ); + // if (fulfillment.type !== bppfulfillment?.type) { + // let itemkey = `flfillmentTypeErr${i}`; + // selectObj[ + // itemkey + // ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + // } + // } + // }); + // } + // itemExists = false; + // }); + // } catch (error) { + // console.log(error); + // } + // try { + // console.log("Checking fulfillment object in /select"); + // if (fulfillments) { + // fulfillments.forEach((fulfillment) => { + // ffId = fulfillment?.id; + // ffState = fulfillment?.state?.descriptor?.code; + // }); + // } + // } catch (error) { + // console.log(error); + // } + + return selectObj; +}; +module.exports = checkSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index ae9f2dc..ce96288 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -1,5 +1,6 @@ const checkConfirm = require("./b2bConfirm"); const checkInit = require("./b2bInit"); +const checkSelect = require("./b2bSelect"); const checkOnInit = require("./b2bOnInit"); const checkOnConfirm = require("./b2bOnConfirm"); const checkOnSelect = require("./b2bOnSelect"); @@ -19,6 +20,9 @@ const b2bVal = (element, action, msgIdSet) => { case "on_search": return checkOnSearch(element, msgIdSet); + case "select": + return checkSelect(element, msgIdSet); + case "on_select": return checkOnSelect(element, msgIdSet); From 9918bd503579b8b1caec95147f394e2178a01449 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 22 Jan 2024 15:56:15 +0530 Subject: [PATCH 103/228] updated --- .../schema/B2B_json_schema/v2/on_select.js | 65 ++++++++++++++++++ .../schema/B2B_json_schema/v2/select.js | 67 ++++++++++++++++++- .../utils/b2b/b2bConfirm.js | 26 ++++++- 3 files changed, 154 insertions(+), 4 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 8729009..309dd8f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -257,6 +257,71 @@ module.exports = { }, required: ["descriptor"], }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, }, required: [ "id", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index dae5330..ced30ea 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations"], + required: ["id", "locations","ttl"], }, items: { type: "array", @@ -300,6 +300,71 @@ module.exports = { }, required: ["person"], }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, }, additionalProperties:false, required: ["id","type","stops"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index eafad54..ed7ed39 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -14,12 +14,32 @@ const checkConfirm = async (data, msgIdSet) => { payments.forEach((payment) => { let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let params = payment?.params; if (feeType != dao.getValue("buyerFinderFeeType")) { - onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + cnfrmObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { - onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + cnfrmObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + + if (paymentStatus === "PAID" && !params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + cnfrmObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; } }); } catch (error) { From 95b72a275d670e4934a2c244c7f32801cb037bfd Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 23 Jan 2024 16:19:45 +0530 Subject: [PATCH 104/228] added b2b checks --- .../schema/B2B_json_schema/v2/confirm.js | 7 +- .../schema/B2B_json_schema/v2/init.js | 7 +- .../schema/B2B_json_schema/v2/on_confirm.js | 6 +- .../schema/B2B_json_schema/v2/on_init.js | 7 +- .../schema/B2B_json_schema/v2/on_select.js | 8 +- .../schema/B2B_json_schema/v2/select.js | 11 +- .../utils/b2b/b2bConfirm.js | 18 ++ .../utils/b2b/b2bInit.js | 87 +------ .../utils/b2b/b2bOnSearch.js | 6 + .../utils/b2b/b2bOnSelect.js | 44 +++- .../utils/b2b/b2bOnStatus.js | 53 +++- .../utils/b2b/b2bSelect.js | 231 ++++++++---------- .../utils/constants.js | 3 +- .../utils/logistics/logInit.js | 2 +- .../log-verification-utility/utils/utils.js | 39 +++ 15 files changed, 302 insertions(+), 227 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index ceb53cb..6598048 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/confirmSchema", type: "object", @@ -756,6 +757,7 @@ module.exports = { }, tags: { type: "array", + minItems: 3, items: { type: "object", properties: { @@ -763,7 +765,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -776,7 +778,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, @@ -813,6 +815,7 @@ module.exports = { "payments", "created_at", "updated_at", + "tags" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 24c21ce..70d6924 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -1,3 +1,5 @@ +const constants = require("../../../utils/constants"); + module.exports = { $id: "http://example.com/schema/initSchema", type: "object", @@ -499,6 +501,7 @@ module.exports = { }, tags: { type: "array", + minItems: 1, items: { type: "object", properties: { @@ -506,7 +509,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -519,7 +522,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 21b1007..97cf393 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onConfirmSchema", type: "object", @@ -763,6 +764,7 @@ module.exports = { }, tags: { type: "array", + minItems: 3, items: { type: "object", properties: { @@ -770,7 +772,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -783,7 +785,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 6c7d5fc..7095ff1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onInitSchema", type: "object", @@ -714,6 +715,7 @@ module.exports = { }, tags: { type: "array", + minItems: 2, items: { type: "object", properties: { @@ -721,7 +723,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -734,7 +736,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, @@ -759,6 +761,7 @@ module.exports = { "fulfillments", "quote", "payments", + "tags" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 309dd8f..fd73c5e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -480,7 +480,13 @@ module.exports = { }, }, }, - required: ["provider", "items", "quote", "payments", "fulfillments"], + required: [ + "provider", + "items", + "quote", + "payments", + "fulfillments" + ], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index ced30ea..1652dfa 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations","ttl"], + required: ["id", "locations", "ttl"], }, items: { type: "array", @@ -215,7 +215,7 @@ module.exports = { }, }, }, - required: ["id", "location_ids", "quantity","fulfillment_ids"], + required: ["id", "location_ids", "quantity", "fulfillment_ids"], }, }, fulfillments: { @@ -244,7 +244,8 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, area_code: { type: "string", @@ -366,8 +367,8 @@ module.exports = { }, }, }, - additionalProperties:false, - required: ["id","type","stops"], + additionalProperties: false, + required: ["id", "type", "stops"], }, }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index ed7ed39..f02e68b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -7,8 +7,26 @@ const checkConfirm = async (data, msgIdSet) => { const cnfrmObj = {}; let confirm = data; confirm = confirm.message.order; + let orderState = confirm.state; let payments = confirm?.payments; + let items = confirm.items; + const selectedItems = dao.getValue("slctdItemsArray"); + + try { + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + let itemkey = `item-${i}-DiffErr`; + cnfrmObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select`; + }); + } catch (error) { + console.log(error); + } + try { console.log(`Checking payment object in /confirm api`); payments.forEach((payment) => { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index b7cc0ce..f201555 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -8,86 +8,21 @@ const checkInit = (data, msgIdSet) => { let init = data; init = init.message.order; - let itemsArr = init.items; - let fulfillmentsArr = init.fulfillments; - let onSearchitemsArr; - let providersArr = dao.getValue("providersArr"); + let items = init.items; + const selectedItems = dao.getValue("slctdItemsArray"); - //provider check try { - console.log(`Comparing provider object in /init and /on_search`); - if (init.provider) { - onSearchitemsArr = dao.getValue(`${init.provider.id}itemsArr`); - let providerObj = providersArr?.filter( - (prov) => prov.id === init.provider.id - ); - if (providerObj?.length < 1) { - initObj.prvdrErr = `Provider with id '${init.provider.id}' does not exist in the catalog provided in /on_search`; - } else { - if ( - (!init?.provider?.locations || - init?.provider?.locations?.length < 1) && - providerObj[0]?.locations?.length > 1 - ) { - initObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; - } else if (init?.provider?.locations) { - let providerLocArr = init.provider.locations; - let providerLocExists = false; - - if (providerLocArr) { - providerLocArr.forEach((location, i) => { - if (providerObj) { - providerObj[0]?.locations?.forEach((element) => { - console.log(location.id, element.id); - - if (location.id === element.id) providerLocExists = true; - }); - } - - if (!providerLocExists) { - let itemkey = `providerLocErr${i}`; - initObj[ - itemkey - ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; - } - providerLocExists = false; - }); - } - } - } - } - } catch (error) { - console.log( - `!!Error while checking provider object in /${constants.LOG_INIT}`, - error - ); - } - - //item check - try { - console.log(`Comparing item object in /init and /on_search`); - let itemExists = false; - - itemsArr.forEach((item, i) => { - if (onSearchitemsArr) { - onSearchitemsArr.forEach((element) => { - if (item.id === element.id) itemExists = true; - }); - } - - if (!itemExists) { - let itemkey = `itemErr${i}`; - initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; - } else { - let itemObj = onSearchitemsArr.filter( - (element) => item.id === element.id - ); - itemObj = itemObj[0]; - } - itemExists = false; + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + let itemkey = `item-${i}-DiffErr`; + initObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select`; }); } catch (error) { - console.log(`!!Error while checking items array in /on_init API`, error); + console.log(error); } return initObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index a6bfe43..56bc22a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -10,6 +10,12 @@ const checkOnSearch = async (data, msgIdSet) => { let domain = onSearch.context.domain; onSearch = onSearch.message.catalog; + //saving fulfillments + + const fulfillments = onSearch?.fulfillments; + + dao.setValue("fulfillmentsArr", fulfillments); + try { console.log(`Saving provider items array in /on_search api`); if (onSearch["providers"]) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index b7f7717..f99599e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -8,9 +8,11 @@ const checkOnSelect = async (data, msgIdSet) => { let onSelect = data; onSelect = onSelect.message.order; let quote = onSelect?.quote; + const items = onSelect.items; let fulfillments = onSelect?.fulfillments; let ffState, ffId; let deliveryQuoteItem = false; + const selectedItems = dao.getValue("slctdItemsArray"); try { console.log("Checking fulfillment object in /on_select"); if (fulfillments) { @@ -23,14 +25,28 @@ const checkOnSelect = async (data, msgIdSet) => { console.log(error); } + try { + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + let itemkey = `item-${i}-DiffErr`; + onSelectObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select`; + }); + } catch (error) { + console.log(error); + } + + try { console.log(`Checking quote object in /on_select api`); - quote?.breakup.forEach((breakup,i) => { + quote?.breakup.forEach((breakup, i) => { let itemPrice = parseFloat(breakup?.item?.price?.value); - let available = Number(breakup?.item?.quantity?.available?.count) + let available = Number(breakup?.item?.quantity?.available?.count); let quantity = breakup["@ondc/org/item_quantity"]; - if ( breakup["@ondc/org/title_type"] === "delivery" && breakup["@ondc/org/item_id"] === ffId @@ -40,16 +56,24 @@ const checkOnSelect = async (data, msgIdSet) => { if ( breakup["@ondc/org/title_type"] === "item" && quantity && - parseFloat(breakup.price.value).toFixed(2) != parseFloat(itemPrice * quantity?.count).toFixed(2) + parseFloat(breakup.price.value).toFixed(2) != + parseFloat(itemPrice * quantity?.count).toFixed(2) ) { - let item = `quoteErr${i}` - onSelectObj[item] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + let item = `quoteErr${i}`; + onSelectObj[ + item + ] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; } - if( breakup["@ondc/org/title_type"] === "item" && - quantity && quantity?.count>available){ - let item = `quoteErr${i}` - onSelectObj[item] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; + if ( + breakup["@ondc/org/title_type"] === "item" && + quantity && + quantity?.count > available + ) { + let item = `quoteErr${i}`; + onSelectObj[ + item + ] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; } }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 9d12cef..7d1817a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -30,8 +30,12 @@ const checkOnStatus = (data, msgIdSet) => { if (paymentStatus === "NOT-PAID" && params?.transaction_id) { onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; } - if(paymentType==='ON-FULFILLMENT' && orderState!='Completed' && paymentStatus==='PAID'){ - onStatusObj.pymntstsErr= `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'` + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + onStatusObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; } }); } catch (error) { @@ -182,6 +186,51 @@ const checkOnStatus = (data, msgIdSet) => { }); } } + if (fulfillment.type === "Self-Pickup") { + if ( + ffState === "Pending" || + ffState === "Packed" + ) { + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + if (stop?.time?.timestamp) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + + if (ffState === "Order-picked-up") { + if (orderState !== "Completed") { + onStatusObj.ordrStatErr = `Order state should be 'Completed' once the order is picked up`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; + } + + if (_.gt(pickupTime, contextTime)) { + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + } }); } catch (error) { console.log(`Error checking fulfillments/start in /on_status`); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index 9fbfd6a..9a0539f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -7,137 +7,122 @@ const checkSelect = async (data, msgIdSet) => { const selectObj = {}; let select = data; select = select.message.order; - let itemIdList; let fulfillments = select?.fulfillments; - - fulfillments.forEach(fulfillment => { + let providersArr = dao.getValue("providersArr"); + let fulfillmentsArr = dao.getValue("fulfillmentsArr"); + let itemsArr = select.items; + dao.setValue("slctdItemsArray",itemsArr) - const fulId= fulfillment?.id - const fulType = fulfillment?.type + // provider check + try { + console.log(`Comparing provider object in /select and /on_search`); + if (select.provider) { + onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); + let providerObj = providersArr?.filter( + (prov) => prov.id === select.provider.id + ); + if (!providerObj || providerObj?.length < 1) { + selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; + } else { + if ( + (!select?.provider?.locations || + select?.provider?.locations?.length < 1) && + providerObj[0]?.locations?.length > 1 + ) { + selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + } else if (select?.provider?.locations) { + let providerLocArr = select.provider.locations; + let providerLocExists = false; + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); - console.log("Checking if the fulfillment id and type in /select present in /on_search") - - - }); + if (location.id === element.id) providerLocExists = true; + }); + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + selectObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; + }); + } + } + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.LOG_select}`, + error + ); + } - //provider check - // try { - // console.log(`Comparing provider object in /select and /on_search`); - // if (select.provider) { - // onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); - // let providerObj = providersArr?.filter( - // (prov) => prov.id === select.provider.id - // ); - // if (!providerObj || providerObj?.length < 1) { - // selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; - // } else { - // if ( - // (!select?.provider?.locations || - // select?.provider?.locations?.length < 1) && - // providerObj[0]?.locations?.length > 1 - // ) { - // selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; - // } else if (select?.provider?.locations) { - // let providerLocArr = select.provider.locations; - // let providerLocExists = false; - // providerLocArr.forEach((location, i) => { - // providerObj[0]?.locations?.forEach((element) => { - // console.log(location.id, element.id); + //item check + try { + console.log(`Comparing item object in /select and /on_search`); - // if (location.id === element.id) providerLocExists = true; - // }); + itemsArr?.forEach((item, i) => { + let itemExists = false; + onSearchitemsArr?.forEach((element) => { + if (item.id === element.id) itemExists = true; + }); + if (!itemExists) { + let itemkey = `itemErr${i}`; + selectObj[ + itemkey + ] = `Item Id '${item.id}' does not exist in /on_search`; + } else { + let itemObj = onSearchitemsArr.filter( + (element) => element.id === item.id + ); - // if (!providerLocExists) { - // let itemkey = `providerLocErr${i}`; - // selectObj[ - // itemkey - // ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; - // } - // providerLocExists = false; - // }); - // } - // } - // } - // } catch (error) { - // console.log( - // `!!Error while checking provider object in /${constants.LOG_select}`, - // error - // ); - // } + itemObj = itemObj[0]; + // dao.setValue("selectedItem", itemObj.id); + console.log(itemObj.id); + if ( + !_.every(item.fulfillment_ids, (element) => + _.includes(itemObj.fulfillment_ids, element) + ) + ) { + let itemkey = `flflmntIdErr${i}`; + selectObj[ + itemkey + ] = `Fulfillment ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + if ( + !_.every(item.location_ids, (element) => + _.includes(itemObj.location_ids, element) + ) + ) { + let itemkey = `lctnIdErr${i}`; + selectObj[ + itemkey + ] = `Location ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } - // //item check - // try { - // console.log(`Comparing item object in /select and /on_search`); - // let itemExists = false; - - // itemsArr?.forEach((item, i) => { - // if (item.descriptor.code === "P2H2P") { - // p2h2p = true; - // } - // onSearchitemsArr?.forEach((element) => { - // if (item.id === element.id) itemExists = true; - // }); - // if (!itemExists) { - // let itemkey = `itemErr${i}`; - // selectObj[ - // itemkey - // ] = `Item Id '${item.id}' does not exist in /on_search`; - // } else { - // let itemObj = onSearchitemsArr.filter( - // (element) => item.id === element.id - // ); - - // itemObj = itemObj[0]; - // dao.setValue("selectedItem", itemObj.id); - // console.log(itemObj.id); - // if (item.category_id != itemObj.category_id) { - // let itemkey = `catIdErr${i}`; - // selectObj[ - // itemkey - // ] = `Category id '${item.category_id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; - // } - // if (item.descriptor.code != itemObj.descriptor.code) { - // let itemkey = `codeErr${i}`; - // selectObj[ - // itemkey - // ] = `Descriptor code '${item.descriptor.code}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; - // } - // fulfillmentsArr.forEach((fulfillment, i) => { - // if (fulfillment.id !== itemObj.fulfillment_id) { - // let itemkey = `flfillmentErr${i}`; - // selectObj[ - // itemkey - // ] = `Fulfillment id '${fulfillment.id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; - // } else { - // let bppfulfillment = bppFulfillmentsArr?.find( - // (element) => element.id === fulfillment.id - // ); - // if (fulfillment.type !== bppfulfillment?.type) { - // let itemkey = `flfillmentTypeErr${i}`; - // selectObj[ - // itemkey - // ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; - // } - // } - // }); - // } - // itemExists = false; - // }); - // } catch (error) { - // console.log(error); - // } - // try { - // console.log("Checking fulfillment object in /select"); - // if (fulfillments) { - // fulfillments.forEach((fulfillment) => { - // ffId = fulfillment?.id; - // ffState = fulfillment?.state?.descriptor?.code; - // }); - // } - // } catch (error) { - // console.log(error); - // } + //checking fulfillments + fulfillments.forEach((fulfillment, i) => { + let bppfulfillment = fulfillmentsArr?.find( + (element) => element.id === fulfillment.id + ); + if (!bppfulfillment) { + let itemkey = `flfillmentIDerr${i}`; + selectObj[ + itemkey + ] = `Fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + } else if (fulfillment.type !== bppfulfillment?.type) { + let itemkey = `flfillmentTypeErr${i}`; + selectObj[ + itemkey + ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + } + }); + } + }); + } catch (error) { + console.log(error); + } return selectObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 56c887f..3ff9912 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -171,5 +171,6 @@ module.exports = Object.freeze({ CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], - TERMS:["bap_terms","bpp_terms"] + TERMS:["buyer_id","bap_terms","bpp_terms"], + B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index ef36eae..7c2d4c6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -79,7 +79,7 @@ const checkInit = (data, msgIdSet) => { initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; } else { let itemObj = onSearchitemsArr.filter( - (element) => item.id === element.id + (element) => element.id === item.id ); itemObj = itemObj[0]; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 04fd841..3c407dc 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -365,6 +365,44 @@ const isObjectEqual = (obj1, obj2, parentKey = "") => { return notEqualKeys; }; +function findDifferentAttributes(obj1, obj2) { + const differences = []; + + // Iterate over each key in obj1 + _.forOwn(obj1, (value1, key) => { + const value2 = obj2[key]; + + // Check if the values are not equal + if (!_.isEqual(value1, value2)) { + differences.push(key); + } + }); + + return differences; +} + +function findDifferencesInArrays(array1, array2) { + const differences = []; + + // Check if arrays have the same length + if (array1.length !== array2.length) { + return differences; + } + + // Iterate over each item in the arrays + for (let i = 0; i < array1.length; i++) { + const item1 = array1[i]; + const item2 = array2[i]; + + // Check if the properties are equal using lodash's _.isEqual + if (!_.isEqual(item1, item2)) { + const differingAttributes = findDifferentAttributes(item1, item2); + differences.push({ index: i, attributes: differingAttributes }); + } + } + + return differences; +} module.exports = { uuidCheck, timestampCheck, @@ -390,6 +428,7 @@ module.exports = { taxNotInlcusive, isArrayEqual, countDecimalDigits, + findDifferencesInArrays, grocery_categories_id, fnb_categories_id, }; From bc5c327e712646e9e0c933b94633f132c7f5ec85 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 23 Jan 2024 17:08:00 +0530 Subject: [PATCH 105/228] minor fix --- .../log-verification-utility/utils/b2b/b2bConfirm.js | 2 ++ .../log-verification-utility/utils/b2b/b2bInit.js | 2 ++ .../log-verification-utility/utils/b2b/b2bOnSelect.js | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index f02e68b..2309ecf 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -18,10 +18,12 @@ const checkConfirm = async (data, msgIdSet) => { const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ let itemkey = `item-${i}-DiffErr`; cnfrmObj[ itemkey ] = `In /items, '${item.attributes}' mismatch from /select`; + } }); } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index f201555..2bc9084 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -16,10 +16,12 @@ const checkInit = (data, msgIdSet) => { const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ let itemkey = `item-${i}-DiffErr`; initObj[ itemkey ] = `In /items, '${item.attributes}' mismatch from /select`; + } }); } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index f99599e..49714a9 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -30,16 +30,18 @@ const checkOnSelect = async (data, msgIdSet) => { const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ let itemkey = `item-${i}-DiffErr`; onSelectObj[ itemkey ] = `In /items, '${item.attributes}' mismatch from /select`; + } }); } catch (error) { console.log(error); } - + try { console.log(`Checking quote object in /on_select api`); quote?.breakup.forEach((breakup, i) => { From 3792c8f3e5af1a3e40b13716bc8789953df08849 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 106/228] Update readme.md From f1c06234319a6b51b10556f56acd05411ef468eb Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 107/228] Update readme.md From 6102b45cd6c8f7ac4e2c190686774736294bf119 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 108/228] Update readme.md From ca957258b61f2723ea3a0ec98bb27e5713bcc1e0 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 15:52:04 +0530 Subject: [PATCH 109/228] readme updated --- utilities/deep-links/readme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md index efb87e3..2aaefdd 100644 --- a/utilities/deep-links/readme.md +++ b/utilities/deep-links/readme.md @@ -43,10 +43,18 @@ query_string = { ### Run this utility +Option 1: + +** Pass the query_string as a string as an argument ** + ``` python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' ``` +Option 2: + +** Define the query_string in qr_generate.py ** + ## Buyer App Platform Integration Different platforms have different handling mechanisms, for example, Android uses Intent Filters and iOS uses URL schemes or Universal links to identify which apps can handle which URI schemes or use fallback URLs to redirect the consumer to a fallback web URL, usually prompting them to download the relevant app. If multiple apps have registered the same URI scheme, it will either redirect to the default app or prompt the user to select the app they would like to use. Please refer [detailed guide](https://docs.google.com/document/d/1pmwQvF9G37_KwcFViub7m_qYDUjbGLrwvgkv1XZEc08/edit?usp=sharing) on implementation. \ No newline at end of file From b0fb46f403b6dc82d8567ac864055d106c8c0018 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 15:54:07 +0530 Subject: [PATCH 110/228] readme updated --- utilities/deep-links/readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md index 2aaefdd..a0a0087 100644 --- a/utilities/deep-links/readme.md +++ b/utilities/deep-links/readme.md @@ -45,7 +45,7 @@ query_string = { Option 1: -** Pass the query_string as a string as an argument ** +**Pass the query_string as a string as an argument** ``` python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' @@ -53,7 +53,7 @@ python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.prov Option 2: -** Define the query_string in qr_generate.py ** +**Define the query_string in qr_generate.py** ## Buyer App Platform Integration From 8b76897ec0b57ba58333166596149bd0874dec72 Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Fri, 12 Jan 2024 16:07:00 +0530 Subject: [PATCH 111/228] readme updated --- utilities/deep-links/readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/deep-links/readme.md b/utilities/deep-links/readme.md index a0a0087..e5ac5bc 100644 --- a/utilities/deep-links/readme.md +++ b/utilities/deep-links/readme.md @@ -45,7 +45,7 @@ query_string = { Option 1: -**Pass the query_string as a string as an argument** +**Pass the query_string data as an argument** ``` python3 qr_generate.py '{"context.bpp_id": "sellerapp.com", "message.intent.provider.id": "P1", "context.domain": "RET10", "message.intent.category.id": "Foodgrains"}' From 4c8b76e166ae7bf009afce96ff9c8ff0775fe74f Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 4 Jan 2024 12:34:23 +0530 Subject: [PATCH 112/228] fixed bugs and exceptions --- .../schema/B2B_json_schema/keywords/init.js | 2 +- .../schema/B2B_json_schema/keywords/onInit.js | 2 +- .../schema/B2B_json_schema/keywords/search.js | 4 +- .../schema/B2B_json_schema/v2/confirm.js | 2 +- .../schema/B2B_json_schema/v2/init.js | 2 +- .../schema/B2B_json_schema/v2/on_confirm.js | 2 - .../schema/B2B_json_schema/v2/on_init.js | 2 - .../schema/B2B_json_schema/v2/on_search.js | 2 +- .../schema/B2B_json_schema/v2/search.js | 3 ++ .../schema/B2B_json_schema/v2/select.js | 2 +- .../v1.2/confirmSchema.js | 19 ++++++++- .../v1.2/keywords/init.js | 2 +- .../v1.2/keywords/onInit.js | 2 +- .../v1.2/keywords/search.js | 4 +- .../v1.2/onCancelSchema.js | 15 +++++++ .../v1.2/onConfirmSchema.js | 17 +++++++- .../v1.2/onStatusSchema.js | 39 +++++++++++++++++++ .../v1.2/onUpdateSchema.js | 15 +++++++ .../utils/ContextVal.js | 3 +- .../utils/logistics/logInit.js | 6 +-- 20 files changed, 119 insertions(+), 26 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js index 18a4db3..8f448e9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/init.js @@ -1,6 +1,6 @@ module.exports = { isLengthValid: (data) => { - if (data.name.length + data.building.length + data.locality.length > 190) + if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js index b31f2e2..f4081b8 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/onInit.js @@ -1,7 +1,7 @@ module.exports = { isQuoteMatching: (data) => { let quotePrice = parseFloat(data?.price?.value); - const breakupArr = data.breakup; + const breakupArr = data?.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js index 6588a9e..7a14c5b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/search.js @@ -1,7 +1,7 @@ module.exports = { isEndTimeGreater: (data) => { - const startTime = parseInt(data.start); - const endTime = parseInt(data.end); + const startTime = parseInt(data?.start); + const endTime = parseInt(data?.end); return startTime < endTime; }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 5adfe0d..082d0fc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -308,7 +308,7 @@ module.exports = { gps: { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 9b9db05..336f703 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -287,7 +287,7 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 3e87a93..d6f47d8 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -343,8 +343,6 @@ module.exports = { }, gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index d47c1fe..35dfa68 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -300,8 +300,6 @@ module.exports = { properties: { gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 13d05ca..d8d3584 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -238,7 +238,7 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index a10ad82..79d7f96 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -123,6 +123,9 @@ module.exports = { properties: { gps: { type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, area_code: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 444749f..218b65f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -235,7 +235,7 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value", + errorMessage: "Incorrect gps value (minimum of six decimal places are required)", }, area_code: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index c2ac4e6..1b3b5d0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -172,6 +172,21 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "category_id", "descriptor", "fulfillment_id"], // anyOf: [ @@ -1038,7 +1053,6 @@ module.exports = { code: { type: "string", enum: constants.TERMS, - }, list: { type: "array", @@ -1060,7 +1074,8 @@ module.exports = { required: ["code", "list"], }, minItems: 2, - errorMessage: "both 'bpp_terms' and 'bap_terms' tags are required (logistics buyer NP must accept LSP terms. If not accepted, LSP can NACK /confirm with error code 65002)", + errorMessage: + "both 'bpp_terms' and 'bap_terms' tags are required (logistics buyer NP must accept LSP terms. If not accepted, LSP can NACK /confirm with error code 65002)", }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js index 18a4db3..8f448e9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/init.js @@ -1,6 +1,6 @@ module.exports = { isLengthValid: (data) => { - if (data.name.length + data.building.length + data.locality.length > 190) + if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) return false; else return true; }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js index af5d333..a0aebf6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/onInit.js @@ -1,7 +1,7 @@ module.exports = { isQuoteMatching: (data) => { let quotePrice = parseFloat(data?.price?.value); - const breakupArr = data.breakup; + const breakupArr = data?.breakup; let totalBreakup = 0; breakupArr.forEach((breakup) => { totalBreakup += parseFloat(breakup?.price?.value); diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js index 6588a9e..7a14c5b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/keywords/search.js @@ -1,7 +1,7 @@ module.exports = { isEndTimeGreater: (data) => { - const startTime = parseInt(data.start); - const endTime = parseInt(data.end); + const startTime = parseInt(data?.start); + const endTime = parseInt(data?.end); return startTime < endTime; }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 79705df..56701b7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -159,6 +159,21 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "category_id", "descriptor", "fulfillment_id"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index ad3d244..ff7b510 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -198,8 +198,23 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, - required: ["id", "category_id", "descriptor"], + required: ["id", "category_id", "descriptor","time","fulfillment_id"], }, }, quote: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 0b7fbf5..1017c08 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -163,6 +163,21 @@ module.exports = { }, required: ["code"], }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "category_id", "descriptor", "fulfillment_id"], }, @@ -625,6 +640,30 @@ module.exports = { }, }, }, + + if: { properties: { type: { const: "ON-ORDER" } } }, + then: { + properties: { + collected_by: { + const: "BAP", + }, + status:{ + const:"PAID" + } + }, + }, + + if: { properties: { type: { const: "POST-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BAP", + }, + status:{ + const:"NOT-PAID" + } + }, + }, required: ["type", "collected_by","status"], }, billing: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index ab0a17a..7aff9a5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -149,6 +149,21 @@ module.exports = { }, }, }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + duration: { + type: "string", + }, + timestamp: { + type: "string", + }, + }, + required: ["label", "duration", "timestamp"], + }, }, required: ["id", "fulfillment_id", "category_id", "descriptor"], }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 11175d7..8749ce0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -15,7 +15,7 @@ const checkContextVal = (payload, msgIdSet, i) => { let data = payload.context; let domain = payload.context.domain; let maxTimeDiff = 5000; - if (domain === "ONDC:RET10" && payload?.context?.version === "2.0.1") { + if (payload?.context?.version === "2.0.1") { if (action === "init") { maxTimeDiff = utils.iso8601DurationToSeconds(payload.context.ttl); dao.setValue("maxTimeDiff", maxTimeDiff); @@ -25,7 +25,6 @@ const checkContextVal = (payload, msgIdSet, i) => { } else if (domain === "nic2004:60232") { maxTimeDiff = 1000; } else if ( - domain === "ONDC:RET10" && payload?.context?.version === "2.0.2" ) { if (action === "select") { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index 93cdc26..ef36eae 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -6,11 +6,7 @@ const utils = require("../utils"); const checkInit = (data, msgIdSet) => { const billing = data.message.order.billing const billingAdd= billing.address - const len = billingAdd.name.length + billingAdd.building.length +billingAdd.locality.length - console.log(billingAdd.name.length,billingAdd.building.length,billingAdd.locality.length); - console.log("length",len); - if (billingAdd.name.length + billingAdd.building.length +billingAdd.locality.length > 190) return true - else false + const initObj = {}; let init = data; let p2h2p = false; From aff95d4190a5087e513b17bc3ec206c2bf96d9cc Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 15 Jan 2024 13:22:55 +0530 Subject: [PATCH 113/228] updated b2b schema --- .../schema/B2B_json_schema/v2/confirm.js | 111 +++++++++++++----- .../schema/B2B_json_schema/v2/init.js | 27 ++++- .../schema/B2B_json_schema/v2/on_confirm.js | 11 +- .../schema/B2B_json_schema/v2/on_init.js | 110 +++++++++++++---- .../schema/B2B_json_schema/v2/on_search.js | 32 ++++- .../schema/B2B_json_schema/v2/on_select.js | 25 +++- .../schema/B2B_json_schema/v2/on_status.js | 3 + .../schema/B2B_json_schema/v2/search.js | 2 +- .../schema/B2B_json_schema/v2/select.js | 86 +++----------- .../v1.2/onConfirmSchema.js | 2 +- .../v1.2/onStatusSchema.js | 2 +- .../utils/b2b/b2bOnSearch.js | 14 ++- .../utils/b2b/b2bSearch.js | 59 +++++----- .../utils/logistics/logOnInit.js | 17 +-- 14 files changed, 328 insertions(+), 173 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 082d0fc..409f3ef 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -70,7 +70,7 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", @@ -119,13 +119,12 @@ module.exports = { locations: { type: "array", const: { $data: "/init/0/message/order/provider/locations" }, - errorMessage:"mismatch from /init", + errorMessage: "mismatch from /init", items: { type: "object", properties: { id: { type: "string", - }, }, required: ["id"], @@ -209,12 +208,22 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/0/value", + }, + errorMessage: + "Buyer terms should be same as provided in /select", }, { - const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/1/value", + }, + errorMessage: + "Buyer terms should be same as provided in /select", + }, + ], }, }, required: ["descriptor", "value"], @@ -276,7 +285,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -307,8 +316,10 @@ module.exports = { properties: { gps: { type: "string", - pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", @@ -421,12 +432,18 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/0/value", + }, }, { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/1/value", + }, + }, + ], }, }, if: { @@ -501,7 +518,14 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + ], }, price: { type: "object", @@ -602,6 +626,7 @@ module.exports = { type: "string", enum: ["PAID", "NOT-PAID"], }, + type: { type: "string", enum: [ @@ -612,6 +637,7 @@ module.exports = { }, collected_by: { type: "string", + enum: ["BAP", "BPP"], }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", @@ -619,6 +645,16 @@ module.exports = { "@ondc/org/buyer_app_finder_fee_amount": { type: "string", }, + "@ondc/org/settlement_basis": { + type: "string", + }, + "@ondc/org/settlement_window": { + type: "string", + }, + "@ondc/org/withholding_amount": { + type: "string", + }, + "@ondc/org/settlement_details": { type: "array", items: { @@ -687,14 +723,34 @@ module.exports = { }, }, }, - required: [ - "params", - "status", - "type", - "collected_by", - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - ], + if: { properties: { collected_by: { const: "BPP" } } }, + then: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + "@ondc/org/settlement_details", + ], + }, + else: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + ], + }, }, }, tags: { @@ -738,16 +794,16 @@ module.exports = { type: "string", const: { $data: "3/context/timestamp" }, errorMessage: - "created_at does not match context timestamp - ${3/context/timestamp}", + "does not match context timestamp - ${3/context/timestamp}", }, updated_at: { type: "string", const: { $data: "3/context/timestamp" }, errorMessage: - "updated_at does not match context timestamp - ${3/context/timestamp}", + "does not match context timestamp - ${3/context/timestamp}", }, }, - additionalProperties:false, + additionalProperties: false, required: [ "id", "state", @@ -765,5 +821,6 @@ module.exports = { required: ["order"], }, }, + isFutureDated: true, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 336f703..47ab2d3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -127,6 +127,7 @@ module.exports = { } }, required: ["id", "locations"], + additionalProperties:false }, items: { type: "array", @@ -201,6 +202,22 @@ module.exports = { }, value: { type: "string", + anyOf: [ + { + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/0/value", + }, + errorMessage:"Buyer terms should be same as provided in /select" + }, + { + const: { + $data: + "/select/0/message/order/items/0/tags/0/list/1/value", + }, + errorMessage:"Buyer terms should be same as provided in /select" + }, + ], }, }, required: ["descriptor", "value"], @@ -211,7 +228,7 @@ module.exports = { }, }, }, - required: ["id", "quantity"], + required: ["id", "fulfillment_ids","quantity","tags",], }, }, billing: { @@ -471,8 +488,12 @@ module.exports = { "POST-FULFILLMENT", ], }, + collected_by:{ + type:"string", + enum:["BAP","BPP"] + } }, - required: ["type"], + required: ["type","collected_by"], }, }, tags: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index d6f47d8..9851d51 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -215,13 +215,15 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + const: { $data: "/select/0/message/order/items/0/tags/0/list/0/value" }, + errorMessage:"Buyer terms should be same as provided in /select" }, { - const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, + const: { $data: "/select/0/message/order/items/0/tags/0/list/1/value" }, + errorMessage:"Buyer terms should be same as provided in /select" } ] - }, + } }, required: ["descriptor", "value"], }, @@ -803,9 +805,6 @@ module.exports = { updated_at: { type: "string", format: "date-time", - const: { $data: "3/context/timestamp" }, - errorMessage: - " should be updated as per context/timestamp - ${3/context/timestamp}", }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 35dfa68..6c72c5a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -75,7 +75,7 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", @@ -83,7 +83,7 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, }, required: [ @@ -122,7 +122,9 @@ module.exports = { properties: { id: { type: "string", - const: { $data: "/init/0/message/order/provider/locations/0/id"} + const: { + $data: "/init/0/message/order/provider/locations/0/id", + }, }, }, required: ["id"], @@ -178,7 +180,7 @@ module.exports = { properties: { code: { type: "string", - enum:["BUYER_TERMS"] + enum: ["BUYER_TERMS"], }, }, required: ["code"], @@ -193,7 +195,7 @@ module.exports = { properties: { code: { type: "string", - enum:["ITEM_REQ","PACKAGING_REQ"] + enum: ["ITEM_REQ", "PACKAGING_REQ"], }, }, required: ["code"], @@ -202,12 +204,18 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/items/0/tags/0/list/0/value" }, + const: { + $data: + "/init/0/message/order/items/0/tags/0/list/0/value", + }, }, { - const: { $data: "/init/0/message/order/items/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/init/0/message/order/items/0/tags/0/list/1/value", + }, + }, + ], }, }, required: ["descriptor", "value"], @@ -269,7 +277,7 @@ module.exports = { const: { $data: "/init/0/message/order/billing/phone" }, }, }, - + required: ["name", "address", "state", "city", "tax_id", "phone"], }, fulfillments: { @@ -394,12 +402,18 @@ module.exports = { type: "string", anyOf: [ { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/0/value" }, + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/0/value", + }, }, { - const: { $data: "/init/0/message/order/fulfillments/0/tags/0/list/1/value" }, - } - ] + const: { + $data: + "/init/0/message/order/fulfillments/0/tags/0/list/1/value", + }, + }, + ], }, }, if: { @@ -471,7 +485,14 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + ], }, price: { type: "object", @@ -547,7 +568,7 @@ module.exports = { }, }, isQuoteMatching: true, - + required: ["price", "breakup", "ttl"], }, payments: { @@ -555,12 +576,33 @@ module.exports = { items: { type: "object", properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", }, + "@ondc/org/settlement_basis": { + type: "string", + }, + "@ondc/org/settlement_window": { + type: "string", + }, + "@ondc/org/withholding_amount": { + type: "string", + }, "@ondc/org/settlement_details": { type: "array", items: { @@ -629,10 +671,34 @@ module.exports = { }, }, }, - required: [ - "@ondc/org/buyer_app_finder_fee_type", - "@ondc/org/buyer_app_finder_fee_amount", - ], + if: { properties: { collected_by: { const: "BAP" } } }, + then: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + "@ondc/org/settlement_details", + ], + }, + else: { + required: [ + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + ], + }, }, }, tags: { @@ -673,7 +739,7 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: [ "provider", "provider_location", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index d8d3584..4fbe8f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -556,8 +556,38 @@ module.exports = { }, required: ["measure", "count"], }, + minimum: { + type: "object", + properties: { + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: [ + "unit", + "dozen", + "gram", + "kilogram", + "tonne", + "litre", + "millilitre", + ], + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + count: { + type: "string", + }, + }, + required: ["measure", "count"], + }, }, - required: ["unitized", "available", "maximum"], + required: ["unitized", "available"], }, category_ids: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 8e8591b..d10a53e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -220,7 +220,7 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery ", "tax", "misc"] + enum: ["item", "discount", "packing", "delivery", "tax", "misc"] }, price: { type: "object", @@ -324,8 +324,29 @@ module.exports = { required: ["price", "breakup", "ttl"], }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by:{ + type:"string", + enum:["BAP","BPP"] + } + }, + required: ["type","collected_by"], + }, + }, }, - required: ["provider", "items", "quote"], + required: ["provider", "items", "quote","payments","fulfillments"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index ecaf332..be80d41 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -235,12 +235,15 @@ module.exports = { type: "string", enum: [ "Pending", + "Packed", + "Agent-assigned", "Out-for-pickup", "Order-picked-up", "In-transit", "At-destination-hub", "Out-for-delivery", "Order-delivered", + "Cancelled" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index 79d7f96..160bdd1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -255,7 +255,7 @@ module.exports = { }, }, additionalProperties:false, - required: ["item", "fulfillment", "payment", "tags"], + required: ["fulfillment", "payment", "tags"], }, }, required: ["intent"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 218b65f..4cc3b84 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -56,9 +56,6 @@ module.exports = { }, transaction_id: { type: "string", - const: { $data: "/search/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", }, message_id: { type: "string", @@ -127,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations"], + required: ["id", "locations","ttl"], }, items: { type: "array", @@ -143,6 +140,12 @@ module.exports = { type: "string", }, }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, quantity: { type: "object", properties: { @@ -212,7 +215,7 @@ module.exports = { }, }, }, - required: ["id", "location_ids", "quantity"], + required: ["id", "location_ids", "quantity","tags","fulfillment_ids"], }, }, fulfillments: { @@ -220,6 +223,12 @@ module.exports = { items: { type: "object", properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, stops: { type: "array", items: { @@ -291,73 +300,8 @@ module.exports = { }, required: ["person"], }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: ["DELIVERY_TERMS"], - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: [ - "INCOTERMS", - "NAMED_PLACE_OF_DELIVERY", - ], - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - if: { - properties: { - descriptor: { - properties: { code: { const: "INCOTERMS" } }, - }, - }, - }, - then: { - properties: { - value: { - enum: [ - "DPU", - "CIF", - "EXW", - "FOB", - "DAP", - "DDP", - ], - }, - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, }, - required: ["stops"], + required: ["id","type","stops"], }, }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index ff7b510..952d783 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -214,7 +214,7 @@ module.exports = { required: ["label", "duration", "timestamp"], }, }, - required: ["id", "category_id", "descriptor","time","fulfillment_id"], + required: ["id", "category_id", "descriptor","fulfillment_id"], }, }, quote: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 1017c08..8591436 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -795,7 +795,7 @@ module.exports = { const: { $data: "/confirm/0/message/order/created_at", }, - errorMessage: "mismatches in /confirm and /on_update", + errorMessage: "mismatches in /confirm and /on_status", }, updated_at: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 32ee952..cc4f494 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -43,7 +43,7 @@ const checkOnSearch = async (data, msgIdSet) => { if (!match) { onSrchObj[ "bpp/provider:location:" + id + ":RGC" - ] = `Reverse Geocoding for location ID ${id} failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + ] = `Reverse Geocoding for location ID ${id} failed for provider with id '${provider?.id}'. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; } } catch (error) { console.log("bpp/providers error: ", error); @@ -56,6 +56,7 @@ const checkOnSearch = async (data, msgIdSet) => { provider.items.forEach((item) => { let itemTags = item?.tags; let mandatoryAttr; + let attrPresent = false; if (domain === "ONDC:RET12") { mandatoryAttr = constants.FASHION_ATTRIBUTES; @@ -64,11 +65,12 @@ const checkOnSearch = async (data, msgIdSet) => { mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; } itemTags.map(({ descriptor, list }, index) => { - switch (descriptor.code) { + switch (descriptor?.code) { case "attribute": + attrPresent = true; const encounteredAttr = []; list.map(({ descriptor, value }) => { - encounteredAttr.push(descriptor.code); + encounteredAttr.push(descriptor?.code); }); // Check if all mandatory attributes are encountered @@ -81,6 +83,12 @@ const checkOnSearch = async (data, msgIdSet) => { break; } }); + + if ( + (domain === "ONDC:RET12" || domain === "ONDC:RET14") && + !attrPresent + ) + onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; }); } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js index 726d5fa..a8c8112 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js @@ -16,42 +16,45 @@ const checkSearch = async (data, msgIdSet) => { let startLocation, endLocation; stops.forEach((stop) => { if (stop.type === "start") { - startLocation = stop.location; + startLocation = stop?.location; } if (stop.type === "end") { - endLocation = stop.location; + endLocation = stop?.location; } }); - console.log("Checking Reverse Geocoding for `end` location in `fullfilment`"); - try { - const [lat, long] = endLocation.gps.split(","); - const area_code = endLocation.area_code; - const match = await reverseGeoCodingCheck(lat, long, area_code); - if (!match) - srchObj[ - "RGC-end-Err" - ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; - } catch (error) { - console.log("Error in end location", error); - } - - // check for context cityCode and fulfillment end location - try { - const pinToStd = JSON.parse( - fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + if (endLocation) { + console.log( + "Checking Reverse Geocoding for `end` location in `fullfilment`" ); - const stdCode = data.context?.location?.city?.code.split(":")[1]; - const area_code = endLocation?.area_code; - if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { - srchObj[ - "CityCode-Err" - ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + try { + const [lat, long] = endLocation?.gps.split(","); + const area_code = endLocation?.area_code; + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) + srchObj[ + "RGC-end-Err" + ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } catch (error) { + console.log("Error in end location", error); } - } catch (err) { - console.error("Error in city code check: ", err.message); - } + // check for context cityCode and fulfillment end location + try { + const pinToStd = JSON.parse( + fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + ); + const stdCode = data.context?.location?.city?.code.split(":")[1]; + const area_code = endLocation?.area_code; + if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { + srchObj[ + "CityCode-Err" + ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + } + } catch (err) { + console.error("Error in city code check: ", err.message); + } + } dao.setValue("searchObj", search); return srchObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js index d53e7f6..7f94086 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnInit.js @@ -14,9 +14,9 @@ const checkOnInit = (data, msgIdSet) => { let onSearchProvArr = dao.getValue("providersArr"); - console.log(dao.getValue("providerLoc"),on_init.provider_location); - if(dao.getValue("providerLoc")===false && on_init.provider_location){ - onInitObj.prvdrLocErr=`Provider location should be provided only if returned in /on_search, also it is used where the shipment has to be dropped at LSP location` + console.log(dao.getValue("providerLoc"), on_init.provider_location); + if (dao.getValue("providerLoc") === false && on_init.provider_location) { + onInitObj.prvdrLocErr = `Provider location should be provided only if returned in /on_search, also it is used where the shipment has to be dropped at LSP location`; } try { @@ -28,6 +28,7 @@ const checkOnInit = (data, msgIdSet) => { onInitObj.qteDecimalErr = `Quote price value should not have more than 2 decimal places`; } let totalBreakup = 0; + let tax_present = false; on_init.quote.breakup.forEach((breakup, i) => { if (!utils.hasTwoOrLessDecimalPlaces(breakup.price.value)) { let itemkey = `itemPriceErr${i}`; @@ -36,8 +37,8 @@ const checkOnInit = (data, msgIdSet) => { itemkey ] = `Price value for '${breakup["@ondc/org/title_type"]}' should not have more than 2 decimal places`; } - totalBreakup += parseFloat(breakup.price.value); - + totalBreakup += parseFloat(breakup?.price?.value); + if (breakup["@ondc/org/title_type"] === "tax") tax_present = true; onSearchProvArr?.forEach((provider) => { if (provider.id === provId) { provider?.items.forEach((item, i) => { @@ -51,7 +52,7 @@ const checkOnInit = (data, msgIdSet) => { ) { let itemKey = `priceArr${i}`; onInitObj[itemKey] = `Quote price ${parseFloat( - on_init.quote.price.value + on_init?.quote?.price?.value )} for item id '${ breakup["@ondc/org/item_id"] }' does not match item price ${ @@ -64,7 +65,9 @@ const checkOnInit = (data, msgIdSet) => { }); }); - if (parseFloat(on_init.quote.price.value) !== totalBreakup) + if (!tax_present) + onInitObj.taxErr = `fulfillment charges will have separate quote line item for taxes`; + if (parseFloat(on_init?.quote?.price?.value) !== totalBreakup) onInitObj.quotePriceErr = `Quote price ${parseFloat( on_init.quote.price.value )} does not match the breakup total ${totalBreakup} in ${ From 0c7c6dbef2686f10d7ec513d66c0a122794fcc58 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 17 Jan 2024 14:14:32 +0530 Subject: [PATCH 114/228] added b2b validations --- .../schema/B2B_json_schema/v1/on_select.js | 2 +- .../schema/B2B_json_schema/v2/confirm.js | 1 + .../schema/B2B_json_schema/v2/init.js | 1 + .../schema/B2B_json_schema/v2/on_confirm.js | 3 + .../schema/B2B_json_schema/v2/on_init.js | 6 +- .../schema/B2B_json_schema/v2/on_select.js | 50 +++++++------- .../schema/B2B_json_schema/v2/on_status.js | 2 + .../schema/B2B_json_schema/v2/select.js | 2 + .../utils/ContextVal.js | 1 - .../utils/b2b/b2bConfirm.js | 35 ++++++++++ .../utils/b2b/b2bOnInit.js | 35 ++++++++++ .../utils/b2b/b2bOnSelect.js | 66 +++++++++++++++++++ .../utils/b2b/b2bOnStatus.js | 37 +++++++---- .../utils/b2b/b2bSearch.js | 17 +++++ .../utils/b2b/msgValidator.js | 14 ++-- 15 files changed, 222 insertions(+), 50 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js index f2fe7b0..41d3d59 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_select.js @@ -164,7 +164,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["Serviceable", "Non-Serviceable"], + enum: ["Serviceable", "Non-serviceable"], }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 409f3ef..11543ea 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -634,6 +634,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 47ab2d3..6f969ba 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -487,6 +487,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by:{ type:"string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 9851d51..e083acc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -661,6 +661,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by: { type: "string", @@ -668,9 +669,11 @@ module.exports = { }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type" }, }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, }, "@ondc/org/settlement_details": { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 6c72c5a..311aa99 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -583,6 +583,8 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, + }, collected_by: { type: "string", @@ -674,8 +676,6 @@ module.exports = { if: { properties: { collected_by: { const: "BAP" } } }, then: { required: [ - "params", - "status", "type", "collected_by", "@ondc/org/buyer_app_finder_fee_type", @@ -688,8 +688,6 @@ module.exports = { }, else: { required: [ - "params", - "status", "type", "collected_by", "@ondc/org/buyer_app_finder_fee_type", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index d10a53e..f63f43a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -112,10 +112,27 @@ module.exports = { id: { type: "string", const: { $data: "/select/0/message/order/provider/id" }, - }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/select/0/message/order/provider/locations/0/id", + }, + }, + }, + additionalProperties:false, + required: ["id"], + }, + } }, - required: ["id"], + additionalProperties:false, + required: ["id","locations"], }, items: { type: "array", @@ -164,7 +181,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["Serviceable", "Non-Serviceable"], + enum: ["Serviceable", "Non-serviceable"], }, }, required: ["code"], @@ -237,30 +254,6 @@ module.exports = { item: { type: "object", properties: { - quantity: { - type: "object", - properties: { - available: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - maximum: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - }, - required: ["available", "maximum"], - }, price: { type: "object", properties: { @@ -274,7 +267,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["quantity", "price"], + required: ["price"], }, }, if: { @@ -336,6 +329,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, collected_by:{ type:"string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index be80d41..24ad2b9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -626,9 +626,11 @@ module.exports = { }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type" }, }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", + const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, }, "@ondc/org/settlement_details": { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 4cc3b84..1ed6d8f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -301,6 +301,7 @@ module.exports = { required: ["person"], }, }, + additionalProperties:false, required: ["id","type","stops"], }, }, @@ -316,6 +317,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], + const: { $data: "/search/0/message/intent/payment/type" }, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js index 8749ce0..8c7731d 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/ContextVal.js @@ -95,7 +95,6 @@ const checkContextVal = (payload, msgIdSet, i) => { Obj.tmpstmpErr = `Timestamp mismatch for /${action} `; } else { if ( - action === "on_search" || action === "on_select" || action === "on_init" || action === "on_confirm" || diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index e69de29..d078f84 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -0,0 +1,35 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkConfirm = async (data, msgIdSet) => { + const cnfrmObj = {}; + let confirm = data; + confirm = confirm.message.order; + let payments = confirm?.payments; + + try { + console.log(`Checking payment object in /confirm api`); + payments.forEach(payment => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + + if(feeType!=dao.getValue("BuyerFinderFeeType")){ + cnfrmObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` + } + if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ + cnfrmObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` + } + + }); + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return cnfrmObj; +}; +module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index e69de29..c94f90e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -0,0 +1,35 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnInit = async (data, msgIdSet) => { + const onInitObj = {}; + let onInit = data; + onInit = onInit.message.order; + let payments = onInit?.payments; + + try { + console.log(`Checking payment object in /on_init api`); + payments.forEach(payment => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + + if(feeType!=dao.getValue("BuyerFinderFeeType")){ + onInitObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` + } + if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ + onInitObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` + } + + }); + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return onInitObj; +}; +module.exports = checkOnInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js new file mode 100644 index 0000000..1cb2b9e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -0,0 +1,66 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnSelect = async (data, msgIdSet) => { + const onSelectObj = {}; + let onSelect = data; + onSelect = onSelect.message.order; + let quote = onSelect?.quote; + let fulfillments = onSelect?.fulfillments; + let ffState, ffId; + let deliveryQuoteItem = false; + try { + console.log("Checking fulfillment object in /on_select"); + if (fulfillments) { + fulfillments.forEach((fulfillment) => { + ffId = fulfillment?.id; + ffState = fulfillment?.state?.descriptor?.code; + }); + } + } catch (error) { + console.log(error); + } + + try { + console.log(`Checking quote object in /on_select api`); + quote?.breakup.forEach((breakup) => { + let itemPrice = parseFloat(breakup?.item?.price?.value); + let quantity = breakup["@ondc/org/item_quantity"]; + + if ( + breakup["@ondc/org/title_type"] === "delivery" && + breakup["@ondc/org/item_id"] === ffId + ) { + deliveryQuoteItem = true; + } + if ( + breakup["@ondc/org/title_type"] === "item" && + quantity && + parseFloat(breakup.price.value) != itemPrice * quantity?.count + ) { + onSelectObj.quoteErr = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + } + }); + + if (!deliveryQuoteItem && ffState === "Serviceable") { + onSelectObj.deliveryQuoteErr = `Delivery charges should be provided in quote/breakup when fulfillment is 'Serviceable'`; + } + if (deliveryQuoteItem && ffState === "Non-serviceable") { + onSelectObj.deliveryQuoteErr = `Delivery charges are not required in quote/breakup when fulfillment is 'Non-serviceable'`; + } + + if (ffState === "Non-serviceable" && !data.error) { + onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; + } + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + return onSelectObj; +}; +module.exports = checkOnSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 30585b6..9d12cef 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -15,6 +15,28 @@ const checkOnStatus = (data, msgIdSet) => { let items = on_status.items; let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; + let payments = on_status?.payments; + + try { + console.log(`Checking payment object in /on_status`); + payments.forEach((payment) => { + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let params = payment?.params; + + if (paymentStatus === "PAID" && !params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if(paymentType==='ON-FULFILLMENT' && orderState!='Completed' && paymentStatus==='PAID'){ + onStatusObj.pymntstsErr= `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'` + } + }); + } catch (error) { + console.log(error); + } // try { // console.log( @@ -98,7 +120,6 @@ const checkOnStatus = (data, msgIdSet) => { }); } - //Out-for-delivery if (ffState === "Out-for-delivery") { if (orderState !== "In-progress") { @@ -107,13 +128,12 @@ const checkOnStatus = (data, msgIdSet) => { fulfillment.stops.forEach((stop) => { if (stop.type === "start") { pickupTime = stop?.time?.timestamp; - + if (!pickupTime) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - pickupTime !== - dao.getValue("pickupTime") + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } @@ -139,8 +159,7 @@ const checkOnStatus = (data, msgIdSet) => { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; } else if ( dao.getValue("pickupTime") && - pickupTime !== - dao.getValue("pickupTime") + pickupTime !== dao.getValue("pickupTime") ) { onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot change for fulfillment state - ${ffState}`; } @@ -149,7 +168,7 @@ const checkOnStatus = (data, msgIdSet) => { if (stop.type === "end") { deliveryTime = stop?.time?.timestamp; dao.setValue("deliveryTime", deliveryTime); - + if (!deliveryTime) { onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) is required for fulfillment state - ${ffState}`; } @@ -162,10 +181,6 @@ const checkOnStatus = (data, msgIdSet) => { } }); } - - - - } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js index a8c8112..a171cde 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSearch.js @@ -12,6 +12,23 @@ const checkSearch = async (data, msgIdSet) => { let contextTime = search.context.timestamp; search = search.message.intent; + try { + console.log("Checking buyer app finder fee in /search"); + + search.tags.forEach((tag) => { + if (tag?.descriptor?.code === "bap_terms" && tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "finder_fee_type") { + dao.setValue("buyerFinderFeeType", val?.value); + } + if (val?.descriptor?.code === "finder_fee_amount") { + dao.setValue("buyerFinderFeeAmount", val?.value); + } + }); + } + }); + } catch (error) {} + const stops = data?.message?.intent?.fulfillment?.stops; let startLocation, endLocation; stops.forEach((stop) => { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index e15deca..ae9f2dc 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -1,7 +1,8 @@ const checkConfirm = require("./b2bConfirm"); const checkInit = require("./b2bInit"); -const checkOnConfirm = require("./b2bOnConfirm"); const checkOnInit = require("./b2bOnInit"); +const checkOnConfirm = require("./b2bOnConfirm"); +const checkOnSelect = require("./b2bOnSelect"); const checkOnSearch = require("./b2bOnSearch"); const checkOnUpdate = require("./b2bOnUpdate"); const checkUpdate = require("./b2bUpdate"); @@ -18,14 +19,17 @@ const b2bVal = (element, action, msgIdSet) => { case "on_search": return checkOnSearch(element, msgIdSet); + case "on_select": + return checkOnSelect(element, msgIdSet); + case "init": return checkInit(element, msgIdSet); - // case "on_init": - // return checkOnInit(element, msgIdSet); + case "on_init": + return checkOnInit(element, msgIdSet); - // case "confirm": - // return checkConfirm(element, msgIdSet); + case "confirm": + return checkConfirm(element, msgIdSet); // case "on_confirm": // return checkOnConfirm(element, msgIdSet); From a61e2b76e361ce3b81be01504522d220985557f3 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 18 Jan 2024 10:25:19 +0530 Subject: [PATCH 115/228] bug fix --- .../utils/b2b/b2bConfirm.js | 21 +++++++++---------- .../utils/b2b/b2bOnInit.js | 21 +++++++++---------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index d078f84..74c9580 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -11,18 +11,17 @@ const checkConfirm = async (data, msgIdSet) => { try { console.log(`Checking payment object in /confirm api`); - payments.forEach(payment => { - let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] - let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + payments.forEach((payment) => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; - if(feeType!=dao.getValue("BuyerFinderFeeType")){ - cnfrmObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` - } - if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ - cnfrmObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` - } - - }); + if (feeType != dao.getValue("buyerFinderFeeType")) { + onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); } catch (error) { console.log( `!!Error while checking providers array in /on_search api`, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index c94f90e..16f3439 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -11,18 +11,17 @@ const checkOnInit = async (data, msgIdSet) => { try { console.log(`Checking payment object in /on_init api`); - payments.forEach(payment => { - let feeType = payment["@ondc/org/buyer_app_finder_fee_type"] - let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"] + payments.forEach((payment) => { + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; - if(feeType!=dao.getValue("BuyerFinderFeeType")){ - onInitObj.feeTypeErr=`Buyer Finder Fee type mismatches from /search` - } - if(feeAmount!=dao.getValue("BuyerFinderFeeAmount")){ - onInitObj.feeTypeErr=`Buyer Finder Fee amount mismatches from /search` - } - - }); + if (feeType != dao.getValue("buyerFinderFeeType")) { + onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); } catch (error) { console.log( `!!Error while checking providers array in /on_search api`, From d51a2a309190df44d6bb793cd23398e080aa61ba Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 22 Jan 2024 13:23:16 +0530 Subject: [PATCH 116/228] added b2b val --- .../B2B_json_schema/keywords/confirm.js | 1 - .../schema/B2B_json_schema/v2/confirm.js | 9 +- .../schema/B2B_json_schema/v2/init.js | 4 +- .../schema/B2B_json_schema/v2/on_confirm.js | 3 +- .../schema/B2B_json_schema/v2/on_init.js | 21 ++- .../schema/B2B_json_schema/v2/on_select.js | 117 +++++++++++--- .../schema/B2B_json_schema/v2/on_status.js | 19 ++- .../schema/B2B_json_schema/v2/select.js | 5 +- .../utils/b2b/b2bConfirm.js | 4 +- .../utils/b2b/b2bOnInit.js | 4 +- .../utils/b2b/b2bOnSearch.js | 69 ++++----- .../utils/b2b/b2bOnSelect.js | 17 ++- .../utils/b2b/b2bSelect.js | 144 ++++++++++++++++++ .../utils/b2b/msgValidator.js | 4 + 14 files changed, 335 insertions(+), 86 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js index 239d106..5e7963a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/keywords/confirm.js @@ -3,7 +3,6 @@ module.exports = { const contextTime = data?.context?.timestamp; const created_at = data?.message?.order?.created_at; const updated_at = data?.message?.order?.updated_at; - console.log(contextTime,updated_at); if ( (created_at && created_at > contextTime) || (updated_at && updated_at > contextTime) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 11543ea..ceb53cb 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -634,7 +634,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { type: "string", @@ -793,15 +793,12 @@ module.exports = { }, created_at: { type: "string", - const: { $data: "3/context/timestamp" }, - errorMessage: - "does not match context timestamp - ${3/context/timestamp}", }, updated_at: { type: "string", - const: { $data: "3/context/timestamp" }, + const: { $data: "1/created_at" }, errorMessage: - "does not match context timestamp - ${3/context/timestamp}", + "does not match created_at timestamp - ${1/created_at}", }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 6f969ba..24c21ce 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -228,7 +228,7 @@ module.exports = { }, }, }, - required: ["id", "fulfillment_ids","quantity","tags",], + required: ["id", "fulfillment_ids","quantity"], }, }, billing: { @@ -487,7 +487,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by:{ type:"string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index e083acc..21b1007 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -661,7 +661,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { type: "string", @@ -829,5 +829,6 @@ module.exports = { required: ["order"], }, }, + isFutureDated: true, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 311aa99..6c7d5fc 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -287,13 +287,28 @@ module.exports = { properties: { id: { type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/id" }, }, type: { type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/type" }, + }, + "@ondc/org/provider_name": { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1provider_name" }, }, tracking: { type: "boolean", }, + "@ondc/org/category": { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1category" }, + }, + "@ondc/org/TAT": { + type: "string", + format: "duration", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1TAT" }, + }, stops: { type: "array", items: { @@ -459,6 +474,7 @@ module.exports = { }, value: { type: "string", + const: { $data: "/on_select/0/message/order/quote/price/value" }, }, }, required: ["currency", "value"], @@ -583,7 +599,7 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { @@ -680,9 +696,6 @@ module.exports = { "collected_by", "@ondc/org/buyer_app_finder_fee_type", "@ondc/org/buyer_app_finder_fee_amount", - "@ondc/org/settlement_basis", - "@ondc/org/settlement_window", - "@ondc/org/withholding_amount", "@ondc/org/settlement_details", ], }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index f63f43a..8729009 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -58,7 +58,7 @@ module.exports = { type: "string", const: { $data: "/select/0/context/transaction_id" }, errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", }, message_id: { type: "string", @@ -75,14 +75,14 @@ module.exports = { errorMessage: "Message ID should not be equal to transaction_id: ${1/transaction_id}", }, - ] + ], }, timestamp: { type: "string", format: "date-time", }, ttl: { - type: "string" + type: "string", }, }, required: [ @@ -126,30 +126,98 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: ["id"], }, - } + }, }, - additionalProperties:false, - required: ["id","locations"], + additionalProperties: false, + required: ["id", "locations"], }, items: { type: "array", items: { type: "object", properties: { + id: { + type: "string", + }, fulfillment_ids: { type: "array", items: { type: "string", }, }, - id: { - type: "string", + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, + "add-ons": { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BUYER_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["ITEM_REQ", "PACKAGING_REQ"], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, }, }, - required: ["id"], + required: ["id", "quantity", "fulfillment_ids"], }, }, fulfillments: { @@ -171,7 +239,7 @@ module.exports = { }, "@ondc/org/TAT": { type: "string", - format: "duration" + format: "duration", }, state: { type: "object", @@ -237,7 +305,14 @@ module.exports = { }, "@ondc/org/title_type": { type: "string", - enum: ["item", "discount", "packing", "delivery", "tax", "misc"] + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + ], }, price: { type: "object", @@ -310,11 +385,11 @@ module.exports = { }, ttl: { type: "string", - format: "duration" + format: "duration", }, }, isQuoteMatching: true, - + required: ["price", "breakup", "ttl"], }, payments: { @@ -329,18 +404,18 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], }, - collected_by:{ - type:"string", - enum:["BAP","BPP"] - } }, - required: ["type","collected_by"], + required: ["type", "collected_by"], }, }, }, - required: ["provider", "items", "quote","payments","fulfillments"], + required: ["provider", "items", "quote", "payments", "fulfillments"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 24ad2b9..2f37c00 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -243,7 +243,7 @@ module.exports = { "At-destination-hub", "Out-for-delivery", "Order-delivered", - "Cancelled" + "Cancelled", ], }, }, @@ -607,14 +607,15 @@ module.exports = { }, type: { type: "string", - const: { - $data: "/on_confirm/0/message/order/payments/0/type", - }, enum: [ "PRE-FULFILLMENT", "ON-FULFILLMENT", "POST-FULFILLMENT", ], + + const: { + $data: "/on_confirm/0/message/order/payments/0/type", + }, }, collected_by: { type: "string", @@ -626,11 +627,17 @@ module.exports = { }, "@ondc/org/buyer_app_finder_fee_type": { type: "string", - const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type" }, + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type", + }, }, "@ondc/org/buyer_app_finder_fee_amount": { type: "string", - const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount", + }, }, "@ondc/org/settlement_details": { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 1ed6d8f..dae5330 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations","ttl"], + required: ["id", "locations"], }, items: { type: "array", @@ -215,7 +215,7 @@ module.exports = { }, }, }, - required: ["id", "location_ids", "quantity","tags","fulfillment_ids"], + required: ["id", "location_ids", "quantity","fulfillment_ids"], }, }, fulfillments: { @@ -317,7 +317,6 @@ module.exports = { "ON-FULFILLMENT", "POST-FULFILLMENT", ], - const: { $data: "/search/0/message/intent/payment/type" }, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index 74c9580..eafad54 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -18,13 +18,13 @@ const checkConfirm = async (data, msgIdSet) => { if (feeType != dao.getValue("buyerFinderFeeType")) { onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; } }); } catch (error) { console.log( - `!!Error while checking providers array in /on_search api`, + `!!Error while checking providers array in /confirm api`, error ); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index 16f3439..635c8f9 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -18,13 +18,13 @@ const checkOnInit = async (data, msgIdSet) => { if (feeType != dao.getValue("buyerFinderFeeType")) { onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (feeAmount != dao.getValue("buyerFinderFeeAmount")) { + if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; } }); } catch (error) { console.log( - `!!Error while checking providers array in /on_search api`, + `!!Error while checking providers array in /on_init api`, error ); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index cc4f494..a6bfe43 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -52,44 +52,45 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics + if (domain === "ONDC:RET12" || domain === "ONDC:RET14") { + provider.items.forEach((item) => { + let itemTags = item?.tags; + let mandatoryAttr; + let attrPresent = false; - provider.items.forEach((item) => { - let itemTags = item?.tags; - let mandatoryAttr; - let attrPresent = false; + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET14") { + mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + } + itemTags.map(({ descriptor, list }, index) => { + switch (descriptor?.code) { + case "attribute": + attrPresent = true; + const encounteredAttr = []; + list.map(({ descriptor, value }) => { + encounteredAttr.push(descriptor?.code); + }); - if (domain === "ONDC:RET12") { - mandatoryAttr = constants.FASHION_ATTRIBUTES; - } - if (domain === "ONDC:RET14") { - mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; - } - itemTags.map(({ descriptor, list }, index) => { - switch (descriptor?.code) { - case "attribute": - attrPresent = true; - const encounteredAttr = []; - list.map(({ descriptor, value }) => { - encounteredAttr.push(descriptor?.code); - }); + // Check if all mandatory attributes are encountered + const missingAttr = mandatoryAttr.filter( + (code) => !encounteredAttr.includes(code) + ); + if (missingAttr.length > 0) { + onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + } + break; + } + }); - // Check if all mandatory attributes are encountered - const missingAttr = mandatoryAttr.filter( - (code) => !encounteredAttr.includes(code) - ); - if (missingAttr.length > 0) { - onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; - } - break; - } + if ( + (domain === "ONDC:RET12" || domain === "ONDC:RET14") && + !attrPresent + ) + onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; }); - - if ( - (domain === "ONDC:RET12" || domain === "ONDC:RET14") && - !attrPresent - ) - onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; - }); + } } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 1cb2b9e..b7f7717 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -25,10 +25,12 @@ const checkOnSelect = async (data, msgIdSet) => { try { console.log(`Checking quote object in /on_select api`); - quote?.breakup.forEach((breakup) => { + quote?.breakup.forEach((breakup,i) => { let itemPrice = parseFloat(breakup?.item?.price?.value); + let available = Number(breakup?.item?.quantity?.available?.count) let quantity = breakup["@ondc/org/item_quantity"]; + if ( breakup["@ondc/org/title_type"] === "delivery" && breakup["@ondc/org/item_id"] === ffId @@ -38,9 +40,16 @@ const checkOnSelect = async (data, msgIdSet) => { if ( breakup["@ondc/org/title_type"] === "item" && quantity && - parseFloat(breakup.price.value) != itemPrice * quantity?.count + parseFloat(breakup.price.value).toFixed(2) != parseFloat(itemPrice * quantity?.count).toFixed(2) ) { - onSelectObj.quoteErr = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + let item = `quoteErr${i}` + onSelectObj[item] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + } + + if( breakup["@ondc/org/title_type"] === "item" && + quantity && quantity?.count>available){ + let item = `quoteErr${i}` + onSelectObj[item] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; } }); @@ -56,7 +65,7 @@ const checkOnSelect = async (data, msgIdSet) => { } } catch (error) { console.log( - `!!Error while checking providers array in /on_search api`, + `!!Error while checking providers array in /on_select api`, error ); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index e69de29..9fbfd6a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -0,0 +1,144 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkSelect = async (data, msgIdSet) => { + const selectObj = {}; + let select = data; + select = select.message.order; + let itemIdList; + let fulfillments = select?.fulfillments; + + fulfillments.forEach(fulfillment => { + + const fulId= fulfillment?.id + const fulType = fulfillment?.type + + console.log("Checking if the fulfillment id and type in /select present in /on_search") + + + }); + + + //provider check + // try { + // console.log(`Comparing provider object in /select and /on_search`); + // if (select.provider) { + // onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); + // let providerObj = providersArr?.filter( + // (prov) => prov.id === select.provider.id + // ); + // if (!providerObj || providerObj?.length < 1) { + // selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; + // } else { + // if ( + // (!select?.provider?.locations || + // select?.provider?.locations?.length < 1) && + // providerObj[0]?.locations?.length > 1 + // ) { + // selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + // } else if (select?.provider?.locations) { + // let providerLocArr = select.provider.locations; + // let providerLocExists = false; + // providerLocArr.forEach((location, i) => { + // providerObj[0]?.locations?.forEach((element) => { + // console.log(location.id, element.id); + + // if (location.id === element.id) providerLocExists = true; + // }); + + // if (!providerLocExists) { + // let itemkey = `providerLocErr${i}`; + // selectObj[ + // itemkey + // ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + // } + // providerLocExists = false; + // }); + // } + // } + // } + // } catch (error) { + // console.log( + // `!!Error while checking provider object in /${constants.LOG_select}`, + // error + // ); + // } + + // //item check + // try { + // console.log(`Comparing item object in /select and /on_search`); + // let itemExists = false; + + // itemsArr?.forEach((item, i) => { + // if (item.descriptor.code === "P2H2P") { + // p2h2p = true; + // } + // onSearchitemsArr?.forEach((element) => { + // if (item.id === element.id) itemExists = true; + // }); + // if (!itemExists) { + // let itemkey = `itemErr${i}`; + // selectObj[ + // itemkey + // ] = `Item Id '${item.id}' does not exist in /on_search`; + // } else { + // let itemObj = onSearchitemsArr.filter( + // (element) => item.id === element.id + // ); + + // itemObj = itemObj[0]; + // dao.setValue("selectedItem", itemObj.id); + // console.log(itemObj.id); + // if (item.category_id != itemObj.category_id) { + // let itemkey = `catIdErr${i}`; + // selectObj[ + // itemkey + // ] = `Category id '${item.category_id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + // } + // if (item.descriptor.code != itemObj.descriptor.code) { + // let itemkey = `codeErr${i}`; + // selectObj[ + // itemkey + // ] = `Descriptor code '${item.descriptor.code}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + // } + // fulfillmentsArr.forEach((fulfillment, i) => { + // if (fulfillment.id !== itemObj.fulfillment_id) { + // let itemkey = `flfillmentErr${i}`; + // selectObj[ + // itemkey + // ] = `Fulfillment id '${fulfillment.id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; + // } else { + // let bppfulfillment = bppFulfillmentsArr?.find( + // (element) => element.id === fulfillment.id + // ); + // if (fulfillment.type !== bppfulfillment?.type) { + // let itemkey = `flfillmentTypeErr${i}`; + // selectObj[ + // itemkey + // ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + // } + // } + // }); + // } + // itemExists = false; + // }); + // } catch (error) { + // console.log(error); + // } + // try { + // console.log("Checking fulfillment object in /select"); + // if (fulfillments) { + // fulfillments.forEach((fulfillment) => { + // ffId = fulfillment?.id; + // ffState = fulfillment?.state?.descriptor?.code; + // }); + // } + // } catch (error) { + // console.log(error); + // } + + return selectObj; +}; +module.exports = checkSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index ae9f2dc..ce96288 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -1,5 +1,6 @@ const checkConfirm = require("./b2bConfirm"); const checkInit = require("./b2bInit"); +const checkSelect = require("./b2bSelect"); const checkOnInit = require("./b2bOnInit"); const checkOnConfirm = require("./b2bOnConfirm"); const checkOnSelect = require("./b2bOnSelect"); @@ -19,6 +20,9 @@ const b2bVal = (element, action, msgIdSet) => { case "on_search": return checkOnSearch(element, msgIdSet); + case "select": + return checkSelect(element, msgIdSet); + case "on_select": return checkOnSelect(element, msgIdSet); From b3afafc97a6f60c152c6aa222d459eb198548cf4 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 22 Jan 2024 15:56:15 +0530 Subject: [PATCH 117/228] updated --- .../schema/B2B_json_schema/v2/on_select.js | 65 ++++++++++++++++++ .../schema/B2B_json_schema/v2/select.js | 67 ++++++++++++++++++- .../utils/b2b/b2bConfirm.js | 26 ++++++- 3 files changed, 154 insertions(+), 4 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 8729009..309dd8f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -257,6 +257,71 @@ module.exports = { }, required: ["descriptor"], }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, }, required: [ "id", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index dae5330..ced30ea 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations"], + required: ["id", "locations","ttl"], }, items: { type: "array", @@ -300,6 +300,71 @@ module.exports = { }, required: ["person"], }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["DELIVERY_TERMS"], + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: [ + "INCOTERMS", + "NAMED_PLACE_OF_DELIVERY", + ], + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + if: { + properties: { + descriptor: { + properties: { code: { const: "INCOTERMS" } }, + }, + }, + }, + then: { + properties: { + value: { + enum: [ + "DPU", + "CIF", + "EXW", + "FOB", + "DAP", + "DDP", + ], + }, + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, }, additionalProperties:false, required: ["id","type","stops"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index eafad54..ed7ed39 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -14,12 +14,32 @@ const checkConfirm = async (data, msgIdSet) => { payments.forEach((payment) => { let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let params = payment?.params; if (feeType != dao.getValue("buyerFinderFeeType")) { - onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + cnfrmObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { - onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + cnfrmObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + + if (paymentStatus === "PAID" && !params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + cnfrmObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; } }); } catch (error) { From 1a2b7e27ebcb4028863031bf776eec513385d0a3 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 23 Jan 2024 16:19:45 +0530 Subject: [PATCH 118/228] added b2b checks --- .../schema/B2B_json_schema/v2/confirm.js | 7 +- .../schema/B2B_json_schema/v2/init.js | 7 +- .../schema/B2B_json_schema/v2/on_confirm.js | 6 +- .../schema/B2B_json_schema/v2/on_init.js | 7 +- .../schema/B2B_json_schema/v2/on_select.js | 8 +- .../schema/B2B_json_schema/v2/select.js | 11 +- .../utils/b2b/b2bConfirm.js | 18 ++ .../utils/b2b/b2bInit.js | 87 +------ .../utils/b2b/b2bOnSearch.js | 6 + .../utils/b2b/b2bOnSelect.js | 44 +++- .../utils/b2b/b2bOnStatus.js | 53 +++- .../utils/b2b/b2bSelect.js | 231 ++++++++---------- .../utils/constants.js | 3 +- .../utils/logistics/logInit.js | 2 +- .../log-verification-utility/utils/utils.js | 39 +++ 15 files changed, 302 insertions(+), 227 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index ceb53cb..6598048 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/confirmSchema", type: "object", @@ -756,6 +757,7 @@ module.exports = { }, tags: { type: "array", + minItems: 3, items: { type: "object", properties: { @@ -763,7 +765,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -776,7 +778,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, @@ -813,6 +815,7 @@ module.exports = { "payments", "created_at", "updated_at", + "tags" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 24c21ce..70d6924 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -1,3 +1,5 @@ +const constants = require("../../../utils/constants"); + module.exports = { $id: "http://example.com/schema/initSchema", type: "object", @@ -499,6 +501,7 @@ module.exports = { }, tags: { type: "array", + minItems: 1, items: { type: "object", properties: { @@ -506,7 +509,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -519,7 +522,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 21b1007..97cf393 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onConfirmSchema", type: "object", @@ -763,6 +764,7 @@ module.exports = { }, tags: { type: "array", + minItems: 3, items: { type: "object", properties: { @@ -770,7 +772,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -783,7 +785,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 6c7d5fc..7095ff1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onInitSchema", type: "object", @@ -714,6 +715,7 @@ module.exports = { }, tags: { type: "array", + minItems: 2, items: { type: "object", properties: { @@ -721,7 +723,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id"], + enum: constants.TERMS }, }, }, @@ -734,7 +736,7 @@ module.exports = { properties: { code: { type: "string", - enum: ["buyer_id_code", "buyer_id_no"], + enum: constants.B2B_BPP_TERMS }, }, }, @@ -759,6 +761,7 @@ module.exports = { "fulfillments", "quote", "payments", + "tags" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 309dd8f..fd73c5e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -480,7 +480,13 @@ module.exports = { }, }, }, - required: ["provider", "items", "quote", "payments", "fulfillments"], + required: [ + "provider", + "items", + "quote", + "payments", + "fulfillments" + ], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index ced30ea..1652dfa 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,7 +124,7 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations","ttl"], + required: ["id", "locations", "ttl"], }, items: { type: "array", @@ -215,7 +215,7 @@ module.exports = { }, }, }, - required: ["id", "location_ids", "quantity","fulfillment_ids"], + required: ["id", "location_ids", "quantity", "fulfillment_ids"], }, }, fulfillments: { @@ -244,7 +244,8 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, area_code: { type: "string", @@ -366,8 +367,8 @@ module.exports = { }, }, }, - additionalProperties:false, - required: ["id","type","stops"], + additionalProperties: false, + required: ["id", "type", "stops"], }, }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index ed7ed39..f02e68b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -7,8 +7,26 @@ const checkConfirm = async (data, msgIdSet) => { const cnfrmObj = {}; let confirm = data; confirm = confirm.message.order; + let orderState = confirm.state; let payments = confirm?.payments; + let items = confirm.items; + const selectedItems = dao.getValue("slctdItemsArray"); + + try { + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + let itemkey = `item-${i}-DiffErr`; + cnfrmObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select`; + }); + } catch (error) { + console.log(error); + } + try { console.log(`Checking payment object in /confirm api`); payments.forEach((payment) => { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index b7cc0ce..f201555 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -8,86 +8,21 @@ const checkInit = (data, msgIdSet) => { let init = data; init = init.message.order; - let itemsArr = init.items; - let fulfillmentsArr = init.fulfillments; - let onSearchitemsArr; - let providersArr = dao.getValue("providersArr"); + let items = init.items; + const selectedItems = dao.getValue("slctdItemsArray"); - //provider check try { - console.log(`Comparing provider object in /init and /on_search`); - if (init.provider) { - onSearchitemsArr = dao.getValue(`${init.provider.id}itemsArr`); - let providerObj = providersArr?.filter( - (prov) => prov.id === init.provider.id - ); - if (providerObj?.length < 1) { - initObj.prvdrErr = `Provider with id '${init.provider.id}' does not exist in the catalog provided in /on_search`; - } else { - if ( - (!init?.provider?.locations || - init?.provider?.locations?.length < 1) && - providerObj[0]?.locations?.length > 1 - ) { - initObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; - } else if (init?.provider?.locations) { - let providerLocArr = init.provider.locations; - let providerLocExists = false; - - if (providerLocArr) { - providerLocArr.forEach((location, i) => { - if (providerObj) { - providerObj[0]?.locations?.forEach((element) => { - console.log(location.id, element.id); - - if (location.id === element.id) providerLocExists = true; - }); - } - - if (!providerLocExists) { - let itemkey = `providerLocErr${i}`; - initObj[ - itemkey - ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; - } - providerLocExists = false; - }); - } - } - } - } - } catch (error) { - console.log( - `!!Error while checking provider object in /${constants.LOG_INIT}`, - error - ); - } - - //item check - try { - console.log(`Comparing item object in /init and /on_search`); - let itemExists = false; - - itemsArr.forEach((item, i) => { - if (onSearchitemsArr) { - onSearchitemsArr.forEach((element) => { - if (item.id === element.id) itemExists = true; - }); - } - - if (!itemExists) { - let itemkey = `itemErr${i}`; - initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; - } else { - let itemObj = onSearchitemsArr.filter( - (element) => item.id === element.id - ); - itemObj = itemObj[0]; - } - itemExists = false; + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + let itemkey = `item-${i}-DiffErr`; + initObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select`; }); } catch (error) { - console.log(`!!Error while checking items array in /on_init API`, error); + console.log(error); } return initObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index a6bfe43..56bc22a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -10,6 +10,12 @@ const checkOnSearch = async (data, msgIdSet) => { let domain = onSearch.context.domain; onSearch = onSearch.message.catalog; + //saving fulfillments + + const fulfillments = onSearch?.fulfillments; + + dao.setValue("fulfillmentsArr", fulfillments); + try { console.log(`Saving provider items array in /on_search api`); if (onSearch["providers"]) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index b7f7717..f99599e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -8,9 +8,11 @@ const checkOnSelect = async (data, msgIdSet) => { let onSelect = data; onSelect = onSelect.message.order; let quote = onSelect?.quote; + const items = onSelect.items; let fulfillments = onSelect?.fulfillments; let ffState, ffId; let deliveryQuoteItem = false; + const selectedItems = dao.getValue("slctdItemsArray"); try { console.log("Checking fulfillment object in /on_select"); if (fulfillments) { @@ -23,14 +25,28 @@ const checkOnSelect = async (data, msgIdSet) => { console.log(error); } + try { + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + let itemkey = `item-${i}-DiffErr`; + onSelectObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select`; + }); + } catch (error) { + console.log(error); + } + + try { console.log(`Checking quote object in /on_select api`); - quote?.breakup.forEach((breakup,i) => { + quote?.breakup.forEach((breakup, i) => { let itemPrice = parseFloat(breakup?.item?.price?.value); - let available = Number(breakup?.item?.quantity?.available?.count) + let available = Number(breakup?.item?.quantity?.available?.count); let quantity = breakup["@ondc/org/item_quantity"]; - if ( breakup["@ondc/org/title_type"] === "delivery" && breakup["@ondc/org/item_id"] === ffId @@ -40,16 +56,24 @@ const checkOnSelect = async (data, msgIdSet) => { if ( breakup["@ondc/org/title_type"] === "item" && quantity && - parseFloat(breakup.price.value).toFixed(2) != parseFloat(itemPrice * quantity?.count).toFixed(2) + parseFloat(breakup.price.value).toFixed(2) != + parseFloat(itemPrice * quantity?.count).toFixed(2) ) { - let item = `quoteErr${i}` - onSelectObj[item] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; + let item = `quoteErr${i}`; + onSelectObj[ + item + ] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; } - if( breakup["@ondc/org/title_type"] === "item" && - quantity && quantity?.count>available){ - let item = `quoteErr${i}` - onSelectObj[item] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; + if ( + breakup["@ondc/org/title_type"] === "item" && + quantity && + quantity?.count > available + ) { + let item = `quoteErr${i}`; + onSelectObj[ + item + ] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; } }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 9d12cef..7d1817a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -30,8 +30,12 @@ const checkOnStatus = (data, msgIdSet) => { if (paymentStatus === "NOT-PAID" && params?.transaction_id) { onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; } - if(paymentType==='ON-FULFILLMENT' && orderState!='Completed' && paymentStatus==='PAID'){ - onStatusObj.pymntstsErr= `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'` + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + onStatusObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; } }); } catch (error) { @@ -182,6 +186,51 @@ const checkOnStatus = (data, msgIdSet) => { }); } } + if (fulfillment.type === "Self-Pickup") { + if ( + ffState === "Pending" || + ffState === "Packed" + ) { + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + if (stop?.time?.timestamp) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + + if (ffState === "Order-picked-up") { + if (orderState !== "Completed") { + onStatusObj.ordrStatErr = `Order state should be 'Completed' once the order is picked up`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is required for fulfillment state - ${ffState}`; + } + + if (_.gt(pickupTime, contextTime)) { + onStatusObj.tmstmpErr = `Pickup timestamp (fulfillments/start/time/timestamp) cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `Delivery timestamp (fulfillments/end/time/timestamp) cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + } + } }); } catch (error) { console.log(`Error checking fulfillments/start in /on_status`); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index 9fbfd6a..9a0539f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -7,137 +7,122 @@ const checkSelect = async (data, msgIdSet) => { const selectObj = {}; let select = data; select = select.message.order; - let itemIdList; let fulfillments = select?.fulfillments; - - fulfillments.forEach(fulfillment => { + let providersArr = dao.getValue("providersArr"); + let fulfillmentsArr = dao.getValue("fulfillmentsArr"); + let itemsArr = select.items; + dao.setValue("slctdItemsArray",itemsArr) - const fulId= fulfillment?.id - const fulType = fulfillment?.type + // provider check + try { + console.log(`Comparing provider object in /select and /on_search`); + if (select.provider) { + onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); + let providerObj = providersArr?.filter( + (prov) => prov.id === select.provider.id + ); + if (!providerObj || providerObj?.length < 1) { + selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; + } else { + if ( + (!select?.provider?.locations || + select?.provider?.locations?.length < 1) && + providerObj[0]?.locations?.length > 1 + ) { + selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + } else if (select?.provider?.locations) { + let providerLocArr = select.provider.locations; + let providerLocExists = false; + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); - console.log("Checking if the fulfillment id and type in /select present in /on_search") - - - }); + if (location.id === element.id) providerLocExists = true; + }); + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + selectObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; + }); + } + } + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.LOG_select}`, + error + ); + } - //provider check - // try { - // console.log(`Comparing provider object in /select and /on_search`); - // if (select.provider) { - // onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); - // let providerObj = providersArr?.filter( - // (prov) => prov.id === select.provider.id - // ); - // if (!providerObj || providerObj?.length < 1) { - // selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; - // } else { - // if ( - // (!select?.provider?.locations || - // select?.provider?.locations?.length < 1) && - // providerObj[0]?.locations?.length > 1 - // ) { - // selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; - // } else if (select?.provider?.locations) { - // let providerLocArr = select.provider.locations; - // let providerLocExists = false; - // providerLocArr.forEach((location, i) => { - // providerObj[0]?.locations?.forEach((element) => { - // console.log(location.id, element.id); + //item check + try { + console.log(`Comparing item object in /select and /on_search`); - // if (location.id === element.id) providerLocExists = true; - // }); + itemsArr?.forEach((item, i) => { + let itemExists = false; + onSearchitemsArr?.forEach((element) => { + if (item.id === element.id) itemExists = true; + }); + if (!itemExists) { + let itemkey = `itemErr${i}`; + selectObj[ + itemkey + ] = `Item Id '${item.id}' does not exist in /on_search`; + } else { + let itemObj = onSearchitemsArr.filter( + (element) => element.id === item.id + ); - // if (!providerLocExists) { - // let itemkey = `providerLocErr${i}`; - // selectObj[ - // itemkey - // ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; - // } - // providerLocExists = false; - // }); - // } - // } - // } - // } catch (error) { - // console.log( - // `!!Error while checking provider object in /${constants.LOG_select}`, - // error - // ); - // } + itemObj = itemObj[0]; + // dao.setValue("selectedItem", itemObj.id); + console.log(itemObj.id); + if ( + !_.every(item.fulfillment_ids, (element) => + _.includes(itemObj.fulfillment_ids, element) + ) + ) { + let itemkey = `flflmntIdErr${i}`; + selectObj[ + itemkey + ] = `Fulfillment ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + if ( + !_.every(item.location_ids, (element) => + _.includes(itemObj.location_ids, element) + ) + ) { + let itemkey = `lctnIdErr${i}`; + selectObj[ + itemkey + ] = `Location ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } - // //item check - // try { - // console.log(`Comparing item object in /select and /on_search`); - // let itemExists = false; - - // itemsArr?.forEach((item, i) => { - // if (item.descriptor.code === "P2H2P") { - // p2h2p = true; - // } - // onSearchitemsArr?.forEach((element) => { - // if (item.id === element.id) itemExists = true; - // }); - // if (!itemExists) { - // let itemkey = `itemErr${i}`; - // selectObj[ - // itemkey - // ] = `Item Id '${item.id}' does not exist in /on_search`; - // } else { - // let itemObj = onSearchitemsArr.filter( - // (element) => item.id === element.id - // ); - - // itemObj = itemObj[0]; - // dao.setValue("selectedItem", itemObj.id); - // console.log(itemObj.id); - // if (item.category_id != itemObj.category_id) { - // let itemkey = `catIdErr${i}`; - // selectObj[ - // itemkey - // ] = `Category id '${item.category_id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; - // } - // if (item.descriptor.code != itemObj.descriptor.code) { - // let itemkey = `codeErr${i}`; - // selectObj[ - // itemkey - // ] = `Descriptor code '${item.descriptor.code}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; - // } - // fulfillmentsArr.forEach((fulfillment, i) => { - // if (fulfillment.id !== itemObj.fulfillment_id) { - // let itemkey = `flfillmentErr${i}`; - // selectObj[ - // itemkey - // ] = `Fulfillment id '${fulfillment.id}' for item with id '${item.id}' does not match with the catalog provided in /on_search`; - // } else { - // let bppfulfillment = bppFulfillmentsArr?.find( - // (element) => element.id === fulfillment.id - // ); - // if (fulfillment.type !== bppfulfillment?.type) { - // let itemkey = `flfillmentTypeErr${i}`; - // selectObj[ - // itemkey - // ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; - // } - // } - // }); - // } - // itemExists = false; - // }); - // } catch (error) { - // console.log(error); - // } - // try { - // console.log("Checking fulfillment object in /select"); - // if (fulfillments) { - // fulfillments.forEach((fulfillment) => { - // ffId = fulfillment?.id; - // ffState = fulfillment?.state?.descriptor?.code; - // }); - // } - // } catch (error) { - // console.log(error); - // } + //checking fulfillments + fulfillments.forEach((fulfillment, i) => { + let bppfulfillment = fulfillmentsArr?.find( + (element) => element.id === fulfillment.id + ); + if (!bppfulfillment) { + let itemkey = `flfillmentIDerr${i}`; + selectObj[ + itemkey + ] = `Fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + } else if (fulfillment.type !== bppfulfillment?.type) { + let itemkey = `flfillmentTypeErr${i}`; + selectObj[ + itemkey + ] = `Fulfillment type '${fulfillment.type}' for fulfillment id '${fulfillment.id}' does not match with the catalog provided in /on_search`; + } + }); + } + }); + } catch (error) { + console.log(error); + } return selectObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 56c887f..3ff9912 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -171,5 +171,6 @@ module.exports = Object.freeze({ CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], - TERMS:["bap_terms","bpp_terms"] + TERMS:["buyer_id","bap_terms","bpp_terms"], + B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js index ef36eae..7c2d4c6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logInit.js @@ -79,7 +79,7 @@ const checkInit = (data, msgIdSet) => { initObj[itemkey] = `Item Id '${item.id}' does not exist in /on_search`; } else { let itemObj = onSearchitemsArr.filter( - (element) => item.id === element.id + (element) => element.id === item.id ); itemObj = itemObj[0]; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 04fd841..3c407dc 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -365,6 +365,44 @@ const isObjectEqual = (obj1, obj2, parentKey = "") => { return notEqualKeys; }; +function findDifferentAttributes(obj1, obj2) { + const differences = []; + + // Iterate over each key in obj1 + _.forOwn(obj1, (value1, key) => { + const value2 = obj2[key]; + + // Check if the values are not equal + if (!_.isEqual(value1, value2)) { + differences.push(key); + } + }); + + return differences; +} + +function findDifferencesInArrays(array1, array2) { + const differences = []; + + // Check if arrays have the same length + if (array1.length !== array2.length) { + return differences; + } + + // Iterate over each item in the arrays + for (let i = 0; i < array1.length; i++) { + const item1 = array1[i]; + const item2 = array2[i]; + + // Check if the properties are equal using lodash's _.isEqual + if (!_.isEqual(item1, item2)) { + const differingAttributes = findDifferentAttributes(item1, item2); + differences.push({ index: i, attributes: differingAttributes }); + } + } + + return differences; +} module.exports = { uuidCheck, timestampCheck, @@ -390,6 +428,7 @@ module.exports = { taxNotInlcusive, isArrayEqual, countDecimalDigits, + findDifferencesInArrays, grocery_categories_id, fnb_categories_id, }; From 4983e141f1ac6e1c2b2c091092759beee16536f4 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 23 Jan 2024 17:08:00 +0530 Subject: [PATCH 119/228] minor fix --- .../log-verification-utility/utils/b2b/b2bConfirm.js | 2 ++ .../log-verification-utility/utils/b2b/b2bInit.js | 2 ++ .../log-verification-utility/utils/b2b/b2bOnSelect.js | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index f02e68b..2309ecf 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -18,10 +18,12 @@ const checkConfirm = async (data, msgIdSet) => { const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ let itemkey = `item-${i}-DiffErr`; cnfrmObj[ itemkey ] = `In /items, '${item.attributes}' mismatch from /select`; + } }); } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index f201555..2bc9084 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -16,10 +16,12 @@ const checkInit = (data, msgIdSet) => { const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ let itemkey = `item-${i}-DiffErr`; initObj[ itemkey ] = `In /items, '${item.attributes}' mismatch from /select`; + } }); } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index f99599e..49714a9 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -30,16 +30,18 @@ const checkOnSelect = async (data, msgIdSet) => { const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ let itemkey = `item-${i}-DiffErr`; onSelectObj[ itemkey ] = `In /items, '${item.attributes}' mismatch from /select`; + } }); } catch (error) { console.log(error); } - + try { console.log(`Checking quote object in /on_select api`); quote?.breakup.forEach((breakup, i) => { From 93fcc01956e857cd5a9f846804092762f2ad73f9 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 29 Jan 2024 16:07:20 +0530 Subject: [PATCH 120/228] minor bug fixes --- .../schema/B2B_json_schema/v2/on_confirm.js | 12 +++++++ .../schema/B2B_json_schema/v2/on_select.js | 2 ++ .../schema/B2B_json_schema/v2/on_status.js | 24 ++++++++++++++ .../schema/B2B_json_schema/v2/select.js | 1 + .../v1.2/initSchema.js | 33 ++++++++++++++----- .../utils/b2b/b2bOnSearch.js | 16 +++++---- .../utils/constants.js | 3 +- .../utils/logistics/logConfirm.js | 27 +++++++++++++-- .../utils/logistics/logOnSearch.js | 2 +- .../utils/reverseGeoCoding.js | 10 ++++-- 10 files changed, 107 insertions(+), 23 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 97cf393..8b9be10 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -676,6 +676,15 @@ module.exports = { type: "string", const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, }, + "@ondc/org/settlement_basis": { + type: "string", + }, + "@ondc/org/settlement_window": { + type: "string", + }, + "@ondc/org/withholding_amount": { + type: "string", + }, "@ondc/org/settlement_details": { type: "array", items: { @@ -759,6 +768,9 @@ module.exports = { "collected_by", "@ondc/org/buyer_app_finder_fee_type", "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index fd73c5e..a8d8371 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onSelectSchema", type: "object", @@ -236,6 +237,7 @@ module.exports = { }, "@ondc/org/category": { type: "string", + enum: constants.CATEGORY_ID }, "@ondc/org/TAT": { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 2f37c00..0847c1e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -639,6 +639,27 @@ module.exports = { "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount", }, }, + "@ondc/org/settlement_basis": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, + }, + "@ondc/org/settlement_window": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, + }, + "@ondc/org/withholding_amount": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, + }, "@ondc/org/settlement_details": { type: "array", items: { @@ -722,6 +743,9 @@ module.exports = { "collected_by", "@ondc/org/buyer_app_finder_fee_type", "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 1652dfa..9c89d02 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -125,6 +125,7 @@ module.exports = { }, }, required: ["id", "locations", "ttl"], + errorMessage: "id, locations are mandatory attributes and ttl is required for RFQ Flow" }, items: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 0721b13..90f07c2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -196,8 +196,8 @@ module.exports = { type: "string", }, }, - isLengthValid:true, - + isLengthValid: true, + required: [ "name", "building", @@ -274,8 +274,8 @@ module.exports = { type: "string", }, }, - isLengthValid:true, - + isLengthValid: true, + required: [ "name", "building", @@ -456,15 +456,32 @@ module.exports = { type: "string", enum: constants.PAYMENT_TYPE, const: { $data: "/search/0/message/intent/payment/type" }, - errorMessage:"should be same as in /search - ${/search/0/message/intent/payment/type}" + errorMessage: + "should be same as in /search - ${/search/0/message/intent/payment/type}", + }, + collected_by: { + type: "string", + enum: constants.PAYMENT_COLLECTEDBY, + }, + }, + additionalProperties: false, + if: { + properties: { + type: { + const: "ON-ORDER", + }, }, }, - additionalProperties:false, - required: ["type"], + then: { + required: ["type", "collected_by"], + }, + else: { + required: ["type"], + }, }, }, additionalProperties: false, - required: ["provider", "items", "fulfillments", "billing","payment"], + required: ["provider", "items", "fulfillments", "billing", "payment"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 56bc22a..1a77f78 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -11,7 +11,12 @@ const checkOnSearch = async (data, msgIdSet) => { onSearch = onSearch.message.catalog; //saving fulfillments - + try { + console.log("checking attr"); + console.log(constants.ATTR_DOMAINS.includes(domain)); + } catch (error) { + console.log(error); + } const fulfillments = onSearch?.fulfillments; dao.setValue("fulfillmentsArr", fulfillments); @@ -58,10 +63,10 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics - if (domain === "ONDC:RET12" || domain === "ONDC:RET14") { + if (constants.ATTR_DOMAINS.includes(domain)) { provider.items.forEach((item) => { let itemTags = item?.tags; - let mandatoryAttr; + let mandatoryAttr = []; let attrPresent = false; if (domain === "ONDC:RET12") { @@ -90,10 +95,7 @@ const checkOnSearch = async (data, msgIdSet) => { } }); - if ( - (domain === "ONDC:RET12" || domain === "ONDC:RET14") && - !attrPresent - ) + if (!attrPresent) onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; }); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 3ff9912..ad070b4 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -172,5 +172,6 @@ module.exports = Object.freeze({ FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], TERMS:["buyer_id","bap_terms","bpp_terms"], - B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"] + B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], + ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 5b91a63..d4be8b2 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -11,7 +11,7 @@ const checkConfirm = (data, msgIdSet) => { let onSearchProvArr = dao.getValue("providersArr"); confirm = confirm.message.order; let rts; - + let linkedOrder = confirm["@ondc/org/linked_order"] if (confirm?.updated_at > contextTimestamp) { cnfrmObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; } @@ -73,8 +73,8 @@ const checkConfirm = (data, msgIdSet) => { let p2h2p = dao.getValue("p2h2p"); fulfillments.forEach((fulfillment) => { let avgPickupTime= fulfillment?.start?.time?.duration; - - if(avgPickupTime && avgPickupTime!==dao.getValue("avgPickupTime")){ +console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); + if(avgPickupTime && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; @@ -83,6 +83,27 @@ const checkConfirm = (data, msgIdSet) => { } }); + try { + console.log("checking linked order in /confirm"); + + const orderWeight =linkedOrder?.order?.weight?.value; + + let totalUnitWeight=0; + + linkedOrder?.items.forEach(item=>{ + const quantity = item?.quantity?.measure?.value + const count = item?.quantity?.count + + const unitWeight = (quantity*count).toFixed(2) + totalUnitWeight+=unitWeight; + }) + + if(totalUnitWeight!=orderWeight.toFixed(2)){ + cnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` + } + } catch (error) { + console.log(error); + } dao.setValue("awbNo", awbNo); return cnfrmObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js index f295472..029063a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js @@ -107,7 +107,7 @@ const checkOnSearch = async (data, msgIdSet) => { ) { hasForwardShipment = true; avgPickupTime= fulfillment?.start?.time?.duration - dao.setValue("avgPickupTime",avgPickupTime) + dao.setValue(`${fulfillment?.id}-avgPickupTime`,avgPickupTime) } else if ( fulfillment.type === "RTO" || fulfillment.type === "Reverse QC" || diff --git a/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js b/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js index dc1abfc..fdd9549 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js @@ -5,16 +5,20 @@ * @param {string} area_code The Area Code to check the above lat-long pair against * @returns {boolean} Returns `true` if `area_code` matched lat-long pair */ - require("dotenv").config(); +require("dotenv").config(); const reverseGeoCodingCheck = async (lat, long, area_code) => { var fetch = require("node-fetch"); var requestOptions = { method: "GET", }; try { - const res = await fetch(`https://apis.mappls.com/advancedmaps/v1/${process.env.MAPPLS_API_KEY}/rev_geocode?lat=${lat}&lng=${long}`, requestOptions); + const res = await fetch( + `https://apis.mappls.com/advancedmaps/v1/${process.env.MAPPLS_API_KEY}/rev_geocode?lat=${lat}&lng=${long}`, + requestOptions + ); const response = await res.json(); - return response.results[0].pincode === area_code + if (response.results) return response.results[0].pincode === area_code; + else return false; } catch (error) { console.log(error); } From 6565a946484e9ceb6293306ad6c80f546a506001 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 30 Jan 2024 15:38:58 +0530 Subject: [PATCH 121/228] few checks added --- .../schema/B2B_json_schema/v2/search.js | 1 + .../schema/logistics_api_json_schema/v1.2/onConfirmSchema.js | 3 --- .../log-verification-utility/utils/logistics/logConfirm.js | 4 ++-- .../log-verification-utility/utils/logistics/logOnConfirm.js | 4 +++- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index 160bdd1..453ca21 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -117,6 +117,7 @@ module.exports = { properties: { type: { type: "string", + enum:["end"] }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 952d783..2cef21f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -888,9 +888,6 @@ module.exports = { }, updated_at: { type: "string", - const: { $data: "3/context/timestamp" }, - errorMessage: - "does not match context/timestamp - ${3/context/timestamp}", }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index d4be8b2..6716ca3 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -94,11 +94,11 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); const quantity = item?.quantity?.measure?.value const count = item?.quantity?.count - const unitWeight = (quantity*count).toFixed(2) + const unitWeight = (quantity*count) totalUnitWeight+=unitWeight; }) - if(totalUnitWeight!=orderWeight.toFixed(2)){ + if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2)){ cnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` } } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index ce4ce33..5133fd0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -22,7 +22,9 @@ const checkOnConfirm = (data, msgIdSet) => { if (on_confirm?.created_at > contextTimestamp) { onCnfrmObj.createdAtErr = `order/created_at cannot be future dated w.r.t context/timestamp`; } - + if (on_confirm?.created_at > on_confirm?.updated_at) { + onCnfrmObj.createdAtErr = `order/created_at cannot be future dated w.r.t order/updated_at`; + } let categoryId; items.forEach(item=>{ categoryId=item.category_id; From 1c2948ca382b2e68496f6b73b162c629ed96b116 Mon Sep 17 00:00:00 2001 From: Charanpreet Date: Fri, 2 Feb 2024 15:02:32 +0530 Subject: [PATCH 122/228] feat: added 1:1 implementation of PHP signing and verification utility --- .../signing_and_verification/php/.gitignore | 0 .../php/composer.json | 14 + .../php/composer.lock | 940 +++ .../signing_and_verification/php/src/.env | 4 + .../php/src/index.php | 135 + .../php/vendor/autoload.php | 25 + .../php/vendor/composer/ClassLoader.php | 579 ++ .../php/vendor/composer/InstalledVersions.php | 359 ++ .../php/vendor/composer/LICENSE | 21 + .../php/vendor/composer/autoload_classmap.php | 15 + .../php/vendor/composer/autoload_files.php | 13 + .../vendor/composer/autoload_namespaces.php | 9 + .../php/vendor/composer/autoload_psr4.php | 22 + .../php/vendor/composer/autoload_real.php | 50 + .../php/vendor/composer/autoload_static.php | 123 + .../php/vendor/composer/installed.json | 964 +++ .../php/vendor/composer/installed.php | 142 + .../php/vendor/composer/platform_check.php | 26 + .../graham-campbell/result-type/LICENSE | 21 + .../graham-campbell/result-type/composer.json | 33 + .../graham-campbell/result-type/src/Error.php | 121 + .../result-type/src/Result.php | 69 + .../result-type/src/Success.php | 120 + .../constant_time_encoding/LICENSE.txt | 48 + .../constant_time_encoding/README.md | 84 + .../constant_time_encoding/composer.json | 56 + .../constant_time_encoding/src/Base32.php | 519 ++ .../constant_time_encoding/src/Base32Hex.php | 111 + .../constant_time_encoding/src/Base64.php | 314 + .../src/Base64DotSlash.php | 88 + .../src/Base64DotSlashOrdered.php | 82 + .../src/Base64UrlSafe.php | 95 + .../constant_time_encoding/src/Binary.php | 90 + .../src/EncoderInterface.php | 52 + .../constant_time_encoding/src/Encoding.php | 262 + .../constant_time_encoding/src/Hex.php | 146 + .../constant_time_encoding/src/RFC4648.php | 186 + .../vendor/paragonie/random_compat/LICENSE | 22 + .../paragonie/random_compat/build-phar.sh | 5 + .../paragonie/random_compat/composer.json | 34 + .../dist/random_compat.phar.pubkey | 5 + .../dist/random_compat.phar.pubkey.asc | 11 + .../paragonie/random_compat/lib/random.php | 32 + .../random_compat/other/build_phar.php | 57 + .../random_compat/psalm-autoload.php | 9 + .../vendor/paragonie/random_compat/psalm.xml | 19 + .../php/vendor/phpoption/phpoption/LICENSE | 201 + .../vendor/phpoption/phpoption/composer.json | 52 + .../phpoption/src/PhpOption/LazyOption.php | 175 + .../phpoption/src/PhpOption/None.php | 136 + .../phpoption/src/PhpOption/Option.php | 434 ++ .../phpoption/src/PhpOption/Some.php | 169 + .../php/vendor/phpseclib/phpseclib/AUTHORS | 7 + .../php/vendor/phpseclib/phpseclib/BACKERS.md | 16 + .../php/vendor/phpseclib/phpseclib/LICENSE | 20 + .../php/vendor/phpseclib/phpseclib/README.md | 97 + .../vendor/phpseclib/phpseclib/composer.json | 84 + .../phpseclib/Common/Functions/Strings.php | 505 ++ .../phpseclib/phpseclib/Crypt/AES.php | 116 + .../phpseclib/phpseclib/Crypt/Blowfish.php | 918 +++ .../phpseclib/phpseclib/Crypt/ChaCha20.php | 799 +++ .../phpseclib/Crypt/Common/AsymmetricKey.php | 581 ++ .../phpseclib/Crypt/Common/BlockCipher.php | 24 + .../Crypt/Common/Formats/Keys/JWK.php | 69 + .../Crypt/Common/Formats/Keys/OpenSSH.php | 220 + .../Crypt/Common/Formats/Keys/PKCS.php | 72 + .../Crypt/Common/Formats/Keys/PKCS1.php | 209 + .../Crypt/Common/Formats/Keys/PKCS8.php | 725 +++ .../Crypt/Common/Formats/Keys/PuTTY.php | 374 ++ .../Crypt/Common/Formats/Signature/Raw.php | 60 + .../phpseclib/Crypt/Common/PrivateKey.php | 31 + .../phpseclib/Crypt/Common/PublicKey.php | 25 + .../phpseclib/Crypt/Common/StreamCipher.php | 54 + .../phpseclib/Crypt/Common/SymmetricKey.php | 3398 +++++++++++ .../Crypt/Common/Traits/Fingerprint.php | 57 + .../Crypt/Common/Traits/PasswordProtected.php | 46 + .../phpseclib/phpseclib/Crypt/DES.php | 1392 +++++ .../phpseclib/phpseclib/Crypt/DH.php | 405 ++ .../phpseclib/Crypt/DH/Formats/Keys/PKCS1.php | 77 + .../phpseclib/Crypt/DH/Formats/Keys/PKCS8.php | 132 + .../phpseclib/Crypt/DH/Parameters.php | 36 + .../phpseclib/Crypt/DH/PrivateKey.php | 75 + .../phpseclib/Crypt/DH/PublicKey.php | 49 + .../phpseclib/phpseclib/Crypt/DSA.php | 337 + .../Crypt/DSA/Formats/Keys/OpenSSH.php | 118 + .../Crypt/DSA/Formats/Keys/PKCS1.php | 143 + .../Crypt/DSA/Formats/Keys/PKCS8.php | 146 + .../Crypt/DSA/Formats/Keys/PuTTY.php | 109 + .../phpseclib/Crypt/DSA/Formats/Keys/Raw.php | 85 + .../phpseclib/Crypt/DSA/Formats/Keys/XML.php | 132 + .../Crypt/DSA/Formats/Signature/ASN1.php | 62 + .../Crypt/DSA/Formats/Signature/Raw.php | 25 + .../Crypt/DSA/Formats/Signature/SSH2.php | 74 + .../phpseclib/Crypt/DSA/Parameters.php | 36 + .../phpseclib/Crypt/DSA/PrivateKey.php | 152 + .../phpseclib/Crypt/DSA/PublicKey.php | 86 + .../phpseclib/phpseclib/Crypt/EC.php | 480 ++ .../phpseclib/Crypt/EC/BaseCurves/Base.php | 218 + .../phpseclib/Crypt/EC/BaseCurves/Binary.php | 373 ++ .../Crypt/EC/BaseCurves/KoblitzPrime.php | 335 + .../Crypt/EC/BaseCurves/Montgomery.php | 279 + .../phpseclib/Crypt/EC/BaseCurves/Prime.php | 785 +++ .../Crypt/EC/BaseCurves/TwistedEdwards.php | 215 + .../phpseclib/Crypt/EC/Curves/Curve25519.php | 81 + .../phpseclib/Crypt/EC/Curves/Curve448.php | 92 + .../phpseclib/Crypt/EC/Curves/Ed25519.php | 333 + .../phpseclib/Crypt/EC/Curves/Ed448.php | 273 + .../Crypt/EC/Curves/brainpoolP160r1.php | 34 + .../Crypt/EC/Curves/brainpoolP160t1.php | 47 + .../Crypt/EC/Curves/brainpoolP192r1.php | 34 + .../Crypt/EC/Curves/brainpoolP192t1.php | 34 + .../Crypt/EC/Curves/brainpoolP224r1.php | 34 + .../Crypt/EC/Curves/brainpoolP224t1.php | 34 + .../Crypt/EC/Curves/brainpoolP256r1.php | 34 + .../Crypt/EC/Curves/brainpoolP256t1.php | 34 + .../Crypt/EC/Curves/brainpoolP320r1.php | 40 + .../Crypt/EC/Curves/brainpoolP320t1.php | 40 + .../Crypt/EC/Curves/brainpoolP384r1.php | 58 + .../Crypt/EC/Curves/brainpoolP384t1.php | 58 + .../Crypt/EC/Curves/brainpoolP512r1.php | 58 + .../Crypt/EC/Curves/brainpoolP512t1.php | 58 + .../phpseclib/Crypt/EC/Curves/nistb233.php | 18 + .../phpseclib/Crypt/EC/Curves/nistb409.php | 18 + .../phpseclib/Crypt/EC/Curves/nistk163.php | 18 + .../phpseclib/Crypt/EC/Curves/nistk233.php | 18 + .../phpseclib/Crypt/EC/Curves/nistk283.php | 18 + .../phpseclib/Crypt/EC/Curves/nistk409.php | 18 + .../phpseclib/Crypt/EC/Curves/nistp192.php | 18 + .../phpseclib/Crypt/EC/Curves/nistp224.php | 18 + .../phpseclib/Crypt/EC/Curves/nistp256.php | 18 + .../phpseclib/Crypt/EC/Curves/nistp384.php | 18 + .../phpseclib/Crypt/EC/Curves/nistp521.php | 18 + .../phpseclib/Crypt/EC/Curves/nistt571.php | 18 + .../phpseclib/Crypt/EC/Curves/prime192v1.php | 18 + .../phpseclib/Crypt/EC/Curves/prime192v2.php | 34 + .../phpseclib/Crypt/EC/Curves/prime192v3.php | 34 + .../phpseclib/Crypt/EC/Curves/prime239v1.php | 34 + .../phpseclib/Crypt/EC/Curves/prime239v2.php | 34 + .../phpseclib/Crypt/EC/Curves/prime239v3.php | 34 + .../phpseclib/Crypt/EC/Curves/prime256v1.php | 18 + .../phpseclib/Crypt/EC/Curves/secp112r1.php | 34 + .../phpseclib/Crypt/EC/Curves/secp112r2.php | 35 + .../phpseclib/Crypt/EC/Curves/secp128r1.php | 34 + .../phpseclib/Crypt/EC/Curves/secp128r2.php | 35 + .../phpseclib/Crypt/EC/Curves/secp160k1.php | 46 + .../phpseclib/Crypt/EC/Curves/secp160r1.php | 34 + .../phpseclib/Crypt/EC/Curves/secp160r2.php | 35 + .../phpseclib/Crypt/EC/Curves/secp192k1.php | 45 + .../phpseclib/Crypt/EC/Curves/secp192r1.php | 78 + .../phpseclib/Crypt/EC/Curves/secp224k1.php | 45 + .../phpseclib/Crypt/EC/Curves/secp224r1.php | 34 + .../phpseclib/Crypt/EC/Curves/secp256k1.php | 49 + .../phpseclib/Crypt/EC/Curves/secp256r1.php | 34 + .../phpseclib/Crypt/EC/Curves/secp384r1.php | 52 + .../phpseclib/Crypt/EC/Curves/secp521r1.php | 46 + .../phpseclib/Crypt/EC/Curves/sect113r1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect113r2.php | 34 + .../phpseclib/Crypt/EC/Curves/sect131r1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect131r2.php | 34 + .../phpseclib/Crypt/EC/Curves/sect163k1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect163r1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect163r2.php | 34 + .../phpseclib/Crypt/EC/Curves/sect193r1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect193r2.php | 34 + .../phpseclib/Crypt/EC/Curves/sect233k1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect233r1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect239k1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect283k1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect283r1.php | 34 + .../phpseclib/Crypt/EC/Curves/sect409k1.php | 38 + .../phpseclib/Crypt/EC/Curves/sect409r1.php | 38 + .../phpseclib/Crypt/EC/Curves/sect571k1.php | 42 + .../phpseclib/Crypt/EC/Curves/sect571r1.php | 42 + .../Crypt/EC/Formats/Keys/Common.php | 549 ++ .../phpseclib/Crypt/EC/Formats/Keys/JWK.php | 189 + .../EC/Formats/Keys/MontgomeryPrivate.php | 101 + .../EC/Formats/Keys/MontgomeryPublic.php | 71 + .../Crypt/EC/Formats/Keys/OpenSSH.php | 209 + .../phpseclib/Crypt/EC/Formats/Keys/PKCS1.php | 194 + .../phpseclib/Crypt/EC/Formats/Keys/PKCS8.php | 234 + .../phpseclib/Crypt/EC/Formats/Keys/PuTTY.php | 138 + .../phpseclib/Crypt/EC/Formats/Keys/XML.php | 485 ++ .../Crypt/EC/Formats/Keys/libsodium.php | 116 + .../Crypt/EC/Formats/Signature/ASN1.php | 62 + .../Crypt/EC/Formats/Signature/IEEE.php | 66 + .../Crypt/EC/Formats/Signature/Raw.php | 25 + .../Crypt/EC/Formats/Signature/SSH2.php | 94 + .../phpseclib/Crypt/EC/Parameters.php | 36 + .../phpseclib/Crypt/EC/PrivateKey.php | 256 + .../phpseclib/Crypt/EC/PublicKey.php | 172 + .../phpseclib/phpseclib/Crypt/Hash.php | 1455 +++++ .../phpseclib/Crypt/PublicKeyLoader.php | 111 + .../phpseclib/phpseclib/Crypt/RC2.php | 640 ++ .../phpseclib/phpseclib/Crypt/RC4.php | 280 + .../phpseclib/phpseclib/Crypt/RSA.php | 934 +++ .../phpseclib/Crypt/RSA/Formats/Keys/JWK.php | 142 + .../Crypt/RSA/Formats/Keys/MSBLOB.php | 228 + .../Crypt/RSA/Formats/Keys/OpenSSH.php | 132 + .../Crypt/RSA/Formats/Keys/PKCS1.php | 160 + .../Crypt/RSA/Formats/Keys/PKCS8.php | 122 + .../phpseclib/Crypt/RSA/Formats/Keys/PSS.php | 238 + .../Crypt/RSA/Formats/Keys/PuTTY.php | 121 + .../phpseclib/Crypt/RSA/Formats/Keys/Raw.php | 184 + .../phpseclib/Crypt/RSA/Formats/Keys/XML.php | 171 + .../phpseclib/Crypt/RSA/PrivateKey.php | 530 ++ .../phpseclib/Crypt/RSA/PublicKey.php | 513 ++ .../phpseclib/phpseclib/Crypt/Random.php | 222 + .../phpseclib/phpseclib/Crypt/Rijndael.php | 1036 ++++ .../phpseclib/phpseclib/Crypt/Salsa20.php | 526 ++ .../phpseclib/phpseclib/Crypt/TripleDES.php | 436 ++ .../phpseclib/phpseclib/Crypt/Twofish.php | 816 +++ .../Exception/BadConfigurationException.php | 23 + .../Exception/BadDecryptionException.php | 23 + .../phpseclib/Exception/BadModeException.php | 23 + .../Exception/ConnectionClosedException.php | 23 + .../Exception/FileNotFoundException.php | 23 + .../Exception/InconsistentSetupException.php | 23 + .../Exception/InsufficientSetupException.php | 23 + .../Exception/NoKeyLoadedException.php | 23 + .../NoSupportedAlgorithmsException.php | 23 + .../Exception/UnableToConnectException.php | 23 + .../UnsupportedAlgorithmException.php | 23 + .../Exception/UnsupportedCurveException.php | 23 + .../Exception/UnsupportedFormatException.php | 23 + .../UnsupportedOperationException.php | 23 + .../phpseclib/phpseclib/File/ANSI.php | 551 ++ .../phpseclib/phpseclib/File/ASN1.php | 1508 +++++ .../phpseclib/phpseclib/File/ASN1/Element.php | 43 + .../File/ASN1/Maps/AccessDescription.php | 32 + .../ASN1/Maps/AdministrationDomainName.php | 36 + .../File/ASN1/Maps/AlgorithmIdentifier.php | 35 + .../phpseclib/File/ASN1/Maps/AnotherName.php | 37 + .../phpseclib/File/ASN1/Maps/Attribute.php | 37 + .../File/ASN1/Maps/AttributeType.php | 26 + .../File/ASN1/Maps/AttributeTypeAndValue.php | 32 + .../File/ASN1/Maps/AttributeValue.php | 26 + .../phpseclib/File/ASN1/Maps/Attributes.php | 31 + .../ASN1/Maps/AuthorityInfoAccessSyntax.php | 31 + .../File/ASN1/Maps/AuthorityKeyIdentifier.php | 45 + .../phpseclib/File/ASN1/Maps/BaseDistance.php | 26 + .../File/ASN1/Maps/BasicConstraints.php | 39 + .../Maps/BuiltInDomainDefinedAttribute.php | 32 + .../Maps/BuiltInDomainDefinedAttributes.php | 31 + .../ASN1/Maps/BuiltInStandardAttributes.php | 67 + .../phpseclib/File/ASN1/Maps/CPSuri.php | 26 + .../File/ASN1/Maps/CRLDistributionPoints.php | 31 + .../phpseclib/File/ASN1/Maps/CRLNumber.php | 26 + .../phpseclib/File/ASN1/Maps/CRLReason.php | 41 + .../phpseclib/File/ASN1/Maps/CertPolicyId.php | 26 + .../phpseclib/File/ASN1/Maps/Certificate.php | 33 + .../File/ASN1/Maps/CertificateIssuer.php | 24 + .../File/ASN1/Maps/CertificateList.php | 33 + .../File/ASN1/Maps/CertificatePolicies.php | 31 + .../ASN1/Maps/CertificateSerialNumber.php | 26 + .../File/ASN1/Maps/CertificationRequest.php | 33 + .../ASN1/Maps/CertificationRequestInfo.php | 41 + .../File/ASN1/Maps/Characteristic_two.php | 36 + .../phpseclib/File/ASN1/Maps/CountryName.php | 36 + .../phpseclib/File/ASN1/Maps/Curve.php | 36 + .../phpseclib/File/ASN1/Maps/DHParameter.php | 38 + .../phpseclib/File/ASN1/Maps/DSAParams.php | 33 + .../File/ASN1/Maps/DSAPrivateKey.php | 36 + .../phpseclib/File/ASN1/Maps/DSAPublicKey.php | 26 + .../phpseclib/File/ASN1/Maps/DigestInfo.php | 34 + .../File/ASN1/Maps/DirectoryString.php | 35 + .../phpseclib/File/ASN1/Maps/DisplayText.php | 34 + .../File/ASN1/Maps/DistributionPoint.php | 45 + .../File/ASN1/Maps/DistributionPointName.php | 40 + .../phpseclib/File/ASN1/Maps/DssSigValue.php | 32 + .../phpseclib/File/ASN1/Maps/ECParameters.php | 45 + .../phpseclib/File/ASN1/Maps/ECPoint.php | 26 + .../phpseclib/File/ASN1/Maps/ECPrivateKey.php | 48 + .../phpseclib/File/ASN1/Maps/EDIPartyName.php | 42 + .../File/ASN1/Maps/EcdsaSigValue.php | 32 + .../File/ASN1/Maps/EncryptedData.php | 26 + .../ASN1/Maps/EncryptedPrivateKeyInfo.php | 32 + .../File/ASN1/Maps/ExtKeyUsageSyntax.php | 31 + .../phpseclib/File/ASN1/Maps/Extension.php | 43 + .../File/ASN1/Maps/ExtensionAttribute.php | 42 + .../File/ASN1/Maps/ExtensionAttributes.php | 31 + .../phpseclib/File/ASN1/Maps/Extensions.php | 33 + .../phpseclib/File/ASN1/Maps/FieldElement.php | 26 + .../phpseclib/File/ASN1/Maps/FieldID.php | 35 + .../phpseclib/File/ASN1/Maps/GeneralName.php | 80 + .../phpseclib/File/ASN1/Maps/GeneralNames.php | 31 + .../File/ASN1/Maps/GeneralSubtree.php | 42 + .../File/ASN1/Maps/GeneralSubtrees.php | 31 + .../File/ASN1/Maps/HashAlgorithm.php | 24 + .../File/ASN1/Maps/HoldInstructionCode.php | 26 + .../File/ASN1/Maps/InvalidityDate.php | 26 + .../File/ASN1/Maps/IssuerAltName.php | 24 + .../ASN1/Maps/IssuingDistributionPoint.php | 68 + .../File/ASN1/Maps/KeyIdentifier.php | 26 + .../phpseclib/File/ASN1/Maps/KeyPurposeId.php | 26 + .../phpseclib/File/ASN1/Maps/KeyUsage.php | 39 + .../File/ASN1/Maps/MaskGenAlgorithm.php | 24 + .../phpseclib/File/ASN1/Maps/Name.php | 31 + .../File/ASN1/Maps/NameConstraints.php | 40 + .../File/ASN1/Maps/NetworkAddress.php | 26 + .../File/ASN1/Maps/NoticeReference.php | 37 + .../File/ASN1/Maps/NumericUserIdentifier.php | 26 + .../phpseclib/File/ASN1/Maps/ORAddress.php | 33 + .../File/ASN1/Maps/OneAsymmetricKey.php | 48 + .../File/ASN1/Maps/OrganizationName.php | 26 + .../ASN1/Maps/OrganizationalUnitNames.php | 31 + .../File/ASN1/Maps/OtherPrimeInfo.php | 34 + .../File/ASN1/Maps/OtherPrimeInfos.php | 32 + .../phpseclib/File/ASN1/Maps/PBEParameter.php | 34 + .../phpseclib/File/ASN1/Maps/PBES2params.php | 34 + .../phpseclib/File/ASN1/Maps/PBKDF2params.php | 41 + .../phpseclib/File/ASN1/Maps/PBMAC1params.php | 34 + .../phpseclib/File/ASN1/Maps/PKCS9String.php | 32 + .../phpseclib/File/ASN1/Maps/Pentanomial.php | 33 + .../phpseclib/File/ASN1/Maps/PersonalName.php | 54 + .../File/ASN1/Maps/PolicyInformation.php | 38 + .../File/ASN1/Maps/PolicyMappings.php | 37 + .../File/ASN1/Maps/PolicyQualifierId.php | 26 + .../File/ASN1/Maps/PolicyQualifierInfo.php | 32 + .../File/ASN1/Maps/PostalAddress.php | 32 + .../phpseclib/File/ASN1/Maps/Prime_p.php | 26 + .../File/ASN1/Maps/PrivateDomainName.php | 32 + .../phpseclib/File/ASN1/Maps/PrivateKey.php | 26 + .../File/ASN1/Maps/PrivateKeyInfo.php | 41 + .../File/ASN1/Maps/PrivateKeyUsagePeriod.php | 40 + .../phpseclib/File/ASN1/Maps/PublicKey.php | 26 + .../File/ASN1/Maps/PublicKeyAndChallenge.php | 32 + .../File/ASN1/Maps/PublicKeyInfo.php | 35 + .../File/ASN1/Maps/RC2CBCParameter.php | 37 + .../phpseclib/File/ASN1/Maps/RDNSequence.php | 38 + .../File/ASN1/Maps/RSAPrivateKey.php | 44 + .../phpseclib/File/ASN1/Maps/RSAPublicKey.php | 32 + .../File/ASN1/Maps/RSASSA_PSS_params.php | 58 + .../phpseclib/File/ASN1/Maps/ReasonFlags.php | 39 + .../ASN1/Maps/RelativeDistinguishedName.php | 37 + .../File/ASN1/Maps/RevokedCertificate.php | 35 + .../ASN1/Maps/SignedPublicKeyAndChallenge.php | 33 + .../File/ASN1/Maps/SpecifiedECDomain.php | 45 + .../File/ASN1/Maps/SubjectAltName.php | 24 + .../ASN1/Maps/SubjectDirectoryAttributes.php | 31 + .../ASN1/Maps/SubjectInfoAccessSyntax.php | 31 + .../File/ASN1/Maps/SubjectPublicKeyInfo.php | 32 + .../phpseclib/File/ASN1/Maps/TBSCertList.php | 54 + .../File/ASN1/Maps/TBSCertificate.php | 65 + .../File/ASN1/Maps/TerminalIdentifier.php | 26 + .../phpseclib/File/ASN1/Maps/Time.php | 32 + .../phpseclib/File/ASN1/Maps/Trinomial.php | 26 + .../File/ASN1/Maps/UniqueIdentifier.php | 26 + .../phpseclib/File/ASN1/Maps/UserNotice.php | 38 + .../phpseclib/File/ASN1/Maps/Validity.php | 32 + .../File/ASN1/Maps/netscape_ca_policy_url.php | 26 + .../File/ASN1/Maps/netscape_cert_type.php | 40 + .../File/ASN1/Maps/netscape_comment.php | 26 + .../phpseclib/phpseclib/File/X509.php | 4006 ++++++++++++ .../phpseclib/phpseclib/Math/BigInteger.php | 892 +++ .../Math/BigInteger/Engines/BCMath.php | 697 +++ .../Math/BigInteger/Engines/BCMath/Base.php | 110 + .../BigInteger/Engines/BCMath/BuiltIn.php | 40 + .../Engines/BCMath/DefaultEngine.php | 25 + .../BigInteger/Engines/BCMath/OpenSSL.php | 25 + .../Engines/BCMath/Reductions/Barrett.php | 187 + .../Engines/BCMath/Reductions/EvalBarrett.php | 108 + .../Math/BigInteger/Engines/Engine.php | 1285 ++++ .../phpseclib/Math/BigInteger/Engines/GMP.php | 694 +++ .../BigInteger/Engines/GMP/DefaultEngine.php | 40 + .../Math/BigInteger/Engines/OpenSSL.php | 68 + .../phpseclib/Math/BigInteger/Engines/PHP.php | 1344 ++++ .../Math/BigInteger/Engines/PHP/Base.php | 143 + .../BigInteger/Engines/PHP/DefaultEngine.php | 25 + .../BigInteger/Engines/PHP/Montgomery.php | 89 + .../Math/BigInteger/Engines/PHP/OpenSSL.php | 25 + .../Engines/PHP/Reductions/Barrett.php | 281 + .../Engines/PHP/Reductions/Classic.php | 42 + .../Engines/PHP/Reductions/EvalBarrett.php | 484 ++ .../Engines/PHP/Reductions/Montgomery.php | 126 + .../Engines/PHP/Reductions/MontgomeryMult.php | 76 + .../Engines/PHP/Reductions/PowerOfTwo.php | 59 + .../Math/BigInteger/Engines/PHP32.php | 371 ++ .../Math/BigInteger/Engines/PHP64.php | 372 ++ .../phpseclib/phpseclib/Math/BinaryField.php | 203 + .../phpseclib/Math/BinaryField/Integer.php | 516 ++ .../phpseclib/Math/Common/FiniteField.php | 22 + .../Math/Common/FiniteField/Integer.php | 44 + .../phpseclib/phpseclib/Math/PrimeField.php | 118 + .../phpseclib/Math/PrimeField/Integer.php | 419 ++ .../phpseclib/phpseclib/Net/SFTP.php | 3547 +++++++++++ .../phpseclib/phpseclib/Net/SFTP/Stream.php | 756 +++ .../phpseclib/phpseclib/Net/SSH2.php | 5397 +++++++++++++++++ .../phpseclib/phpseclib/System/SSH/Agent.php | 286 + .../phpseclib/System/SSH/Agent/Identity.php | 320 + .../System/SSH/Common/Traits/ReadBytes.php | 37 + .../phpseclib/phpseclib/bootstrap.php | 22 + .../phpseclib/phpseclib/phpseclib/openssl.cnf | 6 + .../php/vendor/sop/asn1/LICENSE | 21 + .../php/vendor/sop/asn1/README.md | 103 + .../php/vendor/sop/asn1/composer.json | 34 + .../asn1/lib/ASN1/Component/Identifier.php | 290 + .../sop/asn1/lib/ASN1/Component/Length.php | 225 + .../php/vendor/sop/asn1/lib/ASN1/DERData.php | 89 + .../php/vendor/sop/asn1/lib/ASN1/Element.php | 465 ++ .../lib/ASN1/Exception/DecodeException.php | 12 + .../sop/asn1/lib/ASN1/Feature/ElementBase.php | 84 + .../sop/asn1/lib/ASN1/Feature/Encodable.php | 16 + .../sop/asn1/lib/ASN1/Feature/Stringable.php | 21 + .../sop/asn1/lib/ASN1/Type/BaseString.php | 59 + .../sop/asn1/lib/ASN1/Type/BaseTime.php | 107 + .../Type/Constructed/ConstructedString.php | 131 + .../lib/ASN1/Type/Constructed/Sequence.php | 25 + .../asn1/lib/ASN1/Type/Constructed/Set.php | 63 + .../lib/ASN1/Type/Primitive/BMPString.php | 40 + .../lib/ASN1/Type/Primitive/BitString.php | 201 + .../asn1/lib/ASN1/Type/Primitive/Boolean.php | 73 + .../ASN1/Type/Primitive/CharacterString.php | 25 + .../sop/asn1/lib/ASN1/Type/Primitive/EOC.php | 54 + .../lib/ASN1/Type/Primitive/Enumerated.php | 22 + .../lib/ASN1/Type/Primitive/GeneralString.php | 34 + .../ASN1/Type/Primitive/GeneralizedTime.php | 125 + .../lib/ASN1/Type/Primitive/GraphicString.php | 34 + .../lib/ASN1/Type/Primitive/IA5String.php | 33 + .../asn1/lib/ASN1/Type/Primitive/Integer.php | 105 + .../asn1/lib/ASN1/Type/Primitive/NullType.php | 54 + .../lib/ASN1/Type/Primitive/NumericString.php | 33 + .../ASN1/Type/Primitive/ObjectDescriptor.php | 33 + .../ASN1/Type/Primitive/ObjectIdentifier.php | 207 + .../lib/ASN1/Type/Primitive/OctetString.php | 25 + .../ASN1/Type/Primitive/PrintableString.php | 34 + .../sop/asn1/lib/ASN1/Type/Primitive/Real.php | 698 +++ .../lib/ASN1/Type/Primitive/RelativeOID.php | 48 + .../lib/ASN1/Type/Primitive/T61String.php | 35 + .../asn1/lib/ASN1/Type/Primitive/UTCTime.php | 83 + .../lib/ASN1/Type/Primitive/UTF8String.php | 35 + .../ASN1/Type/Primitive/UniversalString.php | 39 + .../ASN1/Type/Primitive/VideotexString.php | 34 + .../lib/ASN1/Type/Primitive/VisibleString.php | 33 + .../asn1/lib/ASN1/Type/PrimitiveString.php | 53 + .../sop/asn1/lib/ASN1/Type/PrimitiveType.php | 19 + .../sop/asn1/lib/ASN1/Type/StringType.php | 16 + .../sop/asn1/lib/ASN1/Type/Structure.php | 384 ++ .../lib/ASN1/Type/Tagged/ApplicationType.php | 12 + .../ASN1/Type/Tagged/ContextSpecificType.php | 12 + .../lib/ASN1/Type/Tagged/DERTaggedType.php | 156 + .../lib/ASN1/Type/Tagged/ExplicitTagging.php | 19 + .../ASN1/Type/Tagged/ExplicitlyTaggedType.php | 58 + .../lib/ASN1/Type/Tagged/ImplicitTagging.php | 25 + .../ASN1/Type/Tagged/ImplicitlyTaggedType.php | 68 + .../asn1/lib/ASN1/Type/Tagged/PrivateType.php | 12 + .../lib/ASN1/Type/Tagged/TaggedTypeWrap.php | 35 + .../sop/asn1/lib/ASN1/Type/TaggedType.php | 84 + .../sop/asn1/lib/ASN1/Type/TimeType.php | 16 + .../sop/asn1/lib/ASN1/Type/UniversalClass.php | 21 + .../asn1/lib/ASN1/Type/UnspecifiedType.php | 674 ++ .../vendor/sop/asn1/lib/ASN1/Util/BigInt.php | 218 + .../vendor/sop/asn1/lib/ASN1/Util/Flags.php | 144 + .../php/vendor/sop/crypto-encoding/LICENSE | 21 + .../php/vendor/sop/crypto-encoding/README.md | 24 + .../vendor/sop/crypto-encoding/composer.json | 31 + .../lib/CryptoEncoding/PEM.php | 145 + .../lib/CryptoEncoding/PEMBundle.php | 173 + .../php/vendor/sop/crypto-types/LICENSE | 21 + .../php/vendor/sop/crypto-types/README.md | 42 + .../php/vendor/sop/crypto-types/composer.json | 39 + .../AlgorithmIdentifier.php | 116 + .../AlgorithmIdentifierFactory.php | 119 + .../AlgorithmIdentifierProvider.php | 35 + .../ECPublicKeyAlgorithmIdentifier.php | 303 + .../Asymmetric/Ed25519AlgorithmIdentifier.php | 44 + .../Asymmetric/Ed448AlgorithmIdentifier.php | 44 + .../RFC8410EdAlgorithmIdentifier.php | 59 + .../RFC8410XAlgorithmIdentifier.php | 53 + .../RSAEncryptionAlgorithmIdentifier.php | 68 + .../Asymmetric/X25519AlgorithmIdentifier.php | 29 + .../Asymmetric/X448AlgorithmIdentifier.php | 29 + .../Cipher/AES128CBCAlgorithmIdentifier.php | 42 + .../Cipher/AES192CBCAlgorithmIdentifier.php | 42 + .../Cipher/AES256CBCAlgorithmIdentifier.php | 42 + .../Cipher/AESCBCAlgorithmIdentifier.php | 82 + .../Cipher/BlockCipherAlgorithmIdentifier.php | 16 + .../Cipher/CipherAlgorithmIdentifier.php | 65 + .../Cipher/DESCBCAlgorithmIdentifier.php | 98 + .../Cipher/DESEDE3CBCAlgorithmIdentifier.php | 99 + .../Cipher/RC2CBCAlgorithmIdentifier.php | 215 + .../Feature/AlgorithmIdentifierType.php | 30 + .../AsymmetricCryptoAlgorithmIdentifier.php | 12 + .../Feature/EncryptionAlgorithmIdentifier.php | 12 + .../Feature/HashAlgorithmIdentifier.php | 12 + .../Feature/PRFAlgorithmIdentifier.php | 12 + .../Feature/SignatureAlgorithmIdentifier.php | 18 + .../GenericAlgorithmIdentifier.php | 57 + .../Hash/HMACWithSHA1AlgorithmIdentifier.php | 66 + .../HMACWithSHA224AlgorithmIdentifier.php | 29 + .../HMACWithSHA256AlgorithmIdentifier.php | 29 + .../HMACWithSHA384AlgorithmIdentifier.php | 29 + .../HMACWithSHA512AlgorithmIdentifier.php | 29 + .../Hash/MD5AlgorithmIdentifier.php | 85 + .../Hash/RFC4231HMACAlgorithmIdentifier.php | 56 + .../Hash/SHA1AlgorithmIdentifier.php | 81 + .../Hash/SHA224AlgorithmIdentifier.php | 33 + .../Hash/SHA256AlgorithmIdentifier.php | 32 + .../Hash/SHA2AlgorithmIdentifier.php | 71 + .../Hash/SHA384AlgorithmIdentifier.php | 32 + .../Hash/SHA512AlgorithmIdentifier.php | 32 + .../ECDSAWithSHA1AlgorithmIdentifier.php | 29 + .../ECDSAWithSHA224AlgorithmIdentifier.php | 29 + .../ECDSAWithSHA256AlgorithmIdentifier.php | 29 + .../ECDSAWithSHA384AlgorithmIdentifier.php | 29 + .../ECDSAWithSHA512AlgorithmIdentifier.php | 29 + .../ECSignatureAlgorithmIdentifier.php | 59 + ...D2WithRSAEncryptionAlgorithmIdentifier.php | 29 + ...D4WithRSAEncryptionAlgorithmIdentifier.php | 29 + ...D5WithRSAEncryptionAlgorithmIdentifier.php | 29 + ...RFC3279RSASignatureAlgorithmIdentifier.php | 51 + ...RFC4055RSASignatureAlgorithmIdentifier.php | 65 + .../RSASignatureAlgorithmIdentifier.php | 23 + ...A1WithRSAEncryptionAlgorithmIdentifier.php | 29 + ...24WithRSAEncryptionAlgorithmIdentifier.php | 30 + ...56WithRSAEncryptionAlgorithmIdentifier.php | 30 + ...84WithRSAEncryptionAlgorithmIdentifier.php | 30 + ...12WithRSAEncryptionAlgorithmIdentifier.php | 30 + .../SignatureAlgorithmIdentifierFactory.php | 105 + .../SpecificAlgorithmIdentifier.php | 30 + .../Attribute/OneAsymmetricKeyAttributes.php | 15 + .../Asymmetric/EC/ECConversion.php | 112 + .../Asymmetric/EC/ECPrivateKey.php | 223 + .../CryptoTypes/Asymmetric/EC/ECPublicKey.php | 222 + .../Asymmetric/OneAsymmetricKey.php | 359 ++ .../lib/CryptoTypes/Asymmetric/PrivateKey.php | 74 + .../CryptoTypes/Asymmetric/PrivateKeyInfo.php | 33 + .../lib/CryptoTypes/Asymmetric/PublicKey.php | 60 + .../CryptoTypes/Asymmetric/PublicKeyInfo.php | 197 + .../Curve25519/Curve25519PrivateKey.php | 34 + .../Curve25519/Curve25519PublicKey.php | 29 + .../RFC8410/Curve25519/Ed25519PrivateKey.php | 36 + .../RFC8410/Curve25519/Ed25519PublicKey.php | 24 + .../RFC8410/Curve25519/X25519PrivateKey.php | 36 + .../RFC8410/Curve25519/X25519PublicKey.php | 24 + .../RFC8410/Curve448/Ed448PrivateKey.php | 56 + .../RFC8410/Curve448/Ed448PublicKey.php | 39 + .../RFC8410/Curve448/X448PrivateKey.php | 56 + .../RFC8410/Curve448/X448PublicKey.php | 39 + .../Asymmetric/RFC8410/RFC8410PrivateKey.php | 142 + .../Asymmetric/RFC8410/RFC8410PublicKey.php | 52 + .../Asymmetric/RSA/RSAPrivateKey.php | 286 + .../Asymmetric/RSA/RSAPublicKey.php | 147 + .../lib/CryptoTypes/Signature/ECSignature.php | 108 + .../Signature/Ed25519Signature.php | 44 + .../CryptoTypes/Signature/Ed448Signature.php | 44 + .../Signature/GenericSignature.php | 56 + .../CryptoTypes/Signature/RSASignature.php | 58 + .../lib/CryptoTypes/Signature/Signature.php | 49 + .../php/vendor/sop/x501/LICENSE | 21 + .../php/vendor/sop/x501/README.md | 26 + .../php/vendor/sop/x501/composer.json | 38 + .../sop/x501/lib/X501/ASN1/Attribute.php | 176 + .../sop/x501/lib/X501/ASN1/AttributeType.php | 457 ++ .../lib/X501/ASN1/AttributeTypeAndValue.php | 128 + .../ASN1/AttributeValue/AttributeValue.php | 174 + .../ASN1/AttributeValue/CommonNameValue.php | 29 + .../ASN1/AttributeValue/CountryNameValue.php | 27 + .../ASN1/AttributeValue/DescriptionValue.php | 29 + .../Feature/DirectoryString.php | 179 + .../Feature/PrintableStringValue.php | 88 + .../ASN1/AttributeValue/GivenNameValue.php | 29 + .../ASN1/AttributeValue/LocalityNameValue.php | 29 + .../X501/ASN1/AttributeValue/NameValue.php | 29 + .../AttributeValue/OrganizationNameValue.php | 29 + .../OrganizationalUnitNameValue.php | 29 + .../ASN1/AttributeValue/PseudonymValue.php | 29 + .../ASN1/AttributeValue/SerialNumberValue.php | 27 + .../StateOrProvinceNameValue.php | 29 + .../X501/ASN1/AttributeValue/SurnameValue.php | 29 + .../X501/ASN1/AttributeValue/TitleValue.php | 29 + .../AttributeValue/UnknownAttributeValue.php | 75 + .../ASN1/Collection/AttributeCollection.php | 221 + .../ASN1/Collection/SequenceOfAttributes.php | 44 + .../X501/ASN1/Collection/SetOfAttributes.php | 45 + .../lib/X501/ASN1/Feature/TypedAttribute.php | 40 + .../vendor/sop/x501/lib/X501/ASN1/Name.php | 227 + .../php/vendor/sop/x501/lib/X501/ASN1/RDN.php | 187 + .../vendor/sop/x501/lib/X501/DN/DNParser.php | 428 ++ .../lib/X501/MatchingRule/BinaryMatch.php | 21 + .../lib/X501/MatchingRule/CaseExactMatch.php | 25 + .../lib/X501/MatchingRule/CaseIgnoreMatch.php | 26 + .../lib/X501/MatchingRule/MatchingRule.php | 24 + .../MatchingRule/StringPrepMatchingRule.php | 40 + .../lib/X501/StringPrep/CheckBidiStep.php | 25 + .../InsignificantNonSubstringSpaceStep.php | 35 + .../sop/x501/lib/X501/StringPrep/MapStep.php | 45 + .../lib/X501/StringPrep/NormalizeStep.php | 24 + .../x501/lib/X501/StringPrep/PrepareStep.php | 23 + .../x501/lib/X501/StringPrep/ProhibitStep.php | 27 + .../lib/X501/StringPrep/StringPreparer.php | 87 + .../lib/X501/StringPrep/TranscodeStep.php | 66 + .../vendor/symfony/polyfill-ctype/Ctype.php | 232 + .../php/vendor/symfony/polyfill-ctype/LICENSE | 19 + .../vendor/symfony/polyfill-ctype/README.md | 12 + .../symfony/polyfill-ctype/bootstrap.php | 50 + .../symfony/polyfill-ctype/bootstrap80.php | 46 + .../symfony/polyfill-ctype/composer.json | 41 + .../vendor/symfony/polyfill-mbstring/LICENSE | 19 + .../symfony/polyfill-mbstring/Mbstring.php | 947 +++ .../symfony/polyfill-mbstring/README.md | 13 + .../Resources/unidata/caseFolding.php | 119 + .../Resources/unidata/lowerCase.php | 1397 +++++ .../Resources/unidata/titleCaseRegexp.php | 5 + .../Resources/unidata/upperCase.php | 1489 +++++ .../symfony/polyfill-mbstring/bootstrap.php | 151 + .../symfony/polyfill-mbstring/bootstrap80.php | 147 + .../symfony/polyfill-mbstring/composer.json | 41 + .../php/vendor/symfony/polyfill-php80/LICENSE | 19 + .../vendor/symfony/polyfill-php80/Php80.php | 115 + .../symfony/polyfill-php80/PhpToken.php | 103 + .../vendor/symfony/polyfill-php80/README.md | 25 + .../Resources/stubs/Attribute.php | 31 + .../Resources/stubs/PhpToken.php | 16 + .../Resources/stubs/Stringable.php | 20 + .../Resources/stubs/UnhandledMatchError.php | 16 + .../Resources/stubs/ValueError.php | 16 + .../symfony/polyfill-php80/bootstrap.php | 42 + .../symfony/polyfill-php80/composer.json | 40 + .../php/vendor/vlucas/phpdotenv/LICENSE | 30 + .../php/vendor/vlucas/phpdotenv/composer.json | 60 + .../vendor/vlucas/phpdotenv/src/Dotenv.php | 267 + .../src/Exception/ExceptionInterface.php | 12 + .../Exception/InvalidEncodingException.php | 12 + .../src/Exception/InvalidFileException.php | 12 + .../src/Exception/InvalidPathException.php | 12 + .../src/Exception/ValidationException.php | 12 + .../vlucas/phpdotenv/src/Loader/Loader.php | 47 + .../phpdotenv/src/Loader/LoaderInterface.php | 20 + .../vlucas/phpdotenv/src/Loader/Resolver.php | 65 + .../vlucas/phpdotenv/src/Parser/Entry.php | 59 + .../phpdotenv/src/Parser/EntryParser.php | 300 + .../vlucas/phpdotenv/src/Parser/Lexer.php | 58 + .../vlucas/phpdotenv/src/Parser/Lines.php | 127 + .../vlucas/phpdotenv/src/Parser/Parser.php | 53 + .../phpdotenv/src/Parser/ParserInterface.php | 19 + .../vlucas/phpdotenv/src/Parser/Value.php | 88 + .../Repository/Adapter/AdapterInterface.php | 15 + .../src/Repository/Adapter/ApacheAdapter.php | 89 + .../src/Repository/Adapter/ArrayAdapter.php | 80 + .../Repository/Adapter/EnvConstAdapter.php | 89 + .../src/Repository/Adapter/GuardedWriter.php | 85 + .../Repository/Adapter/ImmutableWriter.php | 110 + .../src/Repository/Adapter/MultiReader.php | 48 + .../src/Repository/Adapter/MultiWriter.php | 64 + .../src/Repository/Adapter/PutenvAdapter.php | 91 + .../Repository/Adapter/ReaderInterface.php | 17 + .../Repository/Adapter/ReplacingWriter.php | 104 + .../Repository/Adapter/ServerConstAdapter.php | 89 + .../Repository/Adapter/WriterInterface.php | 27 + .../src/Repository/AdapterRepository.php | 107 + .../src/Repository/RepositoryBuilder.php | 272 + .../src/Repository/RepositoryInterface.php | 51 + .../vlucas/phpdotenv/src/Store/File/Paths.php | 44 + .../phpdotenv/src/Store/File/Reader.php | 81 + .../vlucas/phpdotenv/src/Store/FileStore.php | 72 + .../phpdotenv/src/Store/StoreBuilder.php | 141 + .../phpdotenv/src/Store/StoreInterface.php | 17 + .../phpdotenv/src/Store/StringStore.php | 37 + .../vlucas/phpdotenv/src/Util/Regex.php | 112 + .../vendor/vlucas/phpdotenv/src/Util/Str.php | 98 + .../vendor/vlucas/phpdotenv/src/Validator.php | 209 + 661 files changed, 91364 insertions(+) create mode 100644 utilities/signing_and_verification/php/.gitignore create mode 100644 utilities/signing_and_verification/php/composer.json create mode 100644 utilities/signing_and_verification/php/composer.lock create mode 100644 utilities/signing_and_verification/php/src/.env create mode 100644 utilities/signing_and_verification/php/src/index.php create mode 100644 utilities/signing_and_verification/php/vendor/autoload.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/ClassLoader.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_files.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_psr4.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_real.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_static.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/installed.json create mode 100644 utilities/signing_and_verification/php/vendor/composer/installed.php create mode 100644 utilities/signing_and_verification/php/vendor/composer/platform_check.php create mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php create mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php create mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/EncoderInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Encoding.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Hex.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE create mode 100755 utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/other/build_phar.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php create mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm.xml create mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php create mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php create mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php create mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php create mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/README.md create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Feature/ElementBase.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Feature/Encodable.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Feature/Stringable.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/StringType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Structure.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ContextSpecificType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/DERTaggedType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitlyTaggedType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitlyTaggedType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/TaggedTypeWrap.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/UniversalClass.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/UnspecifiedType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/ECPublicKeyAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410XAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/CipherAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AsymmetricCryptoAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/EncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/HashAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/PRFAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/SignatureAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/GenericAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/Attribute/OneAsymmetricKeyAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECConversion.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/README.md create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/CaseExactMatch.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/CaseIgnoreMatch.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/StringPrepMatchingRule.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/InsignificantNonSubstringSpaceStep.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/MapStep.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/PrepareStep.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/ProhibitStep.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/StringPreparer.php create mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php create mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Loader.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Value.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/File/Paths.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/File/Reader.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StringStore.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php create mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php diff --git a/utilities/signing_and_verification/php/.gitignore b/utilities/signing_and_verification/php/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/utilities/signing_and_verification/php/composer.json b/utilities/signing_and_verification/php/composer.json new file mode 100644 index 0000000..3e6e13a --- /dev/null +++ b/utilities/signing_and_verification/php/composer.json @@ -0,0 +1,14 @@ +{ + "name": "charnpreet/signver", + "type": "project", + "autoload": { + "psr-4": { + "Charnpreet\\Signver\\": "src/" + } + }, + "require": { + "vlucas/phpdotenv": "^5.6", + "sop/crypto-types": "dev-master", + "phpseclib/phpseclib": "^3.0" + } +} diff --git a/utilities/signing_and_verification/php/composer.lock b/utilities/signing_and_verification/php/composer.lock new file mode 100644 index 0000000..1b0e924 --- /dev/null +++ b/utilities/signing_and_verification/php/composer.lock @@ -0,0 +1,940 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "eec5a6c56eb5dcc64208c9c65fac635b", + "packages": [ + { + "name": "graham-campbell/result-type", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:16:48+00:00" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "type": "library", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "time": "2022-06-14T06:56:20+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.2", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2023-11-12T21:59:55+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.35", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.35" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2023-12-29T01:59:53+00:00" + }, + { + "name": "sop/asn1", + "version": "4.1.1", + "source": { + "type": "git", + "url": "https://github.com/sop/asn1.git", + "reference": "074efe8f7c353c54edc809ac3d74efda83edd776" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/asn1/zipball/074efe8f7c353c54edc809ac3d74efda83edd776", + "reference": "074efe8f7c353c54edc809ac3d74efda83edd776", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "ext-mbstring": "*", + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sop\\ASN1\\": "lib/ASN1/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP library for X.690 ASN.1 DER encoding and decoding.", + "homepage": "https://github.com/sop/asn1", + "keywords": [ + "DER", + "asn.1", + "asn1", + "x.690", + "x690" + ], + "support": { + "issues": "https://github.com/sop/asn1/issues", + "source": "https://github.com/sop/asn1/tree/4.1.1" + }, + "time": "2022-02-17T07:08:51+00:00" + }, + { + "name": "sop/crypto-encoding", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/sop/crypto-encoding.git", + "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/crypto-encoding/zipball/07537353e1b0e76c382a58a9c6e041b7c7dc9052", + "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP implementation of textual encodings of cryptographic structures.", + "homepage": "https://github.com/sop/crypto-encoding", + "keywords": [ + "Private Key", + "certificate", + "pem", + "public key" + ], + "support": { + "issues": "https://github.com/sop/crypto-encoding/issues", + "source": "https://github.com/sop/crypto-encoding/tree/master" + }, + "time": "2019-05-22T11:46:12+00:00" + }, + { + "name": "sop/crypto-types", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sop/crypto-types.git", + "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/crypto-types/zipball/92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", + "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "php": ">=7.2", + "sop/asn1": "^4.0.0", + "sop/crypto-encoding": "^0.3.0", + "sop/x501": "0.6.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Sop\\CryptoTypes\\": "lib/CryptoTypes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP library of various ASN.1 types for cryptographic applications.", + "homepage": "https://github.com/sop/crypto-types", + "keywords": [ + "Private Key", + "algorithm identifier", + "asn1", + "cryptography", + "ec", + "public key", + "rsa", + "signature" + ], + "support": { + "issues": "https://github.com/sop/crypto-types/issues", + "source": "https://github.com/sop/crypto-types/tree/master" + }, + "time": "2021-08-11T06:56:21+00:00" + }, + { + "name": "sop/x501", + "version": "0.6.1", + "source": { + "type": "git", + "url": "https://github.com/sop/x501.git", + "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/x501/zipball/7978bfac25ff73c4c20bed0794d4d88cca8f6895", + "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895", + "shasum": "" + }, + "require": { + "ext-intl": "*", + "ext-mbstring": "*", + "php": ">=7.2", + "sop/asn1": "^4.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Sop\\X501\\": "lib/X501/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP library for X.501 ASN.1 types, X.520 attributes and DN parsing.", + "homepage": "https://github.com/sop/x501", + "keywords": [ + "attribute", + "dn", + "ldap", + "rdn", + "x.501", + "x.520", + "x501", + "x520" + ], + "support": { + "issues": "https://github.com/sop/x501/issues", + "source": "https://github.com/sop/x501/tree/0.6.1" + }, + "time": "2019-06-27T10:30:28+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-07-28T09:04:16+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2023-01-26T09:26:14+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2023-11-12T22:43:29+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "sop/crypto-types": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "plugin-api-version": "2.6.0" +} diff --git a/utilities/signing_and_verification/php/src/.env b/utilities/signing_and_verification/php/src/.env new file mode 100644 index 0000000..0bb1ff8 --- /dev/null +++ b/utilities/signing_and_verification/php/src/.env @@ -0,0 +1,4 @@ +PRIVATE_KEY="3LFlZAAuAMyppOq35pGz1b6ujlX4PAcEuGmMe6ONGuqyx2kXoC1/oh/VzDUzVSMdCqx2yZ3wtqTuoAvN58U5xg==" +PUBLIC_KEY="ssdpF6Atf6If1cw1M1UjHQqsdsmd8Lak7qALzefFOcY=" +SUBSCRIBER_ID="subscriber_id" +UNIQUE_KEY_ID="ukid" \ No newline at end of file diff --git a/utilities/signing_and_verification/php/src/index.php b/utilities/signing_and_verification/php/src/index.php new file mode 100644 index 0000000..fe84563 --- /dev/null +++ b/utilities/signing_and_verification/php/src/index.php @@ -0,0 +1,135 @@ +load(); + +function hash_msg(string $msg): string{ + return base64_encode(sodium_crypto_generichash($msg,"",64)); +} + +function create_signing_string(string $digest_base64, string $created=null, string $expires=null): string { + $now = new DateTime(); + $one_hour = new DateInterval("PT1H"); + + + if ($created == null) { + $created = $now->getTimestamp(); + } + + if ($expires == null) { + $expires = $now->add($one_hour)->getTimestamp(); + } + + $signing_string = "(created): $created\n(expires): $expires\ndigest: BLAKE-512=$digest_base64"; + return $signing_string; +} + +function sign_response(string $signing_key, string $private_key): string { + return base64_encode(sodium_crypto_sign_detached($signing_key, base64_decode($private_key))); +} + +function verify_response(string $signature, string $signing_key, string $public_key): bool { + return sodium_crypto_sign_verify_detached(base64_decode($signature), $signing_key, base64_decode($public_key)); +} + +function create_authorisation_header(string $request_body, string $created=null, string $expires=null) { + $now = new DateTime(); + $one_hour = new DateInterval("PT1H"); + + if($created == null) { + $created = $now->getTimestamp(); + } + + if($expires == null) { + $expires = $now->add($one_hour)->getTimeStamp(); + } + + $signing_key = create_signing_string(hash_msg($request_body), $created, $expires); + $signature = sign_response($signing_key, $_ENV['PRIVATE_KEY']); + + $subscriber_id = $_ENV['SUBSCRIBER_ID']; + $unique_key_id = $_ENV['UNIQUE_KEY_ID']; + + $header = "Signature keyId=\"$subscriber_id|$unique_key_id|ed25519\",algorithm=\"ed25519\",created=\"$created\",expires=\"$expires\",headers=\"($created) ($expires) digest\",signature=\"$signature\""; + return $header; +} + +// util +function get_filter_dict(string $filter_string) { + $filter_string_list = preg_split("/,/", $filter_string); + $filter_string_list = array_map(function($item) { return trim($item, " \n\r\t\v\0\""); }, $filter_string_list); + $filter_string_dict = []; + foreach($filter_string_list as $item) { + $split_item = preg_split("/=/", $item, 2); + $filter_string_dict[$split_item[0]] = trim($split_item[1], " \n\r\t\v\0\""); + } + return $filter_string_dict; +} + +function verify_authorisation_header(string $auth_header, string $request_body_str, string $public_key): bool { + $auth_header = str_replace("Signature ", "", $auth_header); + $header_parts = get_filter_dict($auth_header); + $created = (int) $header_parts["created"]; + $expires = (int) $header_parts["expires"]; + + $now = new DateTime(); + if ($created <= $now->getTimestamp() && $expires >= $now->getTimestamp()) { + $signing_key = create_signing_string(hash_msg($request_body_str), $created, $expires); + return verify_response($header_parts['signature'], $signing_key, $public_key); + } + return false; +} + +function gen_keys() { + $signkeypair = sodium_crypto_sign_keypair(); + $signprivkey = sodium_crypto_sign_secretkey($signkeypair); + $signpubkey = sodium_crypto_sign_publickey($signkeypair); + + // using libsodium + $enckeypair = sodium_crypto_box_keypair(); + $encprivkey = sodium_crypto_box_secretkey($enckeypair); + $encpubkey = sodium_crypto_box_publickey($enckeypair); + + // $openssl = openssl_pkey_get_private($encprivkey); + + echo "Encryption priv key: ", base64_encode($encprivkey), "\n"; + $encprivkey = new OneAsymmetricKey(new X25519AlgorithmIdentifier(), "\x04\x20".$encprivkey); + $encpubkey = new PublicKeyInfo(new X25519AlgorithmIdentifier(), new BitString($encpubkey)); + + echo "Signing priv key: ", base64_encode($signprivkey), "\n"; + echo "Signing pub key: ", base64_encode($signpubkey), "\n"; + echo "Encryption priv key: ", base64_encode($encprivkey->toDER()), "\n"; + echo "Encryption pub key: ", base64_encode($encpubkey->toDER()), "\n"; +} + +function encrypt(string $crypto_private_key, string $crypto_public_key, ?string $message=null): string { + $pkey = OneAsymmetricKey::fromDER(base64_decode($crypto_private_key)); + $pubkey = PublicKeyInfo::fromDER(base64_decode($crypto_public_key)); + $pkey = hex2bin(str_replace("0420","", bin2hex($pkey->privateKeyData()))); + $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); + $shpkey = sodium_crypto_box_secretkey($shkey); + + $cipher = new AES('ecb'); + $cipher->setKey($shpkey); + return base64_encode($cipher->encrypt($message == null ? 'ONDC is a great initiative!':$message)); +} + +function decrypt(string $crypto_private_key, string $crypto_public_key, string $cipher_text): string { + $pkey = OneAsymmetricKey::fromDER(base64_decode($crypto_private_key)); + $pubkey = PublicKeyInfo::fromDER(base64_decode($crypto_public_key)); + $pkey = hex2bin(str_replace("0420","", bin2hex($pkey->privateKeyData()))); + $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); + $shpkey = sodium_crypto_box_secretkey($shkey); + + $cipher = new AES('ecb'); + $cipher->setKey($shpkey); + return ($cipher->decrypt(base64_decode($cipher_text))); +} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/autoload.php b/utilities/signing_and_verification/php/vendor/autoload.php new file mode 100644 index 0000000..e8ac887 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/autoload.php @@ -0,0 +1,25 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see https://www.php-fig.org/psr/psr-0/ + * @see https://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + /** @var \Closure(string):void */ + private static $includeFile; + + /** @var string|null */ + private $vendorDir; + + // PSR-4 + /** + * @var array> + */ + private $prefixLengthsPsr4 = array(); + /** + * @var array> + */ + private $prefixDirsPsr4 = array(); + /** + * @var list + */ + private $fallbackDirsPsr4 = array(); + + // PSR-0 + /** + * List of PSR-0 prefixes + * + * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) + * + * @var array>> + */ + private $prefixesPsr0 = array(); + /** + * @var list + */ + private $fallbackDirsPsr0 = array(); + + /** @var bool */ + private $useIncludePath = false; + + /** + * @var array + */ + private $classMap = array(); + + /** @var bool */ + private $classMapAuthoritative = false; + + /** + * @var array + */ + private $missingClasses = array(); + + /** @var string|null */ + private $apcuPrefix; + + /** + * @var array + */ + private static $registeredLoaders = array(); + + /** + * @param string|null $vendorDir + */ + public function __construct($vendorDir = null) + { + $this->vendorDir = $vendorDir; + self::initializeIncludeClosure(); + } + + /** + * @return array> + */ + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + /** + * @return array> + */ + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + /** + * @return list + */ + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + /** + * @return list + */ + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + /** + * @return array Array of classname => path + */ + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + * + * @return void + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + * + * @return void + */ + public function add($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + $paths = (array) $paths; + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param list|string $paths The PSR-0 base directories + * + * @return void + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param list|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + * + * @return void + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + * + * @return void + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + * + * @return void + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + * + * @return void + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + * + * @return void + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + + if (null === $this->vendorDir) { + return; + } + + if ($prepend) { + self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; + } else { + unset(self::$registeredLoaders[$this->vendorDir]); + self::$registeredLoaders[$this->vendorDir] = $this; + } + } + + /** + * Unregisters this instance as an autoloader. + * + * @return void + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + + if (null !== $this->vendorDir) { + unset(self::$registeredLoaders[$this->vendorDir]); + } + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return true|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + $includeFile = self::$includeFile; + $includeFile($file); + + return true; + } + + return null; + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + /** + * Returns the currently registered loaders keyed by their corresponding vendor directories. + * + * @return array + */ + public static function getRegisteredLoaders() + { + return self::$registeredLoaders; + } + + /** + * @param string $class + * @param string $ext + * @return string|false + */ + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } + + /** + * @return void + */ + private static function initializeIncludeClosure() + { + if (self::$includeFile !== null) { + return; + } + + /** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + * + * @param string $file + * @return void + */ + self::$includeFile = \Closure::bind(static function($file) { + include $file; + }, null, null); + } +} diff --git a/utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php b/utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php new file mode 100644 index 0000000..51e734a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php @@ -0,0 +1,359 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer; + +use Composer\Autoload\ClassLoader; +use Composer\Semver\VersionParser; + +/** + * This class is copied in every Composer installed project and available to all + * + * See also https://getcomposer.org/doc/07-runtime.md#installed-versions + * + * To require its presence, you can require `composer-runtime-api ^2.0` + * + * @final + */ +class InstalledVersions +{ + /** + * @var mixed[]|null + * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null + */ + private static $installed; + + /** + * @var bool|null + */ + private static $canGetVendors; + + /** + * @var array[] + * @psalm-var array}> + */ + private static $installedByVendor = array(); + + /** + * Returns a list of all package names which are present, either by being installed, replaced or provided + * + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackages() + { + $packages = array(); + foreach (self::getInstalled() as $installed) { + $packages[] = array_keys($installed['versions']); + } + + if (1 === \count($packages)) { + return $packages[0]; + } + + return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); + } + + /** + * Returns a list of all package names with a specific type e.g. 'library' + * + * @param string $type + * @return string[] + * @psalm-return list + */ + public static function getInstalledPackagesByType($type) + { + $packagesByType = array(); + + foreach (self::getInstalled() as $installed) { + foreach ($installed['versions'] as $name => $package) { + if (isset($package['type']) && $package['type'] === $type) { + $packagesByType[] = $name; + } + } + } + + return $packagesByType; + } + + /** + * Checks whether the given package is installed + * + * This also returns true if the package name is provided or replaced by another package + * + * @param string $packageName + * @param bool $includeDevRequirements + * @return bool + */ + public static function isInstalled($packageName, $includeDevRequirements = true) + { + foreach (self::getInstalled() as $installed) { + if (isset($installed['versions'][$packageName])) { + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; + } + } + + return false; + } + + /** + * Checks whether the given package satisfies a version constraint + * + * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: + * + * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') + * + * @param VersionParser $parser Install composer/semver to have access to this class and functionality + * @param string $packageName + * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package + * @return bool + */ + public static function satisfies(VersionParser $parser, $packageName, $constraint) + { + $constraint = $parser->parseConstraints((string) $constraint); + $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); + + return $provided->matches($constraint); + } + + /** + * Returns a version constraint representing all the range(s) which are installed for a given package + * + * It is easier to use this via isInstalled() with the $constraint argument if you need to check + * whether a given version of a package is installed, and not just whether it exists + * + * @param string $packageName + * @return string Version constraint usable with composer/semver + */ + public static function getVersionRanges($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + $ranges = array(); + if (isset($installed['versions'][$packageName]['pretty_version'])) { + $ranges[] = $installed['versions'][$packageName]['pretty_version']; + } + if (array_key_exists('aliases', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); + } + if (array_key_exists('replaced', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); + } + if (array_key_exists('provided', $installed['versions'][$packageName])) { + $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); + } + + return implode(' || ', $ranges); + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['version'])) { + return null; + } + + return $installed['versions'][$packageName]['version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present + */ + public static function getPrettyVersion($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['pretty_version'])) { + return null; + } + + return $installed['versions'][$packageName]['pretty_version']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference + */ + public static function getReference($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + if (!isset($installed['versions'][$packageName]['reference'])) { + return null; + } + + return $installed['versions'][$packageName]['reference']; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @param string $packageName + * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. + */ + public static function getInstallPath($packageName) + { + foreach (self::getInstalled() as $installed) { + if (!isset($installed['versions'][$packageName])) { + continue; + } + + return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; + } + + throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); + } + + /** + * @return array + * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} + */ + public static function getRootPackage() + { + $installed = self::getInstalled(); + + return $installed[0]['root']; + } + + /** + * Returns the raw installed.php data for custom implementations + * + * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. + * @return array[] + * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} + */ + public static function getRawData() + { + @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + self::$installed = include __DIR__ . '/installed.php'; + } else { + self::$installed = array(); + } + } + + return self::$installed; + } + + /** + * Returns the raw data of all installed.php which are currently loaded for custom implementations + * + * @return array[] + * @psalm-return list}> + */ + public static function getAllRawData() + { + return self::getInstalled(); + } + + /** + * Lets you reload the static array from another file + * + * This is only useful for complex integrations in which a project needs to use + * this class but then also needs to execute another project's autoloader in process, + * and wants to ensure both projects have access to their version of installed.php. + * + * A typical case would be PHPUnit, where it would need to make sure it reads all + * the data it needs from this class, then call reload() with + * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure + * the project in which it runs can then also use this class safely, without + * interference between PHPUnit's dependencies and the project's dependencies. + * + * @param array[] $data A vendor/composer/installed.php data set + * @return void + * + * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data + */ + public static function reload($data) + { + self::$installed = $data; + self::$installedByVendor = array(); + } + + /** + * @return array[] + * @psalm-return list}> + */ + private static function getInstalled() + { + if (null === self::$canGetVendors) { + self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); + } + + $installed = array(); + + if (self::$canGetVendors) { + foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + if (isset(self::$installedByVendor[$vendorDir])) { + $installed[] = self::$installedByVendor[$vendorDir]; + } elseif (is_file($vendorDir.'/composer/installed.php')) { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require $vendorDir.'/composer/installed.php'; + $installed[] = self::$installedByVendor[$vendorDir] = $required; + if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { + self::$installed = $installed[count($installed) - 1]; + } + } + } + } + + if (null === self::$installed) { + // only require the installed.php file if this file is loaded from its dumped location, + // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 + if (substr(__DIR__, -8, 1) !== 'C') { + /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ + $required = require __DIR__ . '/installed.php'; + self::$installed = $required; + } else { + self::$installed = array(); + } + } + + if (self::$installed !== array()) { + $installed[] = self::$installed; + } + + return $installed; + } +} diff --git a/utilities/signing_and_verification/php/vendor/composer/LICENSE b/utilities/signing_and_verification/php/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/LICENSE @@ -0,0 +1,21 @@ + +Copyright (c) Nils Adermann, Jordi Boggiano + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php b/utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..5490b88 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php @@ -0,0 +1,15 @@ + $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', + 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', + 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', + 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', + 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', +); diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_files.php b/utilities/signing_and_verification/php/vendor/composer/autoload_files.php new file mode 100644 index 0000000..0ad6121 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/autoload_files.php @@ -0,0 +1,13 @@ + $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', + 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', +); diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php b/utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..15a2ff3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($vendorDir . '/phpseclib/phpseclib/phpseclib'), + 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), + 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Sop\\X501\\' => array($vendorDir . '/sop/x501/lib/X501'), + 'Sop\\CryptoTypes\\' => array($vendorDir . '/sop/crypto-types/lib/CryptoTypes'), + 'Sop\\CryptoEncoding\\' => array($vendorDir . '/sop/crypto-encoding/lib/CryptoEncoding'), + 'Sop\\ASN1\\' => array($vendorDir . '/sop/asn1/lib/ASN1'), + 'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'), + 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), + 'GrahamCampbell\\ResultType\\' => array($vendorDir . '/graham-campbell/result-type/src'), + 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), + 'Charnpreet\\Signver\\' => array($baseDir . '/src'), +); diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_real.php b/utilities/signing_and_verification/php/vendor/composer/autoload_real.php new file mode 100644 index 0000000..a97b0eb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/autoload_real.php @@ -0,0 +1,50 @@ +register(true); + + $filesToLoad = \Composer\Autoload\ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$files; + $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + + require $file; + } + }, null, null); + foreach ($filesToLoad as $fileIdentifier => $file) { + $requireFile($fileIdentifier, $file); + } + + return $loader; + } +} diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_static.php b/utilities/signing_and_verification/php/vendor/composer/autoload_static.php new file mode 100644 index 0000000..d811dba --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/autoload_static.php @@ -0,0 +1,123 @@ + __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', + 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', + 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'p' => + array ( + 'phpseclib3\\' => 11, + ), + 'S' => + array ( + 'Symfony\\Polyfill\\Php80\\' => 23, + 'Symfony\\Polyfill\\Mbstring\\' => 26, + 'Symfony\\Polyfill\\Ctype\\' => 23, + 'Sop\\X501\\' => 9, + 'Sop\\CryptoTypes\\' => 16, + 'Sop\\CryptoEncoding\\' => 19, + 'Sop\\ASN1\\' => 9, + ), + 'P' => + array ( + 'PhpOption\\' => 10, + 'ParagonIE\\ConstantTime\\' => 23, + ), + 'G' => + array ( + 'GrahamCampbell\\ResultType\\' => 26, + ), + 'D' => + array ( + 'Dotenv\\' => 7, + ), + 'C' => + array ( + 'Charnpreet\\Signver\\' => 19, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'phpseclib3\\' => + array ( + 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', + ), + 'Symfony\\Polyfill\\Php80\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', + ), + 'Symfony\\Polyfill\\Mbstring\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'Sop\\X501\\' => + array ( + 0 => __DIR__ . '/..' . '/sop/x501/lib/X501', + ), + 'Sop\\CryptoTypes\\' => + array ( + 0 => __DIR__ . '/..' . '/sop/crypto-types/lib/CryptoTypes', + ), + 'Sop\\CryptoEncoding\\' => + array ( + 0 => __DIR__ . '/..' . '/sop/crypto-encoding/lib/CryptoEncoding', + ), + 'Sop\\ASN1\\' => + array ( + 0 => __DIR__ . '/..' . '/sop/asn1/lib/ASN1', + ), + 'PhpOption\\' => + array ( + 0 => __DIR__ . '/..' . '/phpoption/phpoption/src/PhpOption', + ), + 'ParagonIE\\ConstantTime\\' => + array ( + 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', + ), + 'GrahamCampbell\\ResultType\\' => + array ( + 0 => __DIR__ . '/..' . '/graham-campbell/result-type/src', + ), + 'Dotenv\\' => + array ( + 0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src', + ), + 'Charnpreet\\Signver\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + ); + + public static $classMap = array ( + 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', + 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', + 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', + 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', + 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', + 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/utilities/signing_and_verification/php/vendor/composer/installed.json b/utilities/signing_and_verification/php/vendor/composer/installed.json new file mode 100644 index 0000000..a462cb6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/installed.json @@ -0,0 +1,964 @@ +{ + "packages": [ + { + "name": "graham-campbell/result-type", + "version": "v1.1.2", + "version_normalized": "1.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", + "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "time": "2023-11-12T22:16:48+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "install-path": "../graham-campbell/result-type" + }, + { + "name": "paragonie/constant_time_encoding", + "version": "v2.6.3", + "version_normalized": "2.6.3.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/constant_time_encoding.git", + "reference": "58c3f47f650c94ec05a151692652a868995d2938" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", + "reference": "58c3f47f650c94ec05a151692652a868995d2938", + "shasum": "" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "time": "2022-06-14T06:56:20+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base16", + "base32", + "base32_decode", + "base32_encode", + "base64", + "base64_decode", + "base64_encode", + "bin2hex", + "encoding", + "hex", + "hex2bin", + "rfc4648" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "install-path": "../paragonie/constant_time_encoding" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "version_normalized": "9.99.100.0", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "time": "2020-10-15T08:29:30+00:00", + "type": "library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "install-path": "../paragonie/random_compat" + }, + { + "name": "phpoption/phpoption", + "version": "1.9.2", + "version_normalized": "1.9.2.0", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", + "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "time": "2023-11-12T21:59:55+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "install-path": "../phpoption/phpoption" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.35", + "version_normalized": "3.0.35.0", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe", + "shasum": "" + }, + "require": { + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99", + "php": ">=5.6.1" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "time": "2023-12-29T01:59:53+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.35" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "install-path": "../phpseclib/phpseclib" + }, + { + "name": "sop/asn1", + "version": "4.1.1", + "version_normalized": "4.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sop/asn1.git", + "reference": "074efe8f7c353c54edc809ac3d74efda83edd776" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/asn1/zipball/074efe8f7c353c54edc809ac3d74efda83edd776", + "reference": "074efe8f7c353c54edc809ac3d74efda83edd776", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "ext-mbstring": "*", + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "time": "2022-02-17T07:08:51+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sop\\ASN1\\": "lib/ASN1/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP library for X.690 ASN.1 DER encoding and decoding.", + "homepage": "https://github.com/sop/asn1", + "keywords": [ + "DER", + "asn.1", + "asn1", + "x.690", + "x690" + ], + "support": { + "issues": "https://github.com/sop/asn1/issues", + "source": "https://github.com/sop/asn1/tree/4.1.1" + }, + "install-path": "../sop/asn1" + }, + { + "name": "sop/crypto-encoding", + "version": "0.3.0", + "version_normalized": "0.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sop/crypto-encoding.git", + "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/crypto-encoding/zipball/07537353e1b0e76c382a58a9c6e041b7c7dc9052", + "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "time": "2019-05-22T11:46:12+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP implementation of textual encodings of cryptographic structures.", + "homepage": "https://github.com/sop/crypto-encoding", + "keywords": [ + "Private Key", + "certificate", + "pem", + "public key" + ], + "support": { + "issues": "https://github.com/sop/crypto-encoding/issues", + "source": "https://github.com/sop/crypto-encoding/tree/master" + }, + "install-path": "../sop/crypto-encoding" + }, + { + "name": "sop/crypto-types", + "version": "dev-master", + "version_normalized": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sop/crypto-types.git", + "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/crypto-types/zipball/92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", + "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", + "shasum": "" + }, + "require": { + "ext-gmp": "*", + "php": ">=7.2", + "sop/asn1": "^4.0.0", + "sop/crypto-encoding": "^0.3.0", + "sop/x501": "0.6.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "time": "2021-08-11T06:56:21+00:00", + "default-branch": true, + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sop\\CryptoTypes\\": "lib/CryptoTypes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP library of various ASN.1 types for cryptographic applications.", + "homepage": "https://github.com/sop/crypto-types", + "keywords": [ + "Private Key", + "algorithm identifier", + "asn1", + "cryptography", + "ec", + "public key", + "rsa", + "signature" + ], + "support": { + "issues": "https://github.com/sop/crypto-types/issues", + "source": "https://github.com/sop/crypto-types/tree/master" + }, + "install-path": "../sop/crypto-types" + }, + { + "name": "sop/x501", + "version": "0.6.1", + "version_normalized": "0.6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sop/x501.git", + "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sop/x501/zipball/7978bfac25ff73c4c20bed0794d4d88cca8f6895", + "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895", + "shasum": "" + }, + "require": { + "ext-intl": "*", + "ext-mbstring": "*", + "php": ">=7.2", + "sop/asn1": "^4.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "time": "2019-06-27T10:30:28+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Sop\\X501\\": "lib/X501/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "description": "A PHP library for X.501 ASN.1 types, X.520 attributes and DN parsing.", + "homepage": "https://github.com/sop/x501", + "keywords": [ + "attribute", + "dn", + "ldap", + "rdn", + "x.501", + "x.520", + "x501", + "x520" + ], + "support": { + "issues": "https://github.com/sop/x501/issues", + "source": "https://github.com/sop/x501/tree/0.6.1" + }, + "install-path": "../sop/x501" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-ctype" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "time": "2023-07-28T09:04:16+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-mbstring" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "version_normalized": "1.28.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "time": "2023-01-26T09:26:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "install-path": "../symfony/polyfill-php80" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.6.0", + "version_normalized": "5.6.0.0", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-filter": "*", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "time": "2023-11-12T22:43:29+00:00", + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "install-path": "../vlucas/phpdotenv" + } + ], + "dev": true, + "dev-package-names": [] +} diff --git a/utilities/signing_and_verification/php/vendor/composer/installed.php b/utilities/signing_and_verification/php/vendor/composer/installed.php new file mode 100644 index 0000000..0b0a521 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/installed.php @@ -0,0 +1,142 @@ + array( + 'name' => 'charnpreet/signver', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => NULL, + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev' => true, + ), + 'versions' => array( + 'charnpreet/signver' => array( + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => NULL, + 'type' => 'project', + 'install_path' => __DIR__ . '/../../', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'graham-campbell/result-type' => array( + 'pretty_version' => 'v1.1.2', + 'version' => '1.1.2.0', + 'reference' => 'fbd48bce38f73f8a4ec8583362e732e4095e5862', + 'type' => 'library', + 'install_path' => __DIR__ . '/../graham-campbell/result-type', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/constant_time_encoding' => array( + 'pretty_version' => 'v2.6.3', + 'version' => '2.6.3.0', + 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'paragonie/random_compat' => array( + 'pretty_version' => 'v9.99.100', + 'version' => '9.99.100.0', + 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', + 'type' => 'library', + 'install_path' => __DIR__ . '/../paragonie/random_compat', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpoption/phpoption' => array( + 'pretty_version' => '1.9.2', + 'version' => '1.9.2.0', + 'reference' => '80735db690fe4fc5c76dfa7f9b770634285fa820', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpoption/phpoption', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'phpseclib/phpseclib' => array( + 'pretty_version' => '3.0.35', + 'version' => '3.0.35.0', + 'reference' => '4b1827beabce71953ca479485c0ae9c51287f2fe', + 'type' => 'library', + 'install_path' => __DIR__ . '/../phpseclib/phpseclib', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'sop/asn1' => array( + 'pretty_version' => '4.1.1', + 'version' => '4.1.1.0', + 'reference' => '074efe8f7c353c54edc809ac3d74efda83edd776', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sop/asn1', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'sop/crypto-encoding' => array( + 'pretty_version' => '0.3.0', + 'version' => '0.3.0.0', + 'reference' => '07537353e1b0e76c382a58a9c6e041b7c7dc9052', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sop/crypto-encoding', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'sop/crypto-types' => array( + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '92fd19ebd5d9aecdaef919e08296a2ef79a2e80f', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sop/crypto-types', + 'aliases' => array( + 0 => '9999999-dev', + ), + 'dev_requirement' => false, + ), + 'sop/x501' => array( + 'pretty_version' => '0.6.1', + 'version' => '0.6.1.0', + 'reference' => '7978bfac25ff73c4c20bed0794d4d88cca8f6895', + 'type' => 'library', + 'install_path' => __DIR__ . '/../sop/x501', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-ctype' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-mbstring' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '42292d99c55abe617799667f454222c54c60e229', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'symfony/polyfill-php80' => array( + 'pretty_version' => 'v1.28.0', + 'version' => '1.28.0.0', + 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', + 'type' => 'library', + 'install_path' => __DIR__ . '/../symfony/polyfill-php80', + 'aliases' => array(), + 'dev_requirement' => false, + ), + 'vlucas/phpdotenv' => array( + 'pretty_version' => 'v5.6.0', + 'version' => '5.6.0.0', + 'reference' => '2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4', + 'type' => 'library', + 'install_path' => __DIR__ . '/../vlucas/phpdotenv', + 'aliases' => array(), + 'dev_requirement' => false, + ), + ), +); diff --git a/utilities/signing_and_verification/php/vendor/composer/platform_check.php b/utilities/signing_and_verification/php/vendor/composer/platform_check.php new file mode 100644 index 0000000..a8b98d5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/composer/platform_check.php @@ -0,0 +1,26 @@ += 70205)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.'; +} + +if ($issues) { + if (!headers_sent()) { + header('HTTP/1.1 500 Internal Server Error'); + } + if (!ini_get('display_errors')) { + if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { + fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); + } elseif (!headers_sent()) { + echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; + } + } + trigger_error( + 'Composer detected issues in your platform: ' . implode(' ', $issues), + E_USER_ERROR + ); +} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE new file mode 100644 index 0000000..bbd75d1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2020-2023 Graham Campbell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json new file mode 100644 index 0000000..b1ba15a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json @@ -0,0 +1,33 @@ +{ + "name": "graham-campbell/result-type", + "description": "An Implementation Of The Result Type", + "keywords": ["result", "result-type", "Result", "Result Type", "Result-Type", "Graham Campbell", "GrahamCampbell"], + "license": "MIT", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "require": { + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "GrahamCampbell\\Tests\\ResultType\\": "tests/" + } + }, + "config": { + "preferred-install": "dist" + } +} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php new file mode 100644 index 0000000..2c37c3e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace GrahamCampbell\ResultType; + +use PhpOption\None; +use PhpOption\Some; + +/** + * @template T + * @template E + * + * @extends \GrahamCampbell\ResultType\Result + */ +final class Error extends Result +{ + /** + * @var E + */ + private $value; + + /** + * Internal constructor for an error value. + * + * @param E $value + * + * @return void + */ + private function __construct($value) + { + $this->value = $value; + } + + /** + * Create a new error value. + * + * @template F + * + * @param F $value + * + * @return \GrahamCampbell\ResultType\Result + */ + public static function create($value) + { + return new self($value); + } + + /** + * Get the success option value. + * + * @return \PhpOption\Option + */ + public function success() + { + return None::create(); + } + + /** + * Map over the success value. + * + * @template S + * + * @param callable(T):S $f + * + * @return \GrahamCampbell\ResultType\Result + */ + public function map(callable $f) + { + return self::create($this->value); + } + + /** + * Flat map over the success value. + * + * @template S + * @template F + * + * @param callable(T):\GrahamCampbell\ResultType\Result $f + * + * @return \GrahamCampbell\ResultType\Result + */ + public function flatMap(callable $f) + { + /** @var \GrahamCampbell\ResultType\Result */ + return self::create($this->value); + } + + /** + * Get the error option value. + * + * @return \PhpOption\Option + */ + public function error() + { + return Some::create($this->value); + } + + /** + * Map over the error value. + * + * @template F + * + * @param callable(E):F $f + * + * @return \GrahamCampbell\ResultType\Result + */ + public function mapError(callable $f) + { + return self::create($f($this->value)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php new file mode 100644 index 0000000..8c67bcd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace GrahamCampbell\ResultType; + +/** + * @template T + * @template E + */ +abstract class Result +{ + /** + * Get the success option value. + * + * @return \PhpOption\Option + */ + abstract public function success(); + + /** + * Map over the success value. + * + * @template S + * + * @param callable(T):S $f + * + * @return \GrahamCampbell\ResultType\Result + */ + abstract public function map(callable $f); + + /** + * Flat map over the success value. + * + * @template S + * @template F + * + * @param callable(T):\GrahamCampbell\ResultType\Result $f + * + * @return \GrahamCampbell\ResultType\Result + */ + abstract public function flatMap(callable $f); + + /** + * Get the error option value. + * + * @return \PhpOption\Option + */ + abstract public function error(); + + /** + * Map over the error value. + * + * @template F + * + * @param callable(E):F $f + * + * @return \GrahamCampbell\ResultType\Result + */ + abstract public function mapError(callable $f); +} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php new file mode 100644 index 0000000..27cd85e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php @@ -0,0 +1,120 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace GrahamCampbell\ResultType; + +use PhpOption\None; +use PhpOption\Some; + +/** + * @template T + * @template E + * + * @extends \GrahamCampbell\ResultType\Result + */ +final class Success extends Result +{ + /** + * @var T + */ + private $value; + + /** + * Internal constructor for a success value. + * + * @param T $value + * + * @return void + */ + private function __construct($value) + { + $this->value = $value; + } + + /** + * Create a new error value. + * + * @template S + * + * @param S $value + * + * @return \GrahamCampbell\ResultType\Result + */ + public static function create($value) + { + return new self($value); + } + + /** + * Get the success option value. + * + * @return \PhpOption\Option + */ + public function success() + { + return Some::create($this->value); + } + + /** + * Map over the success value. + * + * @template S + * + * @param callable(T):S $f + * + * @return \GrahamCampbell\ResultType\Result + */ + public function map(callable $f) + { + return self::create($f($this->value)); + } + + /** + * Flat map over the success value. + * + * @template S + * @template F + * + * @param callable(T):\GrahamCampbell\ResultType\Result $f + * + * @return \GrahamCampbell\ResultType\Result + */ + public function flatMap(callable $f) + { + return $f($this->value); + } + + /** + * Get the error option value. + * + * @return \PhpOption\Option + */ + public function error() + { + return None::create(); + } + + /** + * Map over the error value. + * + * @template F + * + * @param callable(E):F $f + * + * @return \GrahamCampbell\ResultType\Result + */ + public function mapError(callable $f) + { + return self::create($this->value); + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt new file mode 100644 index 0000000..91acaca --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt @@ -0,0 +1,48 @@ +The MIT License (MIT) + +Copyright (c) 2016 - 2022 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +------------------------------------------------------------------------------ +This library was based on the work of Steve "Sc00bz" Thomas. +------------------------------------------------------------------------------ + +The MIT License (MIT) + +Copyright (c) 2014 Steve Thomas + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md new file mode 100644 index 0000000..cedddd8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md @@ -0,0 +1,84 @@ +# Constant-Time Encoding + +[![Build Status](https://github.com/paragonie/constant_time_encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions) +[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) +[![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) + +Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), +this library aims to offer character encoding functions that do not leak +information about what you are encoding/decoding via processor cache +misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). + +Our fork offers the following enchancements: + +* `mbstring.func_overload` resistance +* Unit tests +* Composer- and Packagist-ready +* Base16 encoding +* Base32 encoding +* Uses `pack()` and `unpack()` instead of `chr()` and `ord()` + +## PHP Version Requirements + +Version 2 of this library should work on **PHP 7** or newer. For PHP 5 +support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). + +If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`. + +## How to Install + +```sh +composer require paragonie/constant_time_encoding +``` + +## How to Use + +```php +use ParagonIE\ConstantTime\Encoding; + +// possibly (if applicable): +// require 'vendor/autoload.php'; + +$data = random_bytes(32); +echo Encoding::base64Encode($data), "\n"; +echo Encoding::base32EncodeUpper($data), "\n"; +echo Encoding::base32Encode($data), "\n"; +echo Encoding::hexEncode($data), "\n"; +echo Encoding::hexEncodeUpper($data), "\n"; +``` + +Example output: + +``` +1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= +2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== +2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== +d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 +D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 +``` + +If you only need a particular variant, you can just reference the +required class like so: + +```php +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Base32; + +$data = random_bytes(32); +echo Base64::encode($data), "\n"; +echo Base32::encode($data), "\n"; +``` + +Example output: + +``` +1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= +2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== +``` + +## Support Contracts + +If your company uses this library in their products or services, you may be +interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json new file mode 100644 index 0000000..2fe9717 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json @@ -0,0 +1,56 @@ +{ + "name": "paragonie/constant_time_encoding", + "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", + "keywords": [ + "base64", + "encoding", + "rfc4648", + "base32", + "base16", + "hex", + "bin2hex", + "hex2bin", + "base64_encode", + "base64_decode", + "base32_encode", + "base32_decode" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com", + "role": "Maintainer" + }, + { + "name": "Steve 'Sc00bz' Thomas", + "email": "steve@tobtu.com", + "homepage": "https://www.tobtu.com", + "role": "Original Developer" + } + ], + "support": { + "issues": "https://github.com/paragonie/constant_time_encoding/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/constant_time_encoding" + }, + "require": { + "php": "^7|^8" + }, + "require-dev": { + "phpunit/phpunit": "^6|^7|^8|^9", + "vimeo/psalm": "^1|^2|^3|^4" + }, + "autoload": { + "psr-4": { + "ParagonIE\\ConstantTime\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "ParagonIE\\ConstantTime\\Tests\\": "tests/" + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php new file mode 100644 index 0000000..7508b3d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php @@ -0,0 +1,519 @@ + 96 && $src < 123) $ret += $src - 97 + 1; // -64 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); + + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src): int + { + $ret = -1; + + // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 + $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src): string + { + $diff = 0x61; + + // if ($src > 25) $ret -= 72; + $diff -= ((25 - $src) >> 8) & 73; + + return \pack('C', $src + $diff); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $ret -= 40; + $diff -= ((25 - $src) >> 8) & 41; + + return \pack('C', $src + $diff); + } + + /** + * @param string $encodedString + * @param bool $upper + * @return string + */ + public static function decodeNoPadding(string $encodedString, bool $upper = false): string + { + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7 && $j < $srcLen; ++$j) { + if ($encodedString[$srcLen - $j - 1] === '=') { + throw new InvalidArgumentException( + "decodeNoPadding() doesn't tolerate padding" + ); + } + } + } + return static::doDecode( + $encodedString, + $upper, + true + ); + } + + /** + * Base32 decoding + * + * @param string $src + * @param bool $upper + * @param bool $strictPadding + * @return string + * + * @throws TypeError + * @psalm-suppress RedundantCondition + */ + protected static function doDecode( + string $src, + bool $upper = false, + bool $strictPadding = false + ): string { + // We do this to reduce code duplication: + $method = $upper + ? 'decode5BitsUpper' + : 'decode5Bits'; + + // Remove padding + $srcLen = Binary::safeStrlen($src); + if ($srcLen === 0) { + return ''; + } + if ($strictPadding) { + if (($srcLen & 7) === 0) { + for ($j = 0; $j < 7; ++$j) { + if ($src[$srcLen - 1] === '=') { + $srcLen--; + } else { + break; + } + } + } + if (($srcLen & 7) === 1) { + throw new RangeException( + 'Incorrect padding' + ); + } + } else { + $src = \rtrim($src, '='); + $srcLen = Binary::safeStrlen($src); + } + + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 8 <= $srcLen; $i += 8) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + /** @var int $c7 */ + $c7 = static::$method($chunk[8]); + + $dest .= \pack( + 'CCCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, + (($c6 << 5) | ($c7 ) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + /** @var int $c0 */ + $c0 = static::$method($chunk[1]); + + if ($i + 6 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + /** @var int $c6 */ + $c6 = static::$method($chunk[7]); + + $dest .= \pack( + 'CCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; + if ($strictPadding) { + $err |= ($c6 << 5) & 0xff; + } + } elseif ($i + 5 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + /** @var int $c5 */ + $c5 = static::$method($chunk[6]); + + $dest .= \pack( + 'CCCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff, + (($c4 << 7) | ($c5 << 2) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; + } elseif ($i + 4 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + /** @var int $c4 */ + $c4 = static::$method($chunk[5]); + + $dest .= \pack( + 'CCC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, + (($c3 << 4) | ($c4 >> 1) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; + if ($strictPadding) { + $err |= ($c4 << 7) & 0xff; + } + } elseif ($i + 3 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + /** @var int $c3 */ + $c3 = static::$method($chunk[4]); + + $dest .= \pack( + 'CC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff + ); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + if ($strictPadding) { + $err |= ($c3 << 4) & 0xff; + } + } elseif ($i + 2 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + /** @var int $c2 */ + $c2 = static::$method($chunk[3]); + + $dest .= \pack( + 'CC', + (($c0 << 3) | ($c1 >> 2) ) & 0xff, + (($c1 << 6) | ($c2 << 1) ) & 0xff + ); + $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= ($c2 << 6) & 0xff; + } + } elseif ($i + 1 < $srcLen) { + /** @var int $c1 */ + $c1 = static::$method($chunk[2]); + + $dest .= \pack( + 'C', + (($c0 << 3) | ($c1 >> 2) ) & 0xff + ); + $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= ($c1 << 6) & 0xff; + } + } else { + $dest .= \pack( + 'C', + (($c0 << 3) ) & 0xff + ); + $err |= ($c0) >> 8; + } + } + $check = ($err === 0); + if (!$check) { + throw new RangeException( + 'Base32::doDecode() only expects characters in the correct base32 alphabet' + ); + } + return $dest; + } + + /** + * Base32 Encoding + * + * @param string $src + * @param bool $upper + * @param bool $pad + * @return string + * @throws TypeError + */ + protected static function doEncode(string $src, bool $upper = false, $pad = true): string + { + // We do this to reduce code duplication: + $method = $upper + ? 'encode5BitsUpper' + : 'encode5Bits'; + + $dest = ''; + $srcLen = Binary::safeStrlen($src); + + // Main loop (no padding): + for ($i = 0; $i + 5 <= $srcLen; $i += 5) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $b4 = $chunk[5]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . + static::$method((($b3 >> 2) ) & 31) . + static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . + static::$method( $b4 & 31); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 3 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $b3 = $chunk[4]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . + static::$method((($b3 >> 2) ) & 31) . + static::$method((($b3 << 3) ) & 31); + if ($pad) { + $dest .= '='; + } + } elseif ($i + 2 < $srcLen) { + $b1 = $chunk[2]; + $b2 = $chunk[3]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . + static::$method((($b2 << 1) ) & 31); + if ($pad) { + $dest .= '==='; + } + } elseif ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . + static::$method((($b1 >> 1) ) & 31) . + static::$method((($b1 << 4) ) & 31); + if ($pad) { + $dest .= '===='; + } + } else { + $dest .= + static::$method( ($b0 >> 3) & 31) . + static::$method( ($b0 << 2) & 31); + if ($pad) { + $dest .= '======'; + } + } + } + return $dest; + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php new file mode 100644 index 0000000..b868dd0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php @@ -0,0 +1,111 @@ + 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); + + // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 + $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 5-bit integers + * into 8-bit integers. + * + * @param int $src + * @return int + */ + protected static function decode5BitsUpper(int $src): int + { + $ret = -1; + + // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); + + // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 + $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode5Bits(int $src): string + { + $src += 0x30; + + // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 + $src += ((0x39 - $src) >> 8) & 39; + + return \pack('C', $src); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 5-bit integers. + * + * Uppercase variant. + * + * @param int $src + * @return string + */ + protected static function encode5BitsUpper(int $src): string + { + $src += 0x30; + + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += ((0x39 - $src) >> 8) & 7; + + return \pack('C', $src); + } +} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php new file mode 100644 index 0000000..f571617 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php @@ -0,0 +1,314 @@ + $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3)); + $b0 = $chunk[1]; + $b1 = $chunk[2]; + $b2 = $chunk[3]; + + $dest .= + static::encode6Bits( $b0 >> 2 ) . + static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . + static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . + static::encode6Bits( $b2 & 63); + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); + $b0 = $chunk[1]; + if ($i + 1 < $srcLen) { + $b1 = $chunk[2]; + $dest .= + static::encode6Bits($b0 >> 2) . + static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . + static::encode6Bits(($b1 << 2) & 63); + if ($pad) { + $dest .= '='; + } + } else { + $dest .= + static::encode6Bits( $b0 >> 2) . + static::encode6Bits(($b0 << 4) & 63); + if ($pad) { + $dest .= '=='; + } + } + } + return $dest; + } + + /** + * decode from base64 into binary + * + * Base64 character set "./[A-Z][a-z][0-9]" + * + * @param string $encodedString + * @param bool $strictPadding + * @return string + * + * @throws RangeException + * @throws TypeError + * @psalm-suppress RedundantCondition + */ + public static function decode(string $encodedString, bool $strictPadding = false): string + { + // Remove padding + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + + if ($strictPadding) { + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + if ($encodedString[$srcLen - 1] === '=') { + $srcLen--; + } + } + } + if (($srcLen & 3) === 1) { + throw new RangeException( + 'Incorrect padding' + ); + } + if ($encodedString[$srcLen - 1] === '=') { + throw new RangeException( + 'Incorrect padding' + ); + } + } else { + $encodedString = \rtrim($encodedString, '='); + $srcLen = Binary::safeStrlen($encodedString); + } + + $err = 0; + $dest = ''; + // Main loop (no padding): + for ($i = 0; $i + 4 <= $srcLen; $i += 4) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4)); + $c0 = static::decode6Bits($chunk[1]); + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $c3 = static::decode6Bits($chunk[4]); + + $dest .= \pack( + 'CCC', + ((($c0 << 2) | ($c1 >> 4)) & 0xff), + ((($c1 << 4) | ($c2 >> 2)) & 0xff), + ((($c2 << 6) | $c3 ) & 0xff) + ); + $err |= ($c0 | $c1 | $c2 | $c3) >> 8; + } + // The last chunk, which may have padding: + if ($i < $srcLen) { + /** @var array $chunk */ + $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i)); + $c0 = static::decode6Bits($chunk[1]); + + if ($i + 2 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $c2 = static::decode6Bits($chunk[3]); + $dest .= \pack( + 'CC', + ((($c0 << 2) | ($c1 >> 4)) & 0xff), + ((($c1 << 4) | ($c2 >> 2)) & 0xff) + ); + $err |= ($c0 | $c1 | $c2) >> 8; + if ($strictPadding) { + $err |= ($c2 << 6) & 0xff; + } + } elseif ($i + 1 < $srcLen) { + $c1 = static::decode6Bits($chunk[2]); + $dest .= \pack( + 'C', + ((($c0 << 2) | ($c1 >> 4)) & 0xff) + ); + $err |= ($c0 | $c1) >> 8; + if ($strictPadding) { + $err |= ($c1 << 4) & 0xff; + } + } elseif ($strictPadding) { + $err |= 1; + } + } + $check = ($err === 0); + if (!$check) { + throw new RangeException( + 'Base64::decode() only expects characters in the correct base64 alphabet' + ); + } + return $dest; + } + + /** + * @param string $encodedString + * @return string + */ + public static function decodeNoPadding(string $encodedString): string + { + $srcLen = Binary::safeStrlen($encodedString); + if ($srcLen === 0) { + return ''; + } + if (($srcLen & 3) === 0) { + if ($encodedString[$srcLen - 1] === '=') { + throw new InvalidArgumentException( + "decodeNoPadding() doesn't tolerate padding" + ); + } + if (($srcLen & 3) > 1) { + if ($encodedString[$srcLen - 2] === '=') { + throw new InvalidArgumentException( + "decodeNoPadding() doesn't tolerate padding" + ); + } + } + } + return static::decode( + $encodedString, + true + ); + } + + /** + * Uses bitwise operators instead of table-lookups to turn 6-bit integers + * into 8-bit integers. + * + * Base64 character set: + * [A-Z] [a-z] [0-9] + / + * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f + * + * @param int $src + * @return int + */ + protected static function decode6Bits(int $src): int + { + $ret = -1; + + // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); + + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); + + // if ($src == 0x2b) $ret += 62 + 1; + $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; + + // if ($src == 0x2f) ret += 63 + 1; + $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += ((25 - $src) >> 8) & 6; + + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= ((51 - $src) >> 8) & 75; + + // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 + $diff -= ((61 - $src) >> 8) & 15; + + // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 + $diff += ((62 - $src) >> 8) & 3; + + return \pack('C', $src + $diff); + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php new file mode 100644 index 0000000..5e98a8f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php @@ -0,0 +1,88 @@ + 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 + $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); + + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); + + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); + + // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $src += 0x2e; + + // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 + $src += ((0x2f - $src) >> 8) & 17; + + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += ((0x5a - $src) >> 8) & 6; + + // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 + $src -= ((0x7a - $src) >> 8) & 75; + + return \pack('C', $src); + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php new file mode 100644 index 0000000..9780b14 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php @@ -0,0 +1,82 @@ + 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 + $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); + + // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); + + // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $src += 0x2e; + + // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 + $src += ((0x39 - $src) >> 8) & 7; + + // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 + $src += ((0x5a - $src) >> 8) & 6; + + return \pack('C', $src); + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php new file mode 100644 index 0000000..8192c63 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php @@ -0,0 +1,95 @@ + 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 + $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); + + // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 + $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); + + // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 + $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); + + // if ($src == 0x2c) $ret += 62 + 1; + $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; + + // if ($src == 0x5f) ret += 63 + 1; + $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; + + return $ret; + } + + /** + * Uses bitwise operators instead of table-lookups to turn 8-bit integers + * into 6-bit integers. + * + * @param int $src + * @return string + */ + protected static function encode6Bits(int $src): string + { + $diff = 0x41; + + // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 + $diff += ((25 - $src) >> 8) & 6; + + // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 + $diff -= ((51 - $src) >> 8) & 75; + + // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 + $diff -= ((61 - $src) >> 8) & 13; + + // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 + $diff += ((62 - $src) >> 8) & 49; + + return \pack('C', $src + $diff); + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php new file mode 100644 index 0000000..828f3e0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php @@ -0,0 +1,90 @@ + $chunk */ + $chunk = \unpack('C', $binString[$i]); + $c = $chunk[1] & 0xf; + $b = $chunk[1] >> 4; + + $hex .= \pack( + 'CC', + (87 + $b + ((($b - 10) >> 8) & ~38)), + (87 + $c + ((($c - 10) >> 8) & ~38)) + ); + } + return $hex; + } + + /** + * Convert a binary string into a hexadecimal string without cache-timing + * leaks, returning uppercase letters (as per RFC 4648) + * + * @param string $binString (raw binary) + * @return string + * @throws TypeError + */ + public static function encodeUpper(string $binString): string + { + $hex = ''; + $len = Binary::safeStrlen($binString); + + for ($i = 0; $i < $len; ++$i) { + /** @var array $chunk */ + $chunk = \unpack('C', $binString[$i]); + $c = $chunk[1] & 0xf; + $b = $chunk[1] >> 4; + + $hex .= \pack( + 'CC', + (55 + $b + ((($b - 10) >> 8) & ~6)), + (55 + $c + ((($c - 10) >> 8) & ~6)) + ); + } + return $hex; + } + + /** + * Convert a hexadecimal string into a binary string without cache-timing + * leaks + * + * @param string $encodedString + * @param bool $strictPadding + * @return string (raw binary) + * @throws RangeException + */ + public static function decode( + string $encodedString, + bool $strictPadding = false + ): string { + $hex_pos = 0; + $bin = ''; + $c_acc = 0; + $hex_len = Binary::safeStrlen($encodedString); + $state = 0; + if (($hex_len & 1) !== 0) { + if ($strictPadding) { + throw new RangeException( + 'Expected an even number of hexadecimal characters' + ); + } else { + $encodedString = '0' . $encodedString; + ++$hex_len; + } + } + + /** @var array $chunk */ + $chunk = \unpack('C*', $encodedString); + while ($hex_pos < $hex_len) { + ++$hex_pos; + $c = $chunk[$hex_pos]; + $c_num = $c ^ 48; + $c_num0 = ($c_num - 10) >> 8; + $c_alpha = ($c & ~32) - 55; + $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; + + if (($c_num0 | $c_alpha0) === 0) { + throw new RangeException( + 'Expected hexadecimal character' + ); + } + $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); + if ($state === 0) { + $c_acc = $c_val * 16; + } else { + $bin .= \pack('C', $c_acc | $c_val); + } + $state ^= 1; + } + return $bin; + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php new file mode 100644 index 0000000..f124d65 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php @@ -0,0 +1,186 @@ + "Zm9v" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64Encode(string $str): string + { + return Base64::encode($str); + } + + /** + * RFC 4648 Base64 decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64Decode(string $str): string + { + return Base64::decode($str, true); + } + + /** + * RFC 4648 Base64 (URL Safe) encoding + * + * "foo" -> "Zm9v" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64UrlSafeEncode(string $str): string + { + return Base64UrlSafe::encode($str); + } + + /** + * RFC 4648 Base64 (URL Safe) decoding + * + * "Zm9v" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base64UrlSafeDecode(string $str): string + { + return Base64UrlSafe::decode($str, true); + } + + /** + * RFC 4648 Base32 encoding + * + * "foo" -> "MZXW6===" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32Encode(string $str): string + { + return Base32::encodeUpper($str); + } + + /** + * RFC 4648 Base32 encoding + * + * "MZXW6===" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32Decode(string $str): string + { + return Base32::decodeUpper($str, true); + } + + /** + * RFC 4648 Base32-Hex encoding + * + * "foo" -> "CPNMU===" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32HexEncode(string $str): string + { + return Base32::encodeUpper($str); + } + + /** + * RFC 4648 Base32-Hex decoding + * + * "CPNMU===" -> "foo" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base32HexDecode(string $str): string + { + return Base32::decodeUpper($str, true); + } + + /** + * RFC 4648 Base16 decoding + * + * "foo" -> "666F6F" + * + * @param string $str + * @return string + * + * @throws TypeError + */ + public static function base16Encode(string $str): string + { + return Hex::encodeUpper($str); + } + + /** + * RFC 4648 Base16 decoding + * + * "666F6F" -> "foo" + * + * @param string $str + * @return string + */ + public static function base16Decode(string $str): string + { + return Hex::decode($str, true); + } +} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE new file mode 100644 index 0000000..45c7017 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Paragon Initiative Enterprises + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh new file mode 100755 index 0000000..b4a5ba3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) + +php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json new file mode 100644 index 0000000..f2b9c4e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json @@ -0,0 +1,34 @@ +{ + "name": "paragonie/random_compat", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "random", + "polyfill", + "pseudorandom" + ], + "license": "MIT", + "type": "library", + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "support": { + "issues": "https://github.com/paragonie/random_compat/issues", + "email": "info@paragonie.com", + "source": "https://github.com/paragonie/random_compat" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "vimeo/psalm": "^1", + "phpunit/phpunit": "4.*|5.*" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey new file mode 100644 index 0000000..eb50ebf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey @@ -0,0 +1,5 @@ +-----BEGIN PUBLIC KEY----- +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm +pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p ++h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc +-----END PUBLIC KEY----- diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc new file mode 100644 index 0000000..6a1d7f3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc @@ -0,0 +1,11 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.0.22 (MingW32) + +iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip +QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg +1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW +NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA +NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV +JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= +=B6+8 +-----END PGP SIGNATURE----- diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php new file mode 100644 index 0000000..c7731a5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php @@ -0,0 +1,32 @@ +buildFromDirectory(dirname(__DIR__).'/lib'); +rename( + dirname(__DIR__).'/lib/index.php', + dirname(__DIR__).'/lib/random.php' +); + +/** + * If we pass an (optional) path to a private key as a second argument, we will + * sign the Phar with OpenSSL. + * + * If you leave this out, it will produce an unsigned .phar! + */ +if ($argc > 1) { + if (!@is_readable($argv[1])) { + echo 'Could not read the private key file:', $argv[1], "\n"; + exit(255); + } + $pkeyFile = file_get_contents($argv[1]); + + $private = openssl_get_privatekey($pkeyFile); + if ($private !== false) { + $pkey = ''; + openssl_pkey_export($private, $pkey); + $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); + + /** + * Save the corresponding public key to the file + */ + if (!@is_readable($dist.'/random_compat.phar.pubkey')) { + $details = openssl_pkey_get_details($private); + file_put_contents( + $dist.'/random_compat.phar.pubkey', + $details['key'] + ); + } + } else { + echo 'An error occurred reading the private key from OpenSSL.', "\n"; + exit(255); + } +} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php new file mode 100644 index 0000000..d71d1b8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php @@ -0,0 +1,9 @@ + + + + + + + + + + + + + + + diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE new file mode 100644 index 0000000..f49a4e1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json new file mode 100644 index 0000000..77f50a3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json @@ -0,0 +1,52 @@ +{ + "name": "phpoption/phpoption", + "description": "Option Type for PHP", + "keywords": ["php", "option", "language", "type"], + "license": "Apache-2.0", + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "autoload-dev": { + "psr-4": { + "PhpOption\\Tests\\": "tests/PhpOption/Tests/" + } + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + }, + "preferred-install": "dist" + }, + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php new file mode 100644 index 0000000..9cb77c8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php @@ -0,0 +1,175 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace PhpOption; + +use Traversable; + +/** + * @template T + * + * @extends Option + */ +final class LazyOption extends Option +{ + /** @var callable(mixed...):(Option) */ + private $callback; + + /** @var array */ + private $arguments; + + /** @var Option|null */ + private $option; + + /** + * @template S + * @param callable(mixed...):(Option) $callback + * @param array $arguments + * + * @return LazyOption + */ + public static function create($callback, array $arguments = []): self + { + return new self($callback, $arguments); + } + + /** + * @param callable(mixed...):(Option) $callback + * @param array $arguments + */ + public function __construct($callback, array $arguments = []) + { + if (!is_callable($callback)) { + throw new \InvalidArgumentException('Invalid callback given'); + } + + $this->callback = $callback; + $this->arguments = $arguments; + } + + public function isDefined(): bool + { + return $this->option()->isDefined(); + } + + public function isEmpty(): bool + { + return $this->option()->isEmpty(); + } + + public function get() + { + return $this->option()->get(); + } + + public function getOrElse($default) + { + return $this->option()->getOrElse($default); + } + + public function getOrCall($callable) + { + return $this->option()->getOrCall($callable); + } + + public function getOrThrow(\Exception $ex) + { + return $this->option()->getOrThrow($ex); + } + + public function orElse(Option $else) + { + return $this->option()->orElse($else); + } + + public function ifDefined($callable) + { + $this->option()->forAll($callable); + } + + public function forAll($callable) + { + return $this->option()->forAll($callable); + } + + public function map($callable) + { + return $this->option()->map($callable); + } + + public function flatMap($callable) + { + return $this->option()->flatMap($callable); + } + + public function filter($callable) + { + return $this->option()->filter($callable); + } + + public function filterNot($callable) + { + return $this->option()->filterNot($callable); + } + + public function select($value) + { + return $this->option()->select($value); + } + + public function reject($value) + { + return $this->option()->reject($value); + } + + /** + * @return Traversable + */ + public function getIterator(): Traversable + { + return $this->option()->getIterator(); + } + + public function foldLeft($initialValue, $callable) + { + return $this->option()->foldLeft($initialValue, $callable); + } + + public function foldRight($initialValue, $callable) + { + return $this->option()->foldRight($initialValue, $callable); + } + + /** + * @return Option + */ + private function option(): Option + { + if (null === $this->option) { + /** @var mixed */ + $option = call_user_func_array($this->callback, $this->arguments); + if ($option instanceof Option) { + $this->option = $option; + } else { + throw new \RuntimeException(sprintf('Expected instance of %s', Option::class)); + } + } + + return $this->option; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php new file mode 100644 index 0000000..4b85d22 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php @@ -0,0 +1,136 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace PhpOption; + +use EmptyIterator; + +/** + * @extends Option + */ +final class None extends Option +{ + /** @var None|null */ + private static $instance; + + /** + * @return None + */ + public static function create(): self + { + if (null === self::$instance) { + self::$instance = new self(); + } + + return self::$instance; + } + + public function get() + { + throw new \RuntimeException('None has no value.'); + } + + public function getOrCall($callable) + { + return $callable(); + } + + public function getOrElse($default) + { + return $default; + } + + public function getOrThrow(\Exception $ex) + { + throw $ex; + } + + public function isEmpty(): bool + { + return true; + } + + public function isDefined(): bool + { + return false; + } + + public function orElse(Option $else) + { + return $else; + } + + public function ifDefined($callable) + { + // Just do nothing in that case. + } + + public function forAll($callable) + { + return $this; + } + + public function map($callable) + { + return $this; + } + + public function flatMap($callable) + { + return $this; + } + + public function filter($callable) + { + return $this; + } + + public function filterNot($callable) + { + return $this; + } + + public function select($value) + { + return $this; + } + + public function reject($value) + { + return $this; + } + + public function getIterator(): EmptyIterator + { + return new EmptyIterator(); + } + + public function foldLeft($initialValue, $callable) + { + return $initialValue; + } + + public function foldRight($initialValue, $callable) + { + return $initialValue; + } + + private function __construct() + { + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php new file mode 100644 index 0000000..172924c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php @@ -0,0 +1,434 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace PhpOption; + +use ArrayAccess; +use IteratorAggregate; + +/** + * @template T + * + * @implements IteratorAggregate + */ +abstract class Option implements IteratorAggregate +{ + /** + * Creates an option given a return value. + * + * This is intended for consuming existing APIs and allows you to easily + * convert them to an option. By default, we treat ``null`` as the None + * case, and everything else as Some. + * + * @template S + * + * @param S $value The actual return value. + * @param S $noneValue The value which should be considered "None"; null by + * default. + * + * @return Option + */ + public static function fromValue($value, $noneValue = null) + { + if ($value === $noneValue) { + return None::create(); + } + + return new Some($value); + } + + /** + * Creates an option from an array's value. + * + * If the key does not exist in the array, the array is not actually an + * array, or the array's value at the given key is null, None is returned. + * Otherwise, Some is returned wrapping the value at the given key. + * + * @template S + * + * @param array|ArrayAccess|null $array A potential array or \ArrayAccess value. + * @param string $key The key to check. + * + * @return Option + */ + public static function fromArraysValue($array, $key) + { + if (!(is_array($array) || $array instanceof ArrayAccess) || !isset($array[$key])) { + return None::create(); + } + + return new Some($array[$key]); + } + + /** + * Creates a lazy-option with the given callback. + * + * This is also a helper constructor for lazy-consuming existing APIs where + * the return value is not yet an option. By default, we treat ``null`` as + * None case, and everything else as Some. + * + * @template S + * + * @param callable $callback The callback to evaluate. + * @param array $arguments The arguments for the callback. + * @param S $noneValue The value which should be considered "None"; + * null by default. + * + * @return LazyOption + */ + public static function fromReturn($callback, array $arguments = [], $noneValue = null) + { + return new LazyOption(static function () use ($callback, $arguments, $noneValue) { + /** @var mixed */ + $return = call_user_func_array($callback, $arguments); + + if ($return === $noneValue) { + return None::create(); + } + + return new Some($return); + }); + } + + /** + * Option factory, which creates new option based on passed value. + * + * If value is already an option, it simply returns. If value is callable, + * LazyOption with passed callback created and returned. If Option + * returned from callback, it returns directly. On other case value passed + * to Option::fromValue() method. + * + * @template S + * + * @param Option|callable|S $value + * @param S $noneValue Used when $value is mixed or + * callable, for None-check. + * + * @return Option|LazyOption + */ + public static function ensure($value, $noneValue = null) + { + if ($value instanceof self) { + return $value; + } elseif (is_callable($value)) { + return new LazyOption(static function () use ($value, $noneValue) { + /** @var mixed */ + $return = $value(); + + if ($return instanceof self) { + return $return; + } else { + return self::fromValue($return, $noneValue); + } + }); + } else { + return self::fromValue($value, $noneValue); + } + } + + /** + * Lift a function so that it accepts Option as parameters. + * + * We return a new closure that wraps the original callback. If any of the + * parameters passed to the lifted function is empty, the function will + * return a value of None. Otherwise, we will pass all parameters to the + * original callback and return the value inside a new Option, unless an + * Option is returned from the function, in which case, we use that. + * + * @template S + * + * @param callable $callback + * @param mixed $noneValue + * + * @return callable + */ + public static function lift($callback, $noneValue = null) + { + return static function () use ($callback, $noneValue) { + /** @var array */ + $args = func_get_args(); + + $reduced_args = array_reduce( + $args, + /** @param bool $status */ + static function ($status, self $o) { + return $o->isEmpty() ? true : $status; + }, + false + ); + // if at least one parameter is empty, return None + if ($reduced_args) { + return None::create(); + } + + $args = array_map( + /** @return T */ + static function (self $o) { + // it is safe to do so because the fold above checked + // that all arguments are of type Some + /** @var T */ + return $o->get(); + }, + $args + ); + + return self::ensure(call_user_func_array($callback, $args), $noneValue); + }; + } + + /** + * Returns the value if available, or throws an exception otherwise. + * + * @throws \RuntimeException If value is not available. + * + * @return T + */ + abstract public function get(); + + /** + * Returns the value if available, or the default value if not. + * + * @template S + * + * @param S $default + * + * @return T|S + */ + abstract public function getOrElse($default); + + /** + * Returns the value if available, or the results of the callable. + * + * This is preferable over ``getOrElse`` if the computation of the default + * value is expensive. + * + * @template S + * + * @param callable():S $callable + * + * @return T|S + */ + abstract public function getOrCall($callable); + + /** + * Returns the value if available, or throws the passed exception. + * + * @param \Exception $ex + * + * @return T + */ + abstract public function getOrThrow(\Exception $ex); + + /** + * Returns true if no value is available, false otherwise. + * + * @return bool + */ + abstract public function isEmpty(); + + /** + * Returns true if a value is available, false otherwise. + * + * @return bool + */ + abstract public function isDefined(); + + /** + * Returns this option if non-empty, or the passed option otherwise. + * + * This can be used to try multiple alternatives, and is especially useful + * with lazy evaluating options: + * + * ```php + * $repo->findSomething() + * ->orElse(new LazyOption(array($repo, 'findSomethingElse'))) + * ->orElse(new LazyOption(array($repo, 'createSomething'))); + * ``` + * + * @param Option $else + * + * @return Option + */ + abstract public function orElse(self $else); + + /** + * This is similar to map() below except that the return value has no meaning; + * the passed callable is simply executed if the option is non-empty, and + * ignored if the option is empty. + * + * In all cases, the return value of the callable is discarded. + * + * ```php + * $comment->getMaybeFile()->ifDefined(function($file) { + * // Do something with $file here. + * }); + * ``` + * + * If you're looking for something like ``ifEmpty``, you can use ``getOrCall`` + * and ``getOrElse`` in these cases. + * + * @deprecated Use forAll() instead. + * + * @param callable(T):mixed $callable + * + * @return void + */ + abstract public function ifDefined($callable); + + /** + * This is similar to map() except that the return value of the callable has no meaning. + * + * The passed callable is simply executed if the option is non-empty, and ignored if the + * option is empty. This method is preferred for callables with side-effects, while map() + * is intended for callables without side-effects. + * + * @param callable(T):mixed $callable + * + * @return Option + */ + abstract public function forAll($callable); + + /** + * Applies the callable to the value of the option if it is non-empty, + * and returns the return value of the callable wrapped in Some(). + * + * If the option is empty, then the callable is not applied. + * + * ```php + * (new Some("foo"))->map('strtoupper')->get(); // "FOO" + * ``` + * + * @template S + * + * @param callable(T):S $callable + * + * @return Option + */ + abstract public function map($callable); + + /** + * Applies the callable to the value of the option if it is non-empty, and + * returns the return value of the callable directly. + * + * In contrast to ``map``, the return value of the callable is expected to + * be an Option itself; it is not automatically wrapped in Some(). + * + * @template S + * + * @param callable(T):Option $callable must return an Option + * + * @return Option + */ + abstract public function flatMap($callable); + + /** + * If the option is empty, it is returned immediately without applying the callable. + * + * If the option is non-empty, the callable is applied, and if it returns true, + * the option itself is returned; otherwise, None is returned. + * + * @param callable(T):bool $callable + * + * @return Option + */ + abstract public function filter($callable); + + /** + * If the option is empty, it is returned immediately without applying the callable. + * + * If the option is non-empty, the callable is applied, and if it returns false, + * the option itself is returned; otherwise, None is returned. + * + * @param callable(T):bool $callable + * + * @return Option + */ + abstract public function filterNot($callable); + + /** + * If the option is empty, it is returned immediately. + * + * If the option is non-empty, and its value does not equal the passed value + * (via a shallow comparison ===), then None is returned. Otherwise, the + * Option is returned. + * + * In other words, this will filter all but the passed value. + * + * @param T $value + * + * @return Option + */ + abstract public function select($value); + + /** + * If the option is empty, it is returned immediately. + * + * If the option is non-empty, and its value does equal the passed value (via + * a shallow comparison ===), then None is returned; otherwise, the Option is + * returned. + * + * In other words, this will let all values through except the passed value. + * + * @param T $value + * + * @return Option + */ + abstract public function reject($value); + + /** + * Binary operator for the initial value and the option's value. + * + * If empty, the initial value is returned. If non-empty, the callable + * receives the initial value and the option's value as arguments. + * + * ```php + * + * $some = new Some(5); + * $none = None::create(); + * $result = $some->foldLeft(1, function($a, $b) { return $a + $b; }); // int(6) + * $result = $none->foldLeft(1, function($a, $b) { return $a + $b; }); // int(1) + * + * // This can be used instead of something like the following: + * $option = Option::fromValue($integerOrNull); + * $result = 1; + * if ( ! $option->isEmpty()) { + * $result += $option->get(); + * } + * ``` + * + * @template S + * + * @param S $initialValue + * @param callable(S, T):S $callable + * + * @return S + */ + abstract public function foldLeft($initialValue, $callable); + + /** + * foldLeft() but with reversed arguments for the callable. + * + * @template S + * + * @param S $initialValue + * @param callable(T, S):S $callable + * + * @return S + */ + abstract public function foldRight($initialValue, $callable); +} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php new file mode 100644 index 0000000..032632e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php @@ -0,0 +1,169 @@ + + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +namespace PhpOption; + +use ArrayIterator; + +/** + * @template T + * + * @extends Option + */ +final class Some extends Option +{ + /** @var T */ + private $value; + + /** + * @param T $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * @template U + * + * @param U $value + * + * @return Some + */ + public static function create($value): self + { + return new self($value); + } + + public function isDefined(): bool + { + return true; + } + + public function isEmpty(): bool + { + return false; + } + + public function get() + { + return $this->value; + } + + public function getOrElse($default) + { + return $this->value; + } + + public function getOrCall($callable) + { + return $this->value; + } + + public function getOrThrow(\Exception $ex) + { + return $this->value; + } + + public function orElse(Option $else) + { + return $this; + } + + public function ifDefined($callable) + { + $this->forAll($callable); + } + + public function forAll($callable) + { + $callable($this->value); + + return $this; + } + + public function map($callable) + { + return new self($callable($this->value)); + } + + public function flatMap($callable) + { + /** @var mixed */ + $rs = $callable($this->value); + if (!$rs instanceof Option) { + throw new \RuntimeException('Callables passed to flatMap() must return an Option. Maybe you should use map() instead?'); + } + + return $rs; + } + + public function filter($callable) + { + if (true === $callable($this->value)) { + return $this; + } + + return None::create(); + } + + public function filterNot($callable) + { + if (false === $callable($this->value)) { + return $this; + } + + return None::create(); + } + + public function select($value) + { + if ($this->value === $value) { + return $this; + } + + return None::create(); + } + + public function reject($value) + { + if ($this->value === $value) { + return None::create(); + } + + return $this; + } + + /** + * @return ArrayIterator + */ + public function getIterator(): ArrayIterator + { + return new ArrayIterator([$this->value]); + } + + public function foldLeft($initialValue, $callable) + { + return $callable($initialValue, $this->value); + } + + public function foldRight($initialValue, $callable) + { + return $callable($this->value, $initialValue); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS new file mode 100644 index 0000000..9f10d26 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS @@ -0,0 +1,7 @@ +phpseclib Lead Developer: TerraFrost (Jim Wigginton) + +phpseclib Developers: monnerat (Patrick Monnerat) + bantu (Andreas Fischer) + petrich (Hans-Jürgen Petrich) + GrahamCampbell (Graham Campbell) + hc-jworman \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md new file mode 100644 index 0000000..4ee6a4f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md @@ -0,0 +1,16 @@ +# Backers + +phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you. + +## Backers + +- Allan Simon +- [ChargeOver](https://chargeover.com/) +- Raghu Veer Dendukuri +- Zane Hooper +- [Setasign](https://www.setasign.com/) +- [Charles Severance](https://github.com/csev) +- [Rachel Fish](https://github.com/itsrachelfish) +- Tharyrok +- [cjhaas](https://github.com/cjhaas) +- [istiak-tridip](https://github.com/istiak-tridip) \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE new file mode 100644 index 0000000..e7214eb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2011-2019 TerraFrost and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md new file mode 100644 index 0000000..98e5796 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md @@ -0,0 +1,97 @@ +# phpseclib - PHP Secure Communications Library + +[![CI Status](https://github.com/phpseclib/phpseclib/actions/workflows/ci.yml/badge.svg?branch=3.0&event=push "CI Status")](https://github.com/phpseclib/phpseclib) + +## Supporting phpseclib + +- [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib) +- [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487) +- [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) + +## Introduction + +MIT-licensed pure-PHP implementations of the following: + +SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305 + +* [Browse Git](https://github.com/phpseclib/phpseclib) + +## Documentation + +* [Documentation / Manual](https://phpseclib.com/) +* [API Documentation](https://api.phpseclib.com/3.0/) (generated by Doctum) + +## Branches + +### master + +* Development Branch +* Unstable API +* Do not use in production + +### 3.0 + +* Long term support (LTS) release +* Major expansion of cryptographic primitives +* Minimum PHP version: 5.6.1 +* PSR-4 autoloading with namespace rooted at `\phpseclib3` +* Install via Composer: `composer require phpseclib/phpseclib:~3.0` + +### 2.0 + +* Long term support (LTS) release +* Modernized version of 1.0 +* Minimum PHP version: 5.3.3 +* PSR-4 autoloading with namespace rooted at `\phpseclib` +* Install via Composer: `composer require phpseclib/phpseclib:~2.0` + +### 1.0 + +* Long term support (LTS) release +* PHP4 compatible +* Composer compatible (PSR-0 autoloading) +* Install using Composer: `composer require phpseclib/phpseclib:~1.0` +* [Download 1.0.22 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.22.zip/download) + +## Security contact information + +To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. + +## Support + +Need Support? + +* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib) +* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new) +* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use) + +## Special Thanks + +Special Thanks to our $50+ sponsors!: + +- Allan Simon +- [ChargeOver](https://chargeover.com/) + +## Contributing + +1. Fork the Project + +2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/)) + +3. Install Development Dependencies + ```sh + composer install + ``` + +4. Create a Feature Branch + +5. Run continuous integration checks: + ```sh + composer global require php:^8.1 squizlabs/php_codesniffer friendsofphp/php-cs-fixer vimeo/psalm + phpcs --standard=build/php_codesniffer.xml + php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no + psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text + vendor/bin/phpunit --verbose --configuration tests/phpunit.xml + ``` + +6. Send us a Pull Request diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json new file mode 100644 index 0000000..5052d5f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json @@ -0,0 +1,84 @@ +{ + "name": "phpseclib/phpseclib", + "type": "library", + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "keywords": [ + "security", + "crypto", + "cryptography", + "encryption", + "signature", + "signing", + "rsa", + "aes", + "blowfish", + "twofish", + "ssh", + "sftp", + "x509", + "x.509", + "asn1", + "asn.1", + "BigInteger" + ], + "homepage": "http://phpseclib.sourceforge.net", + "license": "MIT", + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "require": { + "php": ">=5.6.1", + "paragonie/constant_time_encoding": "^1|^2", + "paragonie/random_compat": "^1.4|^2.0|^9.99.99" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "suggest": { + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-dom": "Install the DOM extension to load XML formatted public keys." + }, + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib3\\": "phpseclib/" + } + }, + "autoload-dev": { + "psr-4": { + "phpseclib3\\Tests\\": "tests/" + } + }, + "config": { + "sort-packages": true + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php new file mode 100644 index 0000000..eac793a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php @@ -0,0 +1,505 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Common\Functions; + +use ParagonIE\ConstantTime\Base64; +use ParagonIE\ConstantTime\Base64UrlSafe; +use ParagonIE\ConstantTime\Hex; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField; + +/** + * Common String Functions + * + * @author Jim Wigginton + */ +abstract class Strings +{ + /** + * String Shift + * + * Inspired by array_shift + * + * @param string $string + * @param int $index + * @return string + */ + public static function shift(&$string, $index = 1) + { + $substr = substr($string, 0, $index); + $string = substr($string, $index); + return $substr; + } + + /** + * String Pop + * + * Inspired by array_pop + * + * @param string $string + * @param int $index + * @return string + */ + public static function pop(&$string, $index = 1) + { + $substr = substr($string, -$index); + $string = substr($string, 0, -$index); + return $substr; + } + + /** + * Parse SSH2-style string + * + * Returns either an array or a boolean if $data is malformed. + * + * Valid characters for $format are as follows: + * + * C = byte + * b = boolean (true/false) + * N = uint32 + * Q = uint64 + * s = string + * i = mpint + * L = name-list + * + * uint64 is not supported. + * + * @param string $format + * @param string $data + * @return mixed + */ + public static function unpackSSH2($format, &$data) + { + $format = self::formatPack($format); + $result = []; + for ($i = 0; $i < strlen($format); $i++) { + switch ($format[$i]) { + case 'C': + case 'b': + if (!strlen($data)) { + throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); + } + break; + case 'N': + case 'i': + case 's': + case 'L': + if (strlen($data) < 4) { + throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); + } + break; + case 'Q': + if (strlen($data) < 8) { + throw new \LengthException('At least eight byte needs to be present for successful N / i / s / L decodes'); + } + break; + + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + switch ($format[$i]) { + case 'C': + $result[] = ord(self::shift($data)); + continue 2; + case 'b': + $result[] = ord(self::shift($data)) != 0; + continue 2; + case 'N': + list(, $temp) = unpack('N', self::shift($data, 4)); + $result[] = $temp; + continue 2; + case 'Q': + // pack() added support for Q in PHP 5.6.3 and PHP 5.6 is phpseclib 3's minimum version + // so in theory we could support this BUT, "64-bit format codes are not available for + // 32-bit versions" and phpseclib works on 32-bit installs. on 32-bit installs + // 64-bit floats can be used to get larger numbers then 32-bit signed ints would allow + // for. sure, you're not gonna get the full precision of 64-bit numbers but just because + // you need > 32-bit precision doesn't mean you need the full 64-bit precision + extract(unpack('Nupper/Nlower', self::shift($data, 8))); + $temp = $upper ? 4294967296 * $upper : 0; + $temp += $lower < 0 ? ($lower & 0x7FFFFFFFF) + 0x80000000 : $lower; + // $temp = hexdec(bin2hex(self::shift($data, 8))); + $result[] = $temp; + continue 2; + } + list(, $length) = unpack('N', self::shift($data, 4)); + if (strlen($data) < $length) { + throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); + } + $temp = self::shift($data, $length); + switch ($format[$i]) { + case 'i': + $result[] = new BigInteger($temp, -256); + break; + case 's': + $result[] = $temp; + break; + case 'L': + $result[] = explode(',', $temp); + } + } + + return $result; + } + + /** + * Create SSH2-style string + * + * @param string $format + * @param string|int|float|array|bool ...$elements + * @return string + */ + public static function packSSH2($format, ...$elements) + { + $format = self::formatPack($format); + if (strlen($format) != count($elements)) { + throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); + } + $result = ''; + for ($i = 0; $i < strlen($format); $i++) { + $element = $elements[$i]; + switch ($format[$i]) { + case 'C': + if (!is_int($element)) { + throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); + } + $result .= pack('C', $element); + break; + case 'b': + if (!is_bool($element)) { + throw new \InvalidArgumentException('A boolean parameter was expected.'); + } + $result .= $element ? "\1" : "\0"; + break; + case 'Q': + if (!is_int($element) && !is_float($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + // 4294967296 == 1 << 32 + $result .= pack('NN', $element / 4294967296, $element); + break; + case 'N': + if (is_float($element)) { + $element = (int) $element; + } + if (!is_int($element)) { + throw new \InvalidArgumentException('An integer was expected.'); + } + $result .= pack('N', $element); + break; + case 's': + if (!self::is_stringable($element)) { + throw new \InvalidArgumentException('A string was expected.'); + } + $result .= pack('Na*', strlen($element), $element); + break; + case 'i': + if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { + throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); + } + $element = $element->toBytes(true); + $result .= pack('Na*', strlen($element), $element); + break; + case 'L': + if (!is_array($element)) { + throw new \InvalidArgumentException('An array was expected.'); + } + $element = implode(',', $element); + $result .= pack('Na*', strlen($element), $element); + break; + default: + throw new \InvalidArgumentException('$format contains an invalid character'); + } + } + return $result; + } + + /** + * Expand a pack string + * + * Converts C5 to CCCCC, for example. + * + * @param string $format + * @return string + */ + private static function formatPack($format) + { + $parts = preg_split('#(\d+)#', $format, -1, PREG_SPLIT_DELIM_CAPTURE); + $format = ''; + for ($i = 1; $i < count($parts); $i += 2) { + $format .= substr($parts[$i - 1], 0, -1) . str_repeat(substr($parts[$i - 1], -1), $parts[$i]); + } + $format .= $parts[$i - 1]; + + return $format; + } + + /** + * Convert binary data into bits + * + * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst + * decbin / bindec refer to base-2 encoded data as binary. For the purposes + * of this function, bin refers to base-256 encoded data whilst bits refers + * to base-2 encoded data + * + * @param string $x + * @return string + */ + public static function bits2bin($x) + { + /* + // the pure-PHP approach is faster than the GMP approach + if (function_exists('gmp_export')) { + return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); + } + */ + + if (preg_match('#[^01]#', $x)) { + throw new \RuntimeException('The only valid characters are 0 and 1'); + } + + if (!defined('PHP_INT_MIN')) { + define('PHP_INT_MIN', ~PHP_INT_MAX); + } + + $length = strlen($x); + if (!$length) { + return ''; + } + $block_size = PHP_INT_SIZE << 3; + $pad = $block_size - ($length % $block_size); + if ($pad != $block_size) { + $x = str_repeat('0', $pad) . $x; + } + + $parts = str_split($x, $block_size); + $str = ''; + foreach ($parts as $part) { + $xor = $part[0] == '1' ? PHP_INT_MIN : 0; + $part[0] = '0'; + $str .= pack( + PHP_INT_SIZE == 4 ? 'N' : 'J', + $xor ^ eval('return 0b' . $part . ';') + ); + } + return ltrim($str, "\0"); + } + + /** + * Convert bits to binary data + * + * @param string $x + * @return string + */ + public static function bin2bits($x, $trim = true) + { + /* + // the pure-PHP approach is slower than the GMP approach BUT + // i want to the pure-PHP version to be easily unit tested as well + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + */ + + $len = strlen($x); + $mod = $len % PHP_INT_SIZE; + if ($mod) { + $x = str_pad($x, $len + PHP_INT_SIZE - $mod, "\0", STR_PAD_LEFT); + } + + $bits = ''; + if (PHP_INT_SIZE == 4) { + $digits = unpack('N*', $x); + foreach ($digits as $digit) { + $bits .= sprintf('%032b', $digit); + } + } else { + $digits = unpack('J*', $x); + foreach ($digits as $digit) { + $bits .= sprintf('%064b', $digit); + } + } + + return $trim ? ltrim($bits, '0') : $bits; + } + + /** + * Switch Endianness Bit Order + * + * @param string $x + * @return string + */ + public static function switchEndianness($x) + { + $r = ''; + for ($i = strlen($x) - 1; $i >= 0; $i--) { + $b = ord($x[$i]); + if (PHP_INT_SIZE === 8) { + // 3 operations + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv + $r .= chr((($b * 0x0202020202) & 0x010884422010) % 1023); + } else { + // 7 operations + // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits + $p1 = ($b * 0x0802) & 0x22110; + $p2 = ($b * 0x8020) & 0x88440; + $r .= chr( + (($p1 | $p2) * 0x10101) >> 16 + ); + } + } + return $r; + } + + /** + * Increment the current string + * + * @param string $var + * @return string + */ + public static function increment_str(&$var) + { + if (function_exists('sodium_increment')) { + $var = strrev($var); + sodium_increment($var); + $var = strrev($var); + return $var; + } + + for ($i = 4; $i <= strlen($var); $i += 4) { + $temp = substr($var, -$i, 4); + switch ($temp) { + case "\xFF\xFF\xFF\xFF": + $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); + break; + case "\x7F\xFF\xFF\xFF": + $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); + return $var; + default: + $temp = unpack('Nnum', $temp); + $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); + return $var; + } + } + + $remainder = strlen($var) % 4; + + if ($remainder == 0) { + return $var; + } + + $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); + $temp = substr(pack('N', $temp['num'] + 1), -$remainder); + $var = substr_replace($var, $temp, 0, $remainder); + + return $var; + } + + /** + * Find whether the type of a variable is string (or could be converted to one) + * + * @param mixed $var + * @return bool + * @psalm-assert-if-true string|\Stringable $var + */ + public static function is_stringable($var) + { + return is_string($var) || (is_object($var) && method_exists($var, '__toString')); + } + + /** + * Constant Time Base64-decoding + * + * ParagoneIE\ConstantTime doesn't use libsodium if it's available so we'll do so + * ourselves. see https://github.com/paragonie/constant_time_encoding/issues/39 + * + * @param string $data + * @return string + */ + public static function base64_decode($data) + { + return function_exists('sodium_base642bin') ? + sodium_base642bin($data, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, '=') : + Base64::decode($data); + } + + /** + * Constant Time Base64-decoding (URL safe) + * + * @param string $data + * @return string + */ + public static function base64url_decode($data) + { + // return self::base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); + + return function_exists('sodium_base642bin') ? + sodium_base642bin($data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, '=') : + Base64UrlSafe::decode($data); + } + + /** + * Constant Time Base64-encoding + * + * @param string $data + * @return string + */ + public static function base64_encode($data) + { + return function_exists('sodium_bin2base64') ? + sodium_bin2base64($data, SODIUM_BASE64_VARIANT_ORIGINAL) : + Base64::encode($data); + } + + /** + * Constant Time Base64-encoding (URL safe) + * + * @param string $data + * @return string + */ + public static function base64url_encode($data) + { + // return str_replace(['+', '/'], ['-', '_'], self::base64_encode($data)); + + return function_exists('sodium_bin2base64') ? + sodium_bin2base64($data, SODIUM_BASE64_VARIANT_URLSAFE) : + Base64UrlSafe::encode($data); + } + + /** + * Constant Time Hex Decoder + * + * @param string $data + * @return string + */ + public static function hex2bin($data) + { + return function_exists('sodium_hex2bin') ? + sodium_hex2bin($data) : + Hex::decode($data); + } + + /** + * Constant Time Hex Encoder + * + * @param string $data + * @return string + */ + public static function bin2hex($data) + { + return function_exists('sodium_bin2hex') ? + sodium_bin2hex($data) : + Hex::encode($data); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php new file mode 100644 index 0000000..4038716 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php @@ -0,0 +1,116 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $aes->decrypt($aes->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +/** + * Pure-PHP implementation of AES. + * + * @author Jim Wigginton + */ +class AES extends Rijndael +{ + /** + * Dummy function + * + * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. + * + * @see \phpseclib3\Crypt\Rijndael::setBlockLength() + * @param int $length + * @throws \BadMethodCallException anytime it's called + */ + public function setBlockLength($length) + { + throw new \BadMethodCallException('The block length cannot be set for AES.'); + } + + /** + * Sets the key length + * + * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length + * + * @see \phpseclib3\Crypt\Rijndael:setKeyLength() + * @param int $length + * @throws \LengthException if the key length isn't supported + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + case 256: + break; + default: + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); + } + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Rijndael supports five different key lengths, AES only supports three. + * + * @see \phpseclib3\Crypt\Rijndael:setKey() + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKey($key); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php new file mode 100644 index 0000000..1225070 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php @@ -0,0 +1,918 @@ + unpack('N*', $x), $blocks); it jumps up by an additional + * ~90MB, yielding a 106x increase in memory usage. Consequently, it bcrypt calls a different + * _encryptBlock() then the regular Blowfish does. That said, the Blowfish _encryptBlock() is + * basically just a thin wrapper around the bcrypt _encryptBlock(), so there's that. + * + * This explains 3 of the 4 _encryptBlock() implementations. the last _encryptBlock() + * implementation can best be understood by doing Ctrl + F and searching for where + * self::$use_reg_intval is defined. + * + * # phpseclib's three different _setupKey() implementations + * + * Every bcrypt round is the equivalent of encrypting 512KB of data. Since OpenSSH uses 16 + * rounds by default that's ~8MB of data that's essentially being encrypted whenever + * you use bcrypt. That's a lot of data, however, bcrypt operates within tighter constraints + * than regular Blowfish, so we can use that to our advantage. In particular, whereas Blowfish + * supports variable length keys, in bcrypt, the initial "key" is the sha512 hash of the + * password. sha512 hashes are 512 bits or 64 bytes long and thus the bcrypt keys are of a + * fixed length whereas Blowfish keys are not of a fixed length. + * + * bcrypt actually has two different key expansion steps. The first one (expandstate) is + * constantly XOR'ing every _encryptBlock() parameter against the salt prior _encryptBlock()'s + * being called. The second one (expand0state) is more similar to Blowfish's _setupKey() + * but it can still use the fixed length key optimization discussed above and can do away with + * the pack() / unpack() calls. + * + * I suppose _setupKey() could be made to be a thin wrapper around expandstate() but idk it's + * just a lot of work for very marginal benefits as _setupKey() is only called once for + * regular Blowfish vs the 128 times it's called --per round-- with bcrypt. + * + * # blowfish + bcrypt in the same class + * + * Altho there's a lot of Blowfish code that bcrypt doesn't re-use, bcrypt does re-use the + * initial S-boxes, the initial P-array and the int-only _encryptBlock() implementation. + * + * # Credit + * + * phpseclib's bcrypt implementation is based losely off of OpenSSH's implementation: + * + * https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c + * + * Here's a short example of how to use this library: + * + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; + +/** + * Pure-PHP implementation of Blowfish. + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +class Blowfish extends BlockCipher +{ + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 8; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'blowfish'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + */ + protected $cfb_init_len = 500; + + /** + * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each + * + * S-Box 0 + * + * @var array + */ + private static $sbox0 = [ + 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, + 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, + 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, + 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, + 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, + 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, + 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, + 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, + 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, + 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, + 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, + 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, + 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, + 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, + 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, + 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, + 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, + 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, + 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, + 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, + 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, + 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, + 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, + 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, + 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, + 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, + 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, + 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, + 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, + 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, + 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, + 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a + ]; + + /** + * S-Box 1 + * + * @var array + */ + private static $sbox1 = [ + 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, + 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, + 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, + 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, + 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, + 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, + 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, + 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, + 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, + 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, + 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, + 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, + 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, + 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, + 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, + 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, + 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, + 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, + 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, + 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, + 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, + 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, + 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, + 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, + 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, + 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, + 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, + 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, + 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, + 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, + 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, + 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 + ]; + + /** + * S-Box 2 + * + * @var array + */ + private static $sbox2 = [ + 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, + 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, + 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, + 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, + 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, + 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, + 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, + 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, + 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, + 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, + 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, + 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, + 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, + 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, + 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, + 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, + 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, + 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, + 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, + 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, + 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, + 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, + 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, + 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, + 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, + 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, + 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, + 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, + 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, + 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, + 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, + 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 + ]; + + /** + * S-Box 3 + * + * @var array + */ + private static $sbox3 = [ + 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, + 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, + 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, + 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, + 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, + 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, + 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, + 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, + 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, + 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, + 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, + 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, + 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, + 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, + 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, + 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, + 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, + 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, + 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, + 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, + 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, + 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, + 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, + 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, + 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, + 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, + 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, + 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, + 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, + 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, + 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, + 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 + ]; + + /** + * P-Array consists of 18 32-bit subkeys + * + * @var array + */ + private static $parray = [ + 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, + 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, + 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b + ]; + + /** + * The BCTX-working Array + * + * Holds the expanded key [p] and the key-depended s-boxes [sb] + * + * @var array + */ + private $bctx; + + /** + * Holds the last used key + * + * @var array + */ + private $kl; + + /** + * The Key Length (in bytes) + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @var int + */ + protected $key_length = 16; + + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Sets the key length. + * + * Key lengths can be between 32 and 448 bits. + * + * @param int $length + */ + public function setKeyLength($length) + { + if ($length < 32 || $length > 448) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); + } + + $this->key_length = $length >> 3; + + parent::setKeyLength($length); + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + if ($this->key_length < 16) { + return false; + } + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } + $this->cipher_name_openssl_ecb = 'bf-ecb'; + $this->cipher_name_openssl = 'bf-' . $this->openssl_translate_mode(); + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key]; + + /* key-expanding p[] and S-Box building sb[] */ + $this->bctx = [ + 'p' => [], + 'sb' => [ + self::$sbox0, + self::$sbox1, + self::$sbox2, + self::$sbox3 + ] + ]; + + // unpack binary string in unsigned chars + $key = array_values(unpack('C*', $this->key)); + $keyl = count($key); + // with bcrypt $keyl will always be 16 (because the key is the sha512 of the key you provide) + for ($j = 0, $i = 0; $i < 18; ++$i) { + // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ... + for ($data = 0, $k = 0; $k < 4; ++$k) { + $data = ($data << 8) | $key[$j]; + if (++$j >= $keyl) { + $j = 0; + } + } + $this->bctx['p'][] = self::$parray[$i] ^ intval($data); + } + + // encrypt the zero-string, replace P1 and P2 with the encrypted data, + // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys + $data = "\0\0\0\0\0\0\0\0"; + for ($i = 0; $i < 18; $i += 2) { + list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + $this->bctx['p'][$i ] = $l; + $this->bctx['p'][$i + 1] = $r; + } + for ($i = 0; $i < 4; ++$i) { + for ($j = 0; $j < 256; $j += 2) { + list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); + $this->bctx['sb'][$i][$j ] = $l; + $this->bctx['sb'][$i][$j + 1] = $r; + } + } + } + + /** + * Initialize Static Variables + */ + protected static function initialize_static_variables() + { + if (is_float(self::$sbox2[0])) { + self::$sbox0 = array_map('intval', self::$sbox0); + self::$sbox1 = array_map('intval', self::$sbox1); + self::$sbox2 = array_map('intval', self::$sbox2); + self::$sbox3 = array_map('intval', self::$sbox3); + self::$parray = array_map('intval', self::$parray); + } + + parent::initialize_static_variables(); + } + + /** + * bcrypt + * + * @param string $sha2pass + * @param string $sha2salt + * @access private + * @return string + */ + private static function bcrypt_hash($sha2pass, $sha2salt) + { + $p = self::$parray; + $sbox0 = self::$sbox0; + $sbox1 = self::$sbox1; + $sbox2 = self::$sbox2; + $sbox3 = self::$sbox3; + + $cdata = array_values(unpack('N*', 'OxychromaticBlowfishSwatDynamite')); + $sha2pass = array_values(unpack('N*', $sha2pass)); + $sha2salt = array_values(unpack('N*', $sha2salt)); + + self::expandstate($sha2salt, $sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 0; $i < 64; $i++) { + self::expand0state($sha2salt, $sbox0, $sbox1, $sbox2, $sbox3, $p); + self::expand0state($sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + for ($i = 0; $i < 64; $i++) { + for ($j = 0; $j < 8; $j += 2) { // count($cdata) == 8 + list($cdata[$j], $cdata[$j + 1]) = self::encryptBlockHelperFast($cdata[$j], $cdata[$j + 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + } + + return pack('L*', ...$cdata); + } + + /** + * Performs OpenSSH-style bcrypt + * + * @param string $pass + * @param string $salt + * @param int $keylen + * @param int $rounds + * @access public + * @return string + */ + public static function bcrypt_pbkdf($pass, $salt, $keylen, $rounds) + { + self::initialize_static_variables(); + + if (PHP_INT_SIZE == 4) { + throw new \RuntimeException('bcrypt is far too slow to be practical on 32-bit versions of PHP'); + } + + $sha2pass = hash('sha512', $pass, true); + $results = []; + $count = 1; + while (32 * count($results) < $keylen) { + $countsalt = $salt . pack('N', $count++); + $sha2salt = hash('sha512', $countsalt, true); + $out = $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); + for ($i = 1; $i < $rounds; $i++) { + $sha2salt = hash('sha512', $tmpout, true); + $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); + $out ^= $tmpout; + } + $results[] = $out; + } + $output = ''; + for ($i = 0; $i < 32; $i++) { + foreach ($results as $result) { + $output .= $result[$i]; + } + } + return substr($output, 0, $keylen); + } + + /** + * Key expansion without salt + * + * @access private + * @param int[] $key + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @see self::_bcrypt_hash() + */ + private static function expand0state(array $key, array &$sbox0, array &$sbox1, array &$sbox2, array &$sbox3, array &$p) + { + // expand0state is basically the same thing as this: + //return self::expandstate(array_fill(0, 16, 0), $key); + // but this separate function eliminates a bunch of XORs and array lookups + + $p = [ + $p[0] ^ $key[0], + $p[1] ^ $key[1], + $p[2] ^ $key[2], + $p[3] ^ $key[3], + $p[4] ^ $key[4], + $p[5] ^ $key[5], + $p[6] ^ $key[6], + $p[7] ^ $key[7], + $p[8] ^ $key[8], + $p[9] ^ $key[9], + $p[10] ^ $key[10], + $p[11] ^ $key[11], + $p[12] ^ $key[12], + $p[13] ^ $key[13], + $p[14] ^ $key[14], + $p[15] ^ $key[15], + $p[16] ^ $key[0], + $p[17] ^ $key[1] + ]; + + // @codingStandardsIgnoreStart + list( $p[0], $p[1]) = self::encryptBlockHelperFast( 0, 0, $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[2], $p[3]) = self::encryptBlockHelperFast($p[ 0], $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[4], $p[5]) = self::encryptBlockHelperFast($p[ 2], $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[6], $p[7]) = self::encryptBlockHelperFast($p[ 4], $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[8], $p[9]) = self::encryptBlockHelperFast($p[ 6], $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[10], $p[11]) = self::encryptBlockHelperFast($p[ 8], $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[12], $p[13]) = self::encryptBlockHelperFast($p[10], $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[14], $p[15]) = self::encryptBlockHelperFast($p[12], $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[16], $p[17]) = self::encryptBlockHelperFast($p[14], $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p); + // @codingStandardsIgnoreEnd + + list($sbox0[0], $sbox0[1]) = self::encryptBlockHelperFast($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox0[$i], $sbox0[$i + 1]) = self::encryptBlockHelperFast($sbox0[$i - 2], $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox1[0], $sbox1[1]) = self::encryptBlockHelperFast($sbox0[254], $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox1[$i], $sbox1[$i + 1]) = self::encryptBlockHelperFast($sbox1[$i - 2], $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox2[0], $sbox2[1]) = self::encryptBlockHelperFast($sbox1[254], $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox2[$i], $sbox2[$i + 1]) = self::encryptBlockHelperFast($sbox2[$i - 2], $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox3[0], $sbox3[1]) = self::encryptBlockHelperFast($sbox2[254], $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2; $i < 256; $i += 2) { + list($sbox3[$i], $sbox3[$i + 1]) = self::encryptBlockHelperFast($sbox3[$i - 2], $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + } + + /** + * Key expansion with salt + * + * @access private + * @param int[] $data + * @param int[] $key + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @see self::_bcrypt_hash() + */ + private static function expandstate(array $data, array $key, array &$sbox0, array &$sbox1, array &$sbox2, array &$sbox3, array &$p) + { + $p = [ + $p[0] ^ $key[0], + $p[1] ^ $key[1], + $p[2] ^ $key[2], + $p[3] ^ $key[3], + $p[4] ^ $key[4], + $p[5] ^ $key[5], + $p[6] ^ $key[6], + $p[7] ^ $key[7], + $p[8] ^ $key[8], + $p[9] ^ $key[9], + $p[10] ^ $key[10], + $p[11] ^ $key[11], + $p[12] ^ $key[12], + $p[13] ^ $key[13], + $p[14] ^ $key[14], + $p[15] ^ $key[15], + $p[16] ^ $key[0], + $p[17] ^ $key[1] + ]; + + // @codingStandardsIgnoreStart + list( $p[0], $p[1]) = self::encryptBlockHelperFast($data[ 0] , $data[ 1] , $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[2], $p[3]) = self::encryptBlockHelperFast($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[4], $p[5]) = self::encryptBlockHelperFast($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[6], $p[7]) = self::encryptBlockHelperFast($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list( $p[8], $p[9]) = self::encryptBlockHelperFast($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[10], $p[11]) = self::encryptBlockHelperFast($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[12], $p[13]) = self::encryptBlockHelperFast($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[14], $p[15]) = self::encryptBlockHelperFast($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p); + list($p[16], $p[17]) = self::encryptBlockHelperFast($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p); + // @codingStandardsIgnoreEnd + + list($sbox0[0], $sbox0[1]) = self::encryptBlockHelperFast($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better? + list($sbox0[$i], $sbox0[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox0[$i - 2], $data[$j + 1] ^ $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox1[0], $sbox1[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox0[254], $data[3] ^ $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { + list($sbox1[$i], $sbox1[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox1[$i - 2], $data[$j + 1] ^ $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox2[0], $sbox2[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox1[254], $data[3] ^ $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { + list($sbox2[$i], $sbox2[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox2[$i - 2], $data[$j + 1] ^ $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + + list($sbox3[0], $sbox3[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox2[254], $data[3] ^ $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); + for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { + list($sbox3[$i], $sbox3[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox3[$i - 2], $data[$j + 1] ^ $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); + } + } + + /** + * Encrypts a block + * + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + $p = $this->bctx['p']; + // extract($this->bctx['sb'], EXTR_PREFIX_ALL, 'sb'); // slower + $sb_0 = $this->bctx['sb'][0]; + $sb_1 = $this->bctx['sb'][1]; + $sb_2 = $this->bctx['sb'][2]; + $sb_3 = $this->bctx['sb'][3]; + + $in = unpack('N*', $in); + $l = $in[1]; + $r = $in[2]; + + list($r, $l) = PHP_INT_SIZE == 4 ? + self::encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) : + self::encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p); + + return pack("N*", $r, $l); + } + + /** + * Fast helper function for block encryption + * + * @access private + * @param int $x0 + * @param int $x1 + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @return int[] + */ + private static function encryptBlockHelperFast($x0, $x1, array $sbox0, array $sbox1, array $sbox2, array $sbox3, array $p) + { + $x0 ^= $p[0]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; + $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; + $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; + + return [$x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF]; + } + + /** + * Slow helper function for block encryption + * + * @access private + * @param int $x0 + * @param int $x1 + * @param int[] $sbox0 + * @param int[] $sbox1 + * @param int[] $sbox2 + * @param int[] $sbox3 + * @param int[] $p + * @return int[] + */ + private static function encryptBlockHelperSlow($x0, $x1, array $sbox0, array $sbox1, array $sbox2, array $sbox3, array $p) + { + // -16777216 == intval(0xFF000000) on 32-bit PHP installs + $x0 ^= $p[0]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; + $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; + $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; + + return [$x1 ^ $p[17], $x0]; + } + + /** + * Decrypts a block + * + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + $p = $this->bctx['p']; + $sb_0 = $this->bctx['sb'][0]; + $sb_1 = $this->bctx['sb'][1]; + $sb_2 = $this->bctx['sb'][2]; + $sb_3 = $this->bctx['sb'][3]; + + $in = unpack('N*', $in); + $l = $in[1]; + $r = $in[2]; + + for ($i = 17; $i > 2; $i -= 2) { + $l ^= $p[$i]; + $r ^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]); + + $r ^= $p[$i - 1]; + $l ^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]); + } + return pack('N*', $r ^ $p[0], $l ^ $p[1]); + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + $p = $this->bctx['p']; + $init_crypt = ' + static $sb_0, $sb_1, $sb_2, $sb_3; + if (!$sb_0) { + $sb_0 = $this->bctx["sb"][0]; + $sb_1 = $this->bctx["sb"][1]; + $sb_2 = $this->bctx["sb"][2]; + $sb_3 = $this->bctx["sb"][3]; + } + '; + + $safeint = self::safe_intval_inline(); + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + for ($i = 0; $i < 16; $i += 2) { + $encrypt_block .= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i + 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + $encrypt_block .= ' + $in = pack("N*", + $r ^ ' . $p[17] . ', + $l ^ ' . $p[16] . ' + ); + '; + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + '; + + for ($i = 17; $i > 2; $i -= 2) { + $decrypt_block .= ' + $l^= ' . $p[$i] . '; + $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ + $sb_2[$l >> 8 & 0xff]) + + $sb_3[$l & 0xff]') . '; + + $r^= ' . $p[$i - 1] . '; + $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ + $sb_2[$r >> 8 & 0xff]) + + $sb_3[$r & 0xff]') . '; + '; + } + + $decrypt_block .= ' + $in = pack("N*", + $r ^ ' . $p[0] . ', + $l ^ ' . $p[1] . ' + ); + '; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php new file mode 100644 index 0000000..b2691b5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php @@ -0,0 +1,799 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\InsufficientSetupException; + +/** + * Pure-PHP implementation of ChaCha20. + * + * @author Jim Wigginton + */ +class ChaCha20 extends Salsa20 +{ + /** + * The OpenSSL specific name of the cipher + * + * @var string + */ + protected $cipher_name_openssl = 'chacha20'; + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_LIBSODIUM: + // PHP 7.2.0 (30 Nov 2017) added support for libsodium + + // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL + // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm + + // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string + // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority + return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') && + $this->key_length == 32 && + (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) && + !$this->continuousBuffer; + case self::ENGINE_OPENSSL: + // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20. + // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017) + + // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null + // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that + // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode + // whereas libsodium does not + if ($this->key_length != 32) { + return false; + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + $this->setup(); + + if ($this->engine == self::ENGINE_LIBSODIUM) { + return $this->encrypt_with_libsodium($plaintext); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + $this->setup(); + + if ($this->engine == self::ENGINE_LIBSODIUM) { + return $this->decrypt_with_libsodium($ciphertext); + } + + return parent::decrypt($ciphertext); + } + + /** + * Encrypts a message with libsodium + * + * @see self::encrypt() + * @param string $plaintext + * @return string $text + */ + private function encrypt_with_libsodium($plaintext) + { + $params = [$plaintext, $this->aad, $this->nonce, $this->key]; + $ciphertext = strlen($this->nonce) == 8 ? + sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : + sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); + if (!$this->usePoly1305) { + return substr($ciphertext, 0, strlen($plaintext)); + } + + $newciphertext = substr($ciphertext, 0, strlen($plaintext)); + + $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ? + substr($ciphertext, strlen($plaintext)) : + $this->poly1305($newciphertext); + + return $newciphertext; + } + + /** + * Decrypts a message with libsodium + * + * @see self::decrypt() + * @param string $ciphertext + * @return string $text + */ + private function decrypt_with_libsodium($ciphertext) + { + $params = [$ciphertext, $this->aad, $this->nonce, $this->key]; + + if (isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) { + $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params); + $this->oldtag = false; + if ($plaintext === false) { + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + return $plaintext; + } + $newtag = $this->poly1305($ciphertext); + if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + } + + $plaintext = strlen($this->nonce) == 8 ? + sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : + sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); + + return substr($plaintext, 0, strlen($ciphertext)); + } + + /** + * Sets the nonce. + * + * @param string $nonce + */ + public function setNonce($nonce) + { + if (!is_string($nonce)) { + throw new \UnexpectedValueException('The nonce should be a string'); + } + + /* + from https://tools.ietf.org/html/rfc7539#page-7 + + "Note also that the original ChaCha had a 64-bit nonce and 64-bit + block count. We have modified this here to be more consistent with + recommendations in Section 3.2 of [RFC5116]." + */ + switch (strlen($nonce)) { + case 8: // 64 bits + case 12: // 96 bits + break; + default: + throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); + } + + $this->nonce = $nonce; + $this->changed = true; + $this->setEngine(); + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setNonce() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setNonce() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; + + $this->changed = $this->nonIVChanged = false; + + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + if ($this->usePoly1305 && !isset($this->poly1305Key)) { + $this->usingGeneratedPoly1305Key = true; + if ($this->engine == self::ENGINE_LIBSODIUM) { + return; + } + $this->createPoly1305Key(); + } + + $key = $this->key; + if (strlen($key) == 16) { + $constant = 'expand 16-byte k'; + $key .= $key; + } else { + $constant = 'expand 32-byte k'; + } + + $this->p1 = $constant . $key; + $this->p2 = $this->nonce; + if (strlen($this->nonce) == 8) { + $this->p2 = "\0\0\0\0" . $this->p2; + } + } + + /** + * The quarterround function + * + * @param int $a + * @param int $b + * @param int $c + * @param int $d + */ + protected static function quarterRound(&$a, &$b, &$c, &$d) + { + // in https://datatracker.ietf.org/doc/html/rfc7539#section-2.1 the addition, + // xor'ing and rotation are all on the same line so i'm keeping it on the same + // line here as well + // @codingStandardsIgnoreStart + $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 16); + $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 12); + $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 8); + $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 7); + // @codingStandardsIgnoreEnd + } + + /** + * The doubleround function + * + * @param int $x0 (by reference) + * @param int $x1 (by reference) + * @param int $x2 (by reference) + * @param int $x3 (by reference) + * @param int $x4 (by reference) + * @param int $x5 (by reference) + * @param int $x6 (by reference) + * @param int $x7 (by reference) + * @param int $x8 (by reference) + * @param int $x9 (by reference) + * @param int $x10 (by reference) + * @param int $x11 (by reference) + * @param int $x12 (by reference) + * @param int $x13 (by reference) + * @param int $x14 (by reference) + * @param int $x15 (by reference) + */ + protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) + { + // columnRound + static::quarterRound($x0, $x4, $x8, $x12); + static::quarterRound($x1, $x5, $x9, $x13); + static::quarterRound($x2, $x6, $x10, $x14); + static::quarterRound($x3, $x7, $x11, $x15); + // rowRound + static::quarterRound($x0, $x5, $x10, $x15); + static::quarterRound($x1, $x6, $x11, $x12); + static::quarterRound($x2, $x7, $x8, $x13); + static::quarterRound($x3, $x4, $x9, $x14); + } + + /** + * The Salsa20 hash function function + * + * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in + * 0.65s vs the 0.85s that it takes with the parent method. + * + * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could + * be eliminated and we could knock this done to 0.60s. + * + * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s. + * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval + * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc + * + * @param string $x + */ + protected static function salsa20($x) + { + list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x); + $z0 = $x0; + $z1 = $x1; + $z2 = $x2; + $z3 = $x3; + $z4 = $x4; + $z5 = $x5; + $z6 = $x6; + $z7 = $x7; + $z8 = $x8; + $z9 = $x9; + $z10 = $x10; + $z11 = $x11; + $z12 = $x12; + $z13 = $x13; + $z14 = $x14; + $z15 = $x15; + + // @codingStandardsIgnoreStart + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + + // columnRound + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); + $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); + $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); + + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); + $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); + $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); + + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); + $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); + $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); + + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); + $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); + $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); + + // rowRound + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); + $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); + $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); + + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); + $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); + $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); + + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); + $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); + $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); + + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); + $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); + $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); + // @codingStandardsIgnoreEnd + + $x0 += $z0; + $x1 += $z1; + $x2 += $z2; + $x3 += $z3; + $x4 += $z4; + $x5 += $z5; + $x6 += $z6; + $x7 += $z7; + $x8 += $z8; + $x9 += $z9; + $x10 += $z10; + $x11 += $z11; + $x12 += $z12; + $x13 += $z13; + $x14 += $z14; + $x15 += $z15; + + return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php new file mode 100644 index 0000000..09eb5b1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php @@ -0,0 +1,581 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Base Class for all asymmetric cipher classes + * + * @author Jim Wigginton + */ +abstract class AsymmetricKey +{ + /** + * Precomputed Zero + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $zero; + + /** + * Precomputed One + * + * @var \phpseclib3\Math\BigInteger + */ + protected static $one; + + /** + * Format of the loaded key + * + * @var string + */ + protected $format; + + /** + * Hash function + * + * @var \phpseclib3\Crypt\Hash + */ + protected $hash; + + /** + * HMAC function + * + * @var \phpseclib3\Crypt\Hash + */ + private $hmac; + + /** + * Supported plugins (lower case) + * + * @see self::initialize_static_variables() + * @var array + */ + private static $plugins = []; + + /** + * Invisible plugins + * + * @see self::initialize_static_variables() + * @var array + */ + private static $invisiblePlugins = []; + + /** + * Available Engines + * + * @var boolean[] + */ + protected static $engines = []; + + /** + * Key Comment + * + * @var null|string + */ + private $comment; + + /** + * @param string $type + * @return array|string + */ + abstract public function toString($type, array $options = []); + + /** + * The constructor + */ + protected function __construct() + { + self::initialize_static_variables(); + + $this->hash = new Hash('sha256'); + $this->hmac = new Hash('sha256'); + } + + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$zero)) { + self::$zero = new BigInteger(0); + self::$one = new BigInteger(1); + } + + self::loadPlugins('Keys'); + if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { + self::loadPlugins('Signature'); + } + } + + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return \phpseclib3\Crypt\Common\PublicKey|\phpseclib3\Crypt\Common\PrivateKey + */ + public static function load($key, $password = false) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('load() should not be called from final classes (' . static::class . ')'); + } + + $components = false; + foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { + if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { + continue; + } + try { + $components = $format::load($key, $password); + } catch (\Exception $e) { + $components = false; + } + if ($components !== false) { + break; + } + } + + if ($components === false) { + throw new NoKeyLoadedException('Unable to read key'); + } + + $components['format'] = $format; + $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; + $comment = isset($components['comment']) ? $components['comment'] : null; + $new = static::onLoad($components); + $new->format = $format; + $new->comment = $comment; + return $new instanceof PrivateKey ? + $new->withPassword($password) : + $new; + } + + /** + * Loads a private key + * + * @return PrivateKey + * @param string|array $key + * @param string $password optional + */ + public static function loadPrivateKey($key, $password = '') + { + $key = self::load($key, $password); + if (!$key instanceof PrivateKey) { + throw new NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + + /** + * Loads a public key + * + * @return PublicKey + * @param string|array $key + */ + public static function loadPublicKey($key) + { + $key = self::load($key); + if (!$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string|array $key + */ + public static function loadParameters($key) + { + $key = self::load($key); + if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } + + /** + * Load the key, assuming a specific format + * + * @param string $type + * @param string $key + * @param string $password optional + * @return static + */ + public static function loadFormat($type, $key, $password = false) + { + self::initialize_static_variables(); + + $components = false; + $format = strtolower($type); + if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { + $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; + $components = $format::load($key, $password); + } + + if ($components === false) { + throw new NoKeyLoadedException('Unable to read key'); + } + + $components['format'] = $format; + $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; + + $new = static::onLoad($components); + $new->format = $format; + return $new instanceof PrivateKey ? + $new->withPassword($password) : + $new; + } + + /** + * Loads a private key + * + * @return PrivateKey + * @param string $type + * @param string $key + * @param string $password optional + */ + public static function loadPrivateKeyFormat($type, $key, $password = false) + { + $key = self::loadFormat($type, $key, $password); + if (!$key instanceof PrivateKey) { + throw new NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + + /** + * Loads a public key + * + * @return PublicKey + * @param string $type + * @param string $key + */ + public static function loadPublicKeyFormat($type, $key) + { + $key = self::loadFormat($type, $key); + if (!$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string $type + * @param string|array $key + */ + public static function loadParametersFormat($type, $key) + { + $key = self::loadFormat($type, $key); + if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } + + /** + * Validate Plugin + * + * @param string $format + * @param string $type + * @param string $method optional + * @return mixed + */ + protected static function validatePlugin($format, $type, $method = null) + { + $type = strtolower($type); + if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { + throw new UnsupportedFormatException("$type is not a supported format"); + } + $type = self::$plugins[static::ALGORITHM][$format][$type]; + if (isset($method) && !method_exists($type, $method)) { + throw new UnsupportedFormatException("$type does not implement $method"); + } + + return $type; + } + + /** + * Load Plugins + * + * @param string $format + */ + private static function loadPlugins($format) + { + if (!isset(self::$plugins[static::ALGORITHM][$format])) { + self::$plugins[static::ALGORITHM][$format] = []; + foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $name = $file->getBasename('.php'); + if ($name[0] == '.') { + continue; + } + $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; + $reflect = new \ReflectionClass($type); + if ($reflect->isTrait()) { + continue; + } + self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type; + if ($reflect->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM][] = $type; + } + } + } + } + + /** + * Returns a list of supported formats. + * + * @return array + */ + public static function getSupportedKeyFormats() + { + self::initialize_static_variables(); + + return self::$plugins[static::ALGORITHM]['Keys']; + } + + /** + * Add a fileformat plugin + * + * The plugin needs to either already be loaded or be auto-loadable. + * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. + * + * @see self::load() + * @param string $fullname + * @return bool + */ + public static function addFileFormat($fullname) + { + self::initialize_static_variables(); + + if (class_exists($fullname)) { + $meta = new \ReflectionClass($fullname); + $shortname = $meta->getShortName(); + self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; + if ($meta->hasConstant('IS_INVISIBLE')) { + self::$invisiblePlugins[static::ALGORITHM][] = strtolower($shortname); + } + } + } + + /** + * Returns the format of the loaded key. + * + * If the key that was loaded wasn't in a valid or if the key was auto-generated + * with RSA::createKey() then this will throw an exception. + * + * @see self::load() + * @return mixed + */ + public function getLoadedFormat() + { + if (empty($this->format)) { + throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); + } + + $meta = new \ReflectionClass($this->format); + return $meta->getShortName(); + } + + /** + * Returns the key's comment + * + * Not all key formats support comments. If you want to set a comment use toString() + * + * @return null|string + */ + public function getComment() + { + return $this->comment; + } + + /** + * Tests engine validity + * + */ + public static function useBestEngine() + { + static::$engines = [ + 'PHP' => true, + 'OpenSSL' => extension_loaded('openssl'), + // this test can be satisfied by either of the following: + // http://php.net/manual/en/book.sodium.php + // https://github.com/paragonie/sodium_compat + 'libsodium' => function_exists('sodium_crypto_sign_keypair') + ]; + + return static::$engines; + } + + /** + * Flag to use internal engine only (useful for unit testing) + * + */ + public static function useInternalEngine() + { + static::$engines = [ + 'PHP' => true, + 'OpenSSL' => false, + 'libsodium' => false + ]; + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return $this->toString('PKCS8'); + } + + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + $new->hash = new Hash($hash); + $new->hmac = new Hash($hash); + + return $new; + } + + /** + * Returns the hash algorithm currently being used + * + */ + public function getHash() + { + return clone $this->hash; + } + + /** + * Compute the pseudorandom k for signature generation, + * using the process specified for deterministic DSA. + * + * @param string $h1 + * @return string + */ + protected function computek($h1) + { + $v = str_repeat("\1", strlen($h1)); + + $k = str_repeat("\0", strlen($h1)); + + $x = $this->int2octets($this->x); + $h1 = $this->bits2octets($h1); + + $this->hmac->setKey($k); + $k = $this->hmac->hash($v . "\0" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + $k = $this->hmac->hash($v . "\1" . $x . $h1); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + + $qlen = $this->q->getLengthInBytes(); + + while (true) { + $t = ''; + while (strlen($t) < $qlen) { + $v = $this->hmac->hash($v); + $t = $t . $v; + } + $k = $this->bits2int($t); + + if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { + break; + } + $k = $this->hmac->hash($v . "\0"); + $this->hmac->setKey($k); + $v = $this->hmac->hash($v); + } + + return $k; + } + + /** + * Integer to Octet String + * + * @param \phpseclib3\Math\BigInteger $v + * @return string + */ + private function int2octets($v) + { + $out = $v->toBytes(); + $rolen = $this->q->getLengthInBytes(); + if (strlen($out) < $rolen) { + return str_pad($out, $rolen, "\0", STR_PAD_LEFT); + } elseif (strlen($out) > $rolen) { + return substr($out, -$rolen); + } else { + return $out; + } + } + + /** + * Bit String to Integer + * + * @param string $in + * @return \phpseclib3\Math\BigInteger + */ + protected function bits2int($in) + { + $v = new BigInteger($in, 256); + $vlen = strlen($in) << 3; + $qlen = $this->q->getLength(); + if ($vlen > $qlen) { + return $v->bitwise_rightShift($vlen - $qlen); + } + return $v; + } + + /** + * Bit String to Octet String + * + * @param string $in + * @return string + */ + private function bits2octets($in) + { + $z1 = $this->bits2int($in); + $z2 = $z1->subtract($this->q); + return $z2->compare(self::$zero) < 0 ? + $this->int2octets($z1) : + $this->int2octets($z2); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php new file mode 100644 index 0000000..b2642be --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php @@ -0,0 +1,24 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * Base Class for all block cipher classes + * + * @author Jim Wigginton + */ +abstract class BlockCipher extends SymmetricKey +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php new file mode 100644 index 0000000..4c761b8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php @@ -0,0 +1,69 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; + +/** + * JSON Web Key Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class JWK +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $key = preg_replace('#\s#', '', $key); // remove whitespace + + if (PHP_VERSION_ID >= 73000) { + $key = json_decode($key, null, 512, JSON_THROW_ON_ERROR); + } else { + $key = json_decode($key); + if (!$key) { + throw new \RuntimeException('Unable to decode JSON'); + } + } + + if (isset($key->kty)) { + return $key; + } + + if (count($key->keys) != 1) { + throw new \RuntimeException('Although the JWK key format supports multiple keys phpseclib does not'); + } + + return $key->keys[0]; + } + + /** + * Wrap a key appropriately + * + * @return string + */ + protected static function wrapKey(array $key, array $options) + { + return json_encode(['keys' => [$key + $options]]); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..fe3d85b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php @@ -0,0 +1,220 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\Random; + +/** + * OpenSSH Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH +{ + /** + * Default comment + * + * @var string + */ + protected static $comment = 'phpseclib-generated-key'; + + /** + * Binary key flag + * + * @var bool + */ + protected static $binary = false; + + /** + * Sets the default comment + * + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = str_replace(["\r", "\n"], '', $comment); + } + + /** + * Break a public or private key down into its constituent components + * + * $type can be either ssh-dss or ssh-rsa + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + // key format is described here: + // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD + + if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { + $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); + $key = Strings::base64_decode($key); + $magic = Strings::shift($key, 15); + if ($magic != "openssh-key-v1\0") { + throw new \RuntimeException('Expected openssh-key-v1'); + } + list($ciphername, $kdfname, $kdfoptions, $numKeys) = Strings::unpackSSH2('sssN', $key); + if ($numKeys != 1) { + // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys + // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass + // that to the appropriate key loading parser $numKey times or something + throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); + } + switch ($ciphername) { + case 'none': + break; + case 'aes256-ctr': + if ($kdfname != 'bcrypt') { + throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)'); + } + list($salt, $rounds) = Strings::unpackSSH2('sN', $kdfoptions); + $crypto = new AES('ctr'); + //$crypto->setKeyLength(256); + //$crypto->disablePadding(); + $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); + break; + default: + throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)'); + } + + list($publicKey, $paddedKey) = Strings::unpackSSH2('ss', $key); + list($type) = Strings::unpackSSH2('s', $publicKey); + if (isset($crypto)) { + $paddedKey = $crypto->decrypt($paddedKey); + } + list($checkint1, $checkint2) = Strings::unpackSSH2('NN', $paddedKey); + // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. + if ($checkint1 != $checkint2) { + throw new \RuntimeException('The two checkints do not match'); + } + self::checkType($type); + + return compact('type', 'publicKey', 'paddedKey'); + } + + $parts = explode(' ', $key, 3); + + if (!isset($parts[1])) { + $key = base64_decode($parts[0]); + $comment = false; + } else { + $asciiType = $parts[0]; + self::checkType($parts[0]); + $key = base64_decode($parts[1]); + $comment = isset($parts[2]) ? $parts[2] : false; + } + if ($key === false) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + list($type) = Strings::unpackSSH2('s', $key); + self::checkType($type); + if (isset($asciiType) && $asciiType != $type) { + throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); + } + if (strlen($key) <= 4) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $publicKey = $key; + + return compact('type', 'publicKey', 'comment'); + } + + /** + * Toggle between binary and printable keys + * + * Printable keys are what are generated by default. These are the ones that go in + * $HOME/.ssh/authorized_key. + * + * @param bool $enabled + */ + public static function setBinaryOutput($enabled) + { + self::$binary = $enabled; + } + + /** + * Checks to see if the type is valid + * + * @param string $candidate + */ + private static function checkType($candidate) + { + if (!in_array($candidate, static::$types)) { + throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); + } + } + + /** + * Wrap a private key appropriately + * + * @param string $publicKey + * @param string $privateKey + * @param string $password + * @param array $options + * @return string + */ + protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) + { + list(, $checkint) = unpack('N', Random::string(4)); + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $paddedKey = Strings::packSSH2('NN', $checkint, $checkint) . + $privateKey . + Strings::packSSH2('s', $comment); + + $usesEncryption = !empty($password) && is_string($password); + + /* + from http://tools.ietf.org/html/rfc4253#section-6 : + + Note that the length of the concatenation of 'packet_length', + 'padding_length', 'payload', and 'random padding' MUST be a multiple + of the cipher block size or 8, whichever is larger. + */ + $blockSize = $usesEncryption ? 16 : 8; + $paddingLength = (($blockSize - 1) * strlen($paddedKey)) % $blockSize; + for ($i = 1; $i <= $paddingLength; $i++) { + $paddedKey .= chr($i); + } + if (!$usesEncryption) { + $key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); + } else { + $rounds = isset($options['rounds']) ? $options['rounds'] : 16; + $salt = Random::string(16); + $kdfoptions = Strings::packSSH2('sN', $salt, $rounds); + $crypto = new AES('ctr'); + $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); + $paddedKey = $crypto->encrypt($paddedKey); + $key = Strings::packSSH2('sssNss', 'aes256-ctr', 'bcrypt', $kdfoptions, 1, $publicKey, $paddedKey); + } + $key = "openssh-key-v1\0$key"; + + return "-----BEGIN OPENSSH PRIVATE KEY-----\n" . + chunk_split(Strings::base64_encode($key), 70, "\n") . + "-----END OPENSSH PRIVATE KEY-----\n"; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php new file mode 100644 index 0000000..0219400 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php @@ -0,0 +1,72 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +/** + * PKCS1 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS +{ + /** + * Auto-detect the format + */ + const MODE_ANY = 0; + /** + * Require base64-encoded PEM's be supplied + */ + const MODE_PEM = 1; + /** + * Require raw DER's be supplied + */ + const MODE_DER = 2; + /**#@-*/ + + /** + * Is the key a base-64 encoded PEM, DER or should it be auto-detected? + * + * @var int + */ + protected static $format = self::MODE_ANY; + + /** + * Require base64-encoded PEM's be supplied + * + */ + public static function requirePEM() + { + self::$format = self::MODE_PEM; + } + + /** + * Require raw DER's be supplied + * + */ + public static function requireDER() + { + self::$format = self::MODE_DER; + } + + /** + * Accept any format and auto detect the format + * + * This is the default setting + * + */ + public static function requireAny() + { + self::$format = self::MODE_ANY; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..4c639c0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php @@ -0,0 +1,209 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\DES; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1; + +/** + * PKCS1 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends PKCS +{ + /** + * Default encryption algorithm + * + * @var string + */ + private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; + + /** + * Sets the default encryption algorithm + * + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + + /** + * Returns the mode constant corresponding to the mode string + * + * @param string $mode + * @return int + * @throws \UnexpectedValueException if the block cipher mode is unsupported + */ + private static function getEncryptionMode($mode) + { + switch ($mode) { + case 'CBC': + case 'ECB': + case 'CFB': + case 'OFB': + case 'CTR': + return $mode; + } + throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); + } + + /** + * Returns a cipher object corresponding to a string + * + * @param string $algo + * @return string + * @throws \UnexpectedValueException if the encryption algorithm is unsupported + */ + private static function getEncryptionObject($algo) + { + $modes = '(CBC|ECB|CFB|OFB|CTR)'; + switch (true) { + case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches): + $cipher = new AES(self::getEncryptionMode($matches[2])); + $cipher->setKeyLength($matches[1]); + return $cipher; + case preg_match("#^DES-EDE3-$modes$#", $algo, $matches): + return new TripleDES(self::getEncryptionMode($matches[1])); + case preg_match("#^DES-$modes$#", $algo, $matches): + return new DES(self::getEncryptionMode($matches[1])); + default: + throw new UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); + } + } + + /** + * Generate a symmetric key for PKCS#1 keys + * + * @param string $password + * @param string $iv + * @param int $length + * @return string + */ + private static function generateSymmetricKey($password, $iv, $length) + { + $symkey = ''; + $iv = substr($iv, 0, 8); + while (strlen($symkey) < $length) { + $symkey .= md5($symkey . $password . $iv, true); + } + return substr($symkey, 0, $length); + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is + "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to + protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding + two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: + + http://tools.ietf.org/html/rfc1421#section-4.6.1.1 + http://tools.ietf.org/html/rfc1421#section-4.6.1.3 + + DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. + DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation + function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's + own implementation. ie. the implementation *is* the standard and any bugs that may exist in that + implementation are part of the standard, as well. + + * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ + if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { + $iv = Strings::hex2bin(trim($matches[2])); + // remove the Proc-Type / DEK-Info sections as they're no longer needed + $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); + $ciphertext = ASN1::extractBER($key); + if ($ciphertext === false) { + $ciphertext = $key; + } + $crypto = self::getEncryptionObject($matches[1]); + $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); + $crypto->setIV($iv); + $key = $crypto->decrypt($ciphertext); + } else { + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + } + + return $key; + } + + /** + * Wrap a private key appropriately + * + * @param string $key + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $type, $password, array $options = []) + { + if (empty($password) || !is_string($password)) { + return "-----BEGIN $type PRIVATE KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END $type PRIVATE KEY-----"; + } + + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + + $cipher = self::getEncryptionObject($encryptionAlgorithm); + $iv = Random::string($cipher->getBlockLength() >> 3); + $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); + $cipher->setIV($iv); + $iv = strtoupper(Strings::bin2hex($iv)); + return "-----BEGIN $type PRIVATE KEY-----\r\n" . + "Proc-Type: 4,ENCRYPTED\r\n" . + "DEK-Info: " . $encryptionAlgorithm . ",$iv\r\n" . + "\r\n" . + chunk_split(Strings::base64_encode($cipher->encrypt($key)), 64) . + "-----END $type PRIVATE KEY-----"; + } + + /** + * Wrap a public key appropriately + * + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + return "-----BEGIN $type PUBLIC KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END $type PUBLIC KEY-----"; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..7aa5548 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php @@ -0,0 +1,725 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\DES; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RC2; +use phpseclib3\Crypt\RC4; +use phpseclib3\Crypt\TripleDES; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; + +/** + * PKCS#8 Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends PKCS +{ + /** + * Default encryption algorithm + * + * @var string + */ + private static $defaultEncryptionAlgorithm = 'id-PBES2'; + + /** + * Default encryption scheme + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + */ + private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; + + /** + * Default PRF + * + * Only used when defaultEncryptionAlgorithm is id-PBES2 + * + * @var string + */ + private static $defaultPRF = 'id-hmacWithSHA256'; + + /** + * Default Iteration Count + * + * @var int + */ + private static $defaultIterationCount = 2048; + + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = false; + + /** + * Sets the default encryption algorithm + * + * @param string $algo + */ + public static function setEncryptionAlgorithm($algo) + { + self::$defaultEncryptionAlgorithm = $algo; + } + + /** + * Sets the default encryption algorithm for PBES2 + * + * @param string $algo + */ + public static function setEncryptionScheme($algo) + { + self::$defaultEncryptionScheme = $algo; + } + + /** + * Sets the iteration count + * + * @param int $count + */ + public static function setIterationCount($count) + { + self::$defaultIterationCount = $count; + } + + /** + * Sets the PRF for PBES2 + * + * @param string $algo + */ + public static function setPRF($algo) + { + self::$defaultPRF = $algo; + } + + /** + * Returns a SymmetricKey object based on a PBES1 $algo + * + * @return \phpseclib3\Crypt\Common\SymmetricKey + * @param string $algo + */ + private static function getPBES1EncryptionObject($algo) + { + $algo = preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? + $matches[1] : + substr($algo, 13); // strlen('pbeWithSHAAnd') == 13 + + switch ($algo) { + case 'DES': + $cipher = new DES('cbc'); + break; + case 'RC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(64); + break; + case '3-KeyTripleDES': + $cipher = new TripleDES('cbc'); + break; + case '2-KeyTripleDES': + $cipher = new TripleDES('cbc'); + $cipher->setKeyLength(128); + break; + case '128BitRC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(128); + break; + case '40BitRC2': + $cipher = new RC2('cbc'); + $cipher->setKeyLength(40); + break; + case '128BitRC4': + $cipher = new RC4(); + $cipher->setKeyLength(128); + break; + case '40BitRC4': + $cipher = new RC4(); + $cipher->setKeyLength(40); + break; + default: + throw new UnsupportedAlgorithmException("$algo is not a supported algorithm"); + } + + return $cipher; + } + + /** + * Returns a hash based on a PBES1 $algo + * + * @return string + * @param string $algo + */ + private static function getPBES1Hash($algo) + { + if (preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { + return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; + } + + return 'sha1'; + } + + /** + * Returns a KDF baesd on a PBES1 $algo + * + * @return string + * @param string $algo + */ + private static function getPBES1KDF($algo) + { + switch ($algo) { + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + return 'pbkdf1'; + } + + return 'pkcs12'; + } + + /** + * Returns a SymmetricKey object baesd on a PBES2 $algo + * + * @return SymmetricKey + * @param string $algo + */ + private static function getPBES2EncryptionObject($algo) + { + switch ($algo) { + case 'desCBC': + $cipher = new DES('cbc'); + break; + case 'des-EDE3-CBC': + $cipher = new TripleDES('cbc'); + break; + case 'rc2CBC': + $cipher = new RC2('cbc'); + // in theory this can be changed + $cipher->setKeyLength(128); + break; + case 'rc5-CBC-PAD': + throw new UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); + case 'aes128-CBC-PAD': + case 'aes192-CBC-PAD': + case 'aes256-CBC-PAD': + $cipher = new AES('cbc'); + $cipher->setKeyLength(substr($algo, 3, 3)); + break; + default: + throw new UnsupportedAlgorithmException("$algo is not supported"); + } + + return $cipher; + } + + /** + * Initialize static variables + * + */ + private static function initialize_static_variables() + { + if (!isset(static::$childOIDsLoaded)) { + throw new InsufficientSetupException('This class should not be called directly'); + } + + if (!static::$childOIDsLoaded) { + ASN1::loadOIDs(is_array(static::OID_NAME) ? + array_combine(static::OID_NAME, static::OID_VALUE) : + [static::OID_NAME => static::OID_VALUE]); + static::$childOIDsLoaded = true; + } + if (!self::$oidsLoaded) { + // from https://tools.ietf.org/html/rfc2898 + ASN1::loadOIDs([ + // PBES1 encryption schemes + 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', + 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', + 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', + 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', + 'pbeWithSHA1AndDES-CBC' => '1.2.840.113549.1.5.10', + 'pbeWithSHA1AndRC2-CBC' => '1.2.840.113549.1.5.11', + + // from PKCS#12: + // https://tools.ietf.org/html/rfc7292 + 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', + 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', + 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', + 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', + 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', + 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', + + 'id-PBKDF2' => '1.2.840.113549.1.5.12', + 'id-PBES2' => '1.2.840.113549.1.5.13', + 'id-PBMAC1' => '1.2.840.113549.1.5.14', + + // from PKCS#5 v2.1: + // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf + 'id-hmacWithSHA1' => '1.2.840.113549.2.7', + 'id-hmacWithSHA224' => '1.2.840.113549.2.8', + 'id-hmacWithSHA256' => '1.2.840.113549.2.9', + 'id-hmacWithSHA384' => '1.2.840.113549.2.10', + 'id-hmacWithSHA512' => '1.2.840.113549.2.11', + 'id-hmacWithSHA512-224' => '1.2.840.113549.2.12', + 'id-hmacWithSHA512-256' => '1.2.840.113549.2.13', + + 'desCBC' => '1.3.14.3.2.7', + 'des-EDE3-CBC' => '1.2.840.113549.3.7', + 'rc2CBC' => '1.2.840.113549.3.2', + 'rc5-CBC-PAD' => '1.2.840.113549.3.9', + + 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', + 'aes192-CBC-PAD' => '2.16.840.1.101.3.4.1.22', + 'aes256-CBC-PAD' => '2.16.840.1.101.3.4.1.42' + ]); + self::$oidsLoaded = true; + } + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + protected static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $isPublic = strpos($key, 'PUBLIC') !== false; + $isPrivate = strpos($key, 'PRIVATE') !== false; + + $decoded = self::preParse($key); + + $meta = []; + + $decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); + if (strlen($password) && is_array($decrypted)) { + $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; + switch ($algorithm) { + // PBES1 + case 'pbeWithMD2AndDES-CBC': + case 'pbeWithMD2AndRC2-CBC': + case 'pbeWithMD5AndDES-CBC': + case 'pbeWithMD5AndRC2-CBC': + case 'pbeWithSHA1AndDES-CBC': + case 'pbeWithSHA1AndRC2-CBC': + case 'pbeWithSHAAnd3-KeyTripleDES-CBC': + case 'pbeWithSHAAnd2-KeyTripleDES-CBC': + case 'pbeWithSHAAnd128BitRC2-CBC': + case 'pbeWithSHAAnd40BitRC2-CBC': + case 'pbeWithSHAAnd128BitRC4': + case 'pbeWithSHAAnd40BitRC4': + $cipher = self::getPBES1EncryptionObject($algorithm); + $hash = self::getPBES1Hash($algorithm); + $kdf = self::getPBES1KDF($algorithm); + + $meta['meta']['algorithm'] = $algorithm; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); + $iterationCount = (int) $iterationCount->toString(); + $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER 2'); + } + + break; + case 'id-PBES2': + $meta['meta']['algorithm'] = $algorithm; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); + extract($temp); + + $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); + $meta['meta']['cipher'] = $encryptionScheme['algorithm']; + + $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); + extract($temp); + + if (!$cipher instanceof RC2) { + $cipher->setIV($encryptionScheme['parameters']['octetString']); + } else { + $temp = ASN1::decodeBER($encryptionScheme['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); + $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); + switch ($effectiveKeyLength) { + case 160: + $effectiveKeyLength = 40; + break; + case 120: + $effectiveKeyLength = 64; + break; + case 58: + $effectiveKeyLength = 128; + break; + //default: // should be >= 256 + } + $cipher->setIV($iv); + $cipher->setKeyLength($effectiveKeyLength); + } + + $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; + switch ($keyDerivationFunc['algorithm']) { + case 'id-PBKDF2': + $temp = ASN1::decodeBER($keyDerivationFunc['parameters']); + if (!$temp) { + throw new \RuntimeException('Unable to decode BER'); + } + $prf = ['algorithm' => 'id-hmacWithSHA1']; + $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); + extract($params); + $meta['meta']['prf'] = $prf['algorithm']; + $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); + $params = [ + $password, + 'pbkdf2', + $hash, + $salt, + (int) $iterationCount->toString() + ]; + if (isset($keyLength)) { + $params[] = (int) $keyLength->toString(); + } + $cipher->setPassword(...$params); + $key = $cipher->decrypt($decrypted['encryptedData']); + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER 3'); + } + break; + default: + throw new UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); + } + break; + case 'id-PBMAC1': + //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); + //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); + // since i can't find any implementation that does PBMAC1 it is unsupported + throw new UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); + // at this point we'll assume that the key conforms to PublicKeyInfo + } + } + + $private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP); + if (is_array($private)) { + if ($isPublic) { + throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); + } + + if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { + $temp = $decoded[0]['content'][1]['content'][1]; + $private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); + } + if (is_array(static::OID_NAME)) { + if (!in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($private['publicKey'])) { + if ($private['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); + } + $private['publicKey'] = substr($private['publicKey'], 1); + } + return $private + $meta; + } + + // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference + // is that the former has an octet string and the later has a bit string. the first byte of a bit + // string represents the number of bits in the last byte that are to be ignored but, currently, + // bit strings wanting a non-zero amount of bits trimmed are not supported + $public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP); + + if (is_array($public)) { + if ($isPrivate) { + throw new \UnexpectedValueException('Human readable string claims private key but DER encoded string claims public key'); + } + + if ($public['publicKey'][0] != "\0") { + throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); + } + if (is_array(static::OID_NAME)) { + if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { + throw new UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); + } + } else { + if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { + throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); + } + } + if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { + $temp = $decoded[0]['content'][0]['content'][1]; + $public['publicKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); + } + $public['publicKey'] = substr($public['publicKey'], 1); + return $public; + } + + throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); + } + + /** + * Wrap a private key appropriately + * + * @param string $key + * @param string $attr + * @param mixed $params + * @param string $password + * @param string $oid optional + * @param string $publicKey optional + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) + { + self::initialize_static_variables(); + + $key = [ + 'version' => 'v1', + 'privateKeyAlgorithm' => [ + 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid + ], + 'privateKey' => $key + ]; + if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { + $key['privateKeyAlgorithm']['parameters'] = $params; + } + if (!empty($attr)) { + $key['attributes'] = $attr; + } + if (!empty($publicKey)) { + $key['version'] = 'v2'; + $key['publicKey'] = $publicKey; + } + $key = ASN1::encodeDER($key, Maps\OneAsymmetricKey::MAP); + if (!empty($password) && is_string($password)) { + $salt = Random::string(8); + + $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; + $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; + $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; + $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; + + if ($encryptionAlgorithm == 'id-PBES2') { + $crypto = self::getPBES2EncryptionObject($encryptionScheme); + $hash = str_replace('-', '/', substr($prf, 11)); + $kdf = 'pbkdf2'; + $iv = Random::string($crypto->getBlockLength() >> 3); + + $PBKDF2params = [ + 'salt' => $salt, + 'iterationCount' => $iterationCount, + 'prf' => ['algorithm' => $prf, 'parameters' => null] + ]; + $PBKDF2params = ASN1::encodeDER($PBKDF2params, Maps\PBKDF2params::MAP); + + if (!$crypto instanceof RC2) { + $params = ['octetString' => $iv]; + } else { + $params = [ + 'rc2ParametersVersion' => 58, + 'iv' => $iv + ]; + $params = ASN1::encodeDER($params, Maps\RC2CBCParameter::MAP); + $params = new ASN1\Element($params); + } + + $params = [ + 'keyDerivationFunc' => [ + 'algorithm' => 'id-PBKDF2', + 'parameters' => new ASN1\Element($PBKDF2params) + ], + 'encryptionScheme' => [ + 'algorithm' => $encryptionScheme, + 'parameters' => $params + ] + ]; + $params = ASN1::encodeDER($params, Maps\PBES2params::MAP); + + $crypto->setIV($iv); + } else { + $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); + $hash = self::getPBES1Hash($encryptionAlgorithm); + $kdf = self::getPBES1KDF($encryptionAlgorithm); + + $params = [ + 'salt' => $salt, + 'iterationCount' => $iterationCount + ]; + $params = ASN1::encodeDER($params, Maps\PBEParameter::MAP); + } + $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); + $key = $crypto->encrypt($key); + + $key = [ + 'encryptionAlgorithm' => [ + 'algorithm' => $encryptionAlgorithm, + 'parameters' => new ASN1\Element($params) + ], + 'encryptedData' => $key + ]; + + $key = ASN1::encodeDER($key, Maps\EncryptedPrivateKeyInfo::MAP); + + return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END ENCRYPTED PRIVATE KEY-----"; + } + + return "-----BEGIN PRIVATE KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END PRIVATE KEY-----"; + } + + /** + * Wrap a public key appropriately + * + * @param string $key + * @param mixed $params + * @param string $oid + * @return string + */ + protected static function wrapPublicKey($key, $params, $oid = null) + { + self::initialize_static_variables(); + + $key = [ + 'publicKeyAlgorithm' => [ + 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid + ], + 'publicKey' => "\0" . $key + ]; + + if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { + $key['publicKeyAlgorithm']['parameters'] = $params; + } + + $key = ASN1::encodeDER($key, Maps\PublicKeyInfo::MAP); + + return "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + } + + /** + * Perform some preliminary parsing of the key + * + * @param string $key + * @return array + */ + private static function preParse(&$key) + { + self::initialize_static_variables(); + + if (self::$format != self::MODE_DER) { + $decoded = ASN1::extractBER($key); + if ($decoded !== false) { + $key = $decoded; + } elseif (self::$format == self::MODE_PEM) { + throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); + } + } + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + return $decoded; + } + + /** + * Returns the encryption parameters used by the key + * + * @param string $key + * @return array + */ + public static function extractEncryptionAlgorithm($key) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $decoded = self::preParse($key); + + $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); + if (!is_array($r)) { + throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); + } + + if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { + $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); + + $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; + switch ($kdf['algorithm']) { + case 'id-PBKDF2': + $decoded = ASN1::decodeBER($kdf['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); + } + } + + return $r['encryptionAlgorithm']; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..85da83a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php @@ -0,0 +1,374 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\AES; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Exception\UnsupportedAlgorithmException; + +/** + * PuTTY Formatted Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY +{ + /** + * Default comment + * + * @var string + */ + private static $comment = 'phpseclib-generated-key'; + + /** + * Default version + * + * @var int + */ + private static $version = 2; + + /** + * Sets the default comment + * + * @param string $comment + */ + public static function setComment($comment) + { + self::$comment = str_replace(["\r", "\n"], '', $comment); + } + + /** + * Sets the default version + * + * @param int $version + */ + public static function setVersion($version) + { + if ($version != 2 && $version != 3) { + throw new \RuntimeException('Only supported versions are 2 and 3'); + } + self::$version = $version; + } + + /** + * Generate a symmetric key for PuTTY v2 keys + * + * @param string $password + * @param int $length + * @return string + */ + private static function generateV2Key($password, $length) + { + $symkey = ''; + $sequence = 0; + while (strlen($symkey) < $length) { + $temp = pack('Na*', $sequence++, $password); + $symkey .= Strings::hex2bin(sha1($temp)); + } + return substr($symkey, 0, $length); + } + + /** + * Generate a symmetric key for PuTTY v3 keys + * + * @param string $password + * @param string $flavour + * @param int $memory + * @param int $passes + * @param string $salt + * @return array + */ + private static function generateV3Key($password, $flavour, $memory, $passes, $salt) + { + if (!function_exists('sodium_crypto_pwhash')) { + throw new \RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing'); + } + + switch ($flavour) { + case 'Argon2i': + $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13; + break; + case 'Argon2id': + $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13; + break; + default: + throw new UnsupportedAlgorithmException('Only Argon2i and Argon2id are supported'); + } + + $length = 80; // keylen + ivlen + mac_keylen + $temp = sodium_crypto_pwhash($length, $password, $salt, $passes, $memory << 10, $flavour); + + $symkey = substr($temp, 0, 32); + $symiv = substr($temp, 32, 16); + $hashkey = substr($temp, -32); + + return compact('symkey', 'symiv', 'hashkey'); + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password + * @return array + */ + public static function load($key, $password) + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { + $lines = preg_split('#[\r\n]+#', $key); + switch (true) { + case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); + case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': + throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); + } + $lines = array_splice($lines, 1, -1); + $lines = array_map(function ($line) { + return rtrim($line, "\r\n"); + }, $lines); + $data = $current = ''; + $values = []; + $in_value = false; + foreach ($lines as $line) { + switch (true) { + case preg_match('#^(.*?): (.*)#', $line, $match): + $in_value = $line[strlen($line) - 1] == '\\'; + $current = strtolower($match[1]); + $values[$current] = $in_value ? substr($match[2], 0, -1) : $match[2]; + break; + case $in_value: + $in_value = $line[strlen($line) - 1] == '\\'; + $values[$current] .= $in_value ? substr($line, 0, -1) : $line; + break; + default: + $data .= $line; + } + } + + $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); + if ($components === false) { + throw new \UnexpectedValueException('Unable to decode public key'); + } + $components += $values; + $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); + + return $components; + } + + $components = []; + + $key = preg_split('#\r\n|\r|\n#', trim($key)); + if (Strings::shift($key[0], strlen('PuTTY-User-Key-File-')) != 'PuTTY-User-Key-File-') { + return false; + } + $version = (int) Strings::shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting + if ($version != 2 && $version != 3) { + throw new \RuntimeException('Only v2 and v3 PuTTY private keys are supported'); + } + $components['type'] = $type = rtrim($key[0]); + if (!in_array($type, static::$types)) { + $error = count(static::$types) == 1 ? + 'Only ' . static::$types[0] . ' keys are supported. ' : + ''; + throw new UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); + } + $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); + $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); + + $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); + $public = Strings::base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); + + $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); + + extract(unpack('Nlength', Strings::shift($public, 4))); + $newtype = Strings::shift($public, $length); + if ($newtype != $type) { + throw new \RuntimeException('The binary type does not match the human readable type field'); + } + + $components['public'] = $public; + + switch ($version) { + case 3: + $hashkey = ''; + break; + case 2: + $hashkey = 'putty-private-key-file-mac-key'; + } + + $offset = $publicLength + 4; + switch ($encryption) { + case 'aes256-cbc': + $crypto = new AES('cbc'); + switch ($version) { + case 3: + $flavour = trim(preg_replace('#Key-Derivation: (.*)#', '$1', $key[$offset++])); + $memory = trim(preg_replace('#Argon2-Memory: (\d+)#', '$1', $key[$offset++])); + $passes = trim(preg_replace('#Argon2-Passes: (\d+)#', '$1', $key[$offset++])); + $parallelism = trim(preg_replace('#Argon2-Parallelism: (\d+)#', '$1', $key[$offset++])); + $salt = Strings::hex2bin(trim(preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++]))); + + extract(self::generateV3Key($password, $flavour, $memory, $passes, $salt)); + + break; + case 2: + $symkey = self::generateV2Key($password, 32); + $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); + $hashkey .= $password; + } + } + + switch ($version) { + case 3: + $hash = new Hash('sha256'); + $hash->setKey($hashkey); + break; + case 2: + $hash = new Hash('sha1'); + $hash->setKey(sha1($hashkey, true)); + } + + $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$offset++])); + $private = Strings::base64_decode(implode('', array_map('trim', array_slice($key, $offset, $privateLength)))); + + if ($encryption != 'none') { + $crypto->setKey($symkey); + $crypto->setIV($symiv); + $crypto->disablePadding(); + $private = $crypto->decrypt($private); + } + + $source .= Strings::packSSH2('s', $private); + + $hmac = trim(preg_replace('#Private-MAC: (.+)#', '$1', $key[$offset + $privateLength])); + $hmac = Strings::hex2bin($hmac); + + if (!hash_equals($hash->hash($source), $hmac)) { + throw new \UnexpectedValueException('MAC validation error'); + } + + $components['private'] = $private; + + return $components; + } + + /** + * Wrap a private key appropriately + * + * @param string $public + * @param string $private + * @param string $type + * @param string $password + * @param array $options optional + * @return string + */ + protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) + { + $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $version = isset($options['version']) ? $options['version'] : self::$version; + + $key = "PuTTY-User-Key-File-$version: $type\r\n"; + $key .= "Encryption: $encryption\r\n"; + $key .= "Comment: $comment\r\n"; + + $public = Strings::packSSH2('s', $type) . $public; + + $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); + + $public = Strings::base64_encode($public); + $key .= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; + $key .= chunk_split($public, 64); + + if (empty($password) && !is_string($password)) { + $source .= Strings::packSSH2('s', $private); + switch ($version) { + case 3: + $hash = new Hash('sha256'); + $hash->setKey(''); + break; + case 2: + $hash = new Hash('sha1'); + $hash->setKey(sha1('putty-private-key-file-mac-key', true)); + } + } else { + $private .= Random::string(16 - (strlen($private) & 15)); + $source .= Strings::packSSH2('s', $private); + $crypto = new AES('cbc'); + + switch ($version) { + case 3: + $salt = Random::string(16); + $key .= "Key-Derivation: Argon2id\r\n"; + $key .= "Argon2-Memory: 8192\r\n"; + $key .= "Argon2-Passes: 13\r\n"; + $key .= "Argon2-Parallelism: 1\r\n"; + $key .= "Argon2-Salt: " . Strings::bin2hex($salt) . "\r\n"; + extract(self::generateV3Key($password, 'Argon2id', 8192, 13, $salt)); + + $hash = new Hash('sha256'); + $hash->setKey($hashkey); + + break; + case 2: + $symkey = self::generateV2Key($password, 32); + $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); + $hashkey = 'putty-private-key-file-mac-key' . $password; + + $hash = new Hash('sha1'); + $hash->setKey(sha1($hashkey, true)); + } + + $crypto->setKey($symkey); + $crypto->setIV($symiv); + $crypto->disablePadding(); + $private = $crypto->encrypt($private); + $mac = $hash->hash($source); + } + + $private = Strings::base64_encode($private); + $key .= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; + $key .= chunk_split($private, 64); + $key .= 'Private-MAC: ' . Strings::bin2hex($hash->hash($source)) . "\r\n"; + + return $key; + } + + /** + * Wrap a public key appropriately + * + * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) + * + * @param string $key + * @param string $type + * @return string + */ + protected static function wrapPublicKey($key, $type) + { + $key = pack('Na*a*', strlen($type), $type, $key); + $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . + 'Comment: "' . str_replace(['\\', '"'], ['\\\\', '\"'], self::$comment) . "\"\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + '---- END SSH2 PUBLIC KEY ----'; + return $key; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php new file mode 100644 index 0000000..ab8e7e4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php @@ -0,0 +1,60 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Formats\Signature; + +use phpseclib3\Math\BigInteger; + +/** + * Raw Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Loads a signature + * + * @param array $sig + * @return array|bool + */ + public static function load($sig) + { + switch (true) { + case !is_array($sig): + case !isset($sig['r']) || !isset($sig['s']): + case !$sig['r'] instanceof BigInteger: + case !$sig['s'] instanceof BigInteger: + return false; + } + + return [ + 'r' => $sig['r'], + 's' => $sig['s'] + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return compact('r', 's'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php new file mode 100644 index 0000000..a6e1eb0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php @@ -0,0 +1,31 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * PrivateKey interface + * + * @author Jim Wigginton + */ +interface PrivateKey +{ + public function sign($message); + //public function decrypt($ciphertext); + public function getPublicKey(); + public function toString($type, array $options = []); + + /** + * @param string|false $password + * @return mixed + */ + public function withPassword($password = false); +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php new file mode 100644 index 0000000..48a5875 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php @@ -0,0 +1,25 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * PublicKey interface + * + * @author Jim Wigginton + */ +interface PublicKey +{ + public function verify($message, $signature); + //public function encrypt($plaintext); + public function toString($type, array $options = []); + public function getFingerprint($algorithm); +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php new file mode 100644 index 0000000..0e2d6f0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php @@ -0,0 +1,54 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +/** + * Base Class for all stream cipher classes + * + * @author Jim Wigginton + */ +abstract class StreamCipher extends SymmetricKey +{ + /** + * Block Length of the cipher + * + * Stream ciphers do not have a block size + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 0; + + /** + * Default Constructor. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @return \phpseclib3\Crypt\Common\StreamCipher + */ + public function __construct() + { + parent::__construct('stream'); + } + + /** + * Stream ciphers not use an IV + * + * @return bool + */ + public function usesIV() + { + return false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php new file mode 100644 index 0000000..175508d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php @@ -0,0 +1,3398 @@ + + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Blowfish; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\BadModeException; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\PrimeField; + +/** + * Base Class for all \phpseclib3\Crypt\* cipher classes + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +abstract class SymmetricKey +{ + /** + * Encrypt / decrypt using the Counter mode. + * + * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CTR = -1; + /** + * Encrypt / decrypt using the Electronic Code Book mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_ECB = 1; + /** + * Encrypt / decrypt using the Code Book Chaining mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CBC = 2; + /** + * Encrypt / decrypt using the Cipher Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CFB = 3; + /** + * Encrypt / decrypt using the Cipher Feedback mode (8bit) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_CFB8 = 7; + /** + * Encrypt / decrypt using the Output Feedback mode (8bit) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_OFB8 = 8; + /** + * Encrypt / decrypt using the Output Feedback mode. + * + * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_OFB = 4; + /** + * Encrypt / decrypt using Galois/Counter mode. + * + * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_GCM = 5; + /** + * Encrypt / decrypt using streaming mode. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + */ + const MODE_STREAM = 6; + + /** + * Mode Map + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const MODE_MAP = [ + 'ctr' => self::MODE_CTR, + 'ecb' => self::MODE_ECB, + 'cbc' => self::MODE_CBC, + 'cfb' => self::MODE_CFB, + 'cfb8' => self::MODE_CFB8, + 'ofb' => self::MODE_OFB, + 'ofb8' => self::MODE_OFB8, + 'gcm' => self::MODE_GCM, + 'stream' => self::MODE_STREAM + ]; + + /** + * Base value for the internal implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_INTERNAL = 1; + /** + * Base value for the eval() implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_EVAL = 2; + /** + * Base value for the mcrypt implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_MCRYPT = 3; + /** + * Base value for the openssl implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL = 4; + /** + * Base value for the libsodium implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_LIBSODIUM = 5; + /** + * Base value for the openssl / gcm implementation $engine switch + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + */ + const ENGINE_OPENSSL_GCM = 6; + + /** + * Engine Reverse Map + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() + */ + const ENGINE_MAP = [ + self::ENGINE_INTERNAL => 'PHP', + self::ENGINE_EVAL => 'Eval', + self::ENGINE_MCRYPT => 'mcrypt', + self::ENGINE_OPENSSL => 'OpenSSL', + self::ENGINE_LIBSODIUM => 'libsodium', + self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' + ]; + + /** + * The Encryption Mode + * + * @see self::__construct() + * @var int + */ + protected $mode; + + /** + * The Block Length of the block cipher + * + * @var int + */ + protected $block_size = 16; + + /** + * The Key + * + * @see self::setKey() + * @var string + */ + protected $key = false; + + /** + * HMAC Key + * + * @see self::setupGCM() + * @var ?string + */ + protected $hKey = false; + + /** + * The Initialization Vector + * + * @see self::setIV() + * @var string + */ + protected $iv = false; + + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::clearBuffers() + * @var string + */ + protected $encryptIV; + + /** + * A "sliding" Initialization Vector + * + * @see self::enableContinuousBuffer() + * @see self::clearBuffers() + * @var string + */ + protected $decryptIV; + + /** + * Continuous Buffer status + * + * @see self::enableContinuousBuffer() + * @var bool + */ + protected $continuousBuffer = false; + + /** + * Encryption buffer for CTR, OFB and CFB modes + * + * @see self::encrypt() + * @see self::clearBuffers() + * @var array + */ + protected $enbuffer; + + /** + * Decryption buffer for CTR, OFB and CFB modes + * + * @see self::decrypt() + * @see self::clearBuffers() + * @var array + */ + protected $debuffer; + + /** + * mcrypt resource for encryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::encrypt() + * @var resource + */ + private $enmcrypt; + + /** + * mcrypt resource for decryption + * + * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. + * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. + * + * @see self::decrypt() + * @var resource + */ + private $demcrypt; + + /** + * Does the enmcrypt resource need to be (re)initialized? + * + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() + * @var bool + */ + private $enchanged = true; + + /** + * Does the demcrypt resource need to be (re)initialized? + * + * @see \phpseclib3\Crypt\Twofish::setKey() + * @see \phpseclib3\Crypt\Twofish::setIV() + * @var bool + */ + private $dechanged = true; + + /** + * mcrypt resource for CFB mode + * + * mcrypt's CFB mode, in (and only in) buffered context, + * is broken, so phpseclib implements the CFB mode by it self, + * even when the mcrypt php extension is available. + * + * In order to do the CFB-mode work (fast) phpseclib + * use a separate ECB-mode mcrypt resource. + * + * @link http://phpseclib.sourceforge.net/cfb-demo.phps + * @see self::encrypt() + * @see self::decrypt() + * @see self::setupMcrypt() + * @var resource + */ + private $ecb; + + /** + * Optimizing value while CFB-encrypting + * + * Only relevant if $continuousBuffer enabled + * and $engine == self::ENGINE_MCRYPT + * + * It's faster to re-init $enmcrypt if + * $buffer bytes > $cfb_init_len than + * using the $ecb resource furthermore. + * + * This value depends of the chosen cipher + * and the time it would be needed for it's + * initialization [by mcrypt_generic_init()] + * which, typically, depends on the complexity + * on its internaly Key-expanding algorithm. + * + * @see self::encrypt() + * @var int + */ + protected $cfb_init_len = 600; + + /** + * Does internal cipher state need to be (re)initialized? + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + * @var bool + */ + protected $changed = true; + + /** + * Does Eval engie need to be (re)initialized? + * + * @see self::setup() + * @var bool + */ + protected $nonIVChanged = true; + + /** + * Padding status + * + * @see self::enablePadding() + * @var bool + */ + private $padding = true; + + /** + * Is the mode one that is paddable? + * + * @see self::__construct() + * @var bool + */ + private $paddable = false; + + /** + * Holds which crypt engine internaly should be use, + * which will be determined automatically on __construct() + * + * Currently available $engines are: + * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) + * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) + * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) + * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) + * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) + * + * @see self::setEngine() + * @see self::encrypt() + * @see self::decrypt() + * @var int + */ + protected $engine; + + /** + * Holds the preferred crypt engine + * + * @see self::setEngine() + * @see self::setPreferredEngine() + * @var int + */ + private $preferredEngine; + + /** + * The mcrypt specific name of the cipher + * + * Only used if $engine == self::ENGINE_MCRYPT + * + * @link http://www.php.net/mcrypt_module_open + * @link http://www.php.net/mcrypt_list_algorithms + * @see self::setupMcrypt() + * @var string + */ + protected $cipher_name_mcrypt; + + /** + * The openssl specific name of the cipher + * + * Only used if $engine == self::ENGINE_OPENSSL + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + */ + protected $cipher_name_openssl; + + /** + * The openssl specific name of the cipher in ECB mode + * + * If OpenSSL does not support the mode we're trying to use (CTR) + * it can still be emulated with ECB mode. + * + * @link http://www.php.net/openssl-get-cipher-methods + * @var string + */ + protected $cipher_name_openssl_ecb; + + /** + * The default salt used by setPassword() + * + * @see self::setPassword() + * @var string + */ + private $password_default_salt = 'phpseclib/salt'; + + /** + * The name of the performance-optimized callback function + * + * Used by encrypt() / decrypt() + * only if $engine == self::ENGINE_INTERNAL + * + * @see self::encrypt() + * @see self::decrypt() + * @see self::setupInlineCrypt() + * @var Callback + */ + protected $inline_crypt; + + /** + * If OpenSSL can be used in ECB but not in CTR we can emulate CTR + * + * @see self::openssl_ctr_process() + * @var bool + */ + private $openssl_emulate_ctr = false; + + /** + * Don't truncate / null pad key + * + * @see self::clearBuffers() + * @var bool + */ + private $skip_key_adjustment = false; + + /** + * Has the key length explicitly been set or should it be derived from the key, itself? + * + * @see self::setKeyLength() + * @var bool + */ + protected $explicit_key_length = false; + + /** + * Hash subkey for GHASH + * + * @see self::setupGCM() + * @see self::ghash() + * @var BinaryField\Integer + */ + private $h; + + /** + * Additional authenticated data + * + * @var string + */ + protected $aad = ''; + + /** + * Authentication Tag produced after a round of encryption + * + * @var string + */ + protected $newtag = false; + + /** + * Authentication Tag to be verified during decryption + * + * @var string + */ + protected $oldtag = false; + + /** + * GCM Binary Field + * + * @see self::__construct() + * @see self::ghash() + * @var BinaryField + */ + private static $gcmField; + + /** + * Poly1305 Prime Field + * + * @see self::enablePoly1305() + * @see self::poly1305() + * @var PrimeField + */ + private static $poly1305Field; + + /** + * Flag for using regular vs "safe" intval + * + * @see self::initialize_static_variables() + * @var boolean + */ + protected static $use_reg_intval; + + /** + * Poly1305 Key + * + * @see self::setPoly1305Key() + * @see self::poly1305() + * @var string + */ + protected $poly1305Key; + + /** + * Poly1305 Flag + * + * @see self::setPoly1305Key() + * @see self::enablePoly1305() + * @var boolean + */ + protected $usePoly1305 = false; + + /** + * The Original Initialization Vector + * + * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived + * IV's and user-set IV's + * + * @see self::setIV() + * @var string + */ + private $origIV = false; + + /** + * Nonce + * + * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and + * toggling between GCM and other modes could be more complicated if we re-used setIV() + * + * @see self::setNonce() + * @var string + */ + protected $nonce = false; + + /** + * Default Constructor. + * + * $mode could be: + * + * - ecb + * + * - cbc + * + * - ctr + * + * - cfb + * + * - cfb8 + * + * - ofb + * + * - ofb8 + * + * - gcm + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + $mode = strtolower($mode); + // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 + $map = self::MODE_MAP; + if (!isset($map[$mode])) { + throw new BadModeException('No valid mode has been specified'); + } + + $mode = self::MODE_MAP[$mode]; + + // $mode dependent settings + switch ($mode) { + case self::MODE_ECB: + case self::MODE_CBC: + $this->paddable = true; + break; + case self::MODE_CTR: + case self::MODE_CFB: + case self::MODE_CFB8: + case self::MODE_OFB: + case self::MODE_OFB8: + case self::MODE_STREAM: + $this->paddable = false; + break; + case self::MODE_GCM: + if ($this->block_size != 16) { + throw new BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); + } + if (!isset(self::$gcmField)) { + self::$gcmField = new BinaryField(128, 7, 2, 1, 0); + } + $this->paddable = false; + break; + default: + throw new BadModeException('No valid mode has been specified'); + } + + $this->mode = $mode; + + static::initialize_static_variables(); + } + + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$use_reg_intval)) { + switch (true) { + // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster + case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': + case !function_exists('php_uname'): + case !is_string(php_uname('m')): + case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': + case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: + self::$use_reg_intval = true; + break; + case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': + switch (true) { + /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: + + https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd + + altho the changelogs make no mention of it, this bug was fixed with this commit: + + https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 + + affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ + case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: + case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: + self::$use_reg_intval = false; + break; + default: + self::$use_reg_intval = true; + } + } + } + } + + /** + * Sets the initialization vector. + * + * setIV() is not required when ecb or gcm modes are being used. + * + * {@internal Can be overwritten by a sub class, but does not have to be} + * + * @param string $iv + * @throws \LengthException if the IV length isn't equal to the block size + * @throws \BadMethodCallException if an IV is provided when one shouldn't be + */ + public function setIV($iv) + { + if ($this->mode == self::MODE_ECB) { + throw new \BadMethodCallException('This mode does not require an IV.'); + } + + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Use setNonce instead'); + } + + if (!$this->usesIV()) { + throw new \BadMethodCallException('This algorithm does not use an IV.'); + } + + if (strlen($iv) != $this->block_size) { + throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); + } + + $this->iv = $this->origIV = $iv; + $this->changed = true; + } + + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. + * + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function enablePoly1305() + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + + $this->usePoly1305 = true; + } + + /** + * Enables Poly1305 mode. + * + * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key + * will be made. + * + * @param string $key optional + * @throws \LengthException if the key isn't long enough + * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode + */ + public function setPoly1305Key($key = null) + { + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); + } + + if (!is_string($key) || strlen($key) != 32) { + throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); + } + + if (!isset(self::$poly1305Field)) { + // 2^130-5 + self::$poly1305Field = new PrimeField(new BigInteger('3fffffffffffffffffffffffffffffffb', 16)); + } + + $this->poly1305Key = $key; + $this->usePoly1305 = true; + } + + /** + * Sets the nonce. + * + * setNonce() is only required when gcm is used + * + * @param string $nonce + * @throws \BadMethodCallException if an nonce is provided when one shouldn't be + */ + public function setNonce($nonce) + { + if ($this->mode != self::MODE_GCM) { + throw new \BadMethodCallException('Nonces are only used in GCM mode.'); + } + + $this->nonce = $nonce; + $this->setEngine(); + } + + /** + * Sets additional authenticated data + * + * setAAD() is only used by gcm or in poly1305 mode + * + * @param string $aad + * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized + */ + public function setAAD($aad) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); + } + + $this->aad = $aad; + } + + /** + * Returns whether or not the algorithm uses an IV + * + * @return bool + */ + public function usesIV() + { + return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; + } + + /** + * Returns whether or not the algorithm uses a nonce + * + * @return bool + */ + public function usesNonce() + { + return $this->mode == self::MODE_GCM; + } + + /** + * Returns the current key length in bits + * + * @return int + */ + public function getKeyLength() + { + return $this->key_length << 3; + } + + /** + * Returns the current block length in bits + * + * @return int + */ + public function getBlockLength() + { + return $this->block_size << 3; + } + + /** + * Returns the current block length in bytes + * + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->block_size; + } + + /** + * Sets the key length. + * + * Keys with explicitly set lengths need to be treated accordingly + * + * @param int $length + */ + public function setKeyLength($length) + { + $this->explicit_key_length = $length >> 3; + + if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) { + $this->key = false; + throw new InconsistentSetupException('Key has already been set and is not ' . $this->explicit_key_length . ' bytes long'); + } + } + + /** + * Sets the key. + * + * The min/max length(s) of the key depends on the cipher which is used. + * If the key not fits the length(s) of the cipher it will paded with null bytes + * up to the closest valid key length. If the key is more than max length, + * we trim the excess bits. + * + * If the key is not explicitly set, it'll be assumed to be all null bytes. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @param string $key + */ + public function setKey($key) + { + if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { + throw new InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); + } + + $this->key = $key; + $this->key_length = strlen($key); + $this->setEngine(); + } + + /** + * Sets the password. + * + * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: + * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: + * $hash, $salt, $count, $dkLen + * + * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php + * {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}: + * $salt, $rounds, $keylen + * + * This is a modified version of bcrypt used by OpenSSH. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see Crypt/Hash.php + * @param string $password + * @param string $method + * @param int|string ...$func_args + * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length + * @throws \RuntimeException if bcrypt is being used and a salt isn't provided + * @return bool + */ + public function setPassword($password, $method = 'pbkdf2', ...$func_args) + { + $key = ''; + + $method = strtolower($method); + switch ($method) { + case 'bcrypt': + if (!isset($func_args[2])) { + throw new \RuntimeException('A salt must be provided for bcrypt to work'); + } + + $salt = $func_args[0]; + + $rounds = isset($func_args[1]) ? $func_args[1] : 16; + $keylen = isset($func_args[2]) ? $func_args[2] : $this->key_length; + + $key = Blowfish::bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds); + + $this->setKey(substr($key, 0, $keylen)); + $this->setIV(substr($key, $keylen)); + + return true; + case 'pkcs12': // from https://tools.ietf.org/html/rfc7292#appendix-B.2 + case 'pbkdf1': + case 'pbkdf2': + // Hash function + $hash = isset($func_args[0]) ? strtolower($func_args[0]) : 'sha1'; + $hashObj = new Hash(); + $hashObj->setHash($hash); + + // WPA and WPA2 use the SSID as the salt + $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; + + // RFC2898#section-4.2 uses 1,000 iterations by default + // WPA and WPA2 use 4,096. + $count = isset($func_args[2]) ? $func_args[2] : 1000; + + // Keylength + if (isset($func_args[3])) { + if ($func_args[3] <= 0) { + throw new \LengthException('Derived key length cannot be longer 0 or less'); + } + $dkLen = $func_args[3]; + } else { + $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length; + $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; + } + + switch (true) { + case $method == 'pkcs12': + /* + In this specification, however, all passwords are created from + BMPStrings with a NULL terminator. This means that each character in + the original BMPString is encoded in 2 bytes in big-endian format + (most-significant byte first). There are no Unicode byte order + marks. The 2 bytes produced from the last character in the BMPString + are followed by 2 additional bytes with the value 0x00. + + -- https://tools.ietf.org/html/rfc7292#appendix-B.1 + */ + $password = "\0" . chunk_split($password, 1, "\0") . "\0"; + + /* + This standard specifies 3 different values for the ID byte mentioned + above: + + 1. If ID=1, then the pseudorandom bits being produced are to be used + as key material for performing encryption or decryption. + + 2. If ID=2, then the pseudorandom bits being produced are to be used + as an IV (Initial Value) for encryption or decryption. + + 3. If ID=3, then the pseudorandom bits being produced are to be used + as an integrity key for MACing. + */ + // Construct a string, D (the "diversifier"), by concatenating v/8 + // copies of ID. + $blockLength = $hashObj->getBlockLengthInBytes(); + $d1 = str_repeat(chr(1), $blockLength); + $d2 = str_repeat(chr(2), $blockLength); + $s = ''; + if (strlen($salt)) { + while (strlen($s) < $blockLength) { + $s .= $salt; + } + } + $s = substr($s, 0, $blockLength); + + $p = ''; + if (strlen($password)) { + while (strlen($p) < $blockLength) { + $p .= $password; + } + } + $p = substr($p, 0, $blockLength); + + $i = $s . $p; + + $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); + if ($this->usesIV()) { + $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); + } + + return true; + case $method == 'pbkdf1': + if ($dkLen > $hashObj->getLengthInBytes()) { + throw new \LengthException('Derived key length cannot be longer than the hash length'); + } + $t = $password . $salt; + for ($i = 0; $i < $count; ++$i) { + $t = $hashObj->hash($t); + } + $key = substr($t, 0, $dkLen); + + $this->setKey(substr($key, 0, $dkLen >> 1)); + if ($this->usesIV()) { + $this->setIV(substr($key, $dkLen >> 1)); + } + + return true; + case !in_array($hash, hash_algos()): + $i = 1; + $hashObj->setKey($password); + while (strlen($key) < $dkLen) { + $f = $u = $hashObj->hash($salt . pack('N', $i++)); + for ($j = 2; $j <= $count; ++$j) { + $u = $hashObj->hash($u); + $f ^= $u; + } + $key .= $f; + } + $key = substr($key, 0, $dkLen); + break; + default: + $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); + } + break; + default: + throw new UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); + } + + $this->setKey($key); + + return true; + } + + /** + * PKCS#12 KDF Helper Function + * + * As discussed here: + * + * {@link https://tools.ietf.org/html/rfc7292#appendix-B} + * + * @see self::setPassword() + * @param int $n + * @param \phpseclib3\Crypt\Hash $hashObj + * @param string $i + * @param string $d + * @param int $count + * @return string $a + */ + private static function pkcs12helper($n, $hashObj, $i, $d, $count) + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $blockLength = $hashObj->getBlockLength() >> 3; + + $c = ceil($n / $hashObj->getLengthInBytes()); + $a = ''; + for ($j = 1; $j <= $c; $j++) { + $ai = $d . $i; + for ($k = 0; $k < $count; $k++) { + $ai = $hashObj->hash($ai); + } + $b = ''; + while (strlen($b) < $blockLength) { + $b .= $ai; + } + $b = substr($b, 0, $blockLength); + $b = new BigInteger($b, 256); + $newi = ''; + for ($k = 0; $k < strlen($i); $k += $blockLength) { + $temp = substr($i, $k, $blockLength); + $temp = new BigInteger($temp, 256); + $temp->setPrecision($blockLength << 3); + $temp = $temp->add($b); + $temp = $temp->add($one); + $newi .= $temp->toBytes(false); + } + $i = $newi; + $a .= $ai; + } + + return substr($a, 0, $n); + } + + /** + * Encrypts a message. + * + * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher + * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's + * necessary are discussed in the following + * URL: + * + * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} + * + * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. + * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that + * length. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::decrypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->paddable) { + $plaintext = $this->pad($plaintext); + } + + $this->setup(); + + if ($this->mode == self::MODE_GCM) { + $oldIV = $this->iv; + Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $ciphertext = $cipher->encrypt($plaintext); + + $s = $this->ghash( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + self::len64($this->aad) . + self::len64($ciphertext) + ); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $this->newtag = $cipher->encrypt($s); + return $ciphertext; + } + + if (isset($this->poly1305Key)) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = false; + $ciphertext = $cipher->encrypt($plaintext); + $this->newtag = $this->poly1305($ciphertext); + return $ciphertext; + } + + if ($this->engine === self::ENGINE_OPENSSL) { + switch ($this->mode) { + case self::MODE_STREAM: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + case self::MODE_ECB: + return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + case self::MODE_CBC: + $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + $this->encryptIV = substr($result, -$this->block_size); + } + return $result; + case self::MODE_CTR: + return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $ciphertext = ''; + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $plaintext = substr($plaintext, $i); + } + + $overflow = $len % $this->block_size; + + if ($overflow) { + $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = Strings::pop($ciphertext, $this->block_size); + + $size = $len - $overflow; + $block = $iv ^ substr($plaintext, -$overflow); + $iv = substr_replace($iv, $block, 0, $overflow); + $ciphertext .= $block; + $pos = $overflow; + } elseif ($len) { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + + return $ciphertext; + case self::MODE_CFB8: + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->encryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + return $ciphertext; + case self::MODE_OFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); + $ciphertext .= $plaintext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; + case self::MODE_OFB: + return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); + } + } + + if ($this->engine === self::ENGINE_MCRYPT) { + set_error_handler(function () { + }); + if ($this->enchanged) { + mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); + $this->enchanged = false; + } + + // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's + // rewritten CFB implementation the above outputs the same thing twice. + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $block_size = $this->block_size; + $iv = &$this->encryptIV; + $pos = &$this->enbuffer['pos']; + $len = strlen($plaintext); + $ciphertext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + $this->enbuffer['enmcrypt_init'] = true; + } + if ($len >= $block_size) { + if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { + if ($this->enbuffer['enmcrypt_init'] === true) { + mcrypt_generic_init($this->enmcrypt, $this->key, $iv); + $this->enbuffer['enmcrypt_init'] = false; + } + $ciphertext .= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); + $iv = substr($ciphertext, -$block_size); + $len %= $block_size; + } else { + while ($len >= $block_size) { + $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); + $ciphertext .= $iv; + $len -= $block_size; + $i += $block_size; + } + } + } + + if ($len) { + $iv = mcrypt_generic($this->ecb, $iv); + $block = $iv ^ substr($plaintext, -$len); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext .= $block; + $pos = $len; + } + + restore_error_handler(); + + return $ciphertext; + } + + $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); + + if (!$this->continuousBuffer) { + mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); + } + + restore_error_handler(); + + return $ciphertext; + } + + if ($this->engine === self::ENGINE_EVAL) { + $inline = $this->inline_crypt; + return $inline('encrypt', $plaintext); + } + + $buffer = &$this->enbuffer; + $block_size = $this->block_size; + $ciphertext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $ciphertext .= $this->encryptBlock(substr($plaintext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->encryptIV; + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $block = substr($plaintext, $i, $block_size); + $block = $this->encryptBlock($block ^ $xor); + $xor = $block; + $ciphertext .= $block; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->encryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'] .= $this->encryptBlock($xor); + Strings::increment_str($xor); + } + $key = Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext .= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $block = substr($plaintext, $i, $block_size); + $key = $this->encryptBlock($xor); + Strings::increment_str($xor); + $ciphertext .= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + if ($this->continuousBuffer) { + $iv = &$this->encryptIV; + $pos = &$buffer['pos']; + } else { + $iv = $this->encryptIV; + $pos = 0; + } + $len = strlen($plaintext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $ciphertext = substr($iv, $orig_pos) ^ $plaintext; + $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->encryptBlock($iv) ^ substr($plaintext, $i, $block_size); + $ciphertext .= $iv; + $len -= $block_size; + $i += $block_size; + } + if ($len) { + $iv = $this->encryptBlock($iv); + $block = $iv ^ substr($plaintext, $i); + $iv = substr_replace($iv, $block, 0, $len); + $ciphertext .= $block; + $pos = $len; + } + break; + case self::MODE_CFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); + $iv = substr($iv, 1) . $c; + } + + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->encryptIV = substr($ciphertext, -$block_size); + } else { + $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB8: + $ciphertext = ''; + $len = strlen($plaintext); + $iv = $this->encryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = $this->encryptBlock($iv); + $ciphertext .= $plaintext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $iv; + } + break; + case self::MODE_OFB: + $xor = $this->encryptIV; + if (strlen($buffer['xor'])) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['xor'])) { + $xor = $this->encryptBlock($xor); + $buffer['xor'] .= $xor; + } + $key = Strings::shift($buffer['xor'], $block_size); + $ciphertext .= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $xor = $this->encryptBlock($xor); + $ciphertext .= substr($plaintext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['xor'] = substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $ciphertext = $this->encryptBlock($plaintext); + break; + } + + return $ciphertext; + } + + /** + * Decrypts a message. + * + * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until + * it is. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::encrypt() + * @param string $ciphertext + * @return string $plaintext + * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size + */ + public function decrypt($ciphertext) + { + if ($this->paddable && strlen($ciphertext) % $this->block_size) { + throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); + } + $this->setup(); + + if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + + if (isset($this->poly1305Key)) { + $newtag = $this->poly1305($ciphertext); + } else { + $oldIV = $this->iv; + Strings::increment_str($this->iv); + $cipher = new static('ctr'); + $cipher->setKey($this->key); + $cipher->setIV($this->iv); + $plaintext = $cipher->decrypt($ciphertext); + + $s = $this->ghash( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + self::len64($this->aad) . + self::len64($ciphertext) + ); + $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; + $newtag = $cipher->encrypt($s); + } + if ($this->oldtag != substr($newtag, 0, strlen($newtag))) { + $cipher = clone $this; + unset($cipher->poly1305Key); + $this->usePoly1305 = false; + $plaintext = $cipher->decrypt($ciphertext); + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + return $plaintext; + } + + if ($this->engine === self::ENGINE_OPENSSL) { + switch ($this->mode) { + case self::MODE_STREAM: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + break; + case self::MODE_ECB: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + break; + case self::MODE_CBC: + $offset = $this->block_size; + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); + } + break; + case self::MODE_CTR: + $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); + break; + case self::MODE_CFB: + // cfb loosely routines inspired by openssl's: + // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} + $plaintext = ''; + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->debuffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $this->block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + $ciphertext = substr($ciphertext, $i); + } + $overflow = $len % $this->block_size; + if ($overflow) { + $plaintext .= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + if ($len - $overflow) { + $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); + } + $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $plaintext .= $iv ^ substr($ciphertext, -$overflow); + $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); + $pos = $overflow; + } elseif ($len) { + $plaintext .= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); + $iv = substr($ciphertext, -$this->block_size); + } + break; + case self::MODE_CFB8: + $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); + if ($this->continuousBuffer) { + if (($len = strlen($ciphertext)) >= $this->block_size) { + $this->decryptIV = substr($ciphertext, -$this->block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); + $plaintext .= $ciphertext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + break; + case self::MODE_OFB: + $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); + } + + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + if ($this->engine === self::ENGINE_MCRYPT) { + set_error_handler(function () { + }); + $block_size = $this->block_size; + if ($this->dechanged) { + mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); + $this->dechanged = false; + } + + if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$this->debuffer['pos']; + $len = strlen($ciphertext); + $plaintext = ''; + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + } + if ($len >= $block_size) { + $cb = substr($ciphertext, $i, $len - $len % $block_size); + $plaintext .= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; + $iv = substr($cb, -$block_size); + $len %= $block_size; + } + if ($len) { + $iv = mcrypt_generic($this->ecb, $iv); + $plaintext .= $iv ^ substr($ciphertext, -$len); + $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); + $pos = $len; + } + + restore_error_handler(); + + return $plaintext; + } + + $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); + + if (!$this->continuousBuffer) { + mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); + } + + restore_error_handler(); + + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + if ($this->engine === self::ENGINE_EVAL) { + $inline = $this->inline_crypt; + return $inline('decrypt', $ciphertext); + } + + $block_size = $this->block_size; + + $buffer = &$this->debuffer; + $plaintext = ''; + switch ($this->mode) { + case self::MODE_ECB: + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $plaintext .= $this->decryptBlock(substr($ciphertext, $i, $block_size)); + } + break; + case self::MODE_CBC: + $xor = $this->decryptIV; + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $block = substr($ciphertext, $i, $block_size); + $plaintext .= $this->decryptBlock($block) ^ $xor; + $xor = $block; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + } + break; + case self::MODE_CTR: + $xor = $this->decryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $block = substr($ciphertext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'] .= $this->encryptBlock($xor); + Strings::increment_str($xor); + } + $key = Strings::shift($buffer['ciphertext'], $block_size); + $plaintext .= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $block = substr($ciphertext, $i, $block_size); + $key = $this->encryptBlock($xor); + Strings::increment_str($xor); + $plaintext .= $block ^ $key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + break; + case self::MODE_CFB: + if ($this->continuousBuffer) { + $iv = &$this->decryptIV; + $pos = &$buffer['pos']; + } else { + $iv = $this->decryptIV; + $pos = 0; + } + $len = strlen($ciphertext); + $i = 0; + if ($pos) { + $orig_pos = $pos; + $max = $block_size - $pos; + if ($len >= $max) { + $i = $max; + $len -= $max; + $pos = 0; + } else { + $i = $len; + $pos += $len; + $len = 0; + } + // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize + $plaintext = substr($iv, $orig_pos) ^ $ciphertext; + $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); + } + while ($len >= $block_size) { + $iv = $this->encryptBlock($iv); + $cb = substr($ciphertext, $i, $block_size); + $plaintext .= $iv ^ $cb; + $iv = $cb; + $len -= $block_size; + $i += $block_size; + } + if ($len) { + $iv = $this->encryptBlock($iv); + $plaintext .= $iv ^ substr($ciphertext, $i); + $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); + $pos = $len; + } + break; + case self::MODE_CFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); + $iv = substr($iv, 1) . $ciphertext[$i]; + } + + if ($this->continuousBuffer) { + if ($len >= $block_size) { + $this->decryptIV = substr($ciphertext, -$block_size); + } else { + $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); + } + } + break; + case self::MODE_OFB8: + $plaintext = ''; + $len = strlen($ciphertext); + $iv = $this->decryptIV; + + for ($i = 0; $i < $len; ++$i) { + $xor = $this->encryptBlock($iv); + $plaintext .= $ciphertext[$i] ^ $xor; + $iv = substr($iv, 1) . $xor[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $iv; + } + break; + case self::MODE_OFB: + $xor = $this->decryptIV; + if (strlen($buffer['xor'])) { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $block = substr($ciphertext, $i, $block_size); + if (strlen($block) > strlen($buffer['xor'])) { + $xor = $this->encryptBlock($xor); + $buffer['xor'] .= $xor; + } + $key = Strings::shift($buffer['xor'], $block_size); + $plaintext .= $block ^ $key; + } + } else { + for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { + $xor = $this->encryptBlock($xor); + $plaintext .= substr($ciphertext, $i, $block_size) ^ $xor; + } + $key = $xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $xor; + if ($start = strlen($ciphertext) % $block_size) { + $buffer['xor'] = substr($key, $start) . $buffer['xor']; + } + } + break; + case self::MODE_STREAM: + $plaintext = $this->decryptBlock($ciphertext); + break; + } + return $this->paddable ? $this->unpad($plaintext) : $plaintext; + } + + /** + * Get the authentication tag + * + * Only used in GCM or Poly1305 mode + * + * @see self::encrypt() + * @param int $length optional + * @return string + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function getTag($length = 16) + { + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + + if ($this->newtag === false) { + throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); + } + + // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it + // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially + // easily brute forced. + // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 + // for more info + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + + return $length == 16 ? + $this->newtag : + substr($this->newtag, 0, $length); + } + + /** + * Sets the authentication tag + * + * Only used in GCM mode + * + * @see self::decrypt() + * @param string $tag + * @throws \LengthException if $length isn't of a sufficient length + * @throws \RuntimeException if GCM mode isn't being used + */ + public function setTag($tag) + { + if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + + if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { + throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); + } + + $length = strlen($tag); + if ($length < 4 || $length > 16) { + throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); + } + $this->oldtag = $tag; + } + + /** + * Get the IV + * + * mcrypt requires an IV even if ECB is used + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $iv + * @return string + */ + protected function getIV($iv) + { + return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv; + } + + /** + * OpenSSL CTR Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this + * function will emulate CTR with ECB when necessary. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + */ + private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) + { + $ciphertext = ''; + + $block_size = $this->block_size; + $key = $this->key; + + if ($this->openssl_emulate_ctr) { + $xor = $encryptIV; + if (strlen($buffer['ciphertext'])) { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $block = substr($plaintext, $i, $block_size); + if (strlen($block) > strlen($buffer['ciphertext'])) { + $buffer['ciphertext'] .= openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + } + Strings::increment_str($xor); + $otp = Strings::shift($buffer['ciphertext'], $block_size); + $ciphertext .= $block ^ $otp; + } + } else { + for ($i = 0; $i < strlen($plaintext); $i += $block_size) { + $block = substr($plaintext, $i, $block_size); + $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + Strings::increment_str($xor); + $ciphertext .= $block ^ $otp; + } + } + if ($this->continuousBuffer) { + $encryptIV = $xor; + if ($start = strlen($plaintext) % $block_size) { + $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; + } + } + + return $ciphertext; + } + + if (strlen($buffer['ciphertext'])) { + $ciphertext = $plaintext ^ Strings::shift($buffer['ciphertext'], strlen($plaintext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + + if (!strlen($plaintext)) { + return $ciphertext; + } + } + + $overflow = strlen($plaintext) % $block_size; + if ($overflow) { + $plaintext2 = Strings::pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 + $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $temp = Strings::pop($encrypted, $block_size); + $ciphertext .= $encrypted . ($plaintext2 ^ $temp); + if ($this->continuousBuffer) { + $buffer['ciphertext'] = substr($temp, $overflow); + $encryptIV = $temp; + } + } elseif (!strlen($buffer['ciphertext'])) { + $ciphertext .= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $temp = Strings::pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $temp; + } + } + if ($this->continuousBuffer) { + $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); + if ($overflow) { + Strings::increment_str($encryptIV); + } + } + + return $ciphertext; + } + + /** + * OpenSSL OFB Processor + * + * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream + * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() + * and SymmetricKey::decrypt(). + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $plaintext + * @param string $encryptIV + * @param array $buffer + * @return string + */ + private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) + { + if (strlen($buffer['xor'])) { + $ciphertext = $plaintext ^ $buffer['xor']; + $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); + $plaintext = substr($plaintext, strlen($ciphertext)); + } else { + $ciphertext = ''; + } + + $block_size = $this->block_size; + + $len = strlen($plaintext); + $key = $this->key; + $overflow = $len % $block_size; + + if (strlen($plaintext)) { + if ($overflow) { + $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + $xor = Strings::pop($ciphertext, $block_size); + if ($this->continuousBuffer) { + $encryptIV = $xor; + } + $ciphertext .= Strings::shift($xor, $overflow) ^ substr($plaintext, -$overflow); + if ($this->continuousBuffer) { + $buffer['xor'] = $xor; + } + } else { + $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); + if ($this->continuousBuffer) { + $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); + } + } + } + + return $ciphertext; + } + + /** + * phpseclib <-> OpenSSL Mode Mapper + * + * May need to be overwritten by classes extending this one in some cases + * + * @return string + */ + protected function openssl_translate_mode() + { + switch ($this->mode) { + case self::MODE_ECB: + return 'ecb'; + case self::MODE_CBC: + return 'cbc'; + case self::MODE_CTR: + case self::MODE_GCM: + return 'ctr'; + case self::MODE_CFB: + return 'cfb'; + case self::MODE_CFB8: + return 'cfb8'; + case self::MODE_OFB: + return 'ofb'; + } + } + + /** + * Pad "packets". + * + * Block ciphers working by encrypting between their specified [$this->]block_size at a time + * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to + * pad the input so that it is of the proper length. + * + * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, + * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping + * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is + * transmitted separately) + * + * @see self::disablePadding() + */ + public function enablePadding() + { + $this->padding = true; + } + + /** + * Do not pad packets. + * + * @see self::enablePadding() + */ + public function disablePadding() + { + $this->padding = false; + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->encrypt(substr($plaintext, 16, 16)); + * + * + * echo $rijndael->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $rijndael->encrypt(substr($plaintext, 0, 16)); + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::disableContinuousBuffer() + */ + public function enableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + + if ($this->mode == self::MODE_GCM) { + throw new \BadMethodCallException('This mode does not run in continuous mode'); + } + + $this->continuousBuffer = true; + + $this->setEngine(); + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::enableContinuousBuffer() + */ + public function disableContinuousBuffer() + { + if ($this->mode == self::MODE_ECB) { + return; + } + if (!$this->continuousBuffer) { + return; + } + + $this->continuousBuffer = false; + + $this->setEngine(); + } + + /** + * Test for engine validity + * + * @see self::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_OPENSSL: + $this->openssl_emulate_ctr = false; + $result = $this->cipher_name_openssl && + extension_loaded('openssl'); + if (!$result) { + return false; + } + + $methods = openssl_get_cipher_methods(); + if (in_array($this->cipher_name_openssl, $methods)) { + return true; + } + // not all of openssl's symmetric cipher's support ctr. for those + // that don't we'll emulate it + switch ($this->mode) { + case self::MODE_CTR: + if (in_array($this->cipher_name_openssl_ecb, $methods)) { + $this->openssl_emulate_ctr = true; + return true; + } + } + return false; + case self::ENGINE_MCRYPT: + set_error_handler(function () { + }); + $result = $this->cipher_name_mcrypt && + extension_loaded('mcrypt') && + in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); + restore_error_handler(); + return $result; + case self::ENGINE_EVAL: + return method_exists($this, 'setupInlineCrypt'); + case self::ENGINE_INTERNAL: + return true; + } + + return false; + } + + /** + * Test for engine validity + * + * @see self::__construct() + * @param string $engine + * @return bool + */ + public function isValidEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_map('strtolower', self::ENGINE_MAP); + $reverseMap = array_flip($reverseMap); + } + $engine = strtolower($engine); + if (!isset($reverseMap[$engine])) { + return false; + } + + return $this->isValidEngineHelper($reverseMap[$engine]); + } + + /** + * Sets the preferred crypt engine + * + * Currently, $engine could be: + * + * - libsodium[very fast] + * + * - OpenSSL [very fast] + * + * - mcrypt [fast] + * + * - Eval [slow] + * + * - PHP [slowest] + * + * If the preferred crypt engine is not available the fastest available one will be used + * + * @see self::__construct() + * @param string $engine + */ + public function setPreferredEngine($engine) + { + static $reverseMap; + if (!isset($reverseMap)) { + $reverseMap = array_map('strtolower', self::ENGINE_MAP); + $reverseMap = array_flip($reverseMap); + } + $engine = is_string($engine) ? strtolower($engine) : ''; + $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; + + $this->setEngine(); + } + + /** + * Returns the engine currently being utilized + * + * @see self::setEngine() + */ + public function getEngine() + { + return self::ENGINE_MAP[$this->engine]; + } + + /** + * Sets the engine as appropriate + * + * @see self::__construct() + */ + protected function setEngine() + { + $this->engine = null; + + $candidateEngines = [ + self::ENGINE_LIBSODIUM, + self::ENGINE_OPENSSL_GCM, + self::ENGINE_OPENSSL, + self::ENGINE_MCRYPT, + self::ENGINE_EVAL + ]; + if (isset($this->preferredEngine)) { + $temp = [$this->preferredEngine]; + $candidateEngines = array_merge( + $temp, + array_diff($candidateEngines, $temp) + ); + } + foreach ($candidateEngines as $engine) { + if ($this->isValidEngineHelper($engine)) { + $this->engine = $engine; + break; + } + } + if (!$this->engine) { + $this->engine = self::ENGINE_INTERNAL; + } + + if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { + set_error_handler(function () { + }); + // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, + // (re)open them with the module named in $this->cipher_name_mcrypt + mcrypt_module_close($this->enmcrypt); + mcrypt_module_close($this->demcrypt); + $this->enmcrypt = null; + $this->demcrypt = null; + + if ($this->ecb) { + mcrypt_module_close($this->ecb); + $this->ecb = null; + } + restore_error_handler(); + } + + $this->changed = $this->nonIVChanged = true; + } + + /** + * Encrypts a block + * + * Note: Must be extended by the child \phpseclib3\Crypt\* class + * + * @param string $in + * @return string + */ + abstract protected function encryptBlock($in); + + /** + * Decrypts a block + * + * Note: Must be extended by the child \phpseclib3\Crypt\* class + * + * @param string $in + * @return string + */ + abstract protected function decryptBlock($in); + + /** + * Setup the key (expansion) + * + * Only used if $engine == self::ENGINE_INTERNAL + * + * Note: Must extend by the child \phpseclib3\Crypt\* class + * + * @see self::setup() + */ + abstract protected function setupKey(); + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->changed = false; + + if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { + $this->createPoly1305Key(); + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true]; + //$this->newtag = $this->oldtag = false; + + if ($this->usesNonce()) { + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + if ($this->mode == self::MODE_GCM && !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + $this->setupGCM(); + } + } else { + $this->iv = $this->origIV; + } + + if ($this->iv === false && !in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { + if ($this->mode != self::MODE_GCM || !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { + throw new InsufficientSetupException('No IV has been defined'); + } + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + $this->encryptIV = $this->decryptIV = $this->iv; + + switch ($this->engine) { + case self::ENGINE_MCRYPT: + $this->enchanged = $this->dechanged = true; + + set_error_handler(function () { + }); + + if (!isset($this->enmcrypt)) { + static $mcrypt_modes = [ + self::MODE_CTR => 'ctr', + self::MODE_ECB => MCRYPT_MODE_ECB, + self::MODE_CBC => MCRYPT_MODE_CBC, + self::MODE_CFB => 'ncfb', + self::MODE_CFB8 => MCRYPT_MODE_CFB, + self::MODE_OFB => MCRYPT_MODE_NOFB, + self::MODE_OFB8 => MCRYPT_MODE_OFB, + self::MODE_STREAM => MCRYPT_MODE_STREAM, + ]; + + $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); + + // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() + // to workaround mcrypt's broken ncfb implementation in buffered mode + // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} + if ($this->mode == self::MODE_CFB) { + $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); + } + } // else should mcrypt_generic_deinit be called? + + if ($this->mode == self::MODE_CFB) { + mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); + } + + restore_error_handler(); + + break; + case self::ENGINE_INTERNAL: + $this->setupKey(); + break; + case self::ENGINE_EVAL: + if ($this->nonIVChanged) { + $this->setupKey(); + $this->setupInlineCrypt(); + } + } + + $this->nonIVChanged = false; + } + + /** + * Pads a string + * + * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. + * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to + * chr($this->block_size - (strlen($text) % $this->block_size) + * + * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless + * and padding will, hence forth, be enabled. + * + * @see self::unpad() + * @param string $text + * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size + * @return string + */ + protected function pad($text) + { + $length = strlen($text); + + if (!$this->padding) { + if ($length % $this->block_size == 0) { + return $text; + } else { + throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); + } + } + + $pad = $this->block_size - ($length % $this->block_size); + + return str_pad($text, $length + $pad, chr($pad)); + } + + /** + * Unpads a string. + * + * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong + * and false will be returned. + * + * @see self::pad() + * @param string $text + * @throws \LengthException if the ciphertext's length is not a multiple of the block size + * @return string + */ + protected function unpad($text) + { + if (!$this->padding) { + return $text; + } + + $length = ord($text[strlen($text) - 1]); + + if (!$length || $length > $this->block_size) { + throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); + } + + return substr($text, 0, -$length); + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * Stores the created (or existing) callback function-name + * in $this->inline_crypt + * + * Internally for phpseclib developers: + * + * _setupInlineCrypt() would be called only if: + * + * - $this->engine === self::ENGINE_EVAL + * + * - each time on _setup(), after(!) _setupKey() + * + * + * This ensures that _setupInlineCrypt() has always a + * full ready2go initializated internal cipher $engine state + * where, for example, the keys already expanded, + * keys/block_size calculated and such. + * + * It is, each time if called, the responsibility of _setupInlineCrypt(): + * + * - to set $this->inline_crypt to a valid and fully working callback function + * as a (faster) replacement for encrypt() / decrypt() + * + * - NOT to create unlimited callback functions (for memory reasons!) + * no matter how often _setupInlineCrypt() would be called. At some + * point of amount they must be generic re-useable. + * + * - the code of _setupInlineCrypt() it self, + * and the generated callback code, + * must be, in following order: + * - 100% safe + * - 100% compatible to encrypt()/decrypt() + * - using only php5+ features/lang-constructs/php-extensions if + * compatibility (down to php4) or fallback is provided + * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) + * - >= 10% faster than encrypt()/decrypt() [which is, by the way, + * the reason for the existence of _setupInlineCrypt() :-)] + * - memory-nice + * - short (as good as possible) + * + * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. + * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. + * - The following variable names are reserved: + * - $_* (all variable names prefixed with an underscore) + * - $self (object reference to it self. Do not use $this, but $self instead) + * - $in (the content of $in has to en/decrypt by the generated code) + * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only + * + * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} + * + * @see self::setup() + * @see self::createInlineCryptFunction() + * @see self::encrypt() + * @see self::decrypt() + */ + //protected function setupInlineCrypt(); + + /** + * Creates the performance-optimized function for en/decrypt() + * + * Internally for phpseclib developers: + * + * _createInlineCryptFunction(): + * + * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] + * with the current [$this->]mode of operation code + * + * - create the $inline function, which called by encrypt() / decrypt() + * as its replacement to speed up the en/decryption operations. + * + * - return the name of the created $inline callback function + * + * - used to speed up en/decryption + * + * + * + * The main reason why can speed up things [up to 50%] this way are: + * + * - using variables more effective then regular. + * (ie no use of expensive arrays but integers $k_0, $k_1 ... + * or even, for example, the pure $key[] values hardcoded) + * + * - avoiding 1000's of function calls of ie _encryptBlock() + * but inlining the crypt operations. + * in the mode of operation for() loop. + * + * - full loop unroll the (sometimes key-dependent) rounds + * avoiding this way ++$i counters and runtime-if's etc... + * + * The basic code architectur of the generated $inline en/decrypt() + * lambda function, in pseudo php, is: + * + * + * +----------------------------------------------------------------------------------------------+ + * | callback $inline = create_function: | + * | lambda_function_0001_crypt_ECB($action, $text) | + * | { | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_crypt']; // general init code. | + * | // ie: $sbox'es declarations used for | + * | // encrypt and decrypt'ing. | + * | | + * | switch ($action) { | + * | case 'encrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | + * | ie: specified $key or $box | + * | declarations for encrypt'ing. | + * | | + * | foreach ($ciphertext) { | + * | $in = $block_size of $ciphertext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for encryption. | + * | // $cipher_code['encrypt_block'] has to | + * | // encrypt the content of the $in variable | + * | | + * | $plaintext .= $in; | + * | } | + * | return $plaintext; | + * | | + * | case 'decrypt': | + * | INSERT PHP CODE OF: | + * | $cipher_code['init_decrypt']; // decrypt sepcific init code | + * | ie: specified $key or $box | + * | declarations for decrypt'ing. | + * | foreach ($plaintext) { | + * | $in = $block_size of $plaintext; | + * | | + * | INSERT PHP CODE OF: | + * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | + * | // strlen($in) == $this->block_size | + * | // here comes the cipher algorithm in action | + * | // for decryption. | + * | // $cipher_code['decrypt_block'] has to | + * | // decrypt the content of the $in variable | + * | $ciphertext .= $in; | + * | } | + * | return $ciphertext; | + * | } | + * | } | + * +----------------------------------------------------------------------------------------------+ + * + * + * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for + * productive inline $cipher_code's how they works. + * + * Structure of: + * + * $cipher_code = [ + * 'init_crypt' => (string) '', // optional + * 'init_encrypt' => (string) '', // optional + * 'init_decrypt' => (string) '', // optional + * 'encrypt_block' => (string) '', // required + * 'decrypt_block' => (string) '' // required + * ]; + * + * + * @see self::setupInlineCrypt() + * @see self::encrypt() + * @see self::decrypt() + * @param array $cipher_code + * @return string (the name of the created callback function) + */ + protected function createInlineCryptFunction($cipher_code) + { + $block_size = $this->block_size; + + // optional + $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; + $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; + $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; + // required + $encrypt_block = $cipher_code['encrypt_block']; + $decrypt_block = $cipher_code['decrypt_block']; + + // Generating mode of operation inline code, + // merged with the $cipher_code algorithm + // for encrypt- and decryption. + switch ($this->mode) { + case self::MODE_ECB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . '); + ' . $encrypt_block . ' + $_ciphertext.= $in; + } + + return $_ciphertext; + '; + + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); + $_ciphertext_len = strlen($_text); + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . '); + ' . $decrypt_block . ' + $_plaintext.= $in; + } + + return $this->unpad($_plaintext); + '; + break; + case self::MODE_CTR: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + $in = $_xor; + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_key = $in; + $_ciphertext.= $_block ^ $_key; + } + } + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % ' . $block_size . ') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; + + if (strlen($_buffer["ciphertext"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["ciphertext"])) { + $in = $_xor; + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_buffer["ciphertext"].= $in; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + $in = $_xor; + ' . $encrypt_block . ' + \phpseclib3\Common\Functions\Strings::increment_str($_xor); + $_key = $in; + $_plaintext.= $_block ^ $_key; + } + } + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % ' . $block_size . ') { + $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; + } + } + + return $_plaintext; + '; + break; + case self::MODE_CFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_buffer = &$this->enbuffer; + + if ($this->continuousBuffer) { + $_iv = &$this->encryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $this->encryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = ' . $block_size . ' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); + } + while ($_len >= ' . $block_size . ') { + $in = $_iv; + ' . $encrypt_block . '; + $_iv = $in ^ substr($_text, $_i, ' . $block_size . '); + $_ciphertext.= $_iv; + $_len-= ' . $block_size . '; + $_i+= ' . $block_size . '; + } + if ($_len) { + $in = $_iv; + ' . $encrypt_block . ' + $_iv = $in; + $_block = $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, $_block, 0, $_len); + $_ciphertext.= $_block; + $_pos = $_len; + } + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_buffer = &$this->debuffer; + + if ($this->continuousBuffer) { + $_iv = &$this->decryptIV; + $_pos = &$_buffer["pos"]; + } else { + $_iv = $this->decryptIV; + $_pos = 0; + } + $_len = strlen($_text); + $_i = 0; + if ($_pos) { + $_orig_pos = $_pos; + $_max = ' . $block_size . ' - $_pos; + if ($_len >= $_max) { + $_i = $_max; + $_len-= $_max; + $_pos = 0; + } else { + $_i = $_len; + $_pos+= $_len; + $_len = 0; + } + $_plaintext = substr($_iv, $_orig_pos) ^ $_text; + $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); + } + while ($_len >= ' . $block_size . ') { + $in = $_iv; + ' . $encrypt_block . ' + $_iv = $in; + $cb = substr($_text, $_i, ' . $block_size . '); + $_plaintext.= $_iv ^ $cb; + $_iv = $cb; + $_len-= ' . $block_size . '; + $_i+= ' . $block_size . '; + } + if ($_len) { + $in = $_iv; + ' . $encrypt_block . ' + $_iv = $in; + $_plaintext.= $_iv ^ substr($_text, $_i); + $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); + $_pos = $_len; + } + + return $_plaintext; + '; + break; + case self::MODE_CFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_ciphertext .= ($_c = $_text[$_i] ^ $in); + $_iv = substr($_iv, 1) . $_c; + } + + if ($this->continuousBuffer) { + if ($_len >= ' . $block_size . ') { + $this->encryptIV = substr($_ciphertext, -' . $block_size . '); + } else { + $this->encryptIV = substr($this->encryptIV, $_len - ' . $block_size . ') . substr($_ciphertext, -$_len); + } + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_plaintext .= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $_text[$_i]; + } + + if ($this->continuousBuffer) { + if ($_len >= ' . $block_size . ') { + $this->decryptIV = substr($_text, -' . $block_size . '); + } else { + $this->decryptIV = substr($this->decryptIV, $_len - ' . $block_size . ') . substr($_text, -$_len); + } + } + + return $_plaintext; + '; + break; + case self::MODE_OFB8: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_len = strlen($_text); + $_iv = $this->encryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_ciphertext.= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $in[0]; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $_iv; + } + + return $_ciphertext; + '; + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_len = strlen($_text); + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_len; ++$_i) { + $in = $_iv; + ' . $encrypt_block . ' + $_plaintext.= $_text[$_i] ^ $in; + $_iv = substr($_iv, 1) . $in[0]; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; + } + + return $_plaintext; + '; + break; + case self::MODE_OFB: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + $_xor = $this->encryptIV; + $_buffer = &$this->enbuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); + $_ciphertext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_ciphertext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; + } + $_key = $_xor; + } + if ($this->continuousBuffer) { + $this->encryptIV = $_xor; + if ($_start = $_plaintext_len % ' . $block_size . ') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_ciphertext; + '; + + $decrypt = $init_encrypt . ' + $_plaintext = ""; + $_ciphertext_len = strlen($_text); + $_xor = $this->decryptIV; + $_buffer = &$this->debuffer; + + if (strlen($_buffer["xor"])) { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $_block = substr($_text, $_i, ' . $block_size . '); + if (strlen($_block) > strlen($_buffer["xor"])) { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_buffer["xor"].= $_xor; + } + $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); + $_plaintext.= $_block ^ $_key; + } + } else { + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = $_xor; + ' . $encrypt_block . ' + $_xor = $in; + $_plaintext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; + } + $_key = $_xor; + } + if ($this->continuousBuffer) { + $this->decryptIV = $_xor; + if ($_start = $_ciphertext_len % ' . $block_size . ') { + $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; + } + } + return $_plaintext; + '; + break; + case self::MODE_STREAM: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + ' . $encrypt_block . ' + return $_ciphertext; + '; + $decrypt = $init_decrypt . ' + $_plaintext = ""; + ' . $decrypt_block . ' + return $_plaintext; + '; + break; + // case self::MODE_CBC: + default: + $encrypt = $init_encrypt . ' + $_ciphertext = ""; + $_plaintext_len = strlen($_text); + + $in = $this->encryptIV; + + for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { + $in = substr($_text, $_i, ' . $block_size . ') ^ $in; + ' . $encrypt_block . ' + $_ciphertext.= $in; + } + + if ($this->continuousBuffer) { + $this->encryptIV = $in; + } + + return $_ciphertext; + '; + + $decrypt = $init_decrypt . ' + $_plaintext = ""; + $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); + $_ciphertext_len = strlen($_text); + + $_iv = $this->decryptIV; + + for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { + $in = $_block = substr($_text, $_i, ' . $block_size . '); + ' . $decrypt_block . ' + $_plaintext.= $in ^ $_iv; + $_iv = $_block; + } + + if ($this->continuousBuffer) { + $this->decryptIV = $_iv; + } + + return $this->unpad($_plaintext); + '; + break; + } + + // Before discrediting this, please read the following: + // @see https://github.com/phpseclib/phpseclib/issues/1293 + // @see https://github.com/phpseclib/phpseclib/pull/1143 + eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); + + return \Closure::bind($func, $this, static::class); + } + + /** + * Convert float to int + * + * On ARM CPUs converting floats to ints doesn't always work + * + * @param string $x + * @return int + */ + protected static function safe_intval($x) + { + if (is_int($x)) { + return $x; + } + + if (self::$use_reg_intval) { + return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? intval($x) : $x; + } + + return (fmod($x, 0x80000000) & 0x7FFFFFFF) | + ((fmod(floor($x / 0x80000000), 2) & 1) << 31); + } + + /** + * eval()'able string for in-line float to int + * + * @return string + */ + protected static function safe_intval_inline() + { + if (self::$use_reg_intval) { + return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? 'intval(%s)' : '%s'; + } + + $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; + return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; + } + + /** + * Sets up GCM parameters + * + * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 + * for more info + * + */ + private function setupGCM() + { + // don't keep on re-calculating $this->h + if (!$this->h || $this->hKey != $this->key) { + $cipher = new static('ecb'); + $cipher->setKey($this->key); + $cipher->disablePadding(); + + $this->h = self::$gcmField->newInteger( + Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")) + ); + $this->hKey = $this->key; + } + + if (strlen($this->nonce) == 12) { + $this->iv = $this->nonce . "\0\0\0\1"; + } else { + $this->iv = $this->ghash( + self::nullPad128($this->nonce) . str_repeat("\0", 8) . self::len64($this->nonce) + ); + } + } + + /** + * Performs GHASH operation + * + * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 + * for more info + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $x + * @return string + */ + private function ghash($x) + { + $h = $this->h; + $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; + $x = str_split($x, 16); + $n = 0; + // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer + // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little + // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. + // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. + + // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it + // might be slightly more performant + //$x = Strings::switchEndianness($x); + foreach ($x as $xn) { + $xn = Strings::switchEndianness($xn); + $t = $y[$n] ^ $xn; + $temp = self::$gcmField->newInteger($t); + $y[++$n] = $temp->multiply($h)->toBytes(); + $y[$n] = substr($y[$n], 1); + } + $y[$n] = Strings::switchEndianness($y[$n]); + return $y[$n]; + } + + /** + * Returns the bit length of a string in a packed format + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @param string $str + * @return string + */ + private static function len64($str) + { + return "\0\0\0\0" . pack('N', 8 * strlen($str)); + } + + /** + * NULL pads a string to be a multiple of 128 + * + * @see self::decrypt() + * @see self::encrypt() + * @see self::setupGCM() + * @param string $str + * @return string + */ + protected static function nullPad128($str) + { + $len = strlen($str); + return $str . str_repeat("\0", 16 * ceil($len / 16) - $len); + } + + /** + * Calculates Poly1305 MAC + * + * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation + * it takes 1.2s. + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $text + * @return string + */ + protected function poly1305($text) + { + $s = $this->poly1305Key; // strlen($this->poly1305Key) == 32 + $r = Strings::shift($s, 16); + $r = strrev($r); + $r &= "\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xff"; + $s = strrev($s); + + $r = self::$poly1305Field->newInteger(new BigInteger($r, 256)); + $s = self::$poly1305Field->newInteger(new BigInteger($s, 256)); + $a = self::$poly1305Field->newInteger(new BigInteger()); + + $blocks = str_split($text, 16); + foreach ($blocks as $block) { + $n = strrev($block . chr(1)); + $n = self::$poly1305Field->newInteger(new BigInteger($n, 256)); + $a = $a->add($n); + $a = $a->multiply($r); + } + $r = $a->toBigInteger()->add($s->toBigInteger()); + $mask = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; + return strrev($r->toBytes()) & $mask; + } + + /** + * Return the mode + * + * You can do $obj instanceof AES or whatever to get the cipher but you can't do that to get the mode + * + * @return string + */ + public function getMode() + { + return array_flip(self::MODE_MAP)[$this->mode]; + } + + /** + * Is the continuous buffer enabled? + * + * @return boolean + */ + public function continuousBufferEnabled() + { + return $this->continuousBuffer; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php new file mode 100644 index 0000000..9ca8926 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php @@ -0,0 +1,57 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Traits; + +use phpseclib3\Crypt\Hash; + +/** + * Fingerprint Trait for Private Keys + * + * @author Jim Wigginton + */ +trait Fingerprint +{ + /** + * Returns the public key's fingerprint + * + * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is + * no public key currently loaded, false is returned. + * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) + * + * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned + * for invalid values. + * @return mixed + */ + public function getFingerprint($algorithm = 'md5') + { + $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); + if ($type === false) { + return false; + } + $key = $this->toString('OpenSSH', ['binary' => true]); + if ($key === false) { + return false; + } + switch ($algorithm) { + case 'sha256': + $hash = new Hash('sha256'); + $base = base64_encode($hash->hash($key)); + return substr($base, 0, strlen($base) - 1); + case 'md5': + return substr(chunk_split(md5($key), 2, ':'), 0, -1); + default: + return false; + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php new file mode 100644 index 0000000..0ac274e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php @@ -0,0 +1,46 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\Common\Traits; + +/** + * Password Protected Trait for Private Keys + * + * @author Jim Wigginton + */ +trait PasswordProtected +{ + /** + * Password + * + * @var string|bool + */ + private $password = false; + + /** + * Sets the password + * + * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. + * Or rather, pass in $password such that empty($password) && !is_string($password) is true. + * + * @see self::createKey() + * @see self::load() + * @param string|bool $password + */ + public function withPassword($password = false) + { + $new = clone $this; + $new->password = $password; + return $new; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php new file mode 100644 index 0000000..3b03830 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php @@ -0,0 +1,1392 @@ + + * setKey('abcdefgh'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $des->decrypt($des->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; + +/** + * Pure-PHP implementation of DES. + * + * @author Jim Wigginton + */ +class DES extends BlockCipher +{ + /** + * Contains $keys[self::ENCRYPT] + * + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\DES::processBlock() + */ + const ENCRYPT = 0; + /** + * Contains $keys[self::DECRYPT] + * + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\DES::processBlock() + */ + const DECRYPT = 1; + + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 8; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() + * @var int + */ + protected $key_length = 8; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'des'; + + /** + * The OpenSSL names of the cipher / modes + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::openssl_mode_names + * @var array + */ + protected $openssl_mode_names = [ + self::MODE_ECB => 'des-ecb', + self::MODE_CBC => 'des-cbc', + self::MODE_CFB => 'des-cfb', + self::MODE_OFB => 'des-ofb' + // self::MODE_CTR is undefined for DES + ]; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + */ + protected $cfb_init_len = 500; + + /** + * Switch for DES/3DES encryption + * + * Used only if $engine == self::ENGINE_INTERNAL + * + * @see self::setupKey() + * @see self::processBlock() + * @var int + */ + protected $des_rounds = 1; + + /** + * max possible size of $key + * + * @see self::setKey() + * @var string + */ + protected $key_length_max = 8; + + /** + * The Key Schedule + * + * @see self::setupKey() + * @var array + */ + private $keys; + + /** + * Key Cache "key" + * + * @see self::setupKey() + * @var array + */ + private $kl; + + /** + * Shuffle table. + * + * For each byte value index, the entry holds an 8-byte string + * with each byte containing all bits in the same state as the + * corresponding bit in the index value. + * + * @see self::processBlock() + * @see self::setupKey() + * @var array + */ + protected static $shuffle = [ + "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", + "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", + "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", + "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF", + "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF", + "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF", + "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF", + "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF", + "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF", + "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF", + "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF", + "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF", + "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF", + "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF", + "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF", + "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF", + "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF", + "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF", + "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF", + "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF", + "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF", + "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF", + "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF", + "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF", + "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF", + "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF", + "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF", + "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF", + "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF", + "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF", + "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF", + "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", + "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF", + "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF", + "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF", + "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF", + "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF", + "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF", + "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF", + "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF", + "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF", + "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF", + "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF", + "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF", + "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF", + "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF", + "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF", + "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF", + "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF", + "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF", + "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF", + "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF", + "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF", + "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF", + "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF", + "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF", + "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF", + "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF", + "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF", + "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF", + "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF", + "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF", + "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF", + "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF", + "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF", + "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF", + "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF", + "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF", + "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF", + "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF", + "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF", + "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF", + "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF", + "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF", + "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF", + "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF", + "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF", + "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF", + "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF", + "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF", + "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF", + "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF", + "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF", + "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF", + "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF", + "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF", + "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF", + "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF", + "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF", + "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF", + "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF", + "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF", + "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF", + "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF", + "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF", + "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF", + "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF", + "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF", + "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF", + "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF", + "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF", + "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF", + "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF", + "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF", + "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF", + "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF", + "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF", + "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF", + "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF", + "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF", + "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF", + "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF", + "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF", + "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF", + "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF", + "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF", + "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF", + "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF", + "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF", + "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF", + "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF", + "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF", + "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF", + "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF", + "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", + "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + ]; + + /** + * IP mapping helper table. + * + * Indexing this table with each source byte performs the initial bit permutation. + * + * @var array + */ + protected static $ipmap = [ + 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, + 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, + 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, + 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73, + 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35, + 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37, + 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75, + 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77, + 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1, + 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3, + 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1, + 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3, + 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5, + 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7, + 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5, + 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7, + 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39, + 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B, + 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79, + 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B, + 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D, + 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, + 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D, + 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, + 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9, + 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB, + 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9, + 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB, + 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD, + 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, + 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, + 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF + ]; + + /** + * Inverse IP mapping helper table. + * Indexing this table with a byte value reverses the bit order. + * + * @var array + */ + protected static $invipmap = [ + 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, + 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, + 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, + 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, + 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, + 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, + 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, + 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, + 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, + 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, + 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, + 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, + 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, + 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, + 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, + 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, + 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, + 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, + 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, + 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, + 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, + 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, + 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, + 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, + 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, + 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, + 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, + 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, + 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, + 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, + 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, + 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF + ]; + + /** + * Pre-permuted S-box1 + * + * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the + * P table: concatenation can then be replaced by exclusive ORs. + * + * @var array + */ + protected static $sbox1 = [ + 0x00808200, 0x00000000, 0x00008000, 0x00808202, + 0x00808002, 0x00008202, 0x00000002, 0x00008000, + 0x00000200, 0x00808200, 0x00808202, 0x00000200, + 0x00800202, 0x00808002, 0x00800000, 0x00000002, + 0x00000202, 0x00800200, 0x00800200, 0x00008200, + 0x00008200, 0x00808000, 0x00808000, 0x00800202, + 0x00008002, 0x00800002, 0x00800002, 0x00008002, + 0x00000000, 0x00000202, 0x00008202, 0x00800000, + 0x00008000, 0x00808202, 0x00000002, 0x00808000, + 0x00808200, 0x00800000, 0x00800000, 0x00000200, + 0x00808002, 0x00008000, 0x00008200, 0x00800002, + 0x00000200, 0x00000002, 0x00800202, 0x00008202, + 0x00808202, 0x00008002, 0x00808000, 0x00800202, + 0x00800002, 0x00000202, 0x00008202, 0x00808200, + 0x00000202, 0x00800200, 0x00800200, 0x00000000, + 0x00008002, 0x00008200, 0x00000000, 0x00808002 + ]; + + /** + * Pre-permuted S-box2 + * + * @var array + */ + protected static $sbox2 = [ + 0x40084010, 0x40004000, 0x00004000, 0x00084010, + 0x00080000, 0x00000010, 0x40080010, 0x40004010, + 0x40000010, 0x40084010, 0x40084000, 0x40000000, + 0x40004000, 0x00080000, 0x00000010, 0x40080010, + 0x00084000, 0x00080010, 0x40004010, 0x00000000, + 0x40000000, 0x00004000, 0x00084010, 0x40080000, + 0x00080010, 0x40000010, 0x00000000, 0x00084000, + 0x00004010, 0x40084000, 0x40080000, 0x00004010, + 0x00000000, 0x00084010, 0x40080010, 0x00080000, + 0x40004010, 0x40080000, 0x40084000, 0x00004000, + 0x40080000, 0x40004000, 0x00000010, 0x40084010, + 0x00084010, 0x00000010, 0x00004000, 0x40000000, + 0x00004010, 0x40084000, 0x00080000, 0x40000010, + 0x00080010, 0x40004010, 0x40000010, 0x00080010, + 0x00084000, 0x00000000, 0x40004000, 0x00004010, + 0x40000000, 0x40080010, 0x40084010, 0x00084000 + ]; + + /** + * Pre-permuted S-box3 + * + * @var array + */ + protected static $sbox3 = [ + 0x00000104, 0x04010100, 0x00000000, 0x04010004, + 0x04000100, 0x00000000, 0x00010104, 0x04000100, + 0x00010004, 0x04000004, 0x04000004, 0x00010000, + 0x04010104, 0x00010004, 0x04010000, 0x00000104, + 0x04000000, 0x00000004, 0x04010100, 0x00000100, + 0x00010100, 0x04010000, 0x04010004, 0x00010104, + 0x04000104, 0x00010100, 0x00010000, 0x04000104, + 0x00000004, 0x04010104, 0x00000100, 0x04000000, + 0x04010100, 0x04000000, 0x00010004, 0x00000104, + 0x00010000, 0x04010100, 0x04000100, 0x00000000, + 0x00000100, 0x00010004, 0x04010104, 0x04000100, + 0x04000004, 0x00000100, 0x00000000, 0x04010004, + 0x04000104, 0x00010000, 0x04000000, 0x04010104, + 0x00000004, 0x00010104, 0x00010100, 0x04000004, + 0x04010000, 0x04000104, 0x00000104, 0x04010000, + 0x00010104, 0x00000004, 0x04010004, 0x00010100 + ]; + + /** + * Pre-permuted S-box4 + * + * @var array + */ + protected static $sbox4 = [ + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x00401040, 0x80400040, 0x80400000, 0x80001000, + 0x00000000, 0x00401000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00400040, 0x80400000, + 0x80000000, 0x00001000, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x80001000, 0x00001040, + 0x80400040, 0x80000000, 0x00001040, 0x00400040, + 0x00001000, 0x00401040, 0x80401040, 0x80000040, + 0x00400040, 0x80400000, 0x00401000, 0x80401040, + 0x80000040, 0x00000000, 0x00000000, 0x00401000, + 0x00001040, 0x00400040, 0x80400040, 0x80000000, + 0x80401000, 0x80001040, 0x80001040, 0x00000040, + 0x80401040, 0x80000040, 0x80000000, 0x00001000, + 0x80400000, 0x80001000, 0x00401040, 0x80400040, + 0x80001000, 0x00001040, 0x00400000, 0x80401000, + 0x00000040, 0x00400000, 0x00001000, 0x00401040 + ]; + + /** + * Pre-permuted S-box5 + * + * @var array + */ + protected static $sbox5 = [ + 0x00000080, 0x01040080, 0x01040000, 0x21000080, + 0x00040000, 0x00000080, 0x20000000, 0x01040000, + 0x20040080, 0x00040000, 0x01000080, 0x20040080, + 0x21000080, 0x21040000, 0x00040080, 0x20000000, + 0x01000000, 0x20040000, 0x20040000, 0x00000000, + 0x20000080, 0x21040080, 0x21040080, 0x01000080, + 0x21040000, 0x20000080, 0x00000000, 0x21000000, + 0x01040080, 0x01000000, 0x21000000, 0x00040080, + 0x00040000, 0x21000080, 0x00000080, 0x01000000, + 0x20000000, 0x01040000, 0x21000080, 0x20040080, + 0x01000080, 0x20000000, 0x21040000, 0x01040080, + 0x20040080, 0x00000080, 0x01000000, 0x21040000, + 0x21040080, 0x00040080, 0x21000000, 0x21040080, + 0x01040000, 0x00000000, 0x20040000, 0x21000000, + 0x00040080, 0x01000080, 0x20000080, 0x00040000, + 0x00000000, 0x20040000, 0x01040080, 0x20000080 + ]; + + /** + * Pre-permuted S-box6 + * + * @var array + */ + protected static $sbox6 = [ + 0x10000008, 0x10200000, 0x00002000, 0x10202008, + 0x10200000, 0x00000008, 0x10202008, 0x00200000, + 0x10002000, 0x00202008, 0x00200000, 0x10000008, + 0x00200008, 0x10002000, 0x10000000, 0x00002008, + 0x00000000, 0x00200008, 0x10002008, 0x00002000, + 0x00202000, 0x10002008, 0x00000008, 0x10200008, + 0x10200008, 0x00000000, 0x00202008, 0x10202000, + 0x00002008, 0x00202000, 0x10202000, 0x10000000, + 0x10002000, 0x00000008, 0x10200008, 0x00202000, + 0x10202008, 0x00200000, 0x00002008, 0x10000008, + 0x00200000, 0x10002000, 0x10000000, 0x00002008, + 0x10000008, 0x10202008, 0x00202000, 0x10200000, + 0x00202008, 0x10202000, 0x00000000, 0x10200008, + 0x00000008, 0x00002000, 0x10200000, 0x00202008, + 0x00002000, 0x00200008, 0x10002008, 0x00000000, + 0x10202000, 0x10000000, 0x00200008, 0x10002008 + ]; + + /** + * Pre-permuted S-box7 + * + * @var array + */ + protected static $sbox7 = [ + 0x00100000, 0x02100001, 0x02000401, 0x00000000, + 0x00000400, 0x02000401, 0x00100401, 0x02100400, + 0x02100401, 0x00100000, 0x00000000, 0x02000001, + 0x00000001, 0x02000000, 0x02100001, 0x00000401, + 0x02000400, 0x00100401, 0x00100001, 0x02000400, + 0x02000001, 0x02100000, 0x02100400, 0x00100001, + 0x02100000, 0x00000400, 0x00000401, 0x02100401, + 0x00100400, 0x00000001, 0x02000000, 0x00100400, + 0x02000000, 0x00100400, 0x00100000, 0x02000401, + 0x02000401, 0x02100001, 0x02100001, 0x00000001, + 0x00100001, 0x02000000, 0x02000400, 0x00100000, + 0x02100400, 0x00000401, 0x00100401, 0x02100400, + 0x00000401, 0x02000001, 0x02100401, 0x02100000, + 0x00100400, 0x00000000, 0x00000001, 0x02100401, + 0x00000000, 0x00100401, 0x02100000, 0x00000400, + 0x02000001, 0x02000400, 0x00000400, 0x00100001 + ]; + + /** + * Pre-permuted S-box8 + * + * @var array + */ + protected static $sbox8 = [ + 0x08000820, 0x00000800, 0x00020000, 0x08020820, + 0x08000000, 0x08000820, 0x00000020, 0x08000000, + 0x00020020, 0x08020000, 0x08020820, 0x00020800, + 0x08020800, 0x00020820, 0x00000800, 0x00000020, + 0x08020000, 0x08000020, 0x08000800, 0x00000820, + 0x00020800, 0x00020020, 0x08020020, 0x08020800, + 0x00000820, 0x00000000, 0x00000000, 0x08020020, + 0x08000020, 0x08000800, 0x00020820, 0x00020000, + 0x00020820, 0x00020000, 0x08020800, 0x00000800, + 0x00000020, 0x08020020, 0x00000800, 0x00020820, + 0x08000800, 0x00000020, 0x08000020, 0x08020000, + 0x08020020, 0x08000000, 0x00020000, 0x08000820, + 0x00000000, 0x08020820, 0x00020020, 0x08000020, + 0x08020000, 0x08000800, 0x08000820, 0x00000000, + 0x08020820, 0x00020800, 0x00020800, 0x00000820, + 0x00000820, 0x00020020, 0x08000000, 0x08020800 + ]; + + /** + * Default Constructor. + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($this->key_length_max == 8) { + if ($engine == self::ENGINE_OPENSSL) { + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } + $this->cipher_name_openssl_ecb = 'des-ecb'; + $this->cipher_name_openssl = 'des-' . $this->openssl_translate_mode(); + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the key. + * + * Keys must be 64-bits long or 8 bytes long. + * + * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @param string $key + */ + public function setKey($key) + { + if (!($this instanceof TripleDES) && strlen($key) != 8) { + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); + } + + // Sets the key + parent::setKey($key); + } + + /** + * Encrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::encrypt() + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + return $this->processBlock($in, self::ENCRYPT); + } + + /** + * Decrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::decrypt() + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + return $this->processBlock($in, self::DECRYPT); + } + + /** + * Encrypts or decrypts a 64-bit block + * + * $mode should be either self::ENCRYPT or self::DECRYPT. See + * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general + * idea of what this function does. + * + * @see self::encryptBlock() + * @see self::decryptBlock() + * @param string $block + * @param int $mode + * @return string + */ + private function processBlock($block, $mode) + { + static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; + if (!$sbox1) { + $sbox1 = array_map('intval', self::$sbox1); + $sbox2 = array_map('intval', self::$sbox2); + $sbox3 = array_map('intval', self::$sbox3); + $sbox4 = array_map('intval', self::$sbox4); + $sbox5 = array_map('intval', self::$sbox5); + $sbox6 = array_map('intval', self::$sbox6); + $sbox7 = array_map('intval', self::$sbox7); + $sbox8 = array_map('intval', self::$sbox8); + /* Merge $shuffle with $[inv]ipmap */ + for ($i = 0; $i < 256; ++$i) { + $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; + $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; + } + } + + $keys = $this->keys[$mode]; + $ki = -1; + + // Do the initial IP permutation. + $t = unpack('Nl/Nr', $block); + list($l, $r) = [$t['l'], $t['r']]; + $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + + // Extract L0 and R0. + $t = unpack('Nl/Nr', $block); + list($l, $r) = [$t['l'], $t['r']]; + + for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { + // Perform the 16 steps. + for ($i = 0; $i < 16; $i++) { + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki]; + $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki]; + + // S-box indexing. + $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l; + // end of "the Feistel (F) function" + + $l = $r; + $r = $t; + } + + // Last step should not permute L & R. + $t = $l; + $l = $r; + $r = $t; + } + + // Perform the inverse IP permutation. + return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + } + + /** + * Creates the key schedule + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key, 'des_rounds' => $this->des_rounds]; + + static $shifts = [ // number of key bits shifted per round + 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 + ]; + + static $pc1map = [ + 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C, + 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E, + 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C, + 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E, + 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C, + 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E, + 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C, + 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E, + 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C, + 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E, + 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C, + 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E, + 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C, + 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E, + 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C, + 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E, + 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C, + 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E, + 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C, + 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E, + 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC, + 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE, + 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC, + 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE, + 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC, + 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE, + 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC, + 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE, + 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC, + 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE, + 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC, + 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE + ]; + + // Mapping tables for the PC-2 transformation. + static $pc2mapc1 = [ + 0x00000000, 0x00000400, 0x00200000, 0x00200400, + 0x00000001, 0x00000401, 0x00200001, 0x00200401, + 0x02000000, 0x02000400, 0x02200000, 0x02200400, + 0x02000001, 0x02000401, 0x02200001, 0x02200401 + ]; + static $pc2mapc2 = [ + 0x00000000, 0x00000800, 0x08000000, 0x08000800, + 0x00010000, 0x00010800, 0x08010000, 0x08010800, + 0x00000000, 0x00000800, 0x08000000, 0x08000800, + 0x00010000, 0x00010800, 0x08010000, 0x08010800, + 0x00000100, 0x00000900, 0x08000100, 0x08000900, + 0x00010100, 0x00010900, 0x08010100, 0x08010900, + 0x00000100, 0x00000900, 0x08000100, 0x08000900, + 0x00010100, 0x00010900, 0x08010100, 0x08010900, + 0x00000010, 0x00000810, 0x08000010, 0x08000810, + 0x00010010, 0x00010810, 0x08010010, 0x08010810, + 0x00000010, 0x00000810, 0x08000010, 0x08000810, + 0x00010010, 0x00010810, 0x08010010, 0x08010810, + 0x00000110, 0x00000910, 0x08000110, 0x08000910, + 0x00010110, 0x00010910, 0x08010110, 0x08010910, + 0x00000110, 0x00000910, 0x08000110, 0x08000910, + 0x00010110, 0x00010910, 0x08010110, 0x08010910, + 0x00040000, 0x00040800, 0x08040000, 0x08040800, + 0x00050000, 0x00050800, 0x08050000, 0x08050800, + 0x00040000, 0x00040800, 0x08040000, 0x08040800, + 0x00050000, 0x00050800, 0x08050000, 0x08050800, + 0x00040100, 0x00040900, 0x08040100, 0x08040900, + 0x00050100, 0x00050900, 0x08050100, 0x08050900, + 0x00040100, 0x00040900, 0x08040100, 0x08040900, + 0x00050100, 0x00050900, 0x08050100, 0x08050900, + 0x00040010, 0x00040810, 0x08040010, 0x08040810, + 0x00050010, 0x00050810, 0x08050010, 0x08050810, + 0x00040010, 0x00040810, 0x08040010, 0x08040810, + 0x00050010, 0x00050810, 0x08050010, 0x08050810, + 0x00040110, 0x00040910, 0x08040110, 0x08040910, + 0x00050110, 0x00050910, 0x08050110, 0x08050910, + 0x00040110, 0x00040910, 0x08040110, 0x08040910, + 0x00050110, 0x00050910, 0x08050110, 0x08050910, + 0x01000000, 0x01000800, 0x09000000, 0x09000800, + 0x01010000, 0x01010800, 0x09010000, 0x09010800, + 0x01000000, 0x01000800, 0x09000000, 0x09000800, + 0x01010000, 0x01010800, 0x09010000, 0x09010800, + 0x01000100, 0x01000900, 0x09000100, 0x09000900, + 0x01010100, 0x01010900, 0x09010100, 0x09010900, + 0x01000100, 0x01000900, 0x09000100, 0x09000900, + 0x01010100, 0x01010900, 0x09010100, 0x09010900, + 0x01000010, 0x01000810, 0x09000010, 0x09000810, + 0x01010010, 0x01010810, 0x09010010, 0x09010810, + 0x01000010, 0x01000810, 0x09000010, 0x09000810, + 0x01010010, 0x01010810, 0x09010010, 0x09010810, + 0x01000110, 0x01000910, 0x09000110, 0x09000910, + 0x01010110, 0x01010910, 0x09010110, 0x09010910, + 0x01000110, 0x01000910, 0x09000110, 0x09000910, + 0x01010110, 0x01010910, 0x09010110, 0x09010910, + 0x01040000, 0x01040800, 0x09040000, 0x09040800, + 0x01050000, 0x01050800, 0x09050000, 0x09050800, + 0x01040000, 0x01040800, 0x09040000, 0x09040800, + 0x01050000, 0x01050800, 0x09050000, 0x09050800, + 0x01040100, 0x01040900, 0x09040100, 0x09040900, + 0x01050100, 0x01050900, 0x09050100, 0x09050900, + 0x01040100, 0x01040900, 0x09040100, 0x09040900, + 0x01050100, 0x01050900, 0x09050100, 0x09050900, + 0x01040010, 0x01040810, 0x09040010, 0x09040810, + 0x01050010, 0x01050810, 0x09050010, 0x09050810, + 0x01040010, 0x01040810, 0x09040010, 0x09040810, + 0x01050010, 0x01050810, 0x09050010, 0x09050810, + 0x01040110, 0x01040910, 0x09040110, 0x09040910, + 0x01050110, 0x01050910, 0x09050110, 0x09050910, + 0x01040110, 0x01040910, 0x09040110, 0x09040910, + 0x01050110, 0x01050910, 0x09050110, 0x09050910 + ]; + static $pc2mapc3 = [ + 0x00000000, 0x00000004, 0x00001000, 0x00001004, + 0x00000000, 0x00000004, 0x00001000, 0x00001004, + 0x10000000, 0x10000004, 0x10001000, 0x10001004, + 0x10000000, 0x10000004, 0x10001000, 0x10001004, + 0x00000020, 0x00000024, 0x00001020, 0x00001024, + 0x00000020, 0x00000024, 0x00001020, 0x00001024, + 0x10000020, 0x10000024, 0x10001020, 0x10001024, + 0x10000020, 0x10000024, 0x10001020, 0x10001024, + 0x00080000, 0x00080004, 0x00081000, 0x00081004, + 0x00080000, 0x00080004, 0x00081000, 0x00081004, + 0x10080000, 0x10080004, 0x10081000, 0x10081004, + 0x10080000, 0x10080004, 0x10081000, 0x10081004, + 0x00080020, 0x00080024, 0x00081020, 0x00081024, + 0x00080020, 0x00080024, 0x00081020, 0x00081024, + 0x10080020, 0x10080024, 0x10081020, 0x10081024, + 0x10080020, 0x10080024, 0x10081020, 0x10081024, + 0x20000000, 0x20000004, 0x20001000, 0x20001004, + 0x20000000, 0x20000004, 0x20001000, 0x20001004, + 0x30000000, 0x30000004, 0x30001000, 0x30001004, + 0x30000000, 0x30000004, 0x30001000, 0x30001004, + 0x20000020, 0x20000024, 0x20001020, 0x20001024, + 0x20000020, 0x20000024, 0x20001020, 0x20001024, + 0x30000020, 0x30000024, 0x30001020, 0x30001024, + 0x30000020, 0x30000024, 0x30001020, 0x30001024, + 0x20080000, 0x20080004, 0x20081000, 0x20081004, + 0x20080000, 0x20080004, 0x20081000, 0x20081004, + 0x30080000, 0x30080004, 0x30081000, 0x30081004, + 0x30080000, 0x30080004, 0x30081000, 0x30081004, + 0x20080020, 0x20080024, 0x20081020, 0x20081024, + 0x20080020, 0x20080024, 0x20081020, 0x20081024, + 0x30080020, 0x30080024, 0x30081020, 0x30081024, + 0x30080020, 0x30080024, 0x30081020, 0x30081024, + 0x00000002, 0x00000006, 0x00001002, 0x00001006, + 0x00000002, 0x00000006, 0x00001002, 0x00001006, + 0x10000002, 0x10000006, 0x10001002, 0x10001006, + 0x10000002, 0x10000006, 0x10001002, 0x10001006, + 0x00000022, 0x00000026, 0x00001022, 0x00001026, + 0x00000022, 0x00000026, 0x00001022, 0x00001026, + 0x10000022, 0x10000026, 0x10001022, 0x10001026, + 0x10000022, 0x10000026, 0x10001022, 0x10001026, + 0x00080002, 0x00080006, 0x00081002, 0x00081006, + 0x00080002, 0x00080006, 0x00081002, 0x00081006, + 0x10080002, 0x10080006, 0x10081002, 0x10081006, + 0x10080002, 0x10080006, 0x10081002, 0x10081006, + 0x00080022, 0x00080026, 0x00081022, 0x00081026, + 0x00080022, 0x00080026, 0x00081022, 0x00081026, + 0x10080022, 0x10080026, 0x10081022, 0x10081026, + 0x10080022, 0x10080026, 0x10081022, 0x10081026, + 0x20000002, 0x20000006, 0x20001002, 0x20001006, + 0x20000002, 0x20000006, 0x20001002, 0x20001006, + 0x30000002, 0x30000006, 0x30001002, 0x30001006, + 0x30000002, 0x30000006, 0x30001002, 0x30001006, + 0x20000022, 0x20000026, 0x20001022, 0x20001026, + 0x20000022, 0x20000026, 0x20001022, 0x20001026, + 0x30000022, 0x30000026, 0x30001022, 0x30001026, + 0x30000022, 0x30000026, 0x30001022, 0x30001026, + 0x20080002, 0x20080006, 0x20081002, 0x20081006, + 0x20080002, 0x20080006, 0x20081002, 0x20081006, + 0x30080002, 0x30080006, 0x30081002, 0x30081006, + 0x30080002, 0x30080006, 0x30081002, 0x30081006, + 0x20080022, 0x20080026, 0x20081022, 0x20081026, + 0x20080022, 0x20080026, 0x20081022, 0x20081026, + 0x30080022, 0x30080026, 0x30081022, 0x30081026, + 0x30080022, 0x30080026, 0x30081022, 0x30081026 + ]; + static $pc2mapc4 = [ + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x00000000, 0x00100000, 0x00000008, 0x00100008, + 0x00000200, 0x00100200, 0x00000208, 0x00100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x04000000, 0x04100000, 0x04000008, 0x04100008, + 0x04000200, 0x04100200, 0x04000208, 0x04100208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x00002000, 0x00102000, 0x00002008, 0x00102008, + 0x00002200, 0x00102200, 0x00002208, 0x00102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x04002000, 0x04102000, 0x04002008, 0x04102008, + 0x04002200, 0x04102200, 0x04002208, 0x04102208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x00020000, 0x00120000, 0x00020008, 0x00120008, + 0x00020200, 0x00120200, 0x00020208, 0x00120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x04020000, 0x04120000, 0x04020008, 0x04120008, + 0x04020200, 0x04120200, 0x04020208, 0x04120208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x00022000, 0x00122000, 0x00022008, 0x00122008, + 0x00022200, 0x00122200, 0x00022208, 0x00122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208, + 0x04022000, 0x04122000, 0x04022008, 0x04122008, + 0x04022200, 0x04122200, 0x04022208, 0x04122208 + ]; + static $pc2mapd1 = [ + 0x00000000, 0x00000001, 0x08000000, 0x08000001, + 0x00200000, 0x00200001, 0x08200000, 0x08200001, + 0x00000002, 0x00000003, 0x08000002, 0x08000003, + 0x00200002, 0x00200003, 0x08200002, 0x08200003 + ]; + static $pc2mapd2 = [ + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x00000000, 0x00100000, 0x00000800, 0x00100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x04000000, 0x04100000, 0x04000800, 0x04100800, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x00000004, 0x00100004, 0x00000804, 0x00100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x04000004, 0x04100004, 0x04000804, 0x04100804, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x00020000, 0x00120000, 0x00020800, 0x00120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x04020000, 0x04120000, 0x04020800, 0x04120800, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x00020004, 0x00120004, 0x00020804, 0x00120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x04020004, 0x04120004, 0x04020804, 0x04120804, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, + 0x04020204, 0x04120204, 0x04020A04, 0x04120A04 + ]; + static $pc2mapd3 = [ + 0x00000000, 0x00010000, 0x02000000, 0x02010000, + 0x00000020, 0x00010020, 0x02000020, 0x02010020, + 0x00040000, 0x00050000, 0x02040000, 0x02050000, + 0x00040020, 0x00050020, 0x02040020, 0x02050020, + 0x00002000, 0x00012000, 0x02002000, 0x02012000, + 0x00002020, 0x00012020, 0x02002020, 0x02012020, + 0x00042000, 0x00052000, 0x02042000, 0x02052000, + 0x00042020, 0x00052020, 0x02042020, 0x02052020, + 0x00000000, 0x00010000, 0x02000000, 0x02010000, + 0x00000020, 0x00010020, 0x02000020, 0x02010020, + 0x00040000, 0x00050000, 0x02040000, 0x02050000, + 0x00040020, 0x00050020, 0x02040020, 0x02050020, + 0x00002000, 0x00012000, 0x02002000, 0x02012000, + 0x00002020, 0x00012020, 0x02002020, 0x02012020, + 0x00042000, 0x00052000, 0x02042000, 0x02052000, + 0x00042020, 0x00052020, 0x02042020, 0x02052020, + 0x00000010, 0x00010010, 0x02000010, 0x02010010, + 0x00000030, 0x00010030, 0x02000030, 0x02010030, + 0x00040010, 0x00050010, 0x02040010, 0x02050010, + 0x00040030, 0x00050030, 0x02040030, 0x02050030, + 0x00002010, 0x00012010, 0x02002010, 0x02012010, + 0x00002030, 0x00012030, 0x02002030, 0x02012030, + 0x00042010, 0x00052010, 0x02042010, 0x02052010, + 0x00042030, 0x00052030, 0x02042030, 0x02052030, + 0x00000010, 0x00010010, 0x02000010, 0x02010010, + 0x00000030, 0x00010030, 0x02000030, 0x02010030, + 0x00040010, 0x00050010, 0x02040010, 0x02050010, + 0x00040030, 0x00050030, 0x02040030, 0x02050030, + 0x00002010, 0x00012010, 0x02002010, 0x02012010, + 0x00002030, 0x00012030, 0x02002030, 0x02012030, + 0x00042010, 0x00052010, 0x02042010, 0x02052010, + 0x00042030, 0x00052030, 0x02042030, 0x02052030, + 0x20000000, 0x20010000, 0x22000000, 0x22010000, + 0x20000020, 0x20010020, 0x22000020, 0x22010020, + 0x20040000, 0x20050000, 0x22040000, 0x22050000, + 0x20040020, 0x20050020, 0x22040020, 0x22050020, + 0x20002000, 0x20012000, 0x22002000, 0x22012000, + 0x20002020, 0x20012020, 0x22002020, 0x22012020, + 0x20042000, 0x20052000, 0x22042000, 0x22052000, + 0x20042020, 0x20052020, 0x22042020, 0x22052020, + 0x20000000, 0x20010000, 0x22000000, 0x22010000, + 0x20000020, 0x20010020, 0x22000020, 0x22010020, + 0x20040000, 0x20050000, 0x22040000, 0x22050000, + 0x20040020, 0x20050020, 0x22040020, 0x22050020, + 0x20002000, 0x20012000, 0x22002000, 0x22012000, + 0x20002020, 0x20012020, 0x22002020, 0x22012020, + 0x20042000, 0x20052000, 0x22042000, 0x22052000, + 0x20042020, 0x20052020, 0x22042020, 0x22052020, + 0x20000010, 0x20010010, 0x22000010, 0x22010010, + 0x20000030, 0x20010030, 0x22000030, 0x22010030, + 0x20040010, 0x20050010, 0x22040010, 0x22050010, + 0x20040030, 0x20050030, 0x22040030, 0x22050030, + 0x20002010, 0x20012010, 0x22002010, 0x22012010, + 0x20002030, 0x20012030, 0x22002030, 0x22012030, + 0x20042010, 0x20052010, 0x22042010, 0x22052010, + 0x20042030, 0x20052030, 0x22042030, 0x22052030, + 0x20000010, 0x20010010, 0x22000010, 0x22010010, + 0x20000030, 0x20010030, 0x22000030, 0x22010030, + 0x20040010, 0x20050010, 0x22040010, 0x22050010, + 0x20040030, 0x20050030, 0x22040030, 0x22050030, + 0x20002010, 0x20012010, 0x22002010, 0x22012010, + 0x20002030, 0x20012030, 0x22002030, 0x22012030, + 0x20042010, 0x20052010, 0x22042010, 0x22052010, + 0x20042030, 0x20052030, 0x22042030, 0x22052030 + ]; + static $pc2mapd4 = [ + 0x00000000, 0x00000400, 0x01000000, 0x01000400, + 0x00000000, 0x00000400, 0x01000000, 0x01000400, + 0x00000100, 0x00000500, 0x01000100, 0x01000500, + 0x00000100, 0x00000500, 0x01000100, 0x01000500, + 0x10000000, 0x10000400, 0x11000000, 0x11000400, + 0x10000000, 0x10000400, 0x11000000, 0x11000400, + 0x10000100, 0x10000500, 0x11000100, 0x11000500, + 0x10000100, 0x10000500, 0x11000100, 0x11000500, + 0x00080000, 0x00080400, 0x01080000, 0x01080400, + 0x00080000, 0x00080400, 0x01080000, 0x01080400, + 0x00080100, 0x00080500, 0x01080100, 0x01080500, + 0x00080100, 0x00080500, 0x01080100, 0x01080500, + 0x10080000, 0x10080400, 0x11080000, 0x11080400, + 0x10080000, 0x10080400, 0x11080000, 0x11080400, + 0x10080100, 0x10080500, 0x11080100, 0x11080500, + 0x10080100, 0x10080500, 0x11080100, 0x11080500, + 0x00000008, 0x00000408, 0x01000008, 0x01000408, + 0x00000008, 0x00000408, 0x01000008, 0x01000408, + 0x00000108, 0x00000508, 0x01000108, 0x01000508, + 0x00000108, 0x00000508, 0x01000108, 0x01000508, + 0x10000008, 0x10000408, 0x11000008, 0x11000408, + 0x10000008, 0x10000408, 0x11000008, 0x11000408, + 0x10000108, 0x10000508, 0x11000108, 0x11000508, + 0x10000108, 0x10000508, 0x11000108, 0x11000508, + 0x00080008, 0x00080408, 0x01080008, 0x01080408, + 0x00080008, 0x00080408, 0x01080008, 0x01080408, + 0x00080108, 0x00080508, 0x01080108, 0x01080508, + 0x00080108, 0x00080508, 0x01080108, 0x01080508, + 0x10080008, 0x10080408, 0x11080008, 0x11080408, + 0x10080008, 0x10080408, 0x11080008, 0x11080408, + 0x10080108, 0x10080508, 0x11080108, 0x11080508, + 0x10080108, 0x10080508, 0x11080108, 0x11080508, + 0x00001000, 0x00001400, 0x01001000, 0x01001400, + 0x00001000, 0x00001400, 0x01001000, 0x01001400, + 0x00001100, 0x00001500, 0x01001100, 0x01001500, + 0x00001100, 0x00001500, 0x01001100, 0x01001500, + 0x10001000, 0x10001400, 0x11001000, 0x11001400, + 0x10001000, 0x10001400, 0x11001000, 0x11001400, + 0x10001100, 0x10001500, 0x11001100, 0x11001500, + 0x10001100, 0x10001500, 0x11001100, 0x11001500, + 0x00081000, 0x00081400, 0x01081000, 0x01081400, + 0x00081000, 0x00081400, 0x01081000, 0x01081400, + 0x00081100, 0x00081500, 0x01081100, 0x01081500, + 0x00081100, 0x00081500, 0x01081100, 0x01081500, + 0x10081000, 0x10081400, 0x11081000, 0x11081400, + 0x10081000, 0x10081400, 0x11081000, 0x11081400, + 0x10081100, 0x10081500, 0x11081100, 0x11081500, + 0x10081100, 0x10081500, 0x11081100, 0x11081500, + 0x00001008, 0x00001408, 0x01001008, 0x01001408, + 0x00001008, 0x00001408, 0x01001008, 0x01001408, + 0x00001108, 0x00001508, 0x01001108, 0x01001508, + 0x00001108, 0x00001508, 0x01001108, 0x01001508, + 0x10001008, 0x10001408, 0x11001008, 0x11001408, + 0x10001008, 0x10001408, 0x11001008, 0x11001408, + 0x10001108, 0x10001508, 0x11001108, 0x11001508, + 0x10001108, 0x10001508, 0x11001108, 0x11001508, + 0x00081008, 0x00081408, 0x01081008, 0x01081408, + 0x00081008, 0x00081408, 0x01081008, 0x01081408, + 0x00081108, 0x00081508, 0x01081108, 0x01081508, + 0x00081108, 0x00081508, 0x01081108, 0x01081508, + 0x10081008, 0x10081408, 0x11081008, 0x11081408, + 0x10081008, 0x10081408, 0x11081008, 0x11081408, + 0x10081108, 0x10081508, 0x11081108, 0x11081508, + 0x10081108, 0x10081508, 0x11081108, 0x11081508 + ]; + + $keys = []; + for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { + // pad the key and remove extra characters as appropriate. + $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0"); + + // Perform the PC/1 transformation and compute C and D. + $t = unpack('Nl/Nr', $key); + list($l, $r) = [$t['l'], $t['r']]; + $key = (self::$shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | + (self::$shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | + (self::$shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | + (self::$shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | + (self::$shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | + (self::$shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | + (self::$shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | + (self::$shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); + $key = unpack('Nc/Nd', $key); + $c = ( $key['c'] >> 4) & 0x0FFFFFFF; + $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); + + $keys[$des_round] = [ + self::ENCRYPT => [], + self::DECRYPT => array_fill(0, 32, 0) + ]; + for ($i = 0, $ki = 31; $i < 16; ++$i, $ki -= 2) { + $c <<= $shifts[$i]; + $c = ($c | ($c >> 28)) & 0x0FFFFFFF; + $d <<= $shifts[$i]; + $d = ($d | ($d >> 28)) & 0x0FFFFFFF; + + // Perform the PC-2 transformation. + $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] | + $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF]; + $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] | + $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF]; + + // Reorder: odd bytes/even bytes. Push the result in key schedule. + $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) | + (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); + $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) | + (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); + $keys[$des_round][self::ENCRYPT][ ] = $val1; + $keys[$des_round][self::DECRYPT][$ki - 1] = $val1; + $keys[$des_round][self::ENCRYPT][ ] = $val2; + $keys[$des_round][self::DECRYPT][$ki ] = $val2; + } + } + + switch ($this->des_rounds) { + case 3: // 3DES keys + $this->keys = [ + self::ENCRYPT => array_merge( + $keys[0][self::ENCRYPT], + $keys[1][self::DECRYPT], + $keys[2][self::ENCRYPT] + ), + self::DECRYPT => array_merge( + $keys[2][self::DECRYPT], + $keys[1][self::ENCRYPT], + $keys[0][self::DECRYPT] + ) + ]; + break; + // case 1: // DES keys + default: + $this->keys = [ + self::ENCRYPT => $keys[0][self::ENCRYPT], + self::DECRYPT => $keys[0][self::DECRYPT] + ]; + } + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + // Engine configuration for: + // - DES ($des_rounds == 1) or + // - 3DES ($des_rounds == 3) + $des_rounds = $this->des_rounds; + + $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; + if (!$sbox1) { + $sbox1 = array_map("intval", self::$sbox1); + $sbox2 = array_map("intval", self::$sbox2); + $sbox3 = array_map("intval", self::$sbox3); + $sbox4 = array_map("intval", self::$sbox4); + $sbox5 = array_map("intval", self::$sbox5); + $sbox6 = array_map("intval", self::$sbox6); + $sbox7 = array_map("intval", self::$sbox7); + $sbox8 = array_map("intval", self::$sbox8);' + /* Merge $shuffle with $[inv]ipmap */ . ' + for ($i = 0; $i < 256; ++$i) { + $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; + $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; + } + } + '; + + $k = [ + self::ENCRYPT => $this->keys[self::ENCRYPT], + self::DECRYPT => $this->keys[self::DECRYPT] + ]; + $init_encrypt = ''; + $init_decrypt = ''; + + // Creating code for en- and decryption. + $crypt_block = []; + foreach ([self::ENCRYPT, self::DECRYPT] as $c) { + /* Do the initial IP permutation. */ + $crypt_block[$c] = ' + $in = unpack("N*", $in); + $l = $in[1]; + $r = $in[2]; + $in = unpack("N*", + ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") + ); + ' . /* Extract L0 and R0 */ ' + $l = $in[1]; + $r = $in[2]; + '; + + $l = '$l'; + $r = '$r'; + + // Perform DES or 3DES. + for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { + // Perform the 16 steps. + for ($i = 0; $i < 16; ++$i) { + // start of "the Feistel (F) function" - see the following URL: + // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png + // Merge key schedule. + $crypt_block[$c] .= ' + $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; + $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . + /* S-box indexing. */ + $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ + $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ + $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ + $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; + '; + // end of "the Feistel (F) function" + + // swap L & R + list($l, $r) = [$r, $l]; + } + list($l, $r) = [$r, $l]; + } + + // Perform the inverse IP permutation. + $crypt_block[$c] .= '$in = + ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | + ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | + ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | + ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | + ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | + ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | + ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | + ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); + '; + } + + // Creates the inline-crypt function + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $crypt_block[self::ENCRYPT], + 'decrypt_block' => $crypt_block[self::DECRYPT] + ] + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php new file mode 100644 index 0000000..e1deaf0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php @@ -0,0 +1,405 @@ + + * + * + * + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\DH\Parameters; +use phpseclib3\Crypt\DH\PrivateKey; +use phpseclib3\Crypt\DH\PublicKey; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP (EC)DH implementation + * + * @author Jim Wigginton + */ +abstract class DH extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'DH'; + + /** + * DH prime + * + * @var \phpseclib3\Math\BigInteger + */ + protected $prime; + + /** + * DH Base + * + * Prime divisor of p-1 + * + * @var \phpseclib3\Math\BigInteger + */ + protected $base; + + /** + * Public Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicKey; + + /** + * Create DH parameters + * + * This method is a bit polymorphic. It can take any of the following: + * - two BigInteger's (prime and base) + * - an integer representing the size of the prime in bits (the base is assumed to be 2) + * - a string (eg. diffie-hellman-group14-sha1) + * + * @return Parameters + */ + public static function createParameters(...$args) + { + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); + } + + $params = new Parameters(); + if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { + //if (!$args[0]->isPrime()) { + // throw new \InvalidArgumentException('The first parameter should be a prime number'); + //} + $params->prime = $args[0]; + $params->base = $args[1]; + return $params; + } elseif (count($args) == 1 && is_numeric($args[0])) { + $params->prime = BigInteger::randomPrime($args[0]); + $params->base = new BigInteger(2); + return $params; + } elseif (count($args) != 1 || !is_string($args[0])) { + throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); + } + switch ($args[0]) { + // see http://tools.ietf.org/html/rfc2409#section-6.2 and + // http://tools.ietf.org/html/rfc2412, appendex E + case 'diffie-hellman-group1-sha1': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; + break; + // see http://tools.ietf.org/html/rfc3526#section-3 + case 'diffie-hellman-group14-sha1': // 2048-bit MODP Group + case 'diffie-hellman-group14-sha256': + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-4 + case 'diffie-hellman-group15-sha512': // 3072-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-5 + case 'diffie-hellman-group16-sha512': // 4096-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-6 + case 'diffie-hellman-group17-sha512': // 6144-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . + 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . + 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . + 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . + '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . + 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . + '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'; + break; + // see https://tools.ietf.org/html/rfc3526#section-7 + case 'diffie-hellman-group18-sha512': // 8192-bit MODP Group + $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . + '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . + '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . + 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . + '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . + '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . + 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . + '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . + 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . + 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . + 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . + '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . + '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . + 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . + '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . + '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . + 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . + 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . + 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . + 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . + '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . + 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . + 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . + '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4' . + '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED' . + '2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652D' . + 'E3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B' . + '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6' . + '6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851D' . + 'F9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92' . + '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA' . + '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; + break; + default: + throw new \InvalidArgumentException('Invalid named prime provided'); + } + + $params->prime = new BigInteger($prime, 16); + $params->base = new BigInteger(2); + + return $params; + } + + /** + * Create public / private key pair. + * + * The rationale for the second parameter is described in http://tools.ietf.org/html/rfc4419#section-6.2 : + * + * "To increase the speed of the key exchange, both client and server may + * reduce the size of their private exponents. It should be at least + * twice as long as the key material that is generated from the shared + * secret. For more details, see the paper by van Oorschot and Wiener + * [VAN-OORSCHOT]." + * + * $length is in bits + * + * @param Parameters $params + * @param int $length optional + * @return DH\PrivateKey + */ + public static function createKey(Parameters $params, $length = 0) + { + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + $one = new BigInteger(1); + if ($length) { + $max = $one->bitwise_leftShift($length); + $max = $max->subtract($one); + } else { + $max = $params->prime->subtract($one); + } + + $key = new PrivateKey(); + $key->prime = $params->prime; + $key->base = $params->base; + $key->privateKey = BigInteger::randomRange($one, $max); + $key->publicKey = $key->base->powMod($key->privateKey, $key->prime); + return $key; + } + + /** + * Compute Shared Secret + * + * @param PrivateKey|EC $private + * @param PublicKey|BigInteger|string $public + * @return mixed + */ + public static function computeSecret($private, $public) + { + if ($private instanceof PrivateKey) { // DH\PrivateKey + switch (true) { + case $public instanceof PublicKey: + if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { + throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); + } + return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); + case is_string($public): + $public = new BigInteger($public, -256); + // fall-through + case $public instanceof BigInteger: + return $public->powMod($private->privateKey, $private->prime)->toBytes(true); + default: + throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); + } + } + + if ($private instanceof EC\PrivateKey) { + switch (true) { + case $public instanceof EC\PublicKey: + $public = $public->getEncodedCoordinates(); + // fall-through + case is_string($public): + $point = $private->multiply($public); + switch ($private->getCurve()) { + case 'Curve25519': + case 'Curve448': + $secret = $point; + break; + default: + // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned + $secret = substr($point, 1, (strlen($point) - 1) >> 1); + } + /* + if (($secret[0] & "\x80") === "\x80") { + $secret = "\0$secret"; + } + */ + return $secret; + default: + throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); + } + } + } + + /** + * Load the key + * + * @param string $key + * @param string $password optional + * @return AsymmetricKey + */ + public static function load($key, $password = false) + { + try { + return EC::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + return parent::load($key, $password); + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + if (!isset($components['privateKey']) && !isset($components['publicKey'])) { + $new = new Parameters(); + } else { + $new = isset($components['privateKey']) ? + new PrivateKey() : + new PublicKey(); + } + + $new->prime = $components['prime']; + $new->base = $components['base']; + + if (isset($components['privateKey'])) { + $new->privateKey = $components['privateKey']; + } + if (isset($components['publicKey'])) { + $new->publicKey = $components['publicKey']; + } + + return $new; + } + + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + throw new UnsupportedOperationException('DH does not use a hash algorithm'); + } + + /** + * Returns the hash algorithm currently being used + * + */ + public function getHash() + { + throw new UnsupportedOperationException('DH does not use a hash algorithm'); + } + + /** + * Returns the parameters + * + * A public / private key is only returned if the currently loaded "key" contains an x or y + * value. + * + * @see self::getPublicKey() + * @return mixed + */ + public function getParameters() + { + $type = DH::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + $key = $type::saveParameters($this->prime, $this->base); + return DH::load($key, 'PKCS1'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..65a0a5d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php @@ -0,0 +1,77 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * "PKCS1" Formatted DH Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + return $components; + } + + /** + * Convert EC parameters to the appropriate format + * + * @return string + */ + public static function saveParameters(BigInteger $prime, BigInteger $base, array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + + return "-----BEGIN DH PARAMETERS-----\r\n" . + chunk_split(base64_encode($params), 64) . + "-----END DH PARAMETERS-----\r\n"; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..c330a3c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php @@ -0,0 +1,132 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted DH Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'dhKeyAgreement'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.3.1'; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + $decoded = ASN1::decodeBER($key[$type]); + switch (true) { + case !isset($decoded): + case !isset($decoded[0]['content']): + case !$decoded[0]['content'] instanceof BigInteger: + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components[$type] = $decoded[0]['content']; + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Math\BigInteger $publicKey + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $prime + * @param \phpseclib3\Math\BigInteger $base + * @param \phpseclib3\Math\BigInteger $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = []) + { + $params = [ + 'prime' => $prime, + 'base' => $base + ]; + $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]); + return self::wrapPublicKey($key, $params); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php new file mode 100644 index 0000000..c0ded84 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php @@ -0,0 +1,36 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\DH; + +/** + * DH Parameters + * + * @author Jim Wigginton + */ +final class Parameters extends DH +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->prime, $this->base, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php new file mode 100644 index 0000000..737781f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php @@ -0,0 +1,75 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DH; + +/** + * DH Private Key + * + * @author Jim Wigginton + */ +final class PrivateKey extends DH +{ + use Common\Traits\PasswordProtected; + + /** + * Private Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $privateKey; + + /** + * Public Key + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicKey; + + /** + * Returns the public key + * + * @return DH\PublicKey + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + + $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); + + return DH::loadFormat('PKCS8', $key); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + if (!isset($this->publicKey)) { + $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); + } + + return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php new file mode 100644 index 0000000..87726a5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php @@ -0,0 +1,49 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DH; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DH; + +/** + * DH Public Key + * + * @author Jim Wigginton + */ +final class PublicKey extends DH +{ + use Common\Traits\Fingerprint; + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); + } + + /** + * Returns the public key as a BigInteger + * + * @return \phpseclib3\Math\BigInteger + */ + public function toBigInteger() + { + return $this->publicKey; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php new file mode 100644 index 0000000..0123c66 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php @@ -0,0 +1,337 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\DSA\Parameters; +use phpseclib3\Crypt\DSA\PrivateKey; +use phpseclib3\Crypt\DSA\PublicKey; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP FIPS 186-4 compliant implementation of DSA. + * + * @author Jim Wigginton + */ +abstract class DSA extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'DSA'; + + /** + * DSA Prime P + * + * @var \phpseclib3\Math\BigInteger + */ + protected $p; + + /** + * DSA Group Order q + * + * Prime divisor of p-1 + * + * @var \phpseclib3\Math\BigInteger + */ + protected $q; + + /** + * DSA Group Generator G + * + * @var \phpseclib3\Math\BigInteger + */ + protected $g; + + /** + * DSA public key value y + * + * @var \phpseclib3\Math\BigInteger + */ + protected $y; + + /** + * Signature Format + * + * @var string + */ + protected $sigFormat; + + /** + * Signature Format (Short) + * + * @var string + */ + protected $shortFormat; + + /** + * Create DSA parameters + * + * @param int $L + * @param int $N + * @return \phpseclib3\Crypt\DSA|bool + */ + public static function createParameters($L = 2048, $N = 224) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); + } + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + switch (true) { + case $N == 160: + /* + in FIPS 186-1 and 186-2 N was fixed at 160 whereas K had an upper bound of 1024. + RFC 4253 (SSH Transport Layer Protocol) references FIPS 186-2 and as such most + SSH DSA implementations only support keys with an N of 160. + puttygen let's you set the size of L (but not the size of N) and uses 2048 as the + default L value. that's not really compliant with any of the FIPS standards, however, + for the purposes of maintaining compatibility with puttygen, we'll support it + */ + //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160: + // FIPS 186-3 changed this as follows: + //case $L == 1024 && $N == 160: + case $L == 2048 && $N == 224: + case $L == 2048 && $N == 256: + case $L == 3072 && $N == 256: + break; + default: + throw new \InvalidArgumentException('Invalid values for N and L'); + } + + $two = new BigInteger(2); + + $q = BigInteger::randomPrime($N); + $divisor = $q->multiply($two); + + do { + $x = BigInteger::random($L); + list(, $c) = $x->divide($divisor); + $p = $x->subtract($c->subtract(self::$one)); + } while ($p->getLength() != $L || !$p->isPrime()); + + $p_1 = $p->subtract(self::$one); + list($e) = $p_1->divide($q); + + // quoting http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=50 , + // "h could be obtained from a random number generator or from a counter that + // changes after each use". PuTTY (sshdssg.c) starts h off at 1 and increments + // it on each loop. wikipedia says "commonly h = 2 is used" so we'll just do that + $h = clone $two; + while (true) { + $g = $h->powMod($e, $p); + if (!$g->equals(self::$one)) { + break; + } + $h = $h->add(self::$one); + } + + $dsa = new Parameters(); + $dsa->p = $p; + $dsa->q = $q; + $dsa->g = $g; + + return $dsa; + } + + /** + * Create public / private key pair. + * + * This method is a bit polymorphic. It can take a DSA/Parameters object, L / N as two distinct parameters or + * no parameters (at which point L and N will be generated with this method) + * + * Returns the private key, from which the publickey can be extracted + * + * @param int[] ...$args + * @return DSA\PrivateKey + */ + public static function createKey(...$args) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) { + $params = self::createParameters($args[0], $args[1]); + } elseif (count($args) == 1 && $args[0] instanceof Parameters) { + $params = $args[0]; + } elseif (!count($args)) { + $params = self::createParameters(); + } else { + throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.'); + } + + $private = new PrivateKey(); + $private->p = $params->p; + $private->q = $params->q; + $private->g = $params->g; + + $private->x = BigInteger::randomRange(self::$one, $private->q->subtract(self::$one)); + $private->y = $private->g->powMod($private->x, $private->p); + + //$public = clone $private; + //unset($public->x); + + return $private + ->withHash($params->hash->getHash()) + ->withSignatureFormat($params->shortFormat); + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (!isset($components['x']) && !isset($components['y'])) { + $new = new Parameters(); + } elseif (isset($components['x'])) { + $new = new PrivateKey(); + $new->x = $components['x']; + } else { + $new = new PublicKey(); + } + + $new->p = $components['p']; + $new->q = $components['q']; + $new->g = $components['g']; + + if (isset($components['y'])) { + $new->y = $components['y']; + } + + return $new; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); + $this->shortFormat = 'ASN1'; + + parent::__construct(); + } + + /** + * Returns the key size + * + * More specifically, this L (the length of DSA Prime P) and N (the length of DSA Group Order q) + * + * @return array + */ + public function getLength() + { + return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()]; + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? + 'OpenSSL' : 'PHP'; + } + + /** + * Returns the parameters + * + * A public / private key is only returned if the currently loaded "key" contains an x or y + * value. + * + * @see self::getPublicKey() + * @return mixed + */ + public function getParameters() + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + $key = $type::saveParameters($this->p, $this->q, $this->g); + return DSA::load($key, 'PKCS1') + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @param string $format + */ + public function withSignatureFormat($format) + { + $new = clone $this; + $new->shortFormat = $format; + $new->sigFormat = self::validatePlugin('Signature', $format); + return $new; + } + + /** + * Returns the signature format currently being used + * + */ + public function getSignatureFormat() + { + return $this->shortFormat; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..cc204fa --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,118 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSH Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends Progenitor +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-dss']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + + list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']); + + return compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + + list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']); + + $comment = $parsed['comment']; + + return compact('p', 'q', 'g', 'y', 'comment'); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + // from : + // string "ssh-dss" + // mpint p + // mpint q + // mpint g + // mpint y + $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $DSAPublicKey; + } + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment; + + return $DSAPublicKey; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]); + $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..52a0499 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php @@ -0,0 +1,143 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#1 Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); + if (is_array($key)) { + return $key; + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAPrivateKey::MAP); + if (is_array($key)) { + return $key; + } + + $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); + if (is_array($key)) { + return $key; + } + + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + /** + * Convert DSA parameters to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @return string + */ + public static function saveParameters(BigInteger $p, BigInteger $q, BigInteger $g) + { + $key = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + + $key = ASN1::encodeDER($key, Maps\DSAParams::MAP); + + return "-----BEGIN DSA PARAMETERS-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END DSA PARAMETERS-----\r\n"; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $key = [ + 'version' => 0, + 'p' => $p, + 'q' => $q, + 'g' => $g, + 'y' => $y, + 'x' => $x + ]; + + $key = ASN1::encodeDER($key, Maps\DSAPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'DSA', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); + + return self::wrapPublicKey($key, 'DSA'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..004881e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php @@ -0,0 +1,146 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'id-dsa'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.10040.4.1'; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER of parameters'); + } + $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); + if (!is_array($components)) { + throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); + } + + $decoded = ASN1::decodeBER($key[$type]); + if (empty($decoded)) { + throw new \RuntimeException('Unable to decode BER'); + } + + $var = $type == 'privateKey' ? 'x' : 'y'; + $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); + if (!$components[$var] instanceof BigInteger) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (isset($key['meta'])) { + $components['meta'] = $key['meta']; + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) + { + $params = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($x, Maps\DSAPublicKey::MAP); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) + { + $params = [ + 'p' => $p, + 'q' => $q, + 'g' => $g + ]; + $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); + $params = new ASN1\Element($params); + $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); + return self::wrapPublicKey($key, $params); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..177bfdd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php @@ -0,0 +1,109 @@ + 160 kinda useless, hence this handlers not supporting such keys. + * + * PHP version 5 + * + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * PuTTY Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends Progenitor +{ + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH'; + + /** + * Algorithm Identifier + * + * @var array + */ + protected static $types = ['ssh-dss']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + extract($components); + unset($components['public'], $components['private']); + + list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public); + list($x) = Strings::unpackSSH2('i', $private); + + return compact('p', 'q', 'g', 'y', 'x', 'comment'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = []) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + $public = Strings::packSSH2('iiii', $p, $q, $g, $y); + $private = Strings::packSSH2('i', $x); + + return self::wrapPrivateKey($public, $private, 'ssh-dss', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + if ($q->getLength() != 160) { + throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); + } + + return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dss'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php new file mode 100644 index 0000000..201aa6f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php @@ -0,0 +1,85 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; + +/** + * Raw DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @param array $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); + } + + switch (true) { + case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): + case !$key['p'] instanceof BigInteger: + case !$key['q'] instanceof BigInteger: + case !$key['g'] instanceof BigInteger: + case !isset($key['x']) && !isset($key['y']): + case isset($key['x']) && !$key['x'] instanceof BigInteger: + case isset($key['y']) && !$key['y'] instanceof BigInteger: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; + + return array_intersect_key($key, $options); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @param \phpseclib3\Math\BigInteger $x + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '') + { + return compact('p', 'q', 'g', 'y', 'x'); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + return compact('p', 'q', 'g', 'y'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php new file mode 100644 index 0000000..fc36367 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php @@ -0,0 +1,132 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger; + +/** + * XML Formatted DSA Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (!class_exists('DOMDocument')) { + throw new BadConfigurationException('The dom extension is not setup correctly on this system'); + } + + $use_errors = libxml_use_internal_errors(true); + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); + if (!$temp->length) { + continue; + } + $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'p': // a prime modulus meeting the [DSS] requirements + // Parameters P, Q, and G can be public and common to a group of users. They might be known + // from application context. As such, they are optional but P and Q must either both appear + // or both be absent + $components['p'] = $value; + break; + case 'q': // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 + $components['q'] = $value; + break; + case 'g': // an integer with certain properties with respect to P and Q + $components['g'] = $value; + break; + case 'y': // G**X mod P (where X is part of the private key and not made public) + $components['y'] = $value; + // the remaining options do not do anything + case 'j': // (P - 1) / Q + // Parameter J is available for inclusion solely for efficiency as it is calculatable from + // P and Q + case 'seed': // a DSA prime generation seed + // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm + // specified in [DSS]. As such, they are optional but must either both be present or both + // be absent + case 'pgencounter': // a DSA prime generation counter + } + } + + libxml_use_internal_errors($use_errors); + + if (!isset($components['y'])) { + throw new \UnexpectedValueException('Key is missing y component'); + } + + switch (true) { + case !isset($components['p']): + case !isset($components['q']): + case !isset($components['g']): + return ['y' => $components['y']]; + } + + return $components; + } + + /** + * Convert a public key to the appropriate format + * + * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue + * + * @param \phpseclib3\Math\BigInteger $p + * @param \phpseclib3\Math\BigInteger $q + * @param \phpseclib3\Math\BigInteger $g + * @param \phpseclib3\Math\BigInteger $y + * @return string + */ + public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) + { + return "\r\n" . + '

          ' . Strings::base64_encode($p->toBytes()) . "

          \r\n" . + ' ' . Strings::base64_encode($q->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($g->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($y->toBytes()) . "\r\n" . + '
          '; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php new file mode 100644 index 0000000..df52bee --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php @@ -0,0 +1,62 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\File\ASN1 as Encoder; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @param string $sig + * @return array|bool + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $decoded = Encoder::decodeBER($sig); + if (empty($decoded)) { + return false; + } + $components = Encoder::asn1map($decoded[0], Maps\DssSigValue::MAP); + + return $components; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return Encoder::encodeDER(compact('r', 's'), Maps\DssSigValue::MAP); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php new file mode 100644 index 0000000..2657a2a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php @@ -0,0 +1,25 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; + +/** + * Raw DSA Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw extends Progenitor +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php new file mode 100644 index 0000000..dbfceab --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php @@ -0,0 +1,74 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA\Formats\Signature; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; + +/** + * SSH2 Signature Handler + * + * @author Jim Wigginton + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $result = Strings::unpackSSH2('ss', $sig); + if ($result === false) { + return false; + } + list($type, $blob) = $result; + if ($type != 'ssh-dss' || strlen($blob) != 40) { + return false; + } + + return [ + 'r' => new BigInteger(substr($blob, 0, 20), 256), + 's' => new BigInteger(substr($blob, 20), 256) + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + if ($r->getLength() > 160 || $s->getLength() > 160) { + return false; + } + return Strings::packSSH2( + 'ss', + 'ssh-dss', + str_pad($r->toBytes(), 20, "\0", STR_PAD_LEFT) . + str_pad($s->toBytes(), 20, "\0", STR_PAD_LEFT) + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php new file mode 100644 index 0000000..84d16ba --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php @@ -0,0 +1,36 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\DSA; + +/** + * DSA Parameters + * + * @author Jim Wigginton + */ +final class Parameters extends DSA +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->p, $this->q, $this->g, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php new file mode 100644 index 0000000..74d3e69 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php @@ -0,0 +1,152 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Math\BigInteger; + +/** + * DSA Private Key + * + * @author Jim Wigginton + */ +final class PrivateKey extends DSA implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * DSA secret exponent x + * + * @var \phpseclib3\Math\BigInteger + */ + protected $x; + + /** + * Returns the public key + * + * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key + * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. + * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this + * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g + * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified + * by getting a DSA PKCS8 public key: + * + * "openssl dsa -in private.dsa -pubout -outform PEM" + * + * ie. just swap out rsa with dsa in the rsa command above. + * + * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA + * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature + * without the parameters and the PKCS1 DSA public key format does not include the parameters. + * + * @see self::getPrivateKey() + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + + $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); + + return DSA::loadFormat('PKCS8', $key) + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return mixed + */ + public function sign($message) + { + $format = $this->sigFormat; + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $signature = ''; + $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); + + if ($result) { + if ($this->shortFormat == 'ASN1') { + return $signature; + } + + extract(ASN1Signature::load($signature)); + + return $format::save($r, $s); + } + } + + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + + while (true) { + $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($this->q); + $temp = $h->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + if (!$s->equals(self::$zero)) { + break; + } + } + + // the following is an RFC6979 compliant implementation of deterministic DSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + $r = $this->g->powMod($k, $this->p); + list(, $r) = $r->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($this->x->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + + return $format::save($r, $s); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + if (!isset($this->y)) { + $this->y = $this->g->powMod($this->x, $this->p); + } + + return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php new file mode 100644 index 0000000..c14ffbd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php @@ -0,0 +1,86 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\DSA; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; + +/** + * DSA Public Key + * + * @author Jim Wigginton + */ +final class PublicKey extends DSA implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Verify a signature + * + * @see self::verify() + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + $format = $this->sigFormat; + + $params = $format::load($signature); + if ($params === false || count($params) != 2) { + return false; + } + extract($params); + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; + + $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); + + if ($result != -1) { + return (bool) $result; + } + } + + $q_1 = $this->q->subtract(self::$one); + if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { + return false; + } + + $w = $s->modInverse($this->q); + $h = $this->hash->hash($message); + $h = $this->bits2int($h); + list(, $u1) = $h->multiply($w)->divide($this->q); + list(, $u2) = $r->multiply($w)->divide($this->q); + $v1 = $this->g->powMod($u1, $this->p); + $v2 = $this->y->powMod($u2, $this->p); + list(, $v) = $v1->multiply($v2)->divide($this->p); + list(, $v) = $v->divide($this->q); + + return $v->equals($r); + } + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php new file mode 100644 index 0000000..10b3825 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php @@ -0,0 +1,480 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * @author Jim Wigginton + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Ed448; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\EC\Parameters; +use phpseclib3\Crypt\EC\PrivateKey; +use phpseclib3\Crypt\EC\PublicKey; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps\ECParameters; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP implementation of EC. + * + * @author Jim Wigginton + */ +abstract class EC extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'EC'; + + /** + * Public Key QA + * + * @var object[] + */ + protected $QA; + + /** + * Curve + * + * @var \phpseclib3\Crypt\EC\BaseCurves\Base + */ + protected $curve; + + /** + * Signature Format + * + * @var string + */ + protected $format; + + /** + * Signature Format (Short) + * + * @var string + */ + protected $shortFormat; + + /** + * Curve Name + * + * @var string + */ + private $curveName; + + /** + * Curve Order + * + * Used for deterministic ECDSA + * + * @var \phpseclib3\Math\BigInteger + */ + protected $q; + + /** + * Alias for the private key + * + * Used for deterministic ECDSA. AsymmetricKey expects $x. I don't like x because + * with x you have x * the base point yielding an (x, y)-coordinate that is the + * public key. But the x is different depending on which side of the equal sign + * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. + * + * @var \phpseclib3\Math\BigInteger + */ + protected $x; + + /** + * Context + * + * @var string + */ + protected $context; + + /** + * Signature Format + * + * @var string + */ + protected $sigFormat; + + /** + * Create public / private key pair. + * + * @param string $curve + * @return \phpseclib3\Crypt\EC\PrivateKey + */ + public static function createKey($curve) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + $curve = strtolower($curve); + if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) { + $kp = sodium_crypto_sign_keypair(); + + $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp)); + //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp)); + + $privatekey->curveName = 'Ed25519'; + //$publickey->curveName = $curve; + + return $privatekey; + } + + $privatekey = new PrivateKey(); + + $curveName = $curve; + if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) { + $curveName = ucfirst($curveName); + } elseif (substr($curveName, 0, 10) == 'brainpoolp') { + $curveName = 'brainpoolP' . substr($curveName, 10); + } + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; + + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported'); + } + + $reflect = new \ReflectionClass($curve); + $curveName = $reflect->isFinal() ? + $reflect->getParentClass()->getShortName() : + $reflect->getShortName(); + + $curve = new $curve(); + if ($curve instanceof TwistedEdwardsCurve) { + $arr = $curve->extractSecret(Random::string($curve instanceof Ed448 ? 57 : 32)); + $privatekey->dA = $dA = $arr['dA']; + $privatekey->secret = $arr['secret']; + } else { + $privatekey->dA = $dA = $curve->createRandomMultiplier(); + } + if ($curve instanceof Curve25519 && self::$engines['libsodium']) { + //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000'); + //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r); + $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes()); + $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))]; + } else { + $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA); + } + $privatekey->curve = $curve; + + //$publickey = clone $privatekey; + //unset($publickey->dA); + //unset($publickey->x); + + $privatekey->curveName = $curveName; + //$publickey->curveName = $curveName; + + if ($privatekey->curve instanceof TwistedEdwardsCurve) { + return $privatekey->withHash($curve::HASH); + } + + return $privatekey; + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + if (!isset($components['dA']) && !isset($components['QA'])) { + $new = new Parameters(); + $new->curve = $components['curve']; + return $new; + } + + $new = isset($components['dA']) ? + new PrivateKey() : + new PublicKey(); + $new->curve = $components['curve']; + $new->QA = $components['QA']; + + if (isset($components['dA'])) { + $new->dA = $components['dA']; + $new->secret = $components['secret']; + } + + if ($new->curve instanceof TwistedEdwardsCurve) { + return $new->withHash($components['curve']::HASH); + } + + return $new; + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); + $this->shortFormat = 'ASN1'; + + parent::__construct(); + } + + /** + * Returns the curve + * + * Returns a string if it's a named curve, an array if not + * + * @return string|array + */ + public function getCurve() + { + if ($this->curveName) { + return $this->curveName; + } + + if ($this->curve instanceof MontgomeryCurve) { + $this->curveName = $this->curve instanceof Curve25519 ? 'Curve25519' : 'Curve448'; + return $this->curveName; + } + + if ($this->curve instanceof TwistedEdwardsCurve) { + $this->curveName = $this->curve instanceof Ed25519 ? 'Ed25519' : 'Ed448'; + return $this->curveName; + } + + $params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]); + $decoded = ASN1::extractBER($params); + $decoded = ASN1::decodeBER($decoded); + $decoded = ASN1::asn1map($decoded[0], ECParameters::MAP); + if (isset($decoded['namedCurve'])) { + $this->curveName = $decoded['namedCurve']; + return $decoded['namedCurve']; + } + + if (!$namedCurves) { + PKCS1::useSpecifiedCurve(); + } + + return $decoded; + } + + /** + * Returns the key size + * + * Quoting https://tools.ietf.org/html/rfc5656#section-2, + * + * "The size of a set of elliptic curve domain parameters on a prime + * curve is defined as the number of bits in the binary representation + * of the field order, commonly denoted by p. Size on a + * characteristic-2 curve is defined as the number of bits in the binary + * representation of the field, commonly denoted by m. A set of + * elliptic curve domain parameters defines a group of order n generated + * by a base point P" + * + * @return int + */ + public function getLength() + { + return $this->curve->getLength(); + } + + /** + * Returns the current engine being used + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ? + 'libsodium' : 'PHP'; + } + + return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? + 'OpenSSL' : 'PHP'; + } + + /** + * Returns the public key coordinates as a string + * + * Used by ECDH + * + * @return string + */ + public function getEncodedCoordinates() + { + if ($this->curve instanceof MontgomeryCurve) { + return strrev($this->QA[0]->toBytes(true)); + } + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve->encodePoint($this->QA); + } + return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true); + } + + /** + * Returns the parameters + * + * @see self::getPublicKey() + * @param string $type optional + * @return mixed + */ + public function getParameters($type = 'PKCS1') + { + $type = self::validatePlugin('Keys', $type, 'saveParameters'); + + $key = $type::saveParameters($this->curve); + + return EC::load($key, 'PKCS1') + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @param string $format + */ + public function withSignatureFormat($format) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $new = clone $this; + $new->shortFormat = $format; + $new->sigFormat = self::validatePlugin('Signature', $format); + return $new; + } + + /** + * Returns the signature format currently being used + * + */ + public function getSignatureFormat() + { + return $this->shortFormat; + } + + /** + * Sets the context + * + * Used by Ed25519 / Ed448. + * + * @see self::sign() + * @see self::verify() + * @param string $context optional + */ + public function withContext($context = null) + { + if (!$this->curve instanceof TwistedEdwardsCurve) { + throw new UnsupportedCurveException('Only Ed25519 and Ed448 support contexts'); + } + + $new = clone $this; + if (!isset($context)) { + $new->context = null; + return $new; + } + if (!is_string($context)) { + throw new \InvalidArgumentException('setContext expects a string'); + } + if (strlen($context) > 255) { + throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); + } + $new->context = $context; + return $new; + } + + /** + * Returns the signature format currently being used + * + */ + public function getContext() + { + return $this->context; + } + + /** + * Determines which hashing function should be used + * + * @param string $hash + */ + public function withHash($hash) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + if ($this->curve instanceof Ed25519 && $hash != 'sha512') { + throw new UnsupportedAlgorithmException('Ed25519 only supports sha512 as a hash'); + } + if ($this->curve instanceof Ed448 && $hash != 'shake256-912') { + throw new UnsupportedAlgorithmException('Ed448 only supports shake256 with a length of 114 bytes'); + } + + return parent::withHash($hash); + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + if ($this->curve instanceof MontgomeryCurve) { + return ''; + } + + return parent::__toString(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php new file mode 100644 index 0000000..dbc914b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php @@ -0,0 +1,218 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; + +/** + * Base + * + * @author Jim Wigginton + */ +abstract class Base +{ + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Finite Field Integer factory + * + * @var \phpseclib3\Math\FiniteField\Integer + */ + protected $factory; + + /** + * Returns a random integer + * + * @return object + */ + public function randomInteger() + { + return $this->factory->randomInteger(); + } + + /** + * Converts a BigInteger to a \phpseclib3\Math\FiniteField\Integer integer + * + * @return object + */ + public function convertInteger(BigInteger $x) + { + return $this->factory->newInteger($x); + } + + /** + * Returns the length, in bytes, of the modulo + * + * @return integer + */ + public function getLengthInBytes() + { + return $this->factory->getLengthInBytes(); + } + + /** + * Returns the length, in bits, of the modulo + * + * @return integer + */ + public function getLength() + { + return $this->factory->getLength(); + } + + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + $alreadyInternal = isset($p[2]); + $r = $alreadyInternal ? + [[], $p] : + [[], $this->convertToInternal($p)]; + + $d = $d->toBits(); + for ($i = 0; $i < strlen($d); $i++) { + $d_i = (int) $d[$i]; + $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); + $r[$d_i] = $this->doublePoint($r[$d_i]); + } + + return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); + } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return BigInteger::randomRange($one, $this->order->subtract($one)); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + static $zero; + if (!isset($zero)) { + $zero = new BigInteger(); + } + + if (!isset($this->order)) { + throw new \RuntimeException('setOrder needs to be called before this method'); + } + if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { + throw new \RangeException('x must be between 1 and the order of the curve'); + } + } + + /** + * Sets the Order + */ + public function setOrder(BigInteger $order) + { + $this->order = $order; + } + + /** + * Returns the Order + * + * @return \phpseclib3\Math\BigInteger + */ + public function getOrder() + { + return $this->order; + } + + /** + * Use a custom defined modular reduction function + * + * @return object + */ + public function setReduction(callable $func) + { + $this->factory->setReduction($func); + } + + /** + * Returns the affine point + * + * @return object[] + */ + public function convertToAffine(array $p) + { + return $p; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return object[] + */ + public function convertToInternal(array $p) + { + return $p; + } + + /** + * Negates a point + * + * @return object[] + */ + public function negatePoint(array $p) + { + $temp = [ + $p[0], + $p[1]->negate() + ]; + if (isset($p[2])) { + $temp[] = $p[2]; + } + return $temp; + } + + /** + * Multiply and Add Points + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $p1 = $this->convertToInternal($points[0]); + $p2 = $this->convertToInternal($points[1]); + $p1 = $this->multiplyPoint($p1, $scalars[0]); + $p2 = $this->multiplyPoint($p2, $scalars[1]); + $r = $this->addPoint($p1, $p2); + return $this->convertToAffine($r); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php new file mode 100644 index 0000000..4fc6c70 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php @@ -0,0 +1,373 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\BinaryField\Integer as BinaryInteger; + +/** + * Curves over y^2 + x*y = x^3 + a*x^2 + b + * + * @author Jim Wigginton + */ +class Binary extends Base +{ + /** + * Binary Field Integer factory + * + * @var \phpseclib3\Math\BinaryField + */ + protected $factory; + + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(...$modulo) + { + $this->modulo = $modulo; + $this->factory = new BinaryField(...$modulo); + + $this->one = $this->factory->newInteger("\1"); + } + + /** + * Set coefficients a and b + * + * @param string $a + * @param string $b + */ + public function setCoefficients($a, $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger(pack('H*', $a)); + $this->b = $this->factory->newInteger(pack('H*', $b)); + } + + /** + * Set x and y coordinates for the base point + * + * @param string|BinaryInteger $x + * @param string|BinaryInteger $y + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !is_string($x) && !$x instanceof BinaryInteger: + throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); + case !is_string($y) && !$y instanceof BinaryInteger: + throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, + is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $o1 = $z1->multiply($z1); + $b = $x2->multiply($o1); + + if ($z2->equals($this->one)) { + $d = $y2->multiply($o1)->multiply($z1); + $e = $x1->add($b); + $f = $y1->add($d); + $z3 = $e->multiply($z1); + $h = $f->multiply($x2)->add($z3->multiply($y2)); + $i = $f->add($z3); + $g = $z3->multiply($z3); + $p1 = $this->a->multiply($g); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($h)); + + return [$x3, $y3, $z3]; + } + + $o2 = $z2->multiply($z2); + $a = $x1->multiply($o2); + $c = $y1->multiply($o2)->multiply($z2); + $d = $y2->multiply($o1)->multiply($z1); + $e = $a->add($b); + $f = $c->add($d); + $g = $e->multiply($z1); + $h = $f->multiply($x2)->add($g->multiply($y2)); + $z3 = $g->multiply($z2); + $i = $f->add($z3); + $p1 = $this->a->multiply($z3->multiply($z3)); + $p2 = $f->multiply($i); + $p3 = $e->multiply($e)->multiply($e); + $x3 = $p1->add($p2)->add($p3); + $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); + + return [$x3, $y3, $z3]; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html + + list($x1, $y1, $z1) = $p; + + $a = $x1->multiply($x1); + $b = $a->multiply($a); + + if ($z1->equals($this->one)) { + $x3 = $b->add($this->b); + $z3 = clone $x1; + $p1 = $a->add($y1)->add($z3)->multiply($this->b); + $p2 = $a->add($y1)->multiply($b); + $y3 = $p1->add($p2); + + return [$x3, $y3, $z3]; + } + + $c = $z1->multiply($z1); + $d = $c->multiply($c); + $x3 = $b->add($this->b->multiply($d->multiply($d))); + $z3 = $x1->multiply($c); + $p1 = $b->multiply($z3); + $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); + $y3 = $p1->add($p2); + + return [$x3, $y3, $z3]; + } + + /** + * Returns the X coordinate and the derived Y coordinate + * + * Not supported because it is covered by patents. + * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , + * + * "Due to patent issues the compressed option is disabled by default for binary curves + * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at + * compile time." + * + * @return array + */ + public function derivePoint($m) + { + throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $lhs = $lhs->add($x->multiply($y)); + $x2 = $x->multiply($x); + $x3 = $x2->multiply($x); + $rhs = $x3->add($this->a->multiply($x2))->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [ + $x->multiply($z2), + $y->multiply($z2)->multiply($z) + ]; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p['fresh'] = true; + return $p; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php new file mode 100644 index 0000000..d8492eb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php @@ -0,0 +1,335 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; + +/** + * Curves over y^2 = x^3 + b + * + * @author Jim Wigginton + */ +class KoblitzPrime extends Prime +{ + /** + * Basis + * + * @var list + */ + protected $basis; + + /** + * Beta + * + * @var PrimeField\Integer + */ + protected $beta; + + // don't overwrite setCoefficients() with one that only accepts one parameter so that + // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking + // purposes). + + /** + * Multiply and Add Points + * + * Uses a efficiently computable endomorphism to achieve a slight speedup + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/short.js#L219 + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + static $zero, $one, $two; + if (!isset($two)) { + $two = new BigInteger(2); + $one = new BigInteger(1); + } + + if (!isset($this->beta)) { + // get roots + $inv = $this->one->divide($this->two)->negate(); + $s = $this->three->negate()->squareRoot()->multiply($inv); + $betas = [ + $inv->add($s), + $inv->subtract($s) + ]; + $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; + //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; + } + + if (!isset($this->basis)) { + $factory = new PrimeField($this->order); + $tempOne = $factory->newInteger($one); + $tempTwo = $factory->newInteger($two); + $tempThree = $factory->newInteger(new BigInteger(3)); + + $inv = $tempOne->divide($tempTwo)->negate(); + $s = $tempThree->negate()->squareRoot()->multiply($inv); + + $lambdas = [ + $inv->add($s), + $inv->subtract($s) + ]; + + $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; + $rhs = $this->p[0]->multiply($this->beta); + $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; + + $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); + ///* + foreach ($this->basis as $basis) { + echo strtoupper($basis['a']->toHex(true)) . "\n"; + echo strtoupper($basis['b']->toHex(true)) . "\n\n"; + } + exit; + //*/ + } + + $npoints = $nscalars = []; + for ($i = 0; $i < count($points); $i++) { + $p = $points[$i]; + $k = $scalars[$i]->toBigInteger(); + + // begin split + list($v1, $v2) = $this->basis; + + $c1 = $v2['b']->multiply($k); + list($c1, $r) = $c1->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c1 = $c1->add($one); + } + + $c2 = $v1['b']->negate()->multiply($k); + list($c2, $r) = $c2->divide($this->order); + if ($this->order->compare($r->multiply($two)) <= 0) { + $c2 = $c2->add($one); + } + + $p1 = $c1->multiply($v1['a']); + $p2 = $c2->multiply($v2['a']); + $q1 = $c1->multiply($v1['b']); + $q2 = $c2->multiply($v2['b']); + + $k1 = $k->subtract($p1)->subtract($p2); + $k2 = $q1->add($q2)->negate(); + // end split + + $beta = [ + $p[0]->multiply($this->beta), + $p[1], + clone $this->one + ]; + + if (isset($p['naf'])) { + $beta['naf'] = array_map(function ($p) { + return [ + $p[0]->multiply($this->beta), + $p[1], + clone $this->one + ]; + }, $p['naf']); + $beta['nafwidth'] = $p['nafwidth']; + } + + if ($k1->isNegative()) { + $k1 = $k1->negate(); + $p = $this->negatePoint($p); + } + + if ($k2->isNegative()) { + $k2 = $k2->negate(); + $beta = $this->negatePoint($beta); + } + + $pos = 2 * $i; + $npoints[$pos] = $p; + $nscalars[$pos] = $this->factory->newInteger($k1); + + $pos++; + $npoints[$pos] = $beta; + $nscalars[$pos] = $this->factory->newInteger($k2); + } + + return parent::multiplyAddPoints($npoints, $nscalars); + } + + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0]); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + + /** + * Doubles a jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x1, $y1, $z1) = $p; + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $b->multiply($b); + $d = $x1->add($b); + $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); + $e = $this->three->multiply($a); + $f = $e->multiply($e); + $x3 = $f->subtract($this->two->multiply($d)); + $y3 = $e->multiply($d->subtract($x3))->subtract( + $this->eight->multiply($c) + ); + $z3 = $this->two->multiply($y1)->multiply($z1); + return [$x3, $y3, $z3]; + } + + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x1, $y1) = $p; + $xx = $x1->multiply($x1); + $yy = $y1->multiply($y1); + $yyyy = $yy->multiply($yy); + $s = $x1->add($yy); + $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); + $m = $this->three->multiply($xx); + $t = $m->multiply($m)->subtract($this->two->multiply($s)); + $x3 = $t; + $y3 = $s->subtract($t); + $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); + $z3 = $this->two->multiply($y1); + return [$x3, $y3, $z3]; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($x)->multiply($x); + $rhs = $temp->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Calculates the parameters needed from the Euclidean algorithm as discussed at + * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 + * + * @param BigInteger $u + * @param BigInteger $v + * @return BigInteger[] + */ + protected static function extendedGCD(BigInteger $u, BigInteger $v) + { + $one = new BigInteger(1); + $zero = new BigInteger(); + + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + + $stop = $v->bitwise_rightShift($v->getLength() >> 1); + + $a1 = clone $zero; + $b1 = clone $zero; + $a2 = clone $zero; + $b2 = clone $zero; + + $postGreatestIndex = 0; + + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + + if ($v->compare($stop) > 0) { + $a0 = $v; + $b0 = $c; + } else { + $postGreatestIndex++; + } + + if ($postGreatestIndex == 1) { + $a1 = $v; + $b1 = $c->negate(); + } + + if ($postGreatestIndex == 2) { + $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); + $lhs = $v->multiply($v)->add($b->multiply($b)); + if ($lhs->compare($rhs) <= 0) { + $a2 = $a0; + $b2 = $b0->negate(); + } else { + $a2 = $v; + $b2 = $c->negate(); + } + + break; + } + } + + return [ + ['a' => $a1, 'b' => $b1], + ['a' => $a2, 'b' => $b2] + ]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php new file mode 100644 index 0000000..e3fa50b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php @@ -0,0 +1,279 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + a*x + x + * + * @author Jim Wigginton + */ +class Montgomery extends Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeField + */ + protected $factory; + + /** + * Cofficient for x + * + * @var object + */ + protected $a; + + /** + * Constant used for point doubling + * + * @var object + */ + protected $a24; + + /** + * The Number Zero + * + * @var object + */ + protected $zero; + + /** + * The Number One + * + * @var object + */ + protected $one; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->zero = $this->factory->newInteger(new BigInteger()); + $this->one = $this->factory->newInteger(new BigInteger(1)); + } + + /** + * Set coefficients a + */ + public function setCoefficients(BigInteger $a) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $two = $this->factory->newInteger(new BigInteger(2)); + $four = $this->factory->newInteger(new BigInteger(4)); + $this->a24 = $this->a->subtract($two)->divide($four); + } + + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Doubles and adds a point on a curve + * + * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 + * + * @return FiniteField[][] + */ + private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + return []; + } + + if (!isset($p[1])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); + } + + list($x2, $z2) = $p; + list($x3, $z3) = $q; + + $a = $x2->add($z2); + $aa = $a->multiply($a); + $b = $x2->subtract($z2); + $bb = $b->multiply($b); + $e = $aa->subtract($bb); + $c = $x3->add($z3); + $d = $x3->subtract($z3); + $da = $d->multiply($a); + $cb = $c->multiply($b); + $temp = $da->add($cb); + $x5 = $temp->multiply($temp); + $temp = $da->subtract($cb); + $z5 = $x1->multiply($temp->multiply($temp)); + $x4 = $aa->multiply($bb); + $temp = static::class == Curve25519::class ? $bb : $aa; + $z4 = $e->multiply($temp->add($this->a24->multiply($e))); + + return [ + [$x4, $z4], + [$x5, $z5] + ]; + } + + /** + * Multiply a point on the curve by a scalar + * + * Uses the montgomery ladder technique as described here: + * + * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder + * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + $p1 = [$this->one, $this->zero]; + $alreadyInternal = isset($x[1]); + $p2 = $this->convertToInternal($p); + $x = $p[0]; + + $b = $d->toBits(); + $b = str_pad($b, 256, '0', STR_PAD_LEFT); + for ($i = 0; $i < strlen($b); $i++) { + $b_i = (int) $b[$i]; + if ($b_i) { + list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); + } else { + list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); + } + } + + return $alreadyInternal ? $p1 : $this->convertToAffine($p1); + } + + /** + * Converts an affine point to an XZ coordinate + * + * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html + * + * XZ coordinates represent x y as X Z satsfying the following equations: + * + * x=X/Z + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one]; + } + + if (isset($p[1])) { + return $p; + } + + $p[1] = clone $this->one; + + return $p; + } + + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[1])) { + return $p; + } + list($x, $z) = $p; + return [$x->divide($z)]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php new file mode 100644 index 0000000..6250dfb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php @@ -0,0 +1,785 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField\Integer; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over y^2 = x^3 + a*x + b + * + * @author Jim Wigginton + */ +class Prime extends Base +{ + /** + * Prime Field Integer factory + * + * @var \phpseclib3\Math\PrimeFields + */ + protected $factory; + + /** + * Cofficient for x^1 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^0 + * + * @var object + */ + protected $b; + + /** + * Base Point + * + * @var object + */ + protected $p; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + + /** + * The number three over the specified finite field + * + * @var object + */ + protected $three; + + /** + * The number four over the specified finite field + * + * @var object + */ + protected $four; + + /** + * The number eight over the specified finite field + * + * @var object + */ + protected $eight; + + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * The Order + * + * @var BigInteger + */ + protected $order; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->two = $this->factory->newInteger(new BigInteger(2)); + $this->three = $this->factory->newInteger(new BigInteger(3)); + // used by jacobian coordinates + $this->one = $this->factory->newInteger(new BigInteger(1)); + $this->four = $this->factory->newInteger(new BigInteger(4)); + $this->eight = $this->factory->newInteger(new BigInteger(8)); + } + + /** + * Set coefficients a and b + */ + public function setCoefficients(BigInteger $a, BigInteger $b) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->b = $this->factory->newInteger($b); + } + + /** + * Set x and y coordinates for the base point + * + * @param BigInteger|PrimeInteger $x + * @param BigInteger|PrimeInteger $y + * @return PrimeInteger[] + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Adds two "fresh" jacobian form on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedXY(array $p, array $q) + { + list($u1, $s1) = $p; + list($u2, $s2) = $q; + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3) + )->subtract( + $s1->multiply($h3) + ); + return [$x3, $y3, $h]; + } + + /** + * Adds one "fresh" jacobian form on the curve + * + * The second parameter should be the "fresh" one + * + * @return FiniteField[] + */ + protected function jacobianAddPointMixedX(array $p, array $q) + { + list($u1, $s1, $z1) = $p; + list($x2, $y2) = $q; + + $z12 = $z1->multiply($z1); + + $u2 = $x2->multiply($z12); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3) + )->subtract( + $s1->multiply($h3) + ); + $z3 = $h->multiply($z1); + return [$x3, $y3, $z3]; + } + + /** + * Adds two jacobian coordinates on the curve + * + * @return FiniteField[] + */ + protected function jacobianAddPoint(array $p, array $q) + { + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $z12 = $z1->multiply($z1); + $z22 = $z2->multiply($z2); + + $u1 = $x1->multiply($z22); + $u2 = $x2->multiply($z12); + $s1 = $y1->multiply($z22->multiply($z2)); + $s2 = $y2->multiply($z12->multiply($z1)); + if ($u1->equals($u2)) { + if (!$s1->equals($s2)) { + return []; + } else { + return $this->doublePoint($p); + } + } + $h = $u2->subtract($u1); + $r = $s2->subtract($s1); + $h2 = $h->multiply($h); + $h3 = $h2->multiply($h); + $v = $u1->multiply($h2); + $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); + $y3 = $r->multiply( + $v->subtract($x3) + )->subtract( + $s1->multiply($h3) + ); + $z3 = $h->multiply($z1)->multiply($z2); + return [$x3, $y3, $z3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + // use jacobian coordinates + if (isset($p[2]) && isset($q[2])) { + if (isset($p['fresh']) && isset($q['fresh'])) { + return $this->jacobianAddPointMixedXY($p, $q); + } + if (isset($p['fresh'])) { + return $this->jacobianAddPointMixedX($q, $p); + } + if (isset($q['fresh'])) { + return $this->jacobianAddPointMixedX($p, $q); + } + return $this->jacobianAddPoint($p, $q); + } + + if (isset($p[2]) || isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + if (!$p[1]->equals($q[1])) { + return []; + } else { // eg. doublePoint + list($numerator, $denominator) = $this->doublePointHelper($p); + } + } else { + $numerator = $q[1]->subtract($p[1]); + $denominator = $q[0]->subtract($p[0]); + } + $slope = $numerator->divide($denominator); + $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + + return [$x, $y]; + } + + /** + * Returns the numerator and denominator of the slope + * + * @return FiniteField[] + */ + protected function doublePointHelper(array $p) + { + $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); + $denominator = $this->two->multiply($p[1]); + return [$numerator, $denominator]; + } + + /** + * Doubles a jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePoint(array $p) + { + list($x, $y, $z) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $z2 = $z->multiply($z); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m2 = $this->a->multiply($z2->multiply($z2)); + $m = $m1->add($m2); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract( + $this->eight->multiply($y2->multiply($y2)) + ); + $z1 = $this->two->multiply($y)->multiply($z); + return [$x1, $y1, $z1]; + } + + /** + * Doubles a "fresh" jacobian coordinate on the curve + * + * @return FiniteField[] + */ + protected function jacobianDoublePointMixed(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + $s = $this->four->multiply($x)->multiply($y2); + $m1 = $this->three->multiply($x2); + $m = $m1->add($this->a); + $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); + $y1 = $m->multiply($s->subtract($x1))->subtract( + $this->eight->multiply($y2->multiply($y2)) + ); + $z1 = $this->two->multiply($y); + return [$x1, $y1, $z1]; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + // use jacobian coordinates + if (isset($p[2])) { + if (isset($p['fresh'])) { + return $this->jacobianDoublePointMixed($p); + } + return $this->jacobianDoublePoint($p); + } + + list($numerator, $denominator) = $this->doublePointHelper($p); + + $slope = $numerator->divide($denominator); + + $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); + $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); + + return [$x, $y]; + } + + /** + * Returns the X coordinate and the derived Y coordinate + * + * @return array + */ + public function derivePoint($m) + { + $y = ord(Strings::shift($m)); + $x = new BigInteger($m, 256); + $xp = $this->convertInteger($x); + switch ($y) { + case 2: + $ypn = false; + break; + case 3: + $ypn = true; + break; + default: + throw new \RuntimeException('Coordinate not in recognized format'); + } + $temp = $xp->multiply($this->a); + $temp = $xp->multiply($xp)->multiply($xp)->add($temp); + $temp = $temp->add($this->b); + $b = $temp->squareRoot(); + if (!$b) { + throw new \RuntimeException('Unable to derive Y coordinate'); + } + $bn = $b->isOdd(); + $yp = $ypn == $bn ? $b : $b->negate(); + return [$xp, $yp]; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $lhs = $y->multiply($y); + $temp = $x->multiply($this->a); + $temp = $x->multiply($x)->multiply($x)->add($temp); + $rhs = $temp->add($this->b); + + return $lhs->equals($rhs); + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getB() + { + return $this->b; + } + + /** + * Multiply and Add Points + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L125 + * + * @return int[] + */ + public function multiplyAddPoints(array $points, array $scalars) + { + $length = count($points); + + foreach ($points as &$point) { + $point = $this->convertToInternal($point); + } + + $wnd = [$this->getNAFPoints($points[0], 7)]; + $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; + for ($i = 1; $i < $length; $i++) { + $wnd[] = $this->getNAFPoints($points[$i], 1); + $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; + } + + $naf = []; + + // comb all window NAFs + + $max = 0; + for ($i = $length - 1; $i >= 1; $i -= 2) { + $a = $i - 1; + $b = $i; + if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { + $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); + $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); + $max = max(count($naf[$a]), count($naf[$b]), $max); + continue; + } + + $comb = [ + $points[$a], // 1 + null, // 3 + null, // 5 + $points[$b] // 7 + ]; + + $comb[1] = $this->addPoint($points[$a], $points[$b]); + $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); + + $index = [ + -3, /* -1 -1 */ + -1, /* -1 0 */ + -5, /* -1 1 */ + -7, /* 0 -1 */ + 0, /* 0 -1 */ + 7, /* 0 1 */ + 5, /* 1 -1 */ + 1, /* 1 0 */ + 3 /* 1 1 */ + ]; + + $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); + + $max = max(count($jsf[0]), $max); + if ($max > 0) { + $naf[$a] = array_fill(0, $max, 0); + $naf[$b] = array_fill(0, $max, 0); + } else { + $naf[$a] = []; + $naf[$b] = []; + } + + for ($j = 0; $j < $max; $j++) { + $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; + $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; + + $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; + $naf[$b][$j] = 0; + $wnd[$a] = $comb; + } + } + + $acc = []; + $temp = [0, 0, 0, 0]; + for ($i = $max; $i >= 0; $i--) { + $k = 0; + while ($i >= 0) { + $zero = true; + for ($j = 0; $j < $length; $j++) { + $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; + if ($temp[$j] != 0) { + $zero = false; + } + } + if (!$zero) { + break; + } + $k++; + $i--; + } + + if ($i >= 0) { + $k++; + } + while ($k--) { + $acc = $this->doublePoint($acc); + } + + if ($i < 0) { + break; + } + + for ($j = 0; $j < $length; $j++) { + $z = $temp[$j]; + $p = null; + if ($z == 0) { + continue; + } + $p = $z > 0 ? + $wnd[$j][($z - 1) >> 1] : + $this->negatePoint($wnd[$j][(-$z - 1) >> 1]); + $acc = $this->addPoint($acc, $p); + } + } + + return $this->convertToAffine($acc); + } + + /** + * Precomputes NAF points + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L351 + * + * @return int[] + */ + private function getNAFPoints(array $point, $wnd) + { + if (isset($point['naf'])) { + return $point['naf']; + } + + $res = [$point]; + $max = (1 << $wnd) - 1; + $dbl = $max == 1 ? null : $this->doublePoint($point); + for ($i = 1; $i < $max; $i++) { + $res[] = $this->addPoint($res[$i - 1], $dbl); + } + + $point['naf'] = $res; + + /* + $str = ''; + foreach ($res as $re) { + $re[0] = bin2hex($re[0]->toBytes()); + $re[1] = bin2hex($re[1]->toBytes()); + $str.= " ['$re[0]', '$re[1]'],\r\n"; + } + file_put_contents('temp.txt', $str); + exit; + */ + + return $res; + } + + /** + * Precomputes points in Joint Sparse Form + * + * Adapted from: + * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/utils.js#L96 + * + * @return int[] + */ + private static function getJSFPoints(Integer $k1, Integer $k2) + { + static $three; + if (!isset($three)) { + $three = new BigInteger(3); + } + + $jsf = [[], []]; + $k1 = $k1->toBigInteger(); + $k2 = $k2->toBigInteger(); + $d1 = 0; + $d2 = 0; + + while ($k1->compare(new BigInteger(-$d1)) > 0 || $k2->compare(new BigInteger(-$d2)) > 0) { + // first phase + $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); + $m14 += $d1; + $m14 &= 3; + + $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); + $m24 += $d2; + $m24 &= 3; + + if ($m14 == 3) { + $m14 = -1; + } + if ($m24 == 3) { + $m24 = -1; + } + + $u1 = 0; + if ($m14 & 1) { // if $m14 is odd + $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); + $m8 += $d1; + $m8 &= 7; + $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; + } + $jsf[0][] = $u1; + + $u2 = 0; + if ($m24 & 1) { // if $m24 is odd + $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); + $m8 += $d2; + $m8 &= 7; + $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; + } + $jsf[1][] = $u2; + + // second phase + if (2 * $d1 == $u1 + 1) { + $d1 = 1 - $d1; + } + if (2 * $d2 == $u2 + 1) { + $d2 = 1 - $d2; + } + $k1 = $k1->bitwise_rightShift(1); + $k2 = $k2->bitwise_rightShift(1); + } + + return $jsf; + } + + /** + * Returns the affine point + * + * A Jacobian Coordinate is of the form (x, y, z). + * To convert a Jacobian Coordinate to an Affine Point + * you do (x / z^2, y / z^3) + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + $z2 = $z->multiply($z); + return [ + $x->multiply($z2), + $y->multiply($z2)->multiply($z) + ]; + } + + /** + * Converts an affine point to a jacobian coordinate + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p['fresh'] = true; + return $p; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php new file mode 100644 index 0000000..2521a4c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php @@ -0,0 +1,215 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\BaseCurves; + +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; +use phpseclib3\Math\PrimeField\Integer as PrimeInteger; + +/** + * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 + * + * @author Jim Wigginton + */ +class TwistedEdwards extends Base +{ + /** + * The modulo + * + * @var BigInteger + */ + protected $modulo; + + /** + * Cofficient for x^2 + * + * @var object + */ + protected $a; + + /** + * Cofficient for x^2*y^2 + * + * @var object + */ + protected $d; + + /** + * Base Point + * + * @var object[] + */ + protected $p; + + /** + * The number zero over the specified finite field + * + * @var object + */ + protected $zero; + + /** + * The number one over the specified finite field + * + * @var object + */ + protected $one; + + /** + * The number two over the specified finite field + * + * @var object + */ + protected $two; + + /** + * Sets the modulo + */ + public function setModulo(BigInteger $modulo) + { + $this->modulo = $modulo; + $this->factory = new PrimeField($modulo); + $this->zero = $this->factory->newInteger(new BigInteger(0)); + $this->one = $this->factory->newInteger(new BigInteger(1)); + $this->two = $this->factory->newInteger(new BigInteger(2)); + } + + /** + * Set coefficients a and b + */ + public function setCoefficients(BigInteger $a, BigInteger $d) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->a = $this->factory->newInteger($a); + $this->d = $this->factory->newInteger($d); + } + + /** + * Set x and y coordinates for the base point + */ + public function setBasePoint($x, $y) + { + switch (true) { + case !$x instanceof BigInteger && !$x instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + case !$y instanceof BigInteger && !$y instanceof PrimeInteger: + throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); + } + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + $this->p = [ + $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, + $y instanceof BigInteger ? $this->factory->newInteger($y) : $y + ]; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getA() + { + return $this->a; + } + + /** + * Returns the a coefficient + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function getD() + { + return $this->d; + } + + /** + * Retrieve the base point as an array + * + * @return array + */ + public function getBasePoint() + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + /* + if (!isset($this->p)) { + throw new \RuntimeException('setBasePoint needs to be called before this method'); + } + */ + return $this->p; + } + + /** + * Returns the affine point + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToAffine(array $p) + { + if (!isset($p[2])) { + return $p; + } + list($x, $y, $z) = $p; + $z = $this->one->divide($z); + return [ + $x->multiply($z), + $y->multiply($z) + ]; + } + + /** + * Returns the modulo + * + * @return \phpseclib3\Math\BigInteger + */ + public function getModulo() + { + return $this->modulo; + } + + /** + * Tests whether or not the x / y values satisfy the equation + * + * @return boolean + */ + public function verifyPoint(array $p) + { + list($x, $y) = $p; + $x2 = $x->multiply($x); + $y2 = $y->multiply($y); + + $lhs = $this->a->multiply($x2)->add($y2); + $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); + + return $lhs->equals($rhs); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php new file mode 100644 index 0000000..0f3f4d8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php @@ -0,0 +1,81 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use phpseclib3\Math\BigInteger; + +class Curve25519 extends Montgomery +{ + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->a24 = $this->factory->newInteger(new BigInteger('121666')); + $this->p = [$this->factory->newInteger(new BigInteger(9))]; + // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed + $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + + /* + $this->setCoefficients( + new BigInteger('486662'), // a + ); + $this->setBasePoint( + new BigInteger(9), + new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') + ); + */ + } + + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + + $d = $d->toBytes(); + $d &= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; + $d = strrev($d); + $d |= "\x40"; + $d = new BigInteger($d, -256); + + return parent::multiplyPoint($p, $d); + } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return BigInteger::random(256); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + if ($x->getLength() > 256 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 256 bytes in length'); + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php new file mode 100644 index 0000000..f4a4423 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php @@ -0,0 +1,92 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery; +use phpseclib3\Math\BigInteger; + +class Curve448 extends Montgomery +{ + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + 16 + )); + $this->a24 = $this->factory->newInteger(new BigInteger('39081')); + $this->p = [$this->factory->newInteger(new BigInteger(5))]; + // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d + $this->setOrder(new BigInteger( + '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', + 16 + )); + + /* + $this->setCoefficients( + new BigInteger('156326'), // a + ); + $this->setBasePoint( + new BigInteger(5), + new BigInteger( + '355293926785568175264127502063783334808976399387714271831880898' . + '435169088786967410002932673765864550910142774147268105838985595290' . + '606362') + ); + */ + } + + /** + * Multiply a point on the curve by a scalar + * + * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 + * + * @return array + */ + public function multiplyPoint(array $p, BigInteger $d) + { + //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); + //return [$this->factory->newInteger(new BigInteger($r, 256))]; + + $d = $d->toBytes(); + $d[0] = $d[0] & "\xFC"; + $d = strrev($d); + $d |= "\x80"; + $d = new BigInteger($d, 256); + + return parent::multiplyPoint($p, $d); + } + + /** + * Creates a random scalar multiplier + * + * @return BigInteger + */ + public function createRandomMultiplier() + { + return BigInteger::random(446); + } + + /** + * Performs range check + */ + public function rangeCheck(BigInteger $x) + { + if ($x->getLength() > 448 || $x->isNegative()) { + throw new \RangeException('x must be a positive integer less than 446 bytes in length'); + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php new file mode 100644 index 0000000..9d3de68 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php @@ -0,0 +1,333 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Math\BigInteger; + +class Ed25519 extends TwistedEdwards +{ + const HASH = 'sha512'; + /* + Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: + + 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b + bits, and EdDSA signatures have exactly 2*b bits. b is + recommended to be a multiple of 8, so public key and signature + lengths are an integral number of octets. + + SIZE corresponds to b + */ + const SIZE = 32; + + public function __construct() + { + // 2^255 - 19 + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); + $this->setCoefficients( + // -1 + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), // a + // -121665/121666 + new BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) // d + ); + $this->setBasePoint( + new BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), + new BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16) + ); + $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); + // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 + /* + $this->setReduction(function($x) { + $parts = $x->bitwise_split(255); + $className = $this->className; + + if (count($parts) > 2) { + list(, $r) = $x->divide($className::$modulo); + return $r; + } + + $zero = new BigInteger(); + $c = new BigInteger(19); + + switch (count($parts)) { + case 2: + list($qi, $ri) = $parts; + break; + case 1: + $qi = $zero; + list($ri) = $parts; + break; + case 0: + return $zero; + } + $r = $ri; + + while ($qi->compare($zero) > 0) { + $temp = $qi->multiply($c)->bitwise_split(255); + if (count($temp) == 2) { + list($qi, $ri) = $temp; + } else { + $qi = $zero; + list($ri) = $temp; + } + $r = $r->add($ri); + } + + while ($r->compare($className::$modulo) > 0) { + $r = $r->subtract($className::$modulo); + } + return $r; + }); + */ + } + + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->add($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + /* we don't do $x2->squareRoot() because, quoting from + https://tools.ietf.org/html/rfc8032#section-5.1.1: + + "For point decoding or "decompression", square roots modulo p are + needed. They can be computed using the Tonelli-Shanks algorithm or + the special case for p = 5 (mod 8). To find a square root of a, + first compute the candidate root x = a^((p+3)/8) (mod p)." + */ + $exp = $this->getModulo()->add(new BigInteger(3)); + $exp = $exp->bitwise_rightShift(3); + $x = $x2->pow($exp); + + // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + $temp = $this->getModulo()->subtract(new BigInteger(1)); + $temp = $temp->bitwise_rightShift(2); + $temp = $this->two->pow($temp); + $x = $x->multiply($temp); + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + + return [$x, $y]; + } + + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 + * + * Used by the various key handlers + * + * @param string $str + * @return array + */ + public function extractSecret($str) + { + if (strlen($str) != 32) { + throw new \LengthException('Private Key should be 32-bytes long'); + } + // 1. Hash the 32-byte private key using SHA-512, storing the digest in + // a 64-octet large buffer, denoted h. Only the lower 32 bytes are + // used for generating the public key. + $hash = new Hash('sha512'); + $h = $hash->hash($str); + $h = substr($h, 0, 32); + // 2. Prune the buffer: The lowest three bits of the first octet are + // cleared, the highest bit of the last octet is cleared, and the + // second highest bit of the last octet is set. + $h[0] = $h[0] & chr(0xF8); + $h = strrev($h); + $h[0] = ($h[0] & chr(0x3F)) | chr(0x40); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new BigInteger($h, 256); + + return [ + 'dA' => $dA, + 'secret' => $str + ]; + } + + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = $y->toBytes(); + $y[0] = $y[0] & chr(0x7F); + if ($x->isOdd()) { + $y[0] = $y[0] | chr(0x80); + } + $y = strrev($y); + + return $y; + } + + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(Random::string(32))['dA']; + } + + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; + } + + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + $p[3] = $p[0]->multiply($p[1]); + + return $p; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // from https://tools.ietf.org/html/rfc8032#page-12 + + list($x1, $y1, $z1, $t1) = $p; + + $a = $x1->multiply($x1); + $b = $y1->multiply($y1); + $c = $this->two->multiply($z1)->multiply($z1); + $h = $a->add($b); + $temp = $x1->add($y1); + $e = $h->subtract($temp->multiply($temp)); + $g = $a->subtract($b); + $f = $c->add($g); + + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3, $t3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // from https://tools.ietf.org/html/rfc8032#page-12 + + list($x1, $y1, $z1, $t1) = $p; + list($x2, $y2, $z2, $t2) = $q; + + $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); + $b = $y1->add($x1)->multiply($y2->add($x2)); + $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); + $d = $z1->multiply($this->two)->multiply($z2); + $e = $b->subtract($a); + $f = $d->subtract($c); + $g = $d->add($c); + $h = $b->add($a); + + $x3 = $e->multiply($f); + $y3 = $g->multiply($h); + $t3 = $e->multiply($h); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3, $t3]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php new file mode 100644 index 0000000..5451f90 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php @@ -0,0 +1,273 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Math\BigInteger; + +class Ed448 extends TwistedEdwards +{ + const HASH = 'shake256-912'; + const SIZE = 57; + + public function __construct() + { + // 2^448 - 2^224 - 1 + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', + 16 + )); + $this->setCoefficients( + new BigInteger(1), + // -39081 + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) + ); + $this->setBasePoint( + new BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . + 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), + new BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . + '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16) + ); + $this->setOrder(new BigInteger( + '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', + 16 + )); + } + + /** + * Recover X from Y + * + * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 + * + * Used by EC\Keys\Common.php + * + * @param BigInteger $y + * @param boolean $sign + * @return object[] + */ + public function recoverX(BigInteger $y, $sign) + { + $y = $this->factory->newInteger($y); + + $y2 = $y->multiply($y); + $u = $y2->subtract($this->one); + $v = $this->d->multiply($y2)->subtract($this->one); + $x2 = $u->divide($v); + if ($x2->equals($this->zero)) { + if ($sign) { + throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); + } + return clone $this->zero; + } + // find the square root + $exp = $this->getModulo()->add(new BigInteger(1)); + $exp = $exp->bitwise_rightShift(2); + $x = $x2->pow($exp); + + if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { + throw new \RuntimeException('Unable to recover X coordinate'); + } + if ($x->isOdd() != $sign) { + $x = $x->negate(); + } + + return [$x, $y]; + } + + /** + * Extract Secret Scalar + * + * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 + * + * Used by the various key handlers + * + * @param string $str + * @return array + */ + public function extractSecret($str) + { + if (strlen($str) != 57) { + throw new \LengthException('Private Key should be 57-bytes long'); + } + // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the + // digest in a 114-octet large buffer, denoted h. Only the lower 57 + // bytes are used for generating the public key. + $hash = new Hash('shake256-912'); + $h = $hash->hash($str); + $h = substr($h, 0, 57); + // 2. Prune the buffer: The two least significant bits of the first + // octet are cleared, all eight bits the last octet are cleared, and + // the highest bit of the second to last octet is set. + $h[0] = $h[0] & chr(0xFC); + $h = strrev($h); + $h[0] = "\0"; + $h[1] = $h[1] | chr(0x80); + // 3. Interpret the buffer as the little-endian integer, forming a + // secret scalar s. + $dA = new BigInteger($h, 256); + + return [ + 'dA' => $dA, + 'secret' => $str + ]; + + $dA->secret = $str; + return $dA; + } + + /** + * Encode a point as a string + * + * @param array $point + * @return string + */ + public function encodePoint($point) + { + list($x, $y) = $point; + $y = "\0" . $y->toBytes(); + if ($x->isOdd()) { + $y[0] = $y[0] | chr(0x80); + } + $y = strrev($y); + + return $y; + } + + /** + * Creates a random scalar multiplier + * + * @return \phpseclib3\Math\PrimeField\Integer + */ + public function createRandomMultiplier() + { + return $this->extractSecret(Random::string(57))['dA']; + } + + /** + * Converts an affine point to an extended homogeneous coordinate + * + * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : + * + * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), + * with x = X/Z, y = Y/Z, x * y = T/Z. + * + * @return \phpseclib3\Math\PrimeField\Integer[] + */ + public function convertToInternal(array $p) + { + if (empty($p)) { + return [clone $this->zero, clone $this->one, clone $this->one]; + } + + if (isset($p[2])) { + return $p; + } + + $p[2] = clone $this->one; + + return $p; + } + + /** + * Doubles a point on a curve + * + * @return FiniteField[] + */ + public function doublePoint(array $p) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p)) { + return []; + } + + if (!isset($p[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + // from https://tools.ietf.org/html/rfc8032#page-18 + + list($x1, $y1, $z1) = $p; + + $b = $x1->add($y1); + $b = $b->multiply($b); + $c = $x1->multiply($x1); + $d = $y1->multiply($y1); + $e = $c->add($d); + $h = $z1->multiply($z1); + $j = $e->subtract($this->two->multiply($h)); + + $x3 = $b->subtract($e)->multiply($j); + $y3 = $c->subtract($d)->multiply($e); + $z3 = $e->multiply($j); + + return [$x3, $y3, $z3]; + } + + /** + * Adds two points on the curve + * + * @return FiniteField[] + */ + public function addPoint(array $p, array $q) + { + if (!isset($this->factory)) { + throw new \RuntimeException('setModulo needs to be called before this method'); + } + + if (!count($p) || !count($q)) { + if (count($q)) { + return $q; + } + if (count($p)) { + return $p; + } + return []; + } + + if (!isset($p[2]) || !isset($q[2])) { + throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); + } + + if ($p[0]->equals($q[0])) { + return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); + } + + // from https://tools.ietf.org/html/rfc8032#page-17 + + list($x1, $y1, $z1) = $p; + list($x2, $y2, $z2) = $q; + + $a = $z1->multiply($z2); + $b = $a->multiply($a); + $c = $x1->multiply($x2); + $d = $y1->multiply($y2); + $e = $this->d->multiply($c)->multiply($d); + $f = $b->subtract($e); + $g = $b->add($e); + $h = $x1->add($y1)->multiply($x2->add($y2)); + + $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); + $y3 = $a->multiply($g)->multiply($d->subtract($c)); + $z3 = $f->multiply($g); + + return [$x3, $y3, $z3]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php new file mode 100644 index 0000000..7bc2272 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP160r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), + new BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16) + ); + $this->setBasePoint( + new BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), + new BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16) + ); + $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php new file mode 100644 index 0000000..ebfb29a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php @@ -0,0 +1,47 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP160t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); + $this->setCoefficients( + new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), // eg. -3 + new BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) + ); + $this->setBasePoint( + new BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), + new BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16) + ); + $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php new file mode 100644 index 0000000..6ec848b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP192r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), + new BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16) + ); + $this->setBasePoint( + new BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), + new BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16) + ); + $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php new file mode 100644 index 0000000..e6a86bb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP192t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); + $this->setCoefficients( + new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), // eg. -3 + new BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) + ); + $this->setBasePoint( + new BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), + new BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16) + ); + $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php new file mode 100644 index 0000000..3d7d872 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP224r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), + new BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16) + ); + $this->setBasePoint( + new BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), + new BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16) + ); + $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php new file mode 100644 index 0000000..3d4f928 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP224t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); + $this->setCoefficients( + new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), // eg. -3 + new BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) + ); + $this->setBasePoint( + new BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), + new BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16) + ); + $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php new file mode 100644 index 0000000..5780da7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP256r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), + new BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16) + ); + $this->setBasePoint( + new BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), + new BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16) + ); + $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php new file mode 100644 index 0000000..724d8b8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP256t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); + $this->setCoefficients( + new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), // eg. -3 + new BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) + ); + $this->setBasePoint( + new BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), + new BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16) + ); + $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php new file mode 100644 index 0000000..182e622 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP320r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . + '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . + '92F375A97D860EB4', 16), + new BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . + '6F5EB4AC8FB1F1A6', 16) + ); + $this->setBasePoint( + new BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . + '10AF8D0D39E20611', 16), + new BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . + 'D35245D1692E8EE1', 16) + ); + $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . + '82EC7EE8658E98691555B44C59311', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php new file mode 100644 index 0000000..d5a620d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP320t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . + '2B9EC7893EC28FCD412B1F1B32E27', 16)); + $this->setCoefficients( + new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . + 'FCD412B1F1B32E24', 16), // eg. -3 + new BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . + 'B5B4FEF422340353', 16) + ); + $this->setBasePoint( + new BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . + '3357F624A21BED52', 16), + new BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . + '1B9BC0455FB0D2C3', 16) + ); + $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . + '82EC7EE8658E98691555B44C59311', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php new file mode 100644 index 0000000..a20b4b4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP384r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . + '1874700133107EC53', + 16 + )); + $this->setCoefficients( + new BigInteger( + '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . + 'AD4EB04A8C7DD22CE2826', + 16 + ), + new BigInteger( + '4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . + 'C9943AB78696FA504C11', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . + '646AAEF87B2E247D4AF1E', + 16 + ), + new BigInteger( + '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . + '1811142820341263C5315', + 16 + ) + ); + $this->setOrder(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . + '03B883202E9046565', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php new file mode 100644 index 0000000..366660e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP384t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . + '1874700133107EC53', + 16 + )); + $this->setCoefficients( + new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . + 'D1A71874700133107EC50', + 16 + ), // eg. -3 + new BigInteger( + '7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . + '8805CED70355A33B471EE', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . + 'A5F54D8D0AA2F418808CC', + 16 + ), + new BigInteger( + '25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . + '2B2912675BF5B9E582928', + 16 + ) + ); + $this->setOrder(new BigInteger( + '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . + '03B883202E9046565', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php new file mode 100644 index 0000000..5efe5e1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP512r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', + 16 + )); + $this->setCoefficients( + new BigInteger( + '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . + '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', + 16 + ), + new BigInteger( + '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . + '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . + '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', + 16 + ), + new BigInteger( + '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . + 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . + '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php new file mode 100644 index 0000000..745863a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php @@ -0,0 +1,58 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class brainpoolP512t1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', + 16 + )); + $this->setCoefficients( + new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . + '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', + 16 + ), // eg. -3 + new BigInteger( + '7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . + '76540F6450085F2DAE145C22553B465763689180EA2571867423E', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + '640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . + 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', + 16 + ), + new BigInteger( + '5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . + 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . + '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php new file mode 100644 index 0000000..bae12b0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistb233 extends sect233r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php new file mode 100644 index 0000000..a46153d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistb409 extends sect409r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php new file mode 100644 index 0000000..8b26376 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk163 extends sect163k1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php new file mode 100644 index 0000000..69e1413 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk233 extends sect233k1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php new file mode 100644 index 0000000..9e95f10 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk283 extends sect283k1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php new file mode 100644 index 0000000..06bd9af --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistk409 extends sect409k1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php new file mode 100644 index 0000000..ddead3c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp192 extends secp192r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php new file mode 100644 index 0000000..746571b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp224 extends secp224r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php new file mode 100644 index 0000000..a26c0f9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp256 extends secp256r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php new file mode 100644 index 0000000..1f20c02 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp384 extends secp384r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php new file mode 100644 index 0000000..86fa050 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistp521 extends secp521r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php new file mode 100644 index 0000000..7908b38 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class nistt571 extends sect571k1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php new file mode 100644 index 0000000..e9c13cd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class prime192v1 extends secp192r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php new file mode 100644 index 0000000..e3e341f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime192v2 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16) + ); + $this->setBasePoint( + new BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), + new BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php new file mode 100644 index 0000000..1e97992 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime192v3 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16) + ); + $this->setBasePoint( + new BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), + new BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php new file mode 100644 index 0000000..084be9d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16) + ); + $this->setBasePoint( + new BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), + new BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php new file mode 100644 index 0000000..21941b8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v2 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16) + ); + $this->setBasePoint( + new BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), + new BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php new file mode 100644 index 0000000..78c50f0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class prime239v3 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), + new BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16) + ); + $this->setBasePoint( + new BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), + new BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16) + ); + $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php new file mode 100644 index 0000000..c72b22e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php @@ -0,0 +1,18 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +final class prime256v1 extends secp256r1 +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php new file mode 100644 index 0000000..d1d3194 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp112r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients( + new BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), + new BigInteger('659EF8BA043916EEDE8911702B22', 16) + ); + $this->setBasePoint( + new BigInteger('09487239995A5EE76B55F9C2F098', 16), + new BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16) + ); + $this->setOrder(new BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php new file mode 100644 index 0000000..da44e7f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php @@ -0,0 +1,35 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp112r2 extends Prime +{ + public function __construct() + { + // same modulo as secp112r1 + $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); + $this->setCoefficients( + new BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), + new BigInteger('51DEF1815DB5ED74FCC34C85D709', 16) + ); + $this->setBasePoint( + new BigInteger('4BA30AB5E892B4E1649DD0928643', 16), + new BigInteger('ADCD46F5882E3747DEF36E956E97', 16) + ); + $this->setOrder(new BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php new file mode 100644 index 0000000..34456bc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp128r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), + new BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16) + ); + $this->setBasePoint( + new BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), + new BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php new file mode 100644 index 0000000..e102c34 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php @@ -0,0 +1,35 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp128r2 extends Prime +{ + public function __construct() + { + // same as secp128r1 + $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), + new BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16) + ); + $this->setBasePoint( + new BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), + new BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16) + ); + $this->setOrder(new BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php new file mode 100644 index 0000000..c6a3334 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php @@ -0,0 +1,46 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp160k1 extends KoblitzPrime +{ + public function __construct() + { + // same as secp160r2 + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients( + new BigInteger('0000000000000000000000000000000000000000', 16), + new BigInteger('0000000000000000000000000000000000000007', 16) + ); + $this->setBasePoint( + new BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), + new BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('0096341F1138933BC2F505', -16), + 'b' => new BigInteger('FF6E9D0418C67BB8D5F562', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01BDCB3A09AAAABEAFF4A8', -16), + 'b' => new BigInteger('04D12329FF0EF498EA67', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php new file mode 100644 index 0000000..af46877 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp160r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), + new BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16) + ); + $this->setBasePoint( + new BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), + new BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php new file mode 100644 index 0000000..9bd23d2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php @@ -0,0 +1,35 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp160r2 extends Prime +{ + public function __construct() + { + // same as secp160k1 + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), + new BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16) + ); + $this->setBasePoint( + new BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), + new BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16) + ); + $this->setOrder(new BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php new file mode 100644 index 0000000..79ff2e0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php @@ -0,0 +1,45 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp192k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); + $this->setCoefficients( + new BigInteger('000000000000000000000000000000000000000000000000', 16), + new BigInteger('000000000000000000000000000000000000000000000003', 16) + ); + $this->setBasePoint( + new BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), + new BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), + 'b' => new BigInteger('8EE96418CCF4CFC7124FDA0F', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01D90D03E8F096B9948B20F0A9', -16), + 'b' => new BigInteger('42E49819ABBA9474E1083F6B', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php new file mode 100644 index 0000000..83ab1c7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php @@ -0,0 +1,78 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp192r1 extends Prime +{ + public function __construct() + { + $modulo = new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); + $this->setModulo($modulo); + + // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 + /* in theory this should be faster than regular modular reductions save for one small issue. + to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. + to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. + in short, converting to / from base-2**8 is pretty expensive and that expense is + enough to offset whatever else might be gained by a simplified reduction algorithm. + now, if PHP supported unsigned integers things might be different. no bit-shifting + would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger + uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit + or a 64-bit OS. + */ + /* + $m_length = $this->getLengthInBytes(); + $this->setReduction(function($c) use ($m_length) { + $cBytes = $c->toBytes(); + $className = $this->className; + + if (strlen($cBytes) > 2 * $m_length) { + list(, $r) = $c->divide($className::$modulo); + return $r; + } + + $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); + $c = array_reverse(str_split($c, 8)); + + $null = "\0\0\0\0\0\0\0\0"; + $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); + $s2 = new BigInteger($null . $c[3] . $c[3], 256); + $s3 = new BigInteger($c[4] . $c[4] . $null, 256); + $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); + + $r = $s1->add($s2)->add($s3)->add($s4); + while ($r->compare($className::$modulo) >= 0) { + $r = $r->subtract($className::$modulo); + } + + return $r; + }); + */ + + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), + new BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16) + ); + $this->setBasePoint( + new BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), + new BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php new file mode 100644 index 0000000..79a5c54 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php @@ -0,0 +1,45 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +class secp224k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); + $this->setCoefficients( + new BigInteger('00000000000000000000000000000000000000000000000000000000', 16), + new BigInteger('00000000000000000000000000000000000000000000000000000005', 16) + ); + $this->setBasePoint( + new BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), + new BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16) + ); + $this->setOrder(new BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), + 'b' => new BigInteger('94730F82B358A3776A826298FA6F', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), + 'b' => new BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php new file mode 100644 index 0000000..a9e474a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp224r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), + new BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16) + ); + $this->setBasePoint( + new BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), + new BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php new file mode 100644 index 0000000..462e7a1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php @@ -0,0 +1,49 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +//use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; +use phpseclib3\Math\BigInteger; + +//class secp256k1 extends Prime +class secp256k1 extends KoblitzPrime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); + $this->setCoefficients( + new BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), + new BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); + $this->setBasePoint( + new BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), + new BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16) + ); + + $this->basis = []; + $this->basis[] = [ + 'a' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), + 'b' => new BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16) + ]; + $this->basis[] = [ + 'a' => new BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), + 'b' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16) + ]; + $this->beta = $this->factory->newInteger(new BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php new file mode 100644 index 0000000..9003373 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp256r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); + $this->setCoefficients( + new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), + new BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16) + ); + $this->setBasePoint( + new BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), + new BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16) + ); + $this->setOrder(new BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php new file mode 100644 index 0000000..98764a3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php @@ -0,0 +1,52 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp384r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', + 16 + )); + $this->setCoefficients( + new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', + 16 + ), + new BigInteger( + 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', + 16 + ) + ); + $this->setBasePoint( + new BigInteger( + 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', + 16 + ), + new BigInteger( + '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', + 16 + ) + ); + $this->setOrder(new BigInteger( + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php new file mode 100644 index 0000000..b89a4ea --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php @@ -0,0 +1,46 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Prime; +use phpseclib3\Math\BigInteger; + +class secp521r1 extends Prime +{ + public function __construct() + { + $this->setModulo(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFF', 16)); + $this->setCoefficients( + new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFC', 16), + new BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . + '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . + '3F00', 16) + ); + $this->setBasePoint( + new BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . + '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . + 'BD66', 16), + new BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . + '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . + '6650', 16) + ); + $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . + '6409', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php new file mode 100644 index 0000000..77ec760 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect113r1 extends Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients( + '003088250CA6E7C7FE649CE85820F7', + '00E8BEE4D3E2260744188BE0E9C723' + ); + $this->setBasePoint( + '009D73616F35F4AB1407D73562C10F', + '00A52830277958EE84D1315ED31886' + ); + $this->setOrder(new BigInteger('0100000000000000D9CCEC8A39E56F', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php new file mode 100644 index 0000000..2185d60 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect113r2 extends Binary +{ + public function __construct() + { + $this->setModulo(113, 9, 0); + $this->setCoefficients( + '00689918DBEC7E5A0DD6DFC0AA55C7', + '0095E9A9EC9B297BD4BF36E059184F' + ); + $this->setBasePoint( + '01A57A6A7B26CA5EF52FCDB8164797', + '00B3ADC94ED1FE674C06E695BABA1D' + ); + $this->setOrder(new BigInteger('010000000000000108789B2496AF93', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php new file mode 100644 index 0000000..1365cb6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect131r1 extends Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients( + '07A11B09A76B562144418FF3FF8C2570B8', + '0217C05610884B63B9C6C7291678F9D341' + ); + $this->setBasePoint( + '0081BAF91FDF9833C40F9C181343638399', + '078C6E7EA38C001F73C8134B1B4EF9E150' + ); + $this->setOrder(new BigInteger('0400000000000000023123953A9464B54D', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php new file mode 100644 index 0000000..93c11b2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect131r2 extends Binary +{ + public function __construct() + { + $this->setModulo(131, 8, 3, 2, 0); + $this->setCoefficients( + '03E5A88919D7CAFCBF415F07C2176573B2', + '04B8266A46C55657AC734CE38F018F2192' + ); + $this->setBasePoint( + '0356DCD8F2F95031AD652D23951BB366A8', + '0648F06D867940A5366D9E265DE9EB240F' + ); + $this->setOrder(new BigInteger('0400000000000000016954A233049BA98F', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php new file mode 100644 index 0000000..3c8574b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163k1 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000001', + '000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', + '0289070FB05D38FF58321F2E800536D538CCDAA3D9' + ); + $this->setOrder(new BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php new file mode 100644 index 0000000..26afd87 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163r1 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', + '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9' + ); + $this->setBasePoint( + '0369979697AB43897789566789567F787A7876A654', + '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883' + ); + $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php new file mode 100644 index 0000000..38f9466 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect163r2 extends Binary +{ + public function __construct() + { + $this->setModulo(163, 7, 6, 3, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000001', + '020A601907B8C953CA1481EB10512F78744A3205FD' + ); + $this->setBasePoint( + '03F0EBA16286A2D57EA0991168D4994637E8343E36', + '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1' + ); + $this->setOrder(new BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php new file mode 100644 index 0000000..951f261 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect193r1 extends Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients( + '0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', + '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814' + ); + $this->setBasePoint( + '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', + '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05' + ); + $this->setOrder(new BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php new file mode 100644 index 0000000..e3ff47a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect193r2 extends Binary +{ + public function __construct() + { + $this->setModulo(193, 15, 0); + $this->setCoefficients( + '0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', + '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE' + ); + $this->setBasePoint( + '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', + '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C' + ); + $this->setOrder(new BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php new file mode 100644 index 0000000..eea3f7a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect233k1 extends Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', + '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3' + ); + $this->setOrder(new BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php new file mode 100644 index 0000000..68219f0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect233r1 extends Binary +{ + public function __construct() + { + $this->setModulo(233, 74, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000001', + '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD' + ); + $this->setBasePoint( + '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', + '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052' + ); + $this->setOrder(new BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php new file mode 100644 index 0000000..0e6994b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect239k1 extends Binary +{ + public function __construct() + { + $this->setModulo(239, 158, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', + '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA' + ); + $this->setOrder(new BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php new file mode 100644 index 0000000..279c24a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect283k1 extends Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', + '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259' + ); + $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php new file mode 100644 index 0000000..e44a607 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php @@ -0,0 +1,34 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect283r1 extends Binary +{ + public function __construct() + { + $this->setModulo(283, 12, 7, 5, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000001', + '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5' + ); + $this->setBasePoint( + '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', + '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4' + ); + $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php new file mode 100644 index 0000000..1fe329d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php @@ -0,0 +1,38 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect409k1 extends Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients( + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', + '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B' + ); + $this->setOrder(new BigInteger( + '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . + '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php new file mode 100644 index 0000000..3e209ef --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php @@ -0,0 +1,38 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect409r1 extends Binary +{ + public function __construct() + { + $this->setModulo(409, 87, 0); + $this->setCoefficients( + '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', + '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F' + ); + $this->setBasePoint( + '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', + '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706' + ); + $this->setOrder(new BigInteger( + '010000000000000000000000000000000000000000000000000001E2' . + 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php new file mode 100644 index 0000000..3c54eab --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect571k1 extends Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000000', + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000001' + ); + $this->setBasePoint( + '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . + '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', + '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . + 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3' + ); + $this->setOrder(new BigInteger( + '020000000000000000000000000000000000000000000000000000000000000000000000' . + '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php new file mode 100644 index 0000000..172c1af --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Crypt\EC\Curves; + +use phpseclib3\Crypt\EC\BaseCurves\Binary; +use phpseclib3\Math\BigInteger; + +class sect571r1 extends Binary +{ + public function __construct() + { + $this->setModulo(571, 10, 5, 2, 0); + $this->setCoefficients( + '000000000000000000000000000000000000000000000000000000000000000000000000' . + '000000000000000000000000000000000000000000000000000000000000000000000001', + '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . + '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A' + ); + $this->setBasePoint( + '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . + 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', + '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . + 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B' + ); + $this->setOrder(new BigInteger( + '03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . + 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', + 16 + )); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php new file mode 100644 index 0000000..63402b4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php @@ -0,0 +1,549 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; +use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * Generic EC Key Parsing Helper functions + * + * @author Jim Wigginton + */ +trait Common +{ + /** + * Curve OIDs + * + * @var array + */ + private static $curveOIDs = []; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Use Named Curves + * + * @var bool + */ + private static $useNamedCurves = true; + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (empty(self::$curveOIDs)) { + // the sec* curves are from the standards for efficient cryptography group + // sect* curves are curves over binary finite fields + // secp* curves are curves over prime finite fields + // sec*r* curves are regular curves; sec*k* curves are koblitz curves + // brainpool*r* curves are regular prime finite field curves + // brainpool*t* curves are twisted versions of the brainpool*r* curves + self::$curveOIDs = [ + 'prime192v1' => '1.2.840.10045.3.1.1', // J.5.1, example 1 (aka secp192r1) + 'prime192v2' => '1.2.840.10045.3.1.2', // J.5.1, example 2 + 'prime192v3' => '1.2.840.10045.3.1.3', // J.5.1, example 3 + 'prime239v1' => '1.2.840.10045.3.1.4', // J.5.2, example 1 + 'prime239v2' => '1.2.840.10045.3.1.5', // J.5.2, example 2 + 'prime239v3' => '1.2.840.10045.3.1.6', // J.5.2, example 3 + 'prime256v1' => '1.2.840.10045.3.1.7', // J.5.3, example 1 (aka secp256r1) + + // https://tools.ietf.org/html/rfc5656#section-10 + 'nistp256' => '1.2.840.10045.3.1.7', // aka secp256r1 + 'nistp384' => '1.3.132.0.34', // aka secp384r1 + 'nistp521' => '1.3.132.0.35', // aka secp521r1 + + 'nistk163' => '1.3.132.0.1', // aka sect163k1 + 'nistp192' => '1.2.840.10045.3.1.1', // aka secp192r1 + 'nistp224' => '1.3.132.0.33', // aka secp224r1 + 'nistk233' => '1.3.132.0.26', // aka sect233k1 + 'nistb233' => '1.3.132.0.27', // aka sect233r1 + 'nistk283' => '1.3.132.0.16', // aka sect283k1 + 'nistk409' => '1.3.132.0.36', // aka sect409k1 + 'nistb409' => '1.3.132.0.37', // aka sect409r1 + 'nistt571' => '1.3.132.0.38', // aka sect571k1 + + // from https://tools.ietf.org/html/rfc5915 + 'secp192r1' => '1.2.840.10045.3.1.1', // aka prime192v1 + 'sect163k1' => '1.3.132.0.1', + 'sect163r2' => '1.3.132.0.15', + 'secp224r1' => '1.3.132.0.33', + 'sect233k1' => '1.3.132.0.26', + 'sect233r1' => '1.3.132.0.27', + 'secp256r1' => '1.2.840.10045.3.1.7', // aka prime256v1 + 'sect283k1' => '1.3.132.0.16', + 'sect283r1' => '1.3.132.0.17', + 'secp384r1' => '1.3.132.0.34', + 'sect409k1' => '1.3.132.0.36', + 'sect409r1' => '1.3.132.0.37', + 'secp521r1' => '1.3.132.0.35', + 'sect571k1' => '1.3.132.0.38', + 'sect571r1' => '1.3.132.0.39', + // from http://www.secg.org/SEC2-Ver-1.0.pdf + 'secp112r1' => '1.3.132.0.6', + 'secp112r2' => '1.3.132.0.7', + 'secp128r1' => '1.3.132.0.28', + 'secp128r2' => '1.3.132.0.29', + 'secp160k1' => '1.3.132.0.9', + 'secp160r1' => '1.3.132.0.8', + 'secp160r2' => '1.3.132.0.30', + 'secp192k1' => '1.3.132.0.31', + 'secp224k1' => '1.3.132.0.32', + 'secp256k1' => '1.3.132.0.10', + + 'sect113r1' => '1.3.132.0.4', + 'sect113r2' => '1.3.132.0.5', + 'sect131r1' => '1.3.132.0.22', + 'sect131r2' => '1.3.132.0.23', + 'sect163r1' => '1.3.132.0.2', + 'sect193r1' => '1.3.132.0.24', + 'sect193r2' => '1.3.132.0.25', + 'sect239k1' => '1.3.132.0.3', + + // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 + /* + 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 + 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 + 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 + 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 + 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 + 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 + 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 + 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 + 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 + 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 + 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 + 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 + 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 + 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 + 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 + 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 + 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 + 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 + 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 + 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 + */ + + // http://www.ecc-brainpool.org/download/Domain-parameters.pdf + // https://tools.ietf.org/html/rfc5639 + 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', + 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', + 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', + 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', + 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', + 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', + 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', + 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', + 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', + 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', + 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', + 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', + 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', + 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14' + ]; + ASN1::loadOIDs([ + 'prime-field' => '1.2.840.10045.1.1', + 'characteristic-two-field' => '1.2.840.10045.1.2', + 'characteristic-two-basis' => '1.2.840.10045.1.2.3', + // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" + 'gnBasis' => '1.2.840.10045.1.2.3.1', // NULL + 'tpBasis' => '1.2.840.10045.1.2.3.2', // Trinomial + 'ppBasis' => '1.2.840.10045.1.2.3.3' // Pentanomial + ] + self::$curveOIDs); + } + } + + /** + * Explicitly set the curve + * + * If the key contains an implicit curve phpseclib needs the curve + * to be explicitly provided + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + */ + public static function setImplicitCurve(BaseCurve $curve) + { + self::$implicitCurve = $curve; + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param array $params + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + protected static function loadCurveByParam(array $params) + { + if (count($params) > 1) { + throw new \RuntimeException('No parameters are present'); + } + if (isset($params['namedCurve'])) { + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); + } + return new $curve(); + } + if (isset($params['implicitCurve'])) { + if (!isset(self::$implicitCurve)) { + throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); + } + return self::$implicitCurve; + } + if (isset($params['specifiedCurve'])) { + $data = $params['specifiedCurve']; + switch ($data['fieldID']['fieldType']) { + case 'prime-field': + $curve = new PrimeCurve(); + $curve->setModulo($data['fieldID']['parameters']); + $curve->setCoefficients( + new BigInteger($data['curve']['a'], 256), + new BigInteger($data['curve']['b'], 256) + ); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + case 'characteristic-two-field': + $curve = new BinaryCurve(); + $params = ASN1::decodeBER($data['fieldID']['parameters']); + $params = ASN1::asn1map($params[0], Maps\Characteristic_two::MAP); + $modulo = [(int) $params['m']->toString()]; + switch ($params['basis']) { + case 'tpBasis': + $modulo[] = (int) $params['parameters']->toString(); + break; + case 'ppBasis': + $temp = ASN1::decodeBER($params['parameters']); + $temp = ASN1::asn1map($temp[0], Maps\Pentanomial::MAP); + $modulo[] = (int) $temp['k3']->toString(); + $modulo[] = (int) $temp['k2']->toString(); + $modulo[] = (int) $temp['k1']->toString(); + } + $modulo[] = 0; + $curve->setModulo(...$modulo); + $len = ceil($modulo[0] / 8); + $curve->setCoefficients( + Strings::bin2hex($data['curve']['a']), + Strings::bin2hex($data['curve']['b']) + ); + $point = self::extractPoint("\0" . $data['base'], $curve); + $curve->setBasePoint(...$point); + $curve->setOrder($data['order']); + return $curve; + default: + throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); + } + } + throw new \RuntimeException('No valid parameters are present'); + } + + /** + * Extract points from a string + * + * Supports both compressed and uncompressed points + * + * @param string $str + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + public static function extractPoint($str, BaseCurve $curve) + { + if ($curve instanceof TwistedEdwardsCurve) { + // first step of point deciding as discussed at the following URL's: + // https://tools.ietf.org/html/rfc8032#section-5.1.3 + // https://tools.ietf.org/html/rfc8032#section-5.2.3 + $y = $str; + $y = strrev($y); + $sign = (bool) (ord($y[0]) & 0x80); + $y[0] = $y[0] & chr(0x7F); + $y = new BigInteger($y, 256); + if ($y->compare($curve->getModulo()) >= 0) { + throw new \RuntimeException('The Y coordinate should not be >= the modulo'); + } + $point = $curve->recoverX($y, $sign); + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + + // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, + // currently, bit strings wanting a non-zero amount of bits trimmed are not supported + if (($val = Strings::shift($str)) != "\0") { + throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Strings::bin2hex($val)); + } + if ($str == "\0") { + return []; + } + + $keylen = strlen($str); + $order = $curve->getLengthInBytes(); + // point compression is being used + if ($keylen == $order + 1) { + return $curve->derivePoint($str); + } + + // point compression is not being used + if ($keylen == 2 * $order + 1) { + preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); + list(, $w, $x, $y) = $matches; + if ($w != "\4") { + throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Strings::bin2hex($val)); + } + $point = [ + $curve->convertInteger(new BigInteger($x, 256)), + $curve->convertInteger(new BigInteger($y, 256)) + ]; + + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + + return $point; + } + + throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); + } + + /** + * Encode Parameters + * + * @todo Maybe at some point this could be moved to __toString() for each of the curves? + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param bool $returnArray optional + * @param array $options optional + * @return string|false + */ + private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = []) + { + $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; + + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + if ($useNamedCurves) { + if (isset(self::$curveOIDs[$name])) { + if ($reflect->isFinal()) { + $reflect = $reflect->getParentClass(); + $name = $reflect->getShortName(); + } + return $returnArray ? + ['namedCurve' => $name] : + ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP); + } + foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { + if ($file->getExtension() != 'php') { + continue; + } + $testName = $file->getBasename('.php'); + $class = 'phpseclib3\Crypt\EC\Curves\\' . $testName; + $reflect = new \ReflectionClass($class); + if ($reflect->isFinal()) { + continue; + } + $candidate = new $class(); + switch ($name) { + case 'Prime': + if (!$candidate instanceof PrimeCurve) { + break; + } + if (!$candidate->getModulo()->equals($curve->getModulo())) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + + return $returnArray ? + ['namedCurve' => $testName] : + ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); + case 'Binary': + if (!$candidate instanceof BinaryCurve) { + break; + } + if ($candidate->getModulo() != $curve->getModulo()) { + break; + } + if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { + break; + } + if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { + break; + } + + list($candidateX, $candidateY) = $candidate->getBasePoint(); + list($curveX, $curveY) = $curve->getBasePoint(); + if ($candidateX->toBytes() != $curveX->toBytes()) { + break; + } + if ($candidateY->toBytes() != $curveY->toBytes()) { + break; + } + + return $returnArray ? + ['namedCurve' => $testName] : + ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); + } + } + } + + $order = $curve->getOrder(); + // we could try to calculate the order thusly: + // https://crypto.stackexchange.com/a/27914/4520 + // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm + if (!$order) { + throw new \RuntimeException('Specified Curves need the order to be specified'); + } + $point = $curve->getBasePoint(); + $x = $point[0]->toBytes(); + $y = $point[1]->toBytes(); + + if ($curve instanceof PrimeCurve) { + /* + * valid versions are: + * + * ecdpVer1: + * - neither the curve or the base point are generated verifiably randomly. + * ecdpVer2: + * - curve and base point are generated verifiably at random and curve.seed is present + * ecdpVer3: + * - base point is generated verifiably at random but curve is not. curve.seed is present + */ + // other (optional) parameters can be calculated using the methods discused at + // https://crypto.stackexchange.com/q/28947/4520 + $data = [ + 'version' => 'ecdpVer1', + 'fieldID' => [ + 'fieldType' => 'prime-field', + 'parameters' => $curve->getModulo() + ], + 'curve' => [ + 'a' => $curve->getA()->toBytes(), + 'b' => $curve->getB()->toBytes() + ], + 'base' => "\4" . $x . $y, + 'order' => $order + ]; + + return $returnArray ? + ['specifiedCurve' => $data] : + ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); + } + if ($curve instanceof BinaryCurve) { + $modulo = $curve->getModulo(); + $basis = count($modulo); + $m = array_shift($modulo); + array_pop($modulo); // the last parameter should always be 0 + //rsort($modulo); + switch ($basis) { + case 3: + $basis = 'tpBasis'; + $modulo = new BigInteger($modulo[0]); + break; + case 5: + $basis = 'ppBasis'; + // these should be in strictly ascending order (hence the commented out rsort above) + $modulo = [ + 'k1' => new BigInteger($modulo[2]), + 'k2' => new BigInteger($modulo[1]), + 'k3' => new BigInteger($modulo[0]) + ]; + $modulo = ASN1::encodeDER($modulo, Maps\Pentanomial::MAP); + $modulo = new ASN1\Element($modulo); + } + $params = ASN1::encodeDER([ + 'm' => new BigInteger($m), + 'basis' => $basis, + 'parameters' => $modulo + ], Maps\Characteristic_two::MAP); + $params = new ASN1\Element($params); + $a = ltrim($curve->getA()->toBytes(), "\0"); + if (!strlen($a)) { + $a = "\0"; + } + $b = ltrim($curve->getB()->toBytes(), "\0"); + if (!strlen($b)) { + $b = "\0"; + } + $data = [ + 'version' => 'ecdpVer1', + 'fieldID' => [ + 'fieldType' => 'characteristic-two-field', + 'parameters' => $params + ], + 'curve' => [ + 'a' => $a, + 'b' => $b + ], + 'base' => "\4" . $x . $y, + 'order' => $order + ]; + + return $returnArray ? + ['specifiedCurve' => $data] : + ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); + } + + throw new UnsupportedCurveException('Curve cannot be serialized'); + } + + /** + * Use Specified Curve + * + * A specified curve has all the coefficients, the base points, etc, explicitely included. + * A specified curve is a more verbose way of representing a curve + */ + public static function useSpecifiedCurve() + { + self::$useNamedCurves = false; + } + + /** + * Use Named Curve + * + * A named curve does not include any parameters. It is up to the EC parameters to + * know what the coefficients, the base points, etc, are from the name of the curve. + * A named curve is a more concise way of representing a curve + */ + public static function useNamedCurve() + { + self::$useNamedCurves = true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php new file mode 100644 index 0000000..fd18a98 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php @@ -0,0 +1,189 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\secp256k1; +use phpseclib3\Crypt\EC\Curves\secp256r1; +use phpseclib3\Crypt\EC\Curves\secp384r1; +use phpseclib3\Crypt\EC\Curves\secp521r1; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; + +/** + * JWK Formatted EC Handler + * + * @author Jim Wigginton + */ +abstract class JWK extends Progenitor +{ + use Common; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + switch ($key->kty) { + case 'EC': + switch ($key->crv) { + case 'P-256': + case 'P-384': + case 'P-521': + case 'secp256k1': + break; + default: + throw new UnsupportedCurveException('Only P-256, P-384, P-521 and secp256k1 curves are accepted (' . $key->crv . ' provided)'); + } + break; + case 'OKP': + switch ($key->crv) { + case 'Ed25519': + case 'Ed448': + break; + default: + throw new UnsupportedCurveException('Only Ed25519 and Ed448 curves are accepted (' . $key->crv . ' provided)'); + } + break; + default: + throw new \Exception('Only EC and OKP JWK keys are supported'); + } + + $curve = '\phpseclib3\Crypt\EC\Curves\\' . str_replace('P-', 'nistp', $key->crv); + $curve = new $curve(); + + if ($curve instanceof TwistedEdwardsCurve) { + $QA = self::extractPoint(Strings::base64url_decode($key->x), $curve); + if (!isset($key->d)) { + return compact('curve', 'QA'); + } + $arr = $curve->extractSecret(Strings::base64url_decode($key->d)); + return compact('curve', 'QA') + $arr; + } + + $QA = [ + $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->x), 256)), + $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->y), 256)) + ]; + + if (!$curve->verifyPoint($QA)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + + if (!isset($key->d)) { + return compact('curve', 'QA'); + } + + $dA = new BigInteger(Strings::base64url_decode($key->d), 256); + + $curve->rangeCheck($dA); + + return compact('curve', 'dA', 'QA'); + } + + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(BaseCurve $curve) + { + switch (true) { + case $curve instanceof secp256r1: + return 'P-256'; + case $curve instanceof secp384r1: + return 'P-384'; + case $curve instanceof secp521r1: + return 'P-521'; + case $curve instanceof secp256k1: + return 'secp256k1'; + } + + $reflect = new \ReflectionClass($curve); + $curveName = $reflect->isFinal() ? + $reflect->getParentClass()->getShortName() : + $reflect->getShortName(); + throw new UnsupportedCurveException("$curveName is not a supported curve"); + } + + /** + * Return the array superstructure for an EC public key + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return array + */ + private static function savePublicKeyHelper(BaseCurve $curve, array $publicKey) + { + if ($curve instanceof TwistedEdwardsCurve) { + return [ + 'kty' => 'OKP', + 'crv' => $curve instanceof Ed25519 ? 'Ed25519' : 'Ed448', + 'x' => Strings::base64url_encode($curve->encodePoint($publicKey)) + ]; + } + + return [ + 'kty' => 'EC', + 'crv' => self::getAlias($curve), + 'x' => Strings::base64url_encode($publicKey[0]->toBytes()), + 'y' => Strings::base64url_encode($publicKey[1]->toBytes()) + ]; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + $key = self::savePublicKeyHelper($curve, $publicKey); + + return self::wrapKey($key, $options); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + $key = self::savePublicKeyHelper($curve, $publicKey); + $key['d'] = $curve instanceof TwistedEdwardsCurve ? $secret : $privateKey->toBytes(); + $key['d'] = Strings::base64url_encode($key['d']); + + return self::wrapKey($key, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php new file mode 100644 index 0000000..5741b05 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php @@ -0,0 +1,101 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Curve448; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Montgomery Curve Private Key Handler + * + * @author Jim Wigginton + */ +abstract class MontgomeryPrivate +{ + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $curve = new Curve25519(); + break; + case 56: + $curve = new Curve448(); + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + + $components = ['curve' => $curve]; + $components['dA'] = new BigInteger($key, 256); + $curve->rangeCheck($components['dA']); + // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) + { + return strrev($publicKey[0]->toBytes()); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $secret = null, $password = '') + { + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); + } + + return $privateKey->toBytes(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php new file mode 100644 index 0000000..d1ad48a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php @@ -0,0 +1,71 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Curve448; +use phpseclib3\Math\BigInteger; + +/** + * Montgomery Public Key Handler + * + * @author Jim Wigginton + */ +abstract class MontgomeryPublic +{ + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $curve = new Curve25519(); + break; + case 56: + $curve = new Curve448(); + break; + default: + throw new \LengthException('The only supported lengths are 32 and 56'); + } + + $components = ['curve' => $curve]; + $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key), 256))]; + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) + { + return strrev($publicKey[0]->toBytes()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..2cd3e19 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php @@ -0,0 +1,209 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSH Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends Progenitor +{ + use Common; + + /** + * Supported Key Types + * + * @var array + */ + protected static $types = [ + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'ssh-ed25519' + ]; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + $paddedKey = $parsed['paddedKey']; + list($type) = Strings::unpackSSH2('s', $paddedKey); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + if ($type == 'ssh-ed25519') { + list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey); + $key = libsodium::load($key); + $key['comment'] = $comment; + return $key; + } + list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); + $curve = self::loadCurveByParam(['namedCurve' => $curveName]); + $curve->rangeCheck($privateKey); + return [ + 'curve' => $curve, + 'dA' => $privateKey, + 'QA' => self::extractPoint("\0$publicKey", $curve), + 'comment' => $comment + ]; + } + + if ($parsed['type'] == 'ssh-ed25519') { + if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + + $curve = new Ed25519(); + $qa = self::extractPoint($parsed['publicKey'], $curve); + } else { + list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']); + $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; + $curve = new $curveName(); + + $qa = self::extractPoint("\0" . $publicKey, $curve); + } + + return [ + 'curve' => $curve, + 'QA' => $qa, + 'comment' => $parsed['comment'] + ]; + } + + /** + * Returns the alias that corresponds to a curve + * + * @return string + */ + private static function getAlias(BaseCurve $curve) + { + self::initialize_static_variables(); + + $reflect = new \ReflectionClass($curve); + $name = $reflect->getShortName(); + + $oid = self::$curveOIDs[$name]; + $aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) { + return $v == $oid; + }); + $aliases = array_keys($aliases); + + for ($i = 0; $i < count($aliases); $i++) { + if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { + $alias = $aliases[$i]; + break; + } + } + + if (!isset($alias)) { + throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); + } + + return $alias; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + + if ($curve instanceof Ed25519) { + $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + + $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment; + return $key; + } + + $alias = self::getAlias($curve); + + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $key; + } + + $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment; + + return $key; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + if ($curve instanceof Ed25519) { + if (!isset($secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (strlen($secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + + $pubKey = $curve->encodePoint($publicKey); + + $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); + $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $secret . $pubKey); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } + + $alias = self::getAlias($curve); + + $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]); + + $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..9f4b330 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php @@ -0,0 +1,194 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * "PKCS1" (RFC5915) Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + use Common; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { + $components = []; + + preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); + $decoded = parent::load($matches[0], $password); + $decoded = ASN1::decodeBER($decoded); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (!is_array($ecPrivate)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (isset($ecPrivate['parameters'])) { + $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); + } + + preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); + $decoded = parent::load($matches[0], ''); + $decoded = ASN1::decodeBER($decoded); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (!is_array($ecParams)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + $ecParams = self::loadCurveByParam($ecParams); + + // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes + // even if the modulo is the same + if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { + throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); + } + + if (!isset($components['curve'])) { + $components['curve'] = $ecParams; + } + + $components['dA'] = new BigInteger($ecPrivate['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); + $components['QA'] = isset($ecPrivate['publicKey']) ? + self::extractPoint($ecPrivate['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (is_array($key)) { + return ['curve' => self::loadCurveByParam($key)]; + } + + $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (!is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + if (!isset($key['parameters'])) { + throw new \RuntimeException('Key cannot be loaded without parameters'); + } + + $components = []; + $components['curve'] = self::loadCurveByParam($key['parameters']); + $components['dA'] = new BigInteger($key['privateKey'], 256); + $components['QA'] = isset($ecPrivate['publicKey']) ? + self::extractPoint($ecPrivate['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert EC parameters to the appropriate format + * + * @return string + */ + public static function saveParameters(BaseCurve $curve, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + + $key = self::encodeParameters($curve, false, $options); + + return "-----BEGIN EC PARAMETERS-----\r\n" . + chunk_split(Strings::base64_encode($key), 64) . + "-----END EC PARAMETERS-----\r\n"; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards Curves are not supported'); + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + 'parameters' => new ASN1\Element(self::encodeParameters($curve)), + 'publicKey' => "\0" . $publicKey + ]; + + $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'EC', $password, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..0ec7742 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php @@ -0,0 +1,234 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Curves\Ed448; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + use Common; + + /** + * OID Name + * + * @var array + */ + const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + // initialize_static_variables() is defined in both the trait and the parent class + // when it's defined in two places it's the traits one that's called + // the parent one is needed, as well, but the parent one is called by other methods + // in the parent class as needed and in the context of the parent it's the parent + // one that's called + self::initialize_static_variables(); + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; + + switch ($key[$type . 'Algorithm']['algorithm']) { + case 'id-Ed25519': + case 'id-Ed448': + return self::loadEdDSA($key); + } + + $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); + if (!$params) { + throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); + } + + $components = []; + $components['curve'] = self::loadCurveByParam($params); + + if ($type == 'publicKey') { + $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); + + return $components; + } + + $decoded = ASN1::decodeBER($key['privateKey']); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); + if (isset($key['parameters']) && $params != $key['parameters']) { + throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); + } + + $components['dA'] = new BigInteger($key['privateKey'], 256); + $components['curve']->rangeCheck($components['dA']); + $components['QA'] = isset($key['publicKey']) ? + self::extractPoint($key['publicKey'], $components['curve']) : + $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Break a public or private EdDSA key down into its constituent components + * + * @return array + */ + private static function loadEdDSA(array $key) + { + $components = []; + + if (isset($key['privateKey'])) { + $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); + + // 0x04 == octet string + // 0x20 == length (32 bytes) + if (substr($key['privateKey'], 0, 2) != "\x04\x20") { + throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); + } + $arr = $components['curve']->extractSecret(substr($key['privateKey'], 2)); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } + + if (isset($key['publicKey'])) { + if (!isset($components['curve'])) { + $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); + } + + $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); + } + + if (isset($key['privateKey']) && !isset($components['QA'])) { + $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); + } + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('Montgomery Curves are not supported'); + } + + if ($curve instanceof TwistedEdwardsCurve) { + return self::wrapPublicKey( + $curve->encodePoint($publicKey), + null, + $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' + ); + } + + $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); + + $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + return self::wrapPublicKey($key, $params, 'id-ecPublicKey'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('Montgomery Curves are not supported'); + } + + if ($curve instanceof TwistedEdwardsCurve) { + return self::wrapPrivateKey( + "\x04\x20" . $secret, + [], + null, + $password, + $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' + ); + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); + + $key = [ + 'version' => 'ecPrivkeyVer1', + 'privateKey' => $privateKey->toBytes(), + //'parameters' => $params, + 'publicKey' => "\0" . $publicKey + ]; + + $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); + + return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..866c883 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php @@ -0,0 +1,138 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Math\BigInteger; + +/** + * PuTTY Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends Progenitor +{ + use Common; + + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\EC\Formats\Keys\OpenSSH'; + + /** + * Supported Key Types + * + * @var array + */ + protected static $types = [ + 'ecdsa-sha2-nistp256', + 'ecdsa-sha2-nistp384', + 'ecdsa-sha2-nistp521', + 'ssh-ed25519' + ]; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + + $private = $components['private']; + + $temp = Strings::base64_encode(Strings::packSSH2('s', $components['type']) . $components['public']); + $components = OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); + + if ($components['curve'] instanceof TwistedEdwardsCurve) { + if (Strings::shift($private, 4) != "\0\0\0\x20") { + throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); + } + $arr = $components['curve']->extractSecret($private); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } else { + list($components['dA']) = Strings::unpackSSH2('i', $private); + $components['curve']->rangeCheck($components['dA']); + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = false, array $options = []) + { + self::initialize_static_variables(); + + $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); + $name = $public[0]; + $public = Strings::base64_decode($public[1]); + list(, $length) = unpack('N', Strings::shift($public, 4)); + Strings::shift($public, $length); + + // PuTTY pads private keys with a null byte per the following: + // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 + if (!$curve instanceof TwistedEdwardsCurve) { + $private = $privateKey->toBytes(); + if (!(strlen($privateKey->toBits()) & 7)) { + $private = "\0$private"; + } + } + + $private = $curve instanceof TwistedEdwardsCurve ? + Strings::packSSH2('s', $secret) : + Strings::packSSH2('s', $private); + + return self::wrapPrivateKey($public, $private, $name, $password, $options); + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField[] $publicKey + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey) + { + $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); + $type = $public[0]; + $public = Strings::base64_decode($public[1]); + list(, $length) = unpack('N', Strings::shift($public, 4)); + Strings::shift($public, $length); + + return self::wrapPublicKey($public, $type); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php new file mode 100644 index 0000000..27d9218 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php @@ -0,0 +1,485 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; + +/** + * XML Formatted EC Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + use Common; + + /** + * Default namespace + * + * @var string + */ + private static $namespace; + + /** + * Flag for using RFC4050 syntax + * + * @var bool + */ + private static $rfc4050 = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (!class_exists('DOMDocument')) { + throw new BadConfigurationException('The dom extension is not setup correctly on this system'); + } + + $use_errors = libxml_use_internal_errors(true); + + $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); + if ($temp) { + $key = $temp; + } + + $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); + if ($temp) { + $key = $temp; + } + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + libxml_use_internal_errors($use_errors); + $curve = self::loadCurveByParam($xpath); + + $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); + + $QA = self::query($xpath, 'ecdsakeyvalue')->length ? + self::extractPointRFC4050($xpath, $curve) : + self::extractPoint("\0" . $pubkey, $curve); + + libxml_use_internal_errors($use_errors); + + return compact('curve', 'QA'); + } + + /** + * Case-insensitive xpath query + * + * @param \DOMXPath $xpath + * @param string $name + * @param string $error optional + * @param bool $decode optional + * @return \DOMNodeList + */ + private static function query(\DOMXPath $xpath, $name, $error = null, $decode = true) + { + $query = '/'; + $names = explode('/', $name); + foreach ($names as $name) { + $query .= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$name']"; + } + $result = $xpath->query($query); + if (!isset($error)) { + return $result; + } + + if (!$result->length) { + throw new \RuntimeException($error); + } + return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; + } + + /** + * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. + * + * @param string $xml + * @param string $ns + */ + private static function isolateNamespace($xml, $ns) + { + $dom = new \DOMDocument(); + if (!$dom->loadXML($xml)) { + return false; + } + $xpath = new \DOMXPath($dom); + $nodes = $xpath->query("//*[namespace::*[.='$ns'] and not(../namespace::*[.='$ns'])]"); + if (!$nodes->length) { + return false; + } + $node = $nodes->item(0); + $ns_name = $node->lookupPrefix($ns); + if ($ns_name) { + $node->removeAttributeNS($ns, $ns_name); + } + return $dom->saveXML($node); + } + + /** + * Decodes the value + * + * @param string $value + */ + private static function decodeValue($value) + { + return Strings::base64_decode(str_replace(["\r", "\n", ' ', "\t"], '', $value)); + } + + /** + * Extract points from an XML document + * + * @param \DOMXPath $xpath + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @return object[] + */ + private static function extractPointRFC4050(\DOMXPath $xpath, BaseCurve $curve) + { + $x = self::query($xpath, 'publickey/x'); + $y = self::query($xpath, 'publickey/y'); + if (!$x->length || !$x->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / X coordinate not found'); + } + if (!$y->length || !$y->item(0)->hasAttribute('Value')) { + throw new \RuntimeException('Public Key / Y coordinate not found'); + } + $point = [ + $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), + $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))) + ]; + if (!$curve->verifyPoint($point)) { + throw new \RuntimeException('Unable to verify that point exists on curve'); + } + return $point; + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParam(\DOMXPath $xpath) + { + $namedCurve = self::query($xpath, 'namedcurve'); + if ($namedCurve->length == 1) { + $oid = $namedCurve->item(0)->getAttribute('URN'); + $oid = preg_replace('#[^\d.]#', '', $oid); + $name = array_search($oid, self::$curveOIDs); + if ($name === false) { + throw new UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); + } + + $curve = '\phpseclib3\Crypt\EC\Curves\\' . $name; + if (!class_exists($curve)) { + throw new UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); + } + return new $curve(); + } + + $params = self::query($xpath, 'explicitparams'); + if ($params->length) { + return self::loadCurveByParamRFC4050($xpath); + } + + $params = self::query($xpath, 'ecparameters'); + if (!$params->length) { + throw new \RuntimeException('No parameters are present'); + } + + $fieldTypes = [ + 'prime-field' => ['fieldid/prime/p'], + 'gnb' => ['fieldid/gnb/m'], + 'tnb' => ['fieldid/tnb/k'], + 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], + 'unknown' => [] + ]; + + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = preg_replace('#.*/#', '', $query); + $$param = self::decodeValue($result->item(0)->textContent); + } + break; + } + + $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); + $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); + $base = self::query($xpath, 'base', 'Base point is not present'); + $order = self::query($xpath, 'order', 'Order is not present'); + + switch ($type) { + case 'prime-field': + $curve = new PrimeCurve(); + $curve->setModulo(new BigInteger($p, 256)); + $curve->setCoefficients( + new BigInteger($a, 256), + new BigInteger($b, 256) + ); + $point = self::extractPoint("\0" . $base, $curve); + $curve->setBasePoint(...$point); + $curve->setOrder(new BigInteger($order, 256)); + return $curve; + case 'gnb': + case 'tnb': + case 'pnb': + default: + throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + + /** + * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based + * on the curve parameters + * + * @param \DomXPath $xpath + * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false + */ + private static function loadCurveByParamRFC4050(\DOMXPath $xpath) + { + $fieldTypes = [ + 'prime-field' => ['primefieldparamstype/p'], + 'unknown' => [] + ]; + + foreach ($fieldTypes as $type => $queries) { + foreach ($queries as $query) { + $result = self::query($xpath, $query); + if (!$result->length) { + continue 2; + } + $param = preg_replace('#.*/#', '', $query); + $$param = $result->item(0)->textContent; + } + break; + } + + $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', false); + $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', false); + $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', false); + $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', false); + $order = self::query($xpath, 'order', 'Order is not present', false); + + switch ($type) { + case 'prime-field': + $curve = new PrimeCurve(); + + $p = str_replace(["\r", "\n", ' ', "\t"], '', $p); + $curve->setModulo(new BigInteger($p)); + + $a = str_replace(["\r", "\n", ' ', "\t"], '', $a); + $b = str_replace(["\r", "\n", ' ', "\t"], '', $b); + $curve->setCoefficients( + new BigInteger($a), + new BigInteger($b) + ); + + $x = str_replace(["\r", "\n", ' ', "\t"], '', $x); + $y = str_replace(["\r", "\n", ' ', "\t"], '', $y); + $curve->setBasePoint( + new BigInteger($x), + new BigInteger($y) + ); + + $order = str_replace(["\r", "\n", ' ', "\t"], '', $order); + $curve->setOrder(new BigInteger($order)); + return $curve; + default: + throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); + } + } + + /** + * Sets the namespace. dsig11 is the most common one. + * + * Set to null to unset. Used only for creating public keys. + * + * @param string $namespace + */ + public static function setNamespace($namespace) + { + self::$namespace = $namespace; + } + + /** + * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 + */ + public static function enableRFC4050Syntax() + { + self::$rfc4050 = true; + } + + /** + * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters + */ + public static function disableRFC4050Syntax() + { + self::$rfc4050 = false; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param array $options optional + * @return string + */ + public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) + { + self::initialize_static_variables(); + + if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { + throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); + } + + if (empty(static::$namespace)) { + $pre = $post = ''; + } else { + $pre = static::$namespace . ':'; + $post = ':' . static::$namespace; + } + + if (self::$rfc4050) { + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . + self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . + '<' . $pre . 'PublicKey>' . "\r\n" . + '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . + '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . + '' . "\r\n" . + ''; + } + + $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); + + return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . + self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . + '<' . $pre . 'PublicKey>' . Strings::base64_encode($publicKey) . '' . "\r\n" . + ''; + } + + /** + * Encode Parameters + * + * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve + * @param string $pre + * @param array $options optional + * @return string|false + */ + private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = []) + { + $result = self::encodeParameters($curve, true, $options); + + if (isset($result['namedCurve'])) { + $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; + return self::$rfc4050 ? + '' . str_replace('URI', 'URN', $namedCurve) . '' : + $namedCurve; + } + + if (self::$rfc4050) { + $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . + '<' . $pre . 'FieldParams>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml .= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . + '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . + '' . "\r\n"; + $a = $curve->getA(); + $b = $curve->getB(); + list($x, $y) = $curve->getBasePoint(); + break; + default: + throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml .= '' . "\r\n" . + '<' . $pre . 'CurveParamsType>' . "\r\n" . + '<' . $pre . 'A>' . $a . '' . "\r\n" . + '<' . $pre . 'B>' . $b . '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'BasePointParams>' . "\r\n" . + '<' . $pre . 'BasePoint>' . "\r\n" . + '<' . $pre . 'ECPointType>' . "\r\n" . + '<' . $pre . 'X>' . $x . '' . "\r\n" . + '<' . $pre . 'Y>' . $y . '' . "\r\n" . + '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . + '' . "\r\n" . + '' . "\r\n"; + + return $xml; + } + + if (isset($result['specifiedCurve'])) { + $xml = '<' . $pre . 'ECParameters>' . "\r\n" . + '<' . $pre . 'FieldID>' . "\r\n"; + $temp = $result['specifiedCurve']; + switch ($temp['fieldID']['fieldType']) { + case 'prime-field': + $xml .= '<' . $pre . 'Prime>' . "\r\n" . + '<' . $pre . 'P>' . Strings::base64_encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . + '' . "\r\n" ; + break; + default: + throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); + } + $xml .= '' . "\r\n" . + '<' . $pre . 'Curve>' . "\r\n" . + '<' . $pre . 'A>' . Strings::base64_encode($temp['curve']['a']) . '' . "\r\n" . + '<' . $pre . 'B>' . Strings::base64_encode($temp['curve']['b']) . '' . "\r\n" . + '' . "\r\n" . + '<' . $pre . 'Base>' . Strings::base64_encode($temp['base']) . '' . "\r\n" . + '<' . $pre . 'Order>' . Strings::base64_encode($temp['order']) . '' . "\r\n" . + ''; + return $xml; + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php new file mode 100644 index 0000000..2be6ba5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php @@ -0,0 +1,116 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Keys; + +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * libsodium Key Handler + * + * @author Jim Wigginton + */ +abstract class libsodium +{ + use Common; + + /** + * Is invisible flag + * + */ + const IS_INVISIBLE = true; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + switch (strlen($key)) { + case 32: + $public = $key; + break; + case 64: + $private = substr($key, 0, 32); + $public = substr($key, -32); + break; + case 96: + $public = substr($key, -32); + if (substr($key, 32, 32) != $public) { + throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); + } + $private = substr($key, 0, 32); + break; + default: + throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); + } + + $curve = new Ed25519(); + $components = ['curve' => $curve]; + if (isset($private)) { + $arr = $curve->extractSecret($private); + $components['dA'] = $arr['dA']; + $components['secret'] = $arr['secret']; + } + $components['QA'] = isset($public) ? + self::extractPoint($public, $curve) : + $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); + + return $components; + } + + /** + * Convert an EC public key to the appropriate format + * + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @return string + */ + public static function savePublicKey(Ed25519 $curve, array $publicKey) + { + return $curve->encodePoint($publicKey); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $privateKey + * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve + * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey + * @param string $secret optional + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $secret = null, $password = '') + { + if (!isset($secret)) { + throw new \RuntimeException('Private Key does not have a secret set'); + } + if (strlen($secret) != 32) { + throw new \RuntimeException('Private Key secret is not of the correct length'); + } + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('libsodium private keys do not support encryption'); + } + return $secret . $curve->encodePoint($publicKey); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php new file mode 100644 index 0000000..d2a80a1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php @@ -0,0 +1,62 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\File\ASN1 as Encoder; +use phpseclib3\File\ASN1\Maps\EcdsaSigValue; +use phpseclib3\Math\BigInteger; + +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + /** + * Loads a signature + * + * @param string $sig + * @return array + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $decoded = Encoder::decodeBER($sig); + if (empty($decoded)) { + return false; + } + $components = Encoder::asn1map($decoded[0], EcdsaSigValue::MAP); + + return $components; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + return Encoder::encodeDER(compact('r', 's'), EcdsaSigValue::MAP); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php new file mode 100644 index 0000000..69139da --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php @@ -0,0 +1,66 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Math\BigInteger; + +/** + * ASN1 Signature Handler + * + * @author Jim Wigginton + */ +abstract class IEEE +{ + /** + * Loads a signature + * + * @param string $sig + * @return array + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $len = strlen($sig); + if ($len & 1) { + return false; + } + + $r = new BigInteger(substr($sig, 0, $len >> 1), 256); + $s = new BigInteger(substr($sig, $len >> 1), 256); + + return compact('r', 's'); + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @return string + */ + public static function save(BigInteger $r, BigInteger $s) + { + $r = $r->toBytes(); + $s = $s->toBytes(); + $len = max(strlen($r), strlen($s)); + return str_pad($r, $len, "\0", STR_PAD_LEFT) . str_pad($s, $len, "\0", STR_PAD_LEFT); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php new file mode 100644 index 0000000..7e4b47f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php @@ -0,0 +1,25 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; + +/** + * Raw DSA Signature Handler + * + * @author Jim Wigginton + */ +abstract class Raw extends Progenitor +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php new file mode 100644 index 0000000..e064442 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php @@ -0,0 +1,94 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC\Formats\Signature; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; + +/** + * SSH2 Signature Handler + * + * @author Jim Wigginton + */ +abstract class SSH2 +{ + /** + * Loads a signature + * + * @param string $sig + * @return mixed + */ + public static function load($sig) + { + if (!is_string($sig)) { + return false; + } + + $result = Strings::unpackSSH2('ss', $sig); + if ($result === false) { + return false; + } + list($type, $blob) = $result; + switch ($type) { + // see https://tools.ietf.org/html/rfc5656#section-3.1.2 + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + break; + default: + return false; + } + + $result = Strings::unpackSSH2('ii', $blob); + if ($result === false) { + return false; + } + + return [ + 'r' => $result[0], + 's' => $result[1] + ]; + } + + /** + * Returns a signature in the appropriate format + * + * @param \phpseclib3\Math\BigInteger $r + * @param \phpseclib3\Math\BigInteger $s + * @param string $curve + * @return string + */ + public static function save(BigInteger $r, BigInteger $s, $curve) + { + switch ($curve) { + case 'secp256r1': + $curve = 'nistp256'; + break; + case 'secp384r1': + $curve = 'nistp384'; + break; + case 'secp521r1': + $curve = 'nistp521'; + break; + default: + return false; + } + + $blob = Strings::packSSH2('ii', $r, $s); + + return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php new file mode 100644 index 0000000..c0ed64a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php @@ -0,0 +1,36 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Crypt\EC; + +/** + * EC Parameters + * + * @author Jim Wigginton + */ +final class Parameters extends EC +{ + /** + * Returns the parameters + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type = 'PKCS1', array $options = []) + { + $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); + + return $type::saveParameters($this->curve, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php new file mode 100644 index 0000000..462ea1a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php @@ -0,0 +1,256 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Curve25519; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Math\BigInteger; + +/** + * EC Private Key + * + * @author Jim Wigginton + */ +final class PrivateKey extends EC implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * Private Key dA + * + * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of + * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by + * a certain amount whereas a BigInteger isn't. + * + * @var object + */ + protected $dA; + + /** + * @var string + */ + protected $secret; + + /** + * Multiplies an encoded point by the private key + * + * Used by ECDH + * + * @param string $coordinates + * @return string + */ + public function multiply($coordinates) + { + if ($this->curve instanceof MontgomeryCurve) { + if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) { + return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); + } + + $point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))]; + $point = $this->curve->multiplyPoint($point, $this->dA); + return strrev($point[0]->toBytes(true)); + } + if (!$this->curve instanceof TwistedEdwardsCurve) { + $coordinates = "\0$coordinates"; + } + $point = PKCS1::extractPoint($coordinates, $this->curve); + $point = $this->curve->multiplyPoint($point, $this->dA); + if ($this->curve instanceof TwistedEdwardsCurve) { + return $this->curve->encodePoint($point); + } + if (empty($point)) { + throw new \RuntimeException('The infinity point is invalid'); + } + return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); + } + + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return mixed + */ + public function sign($message) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $dA = $this->dA; + $order = $this->curve->getOrder(); + + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === false) { + return false; + } + + if ($this->curve instanceof TwistedEdwardsCurve) { + if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + $result = sodium_crypto_sign_detached($message, $this->withPassword()->toString('libsodium')); + return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result; + } + + // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. + // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , + // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" + $A = $this->curve->encodePoint($this->QA); + $curve = $this->curve; + $hash = new Hash($curve::HASH); + + $secret = substr($hash->hash($this->secret), $curve::SIZE); + + if ($curve instanceof Ed25519) { + $dom = !isset($this->context) ? '' : + 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom = 'SigEd448' . "\0" . chr(strlen($context)) . $context; + } + // SHA-512(dom2(F, C) || prefix || PH(M)) + $r = $hash->hash($dom . $secret . $message); + $r = strrev($r); + $r = new BigInteger($r, 256); + list(, $r) = $r->divide($order); + $R = $curve->multiplyPoint($curve->getBasePoint(), $r); + $R = $curve->encodePoint($R); + $k = $hash->hash($dom . $R . $A . $message); + $k = strrev($k); + $k = new BigInteger($k, 256); + list(, $k) = $k->divide($order); + $S = $k->multiply($dA)->add($r); + list(, $S) = $S->divide($order); + $S = str_pad(strrev($S->toBytes()), $curve::SIZE, "\0"); + return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S; + } + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $signature = ''; + // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long + // supported signing / verification + // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; + // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even + // has curve-specific optimizations + $result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + + if ($result) { + if ($shortFormat == 'ASN1') { + return $signature; + } + + extract(ASN1Signature::load($signature)); + + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + } + + $e = $this->hash->hash($message); + $e = new BigInteger($e, 256); + + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + + while (true) { + $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($order); + if ($r->equals(self::$zero)) { + continue; + } + $kinv = $k->modInverse($order); + $temp = $z->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($order); + if (!$s->equals(self::$zero)) { + break; + } + } + + // the following is an RFC6979 compliant implementation of deterministic ECDSA + // it's unused because it's mainly intended for use when a good CSPRNG isn't + // available. if phpseclib's CSPRNG isn't good then even key generation is + // suspect + /* + // if this were actually being used it'd probably be better if this lived in load() and createKey() + $this->q = $this->curve->getOrder(); + $dA = $this->dA->toBigInteger(); + $this->x = $dA; + + $h1 = $this->hash->hash($message); + $k = $this->computek($h1); + list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); + $x = $x->toBigInteger(); + list(, $r) = $x->divide($this->q); + $kinv = $k->modInverse($this->q); + $h1 = $this->bits2int($h1); + $temp = $h1->add($dA->multiply($r)); + $temp = $kinv->multiply($temp); + list(, $s) = $temp->divide($this->q); + */ + + return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); + + return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->secret, $this->password, $options); + } + + /** + * Returns the public key + * + * @see self::getPrivateKey() + * @return mixed + */ + public function getPublicKey() + { + $format = 'PKCS8'; + if ($this->curve instanceof MontgomeryCurve) { + $format = 'MontgomeryPublic'; + } + + $type = self::validatePlugin('Keys', $format, 'savePublicKey'); + + $key = $type::savePublicKey($this->curve, $this->QA); + $key = EC::loadFormat($format, $key); + if ($this->curve instanceof MontgomeryCurve) { + return $key; + } + $key = $key + ->withHash($this->hash->getHash()) + ->withSignatureFormat($this->shortFormat); + if ($this->curve instanceof TwistedEdwardsCurve) { + $key = $key->withContext($this->context); + } + return $key; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php new file mode 100644 index 0000000..4558ce3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php @@ -0,0 +1,172 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\EC; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; +use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; +use phpseclib3\Crypt\EC\Curves\Ed25519; +use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; +use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; +use phpseclib3\Crypt\Hash; +use phpseclib3\Exception\UnsupportedOperationException; +use phpseclib3\Math\BigInteger; + +/** + * EC Public Key + * + * @author Jim Wigginton + */ +final class PublicKey extends EC implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Verify a signature + * + * @see self::verify() + * @param string $message + * @param string $signature + * @return mixed + */ + public function verify($message, $signature) + { + if ($this->curve instanceof MontgomeryCurve) { + throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); + } + + $shortFormat = $this->shortFormat; + $format = $this->sigFormat; + if ($format === false) { + return false; + } + + $order = $this->curve->getOrder(); + + if ($this->curve instanceof TwistedEdwardsCurve) { + if ($shortFormat == 'SSH2') { + list(, $signature) = Strings::unpackSSH2('ss', $signature); + } + + if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { + return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); + } + + $curve = $this->curve; + if (strlen($signature) != 2 * $curve::SIZE) { + return false; + } + + $R = substr($signature, 0, $curve::SIZE); + $S = substr($signature, $curve::SIZE); + + try { + $R = PKCS1::extractPoint($R, $curve); + $R = $this->curve->convertToInternal($R); + } catch (\Exception $e) { + return false; + } + + $S = strrev($S); + $S = new BigInteger($S, 256); + + if ($S->compare($order) >= 0) { + return false; + } + + $A = $curve->encodePoint($this->QA); + + if ($curve instanceof Ed25519) { + $dom2 = !isset($this->context) ? '' : + 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; + } else { + $context = isset($this->context) ? $this->context : ''; + $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context; + } + + $hash = new Hash($curve::HASH); + $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message); + $k = strrev($k); + $k = new BigInteger($k, 256); + list(, $k) = $k->divide($order); + + $qa = $curve->convertToInternal($this->QA); + + $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S); + $rhs = $curve->multiplyPoint($qa, $k); + $rhs = $curve->addPoint($rhs, $R); + $rhs = $curve->convertToAffine($rhs); + + return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); + } + + $params = $format::load($signature); + if ($params === false || count($params) != 2) { + return false; + } + extract($params); + + if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { + $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; + + $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); + + if ($result != -1) { + return (bool) $result; + } + } + + $n_1 = $order->subtract(self::$one); + if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { + return false; + } + + $e = $this->hash->hash($message); + $e = new BigInteger($e, 256); + + $Ln = $this->hash->getLength() - $order->getLength(); + $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; + + $w = $s->modInverse($order); + list(, $u1) = $z->multiply($w)->divide($order); + list(, $u2) = $r->multiply($w)->divide($order); + + $u1 = $this->curve->convertInteger($u1); + $u2 = $this->curve->convertInteger($u2); + + list($x1, $y1) = $this->curve->multiplyAddPoints( + [$this->curve->getBasePoint(), $this->QA], + [$u1, $u2] + ); + + $x1 = $x1->toBigInteger(); + list(, $x1) = $x1->divide($order); + + return $x1->equals($r); + } + + /** + * Returns the public key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + return $type::savePublicKey($this->curve, $this->QA, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php new file mode 100644 index 0000000..0e02544 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php @@ -0,0 +1,1455 @@ + + * setKey('abcdefg'); + * + * echo base64_encode($hash->hash('abcdefg')); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2015 Jim Wigginton + * @author Andreas Fischer + * @copyright 2015 Andreas Fischer + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\PrimeField; + +/** + * @author Jim Wigginton + * @author Andreas Fischer + */ +class Hash +{ + /** + * Padding Types + * + */ + const PADDING_KECCAK = 1; + + /** + * Padding Types + * + */ + const PADDING_SHA3 = 2; + + /** + * Padding Types + * + */ + const PADDING_SHAKE = 3; + + /** + * Padding Type + * + * Only used by SHA3 + * + * @var int + */ + private $paddingType = 0; + + /** + * Hash Parameter + * + * @see self::setHash() + * @var int + */ + private $hashParam; + + /** + * Byte-length of hash output (Internal HMAC) + * + * @see self::setHash() + * @var int + */ + private $length; + + /** + * Hash Algorithm + * + * @see self::setHash() + * @var string + */ + private $algo; + + /** + * Key + * + * @see self::setKey() + * @var string + */ + private $key = false; + + /** + * Nonce + * + * @see self::setNonce() + * @var string + */ + private $nonce = false; + + /** + * Hash Parameters + * + * @var array + */ + private $parameters = []; + + /** + * Computed Key + * + * @see self::_computeKey() + * @var string + */ + private $computedKey = false; + + /** + * Outer XOR (Internal HMAC) + * + * Used only for sha512/* + * + * @see self::hash() + * @var string + */ + private $opad; + + /** + * Inner XOR (Internal HMAC) + * + * Used only for sha512/* + * + * @see self::hash() + * @var string + */ + private $ipad; + + /** + * Recompute AES Key + * + * Used only for umac + * + * @see self::hash() + * @var boolean + */ + private $recomputeAESKey; + + /** + * umac cipher object + * + * @see self::hash() + * @var \phpseclib3\Crypt\AES + */ + private $c; + + /** + * umac pad + * + * @see self::hash() + * @var string + */ + private $pad; + + /** + * Block Size + * + * @var int + */ + private $blockSize; + + /**#@+ + * UMAC variables + * + * @var PrimeField + */ + private static $factory36; + private static $factory64; + private static $factory128; + private static $offset64; + private static $offset128; + private static $marker64; + private static $marker128; + private static $maxwordrange64; + private static $maxwordrange128; + /**#@-*/ + + /** + * Default Constructor. + * + * @param string $hash + */ + public function __construct($hash = 'sha256') + { + $this->setHash($hash); + } + + /** + * Sets the key for HMACs + * + * Keys can be of any length. + * + * @param string $key + */ + public function setKey($key = false) + { + $this->key = $key; + $this->computeKey(); + $this->recomputeAESKey = true; + } + + /** + * Sets the nonce for UMACs + * + * Keys can be of any length. + * + * @param string $nonce + */ + public function setNonce($nonce = false) + { + switch (true) { + case !is_string($nonce): + case strlen($nonce) > 0 && strlen($nonce) <= 16: + $this->recomputeAESKey = true; + $this->nonce = $nonce; + return; + } + + throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); + } + + /** + * Pre-compute the key used by the HMAC + * + * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes + * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." + * + * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ + * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during + * every call + * + */ + private function computeKey() + { + if ($this->key === false) { + $this->computedKey = false; + return; + } + + if (strlen($this->key) <= $this->getBlockLengthInBytes()) { + $this->computedKey = $this->key; + return; + } + + $this->computedKey = is_array($this->algo) ? + call_user_func($this->algo, $this->key) : + hash($this->algo, $this->key, true); + } + + /** + * Gets the hash function. + * + * As set by the constructor or by the setHash() method. + * + * @return string + */ + public function getHash() + { + return $this->hashParam; + } + + /** + * Sets the hash function. + * + * @param string $hash + */ + public function setHash($hash) + { + $this->hashParam = $hash = strtolower($hash); + switch ($hash) { + case 'umac-32': + case 'umac-64': + case 'umac-96': + case 'umac-128': + $this->blockSize = 128; + $this->length = abs(substr($hash, -3)) >> 3; + $this->algo = 'umac'; + return; + case 'md2-96': + case 'md5-96': + case 'sha1-96': + case 'sha224-96': + case 'sha256-96': + case 'sha384-96': + case 'sha512-96': + case 'sha512/224-96': + case 'sha512/256-96': + $hash = substr($hash, 0, -3); + $this->length = 12; // 96 / 8 = 12 + break; + case 'md2': + case 'md5': + $this->length = 16; + break; + case 'sha1': + $this->length = 20; + break; + case 'sha224': + case 'sha512/224': + case 'sha3-224': + $this->length = 28; + break; + case 'keccak256': + $this->paddingType = self::PADDING_KECCAK; + // fall-through + case 'sha256': + case 'sha512/256': + case 'sha3-256': + $this->length = 32; + break; + case 'sha384': + case 'sha3-384': + $this->length = 48; + break; + case 'sha512': + case 'sha3-512': + $this->length = 64; + break; + default: + if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { + $this->paddingType = self::PADDING_SHAKE; + $hash = $matches[1]; + $this->length = $matches[2] >> 3; + } else { + throw new UnsupportedAlgorithmException( + "$hash is not a supported algorithm" + ); + } + } + + switch ($hash) { + case 'md2': + case 'md2-96': + $this->blockSize = 128; + break; + case 'md5-96': + case 'sha1-96': + case 'sha224-96': + case 'sha256-96': + case 'md5': + case 'sha1': + case 'sha224': + case 'sha256': + $this->blockSize = 512; + break; + case 'sha3-224': + $this->blockSize = 1152; // 1600 - 2*224 + break; + case 'sha3-256': + case 'shake256': + case 'keccak256': + $this->blockSize = 1088; // 1600 - 2*256 + break; + case 'sha3-384': + $this->blockSize = 832; // 1600 - 2*384 + break; + case 'sha3-512': + $this->blockSize = 576; // 1600 - 2*512 + break; + case 'shake128': + $this->blockSize = 1344; // 1600 - 2*128 + break; + default: + $this->blockSize = 1024; + } + + if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) { + // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": + // http://php.net/ChangeLog-7.php#7.1.0 + if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0, 5) != 'sha3-') { + //preg_match('#(\d+)$#', $hash, $matches); + //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize + //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize + if (!$this->paddingType) { + $this->paddingType = self::PADDING_SHA3; + } + $this->parameters = [ + 'capacity' => 1600 - $this->blockSize, + 'rate' => $this->blockSize, + 'length' => $this->length, + 'padding' => $this->paddingType + ]; + $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; + } + } + + if ($hash == 'sha512/224' || $hash == 'sha512/256') { + // PHP 7.1.0 introduced sha512/224 and sha512/256 support: + // http://php.net/ChangeLog-7.php#7.1.0 + if (version_compare(PHP_VERSION, '7.1.0') < 0) { + // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 + $initial = $hash == 'sha512/256' ? + [ + '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', + '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' + ] : + [ + '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', + '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' + ]; + for ($i = 0; $i < 8; $i++) { + $initial[$i] = new BigInteger($initial[$i], 16); + $initial[$i]->setPrecision(64); + } + + $this->parameters = compact('initial'); + + $hash = ['phpseclib3\Crypt\Hash', 'sha512']; + } + } + + if (is_array($hash)) { + $b = $this->blockSize >> 3; + $this->ipad = str_repeat(chr(0x36), $b); + $this->opad = str_repeat(chr(0x5C), $b); + } + + $this->algo = $hash; + + $this->computeKey(); + } + + /** + * KDF: Key-Derivation Function + * + * The key-derivation function generates pseudorandom bits used to key the hash functions. + * + * @param int $index a non-negative integer less than 2^64 + * @param int $numbytes a non-negative integer less than 2^64 + * @return string string of length numbytes bytes + */ + private function kdf($index, $numbytes) + { + $this->c->setIV(pack('N4', 0, $index, 0, 1)); + + return $this->c->encrypt(str_repeat("\0", $numbytes)); + } + + /** + * PDF Algorithm + * + * @return string string of length taglen bytes. + */ + private function pdf() + { + $k = $this->key; + $nonce = $this->nonce; + $taglen = $this->length; + + // + // Extract and zero low bit(s) of Nonce if needed + // + if ($taglen <= 8) { + $last = strlen($nonce) - 1; + $mask = $taglen == 4 ? "\3" : "\1"; + $index = $nonce[$last] & $mask; + $nonce[$last] = $nonce[$last] ^ $index; + } + + // + // Make Nonce BLOCKLEN bytes by appending zeroes if needed + // + $nonce = str_pad($nonce, 16, "\0"); + + // + // Generate subkey, encipher and extract indexed substring + // + $kp = $this->kdf(0, 16); + $c = new AES('ctr'); + $c->disablePadding(); + $c->setKey($kp); + $c->setIV($nonce); + $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); + + // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you + // unpack() doesn't leak timing info + return $taglen <= 8 ? + substr($t, unpack('C', $index)[1] * $taglen, $taglen) : + substr($t, 0, $taglen); + } + + /** + * UHASH Algorithm + * + * @param string $m string of length less than 2^67 bits. + * @param int $taglen the integer 4, 8, 12 or 16. + * @return string string of length taglen bytes. + */ + private function uhash($m, $taglen) + { + // + // One internal iteration per 4 bytes of output + // + $iters = $taglen >> 2; + + // + // Define total key needed for all iterations using KDF. + // L1Key reuses most key material between iterations. + // + //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); + $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); + $L2Key = $this->kdf(2, $iters * 24); + $L3Key1 = $this->kdf(3, $iters * 64); + $L3Key2 = $this->kdf(4, $iters * 4); + + // + // For each iteration, extract key and do three-layer hash. + // If bytelength(M) <= 1024, then skip L2-HASH. + // + $y = ''; + for ($i = 0; $i < $iters; $i++) { + $L1Key_i = substr($L1Key, $i * 16, 1024); + $L2Key_i = substr($L2Key, $i * 24, 24); + $L3Key1_i = substr($L3Key1, $i * 64, 64); + $L3Key2_i = substr($L3Key2, $i * 4, 4); + + $a = self::L1Hash($L1Key_i, $m); + $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); + $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); + $y .= $c; + } + + return $y; + } + + /** + * L1-HASH Algorithm + * + * The first-layer hash breaks the message into 1024-byte chunks and + * hashes each with a function called NH. Concatenating the results + * forms a string, which is up to 128 times shorter than the original. + * + * @param string $k string of length 1024 bytes. + * @param string $m string of length less than 2^67 bits. + * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. + */ + private static function L1Hash($k, $m) + { + // + // Break M into 1024 byte chunks (final chunk may be shorter) + // + $m = str_split($m, 1024); + + // + // For each chunk, except the last: endian-adjust, NH hash + // and add bit-length. Use results to build Y. + // + $length = new BigInteger(1024 * 8); + $y = ''; + for ($i = 0; $i < count($m) - 1; $i++) { + $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP + $y .= static::nh($k, $m[$i], $length); + } + + // + // For the last chunk: pad to 32-byte boundary, endian-adjust, + // NH hash and add bit-length. Concatenate the result to Y. + // + $length = count($m) ? strlen($m[$i]) : 0; + $pad = 32 - ($length % 32); + $pad = max(32, $length + $pad % 32); + $m[$i] = str_pad(isset($m[$i]) ? $m[$i] : '', $pad, "\0"); // zeropad + $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP + + $y .= static::nh($k, $m[$i], new BigInteger($length * 8)); + + return $y; + } + + /** + * NH Algorithm + * + * @param string $k string of length 1024 bytes. + * @param string $m string with length divisible by 32 bytes. + * @return string string of length 8 bytes. + */ + private static function nh($k, $m, $length) + { + $toUInt32 = function ($x) { + $x = new BigInteger($x, 256); + $x->setPrecision(32); + return $x; + }; + + // + // Break M and K into 4-byte chunks + // + //$t = strlen($m) >> 2; + $m = str_split($m, 4); + $t = count($m); + $k = str_split($k, 4); + $k = array_pad(array_slice($k, 0, $t), $t, 0); + + $m = array_map($toUInt32, $m); + $k = array_map($toUInt32, $k); + + // + // Perform NH hash on the chunks, pairing words for multiplication + // which are 4 apart to accommodate vector-parallelism. + // + $y = new BigInteger(); + $y->setPrecision(64); + $i = 0; + while ($i < $t) { + $temp = $m[$i]->add($k[$i]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 4]->add($k[$i + 4])); + $y = $y->add($temp); + + $temp = $m[$i + 1]->add($k[$i + 1]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 5]->add($k[$i + 5])); + $y = $y->add($temp); + + $temp = $m[$i + 2]->add($k[$i + 2]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 6]->add($k[$i + 6])); + $y = $y->add($temp); + + $temp = $m[$i + 3]->add($k[$i + 3]); + $temp->setPrecision(64); + $temp = $temp->multiply($m[$i + 7]->add($k[$i + 7])); + $y = $y->add($temp); + + $i += 8; + } + + return $y->add($length)->toBytes(); + } + + /** + * L2-HASH: Second-Layer Hash + * + * The second-layer rehashes the L1-HASH output using a polynomial hash + * called POLY. If the L1-HASH output is long, then POLY is called once + * on a prefix of the L1-HASH output and called using different settings + * on the remainder. (This two-step hashing of the L1-HASH output is + * needed only if the message length is greater than 16 megabytes.) + * Careful implementation of POLY is necessary to avoid a possible + * timing attack (see Section 6.6 for more information). + * + * @param string $k string of length 24 bytes. + * @param string $m string of length less than 2^64 bytes. + * @return string string of length 16 bytes. + */ + private static function L2Hash($k, $m) + { + // + // Extract keys and restrict to special key-sets + // + $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; + $k64 = new BigInteger($k64, 256); + $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; + $k128 = new BigInteger($k128, 256); + + // + // If M is no more than 2^17 bytes, hash under 64-bit prime, + // otherwise, hash first 2^17 bytes under 64-bit prime and + // remainder under 128-bit prime. + // + if (strlen($m) <= 0x20000) { // 2^14 64-bit words + $y = self::poly(64, self::$maxwordrange64, $k64, $m); + } else { + $m_1 = substr($m, 0, 0x20000); // 1 << 17 + $m_2 = substr($m, 0x20000) . "\x80"; + $length = strlen($m_2); + $pad = 16 - ($length % 16); + $pad %= 16; + $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad + $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); + $y = str_pad($y, 16, "\0", STR_PAD_LEFT); + $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); + } + + return str_pad($y, 16, "\0", STR_PAD_LEFT); + } + + /** + * POLY Algorithm + * + * @param int $wordbits the integer 64 or 128. + * @param BigInteger $maxwordrange positive integer less than 2^wordbits. + * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. + * @param string $m string with length divisible by (wordbits / 8) bytes. + * @return integer in the range 0 ... prime(wordbits) - 1. + */ + private static function poly($wordbits, $maxwordrange, $k, $m) + { + // + // Define constants used for fixing out-of-range words + // + $wordbytes = $wordbits >> 3; + if ($wordbits == 128) { + $factory = self::$factory128; + $offset = self::$offset128; + $marker = self::$marker128; + } else { + $factory = self::$factory64; + $offset = self::$offset64; + $marker = self::$marker64; + } + + $k = $factory->newInteger($k); + + // + // Break M into chunks of length wordbytes bytes + // + $m_i = str_split($m, $wordbytes); + + // + // Each input word m is compared with maxwordrange. If not smaller + // then 'marker' and (m - offset), both in range, are hashed. + // + $y = $factory->newInteger(new BigInteger(1)); + foreach ($m_i as $m) { + $m = $factory->newInteger(new BigInteger($m, 256)); + if ($m->compare($maxwordrange) >= 0) { + $y = $k->multiply($y)->add($marker); + $y = $k->multiply($y)->add($m->subtract($offset)); + } else { + $y = $k->multiply($y)->add($m); + } + } + + return $y->toBytes(); + } + + /** + * L3-HASH: Third-Layer Hash + * + * The output from L2-HASH is 16 bytes long. This final hash function + * hashes the 16-byte string to a fixed length of 4 bytes. + * + * @param string $k1 string of length 64 bytes. + * @param string $k2 string of length 4 bytes. + * @param string $m string of length 16 bytes. + * @return string string of length 4 bytes. + */ + private static function L3Hash($k1, $k2, $m) + { + $factory = self::$factory36; + + $y = $factory->newInteger(new BigInteger()); + for ($i = 0; $i < 8; $i++) { + $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); + $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); + $y = $y->add($m_i->multiply($k_i)); + } + $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); + $y = $y ^ $k2; + + return $y; + } + + /** + * Compute the Hash / HMAC / UMAC. + * + * @param string $text + * @return string + */ + public function hash($text) + { + $algo = $this->algo; + if ($algo == 'umac') { + if ($this->recomputeAESKey) { + if (!is_string($this->nonce)) { + throw new InsufficientSetupException('No nonce has been set'); + } + if (!is_string($this->key)) { + throw new InsufficientSetupException('No key has been set'); + } + if (strlen($this->key) != 16) { + throw new \LengthException('Key must be 16 bytes long'); + } + + if (!isset(self::$maxwordrange64)) { + $one = new BigInteger(1); + + $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); + self::$factory36 = new PrimeField($prime36); + + $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); + self::$factory64 = new PrimeField($prime64); + + $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); + self::$factory128 = new PrimeField($prime128); + + self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); + self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); + self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); + self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); + + self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); + self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); + + $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); + self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); + + $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); + self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); + } + + $this->c = new AES('ctr'); + $this->c->disablePadding(); + $this->c->setKey($this->key); + + $this->pad = $this->pdf(); + + $this->recomputeAESKey = false; + } + + $hashedmessage = $this->uhash($text, $this->length); + return $hashedmessage ^ $this->pad; + } + + if (is_array($algo)) { + if (empty($this->key) || !is_string($this->key)) { + return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); + } + + // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 + + $key = str_pad($this->computedKey, $b, chr(0)); + $temp = $this->ipad ^ $key; + $temp .= $text; + $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); + $output = $this->opad ^ $key; + $output .= $temp; + $output = $algo($output, ...array_values($this->parameters)); + + return substr($output, 0, $this->length); + } + + $output = !empty($this->key) || is_string($this->key) ? + hash_hmac($algo, $text, $this->computedKey, true) : + hash($algo, $text, true); + + return strlen($output) > $this->length + ? substr($output, 0, $this->length) + : $output; + } + + /** + * Returns the hash length (in bits) + * + * @return int + */ + public function getLength() + { + return $this->length << 3; + } + + /** + * Returns the hash length (in bytes) + * + * @return int + */ + public function getLengthInBytes() + { + return $this->length; + } + + /** + * Returns the block length (in bits) + * + * @return int + */ + public function getBlockLength() + { + return $this->blockSize; + } + + /** + * Returns the block length (in bytes) + * + * @return int + */ + public function getBlockLengthInBytes() + { + return $this->blockSize >> 3; + } + + /** + * Pads SHA3 based on the mode + * + * @param int $padLength + * @param int $padType + * @return string + */ + private static function sha3_pad($padLength, $padType) + { + switch ($padType) { + case self::PADDING_KECCAK: + $temp = chr(0x01) . str_repeat("\0", $padLength - 1); + $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + return $temp; + case self::PADDING_SHAKE: + $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); + $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); + return $temp; + //case self::PADDING_SHA3: + default: + // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 + return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); + } + } + + /** + * Pure-PHP 32-bit implementation of SHA3 + * + * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation + * of SHA3 will *not* work on PHP 64-bit. This is because this implementation + * employees bitwise NOTs and bitwise left shifts. And the round constants only work + * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and + * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow + * things down. + * + * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees + * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed + * 64-bit integers, which complicates addition, whereas that limitation isn't an issue + * for SHA3. + * + * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is + * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and + * capacity c". This is relevant because, altho the KECCAK standard defines a mode + * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 + * + * @param string $p + * @param int $c + * @param int $r + * @param int $d + * @param int $padType + */ + private static function sha3_32($p, $c, $r, $d, $padType) + { + $block_size = $r >> 3; + $padLength = $block_size - (strlen($p) % $block_size); + $num_ints = $block_size >> 2; + + $p .= static::sha3_pad($padLength, $padType); + + $n = strlen($p) / $r; // number of blocks + + $s = [ + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], + [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] + ]; + + $p = str_split($p, $block_size); + + foreach ($p as $pi) { + $pi = unpack('V*', $pi); + $x = $y = 0; + for ($i = 1; $i <= $num_ints; $i += 2) { + $s[$x][$y][0] ^= $pi[$i + 1]; + $s[$x][$y][1] ^= $pi[$i]; + if (++$y == 5) { + $y = 0; + $x++; + } + } + static::processSHA3Block32($s); + } + + $z = ''; + $i = $j = 0; + while (strlen($z) < $d) { + $z .= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); + if ($j == 5) { + $j = 0; + $i++; + if ($i == 5) { + $i = 0; + static::processSHA3Block32($s); + } + } + } + + return $z; + } + + /** + * 32-bit block processing method for SHA3 + * + * @param array $s + */ + private static function processSHA3Block32(&$s) + { + static $rotationOffsets = [ + [ 0, 1, 62, 28, 27], + [36, 44, 6, 55, 20], + [ 3, 10, 43, 25, 39], + [41, 45, 15, 21, 8], + [18, 2, 61, 56, 14] + ]; + + // the standards give these constants in hexadecimal notation. it's tempting to want to use + // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive + // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead + static $roundConstants = [ + [0, 1], + [0, 32898], + [-2147483648, 32906], + [-2147483648, -2147450880], + [0, 32907], + [0, -2147483647], + [-2147483648, -2147450751], + [-2147483648, 32777], + [0, 138], + [0, 136], + [0, -2147450871], + [0, -2147483638], + [0, -2147450741], + [-2147483648, 139], + [-2147483648, 32905], + [-2147483648, 32771], + [-2147483648, 32770], + [-2147483648, 128], + [0, 32778], + [-2147483648, -2147483638], + [-2147483648, -2147450751], + [-2147483648, 32896], + [0, -2147483647], + [-2147483648, -2147450872] + ]; + + for ($round = 0; $round < 24; $round++) { + // theta step + $parity = $rotated = []; + for ($i = 0; $i < 5; $i++) { + $parity[] = [ + $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], + $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] + ]; + $rotated[] = static::rotateLeft32($parity[$i], 1); + } + + $temp = [ + [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], + [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], + [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], + [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], + [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] + ]; + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $s[$i][$j][0] ^= $temp[$j][0]; + $s[$i][$j][1] ^= $temp[$j][1]; + } + } + + $st = $s; + + // rho and pi steps + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); + } + } + + // chi step + for ($i = 0; $i < 5; $i++) { + $s[$i][0] = [ + $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), + $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) + ]; + $s[$i][1] = [ + $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), + $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) + ]; + $s[$i][2] = [ + $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), + $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) + ]; + $s[$i][3] = [ + $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), + $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) + ]; + $s[$i][4] = [ + $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), + $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) + ]; + } + + // iota step + $s[0][0][0] ^= $roundConstants[$round][0]; + $s[0][0][1] ^= $roundConstants[$round][1]; + } + } + + /** + * Rotate 32-bit int + * + * @param array $x + * @param int $shift + */ + private static function rotateLeft32($x, $shift) + { + if ($shift < 32) { + list($hi, $lo) = $x; + } else { + $shift -= 32; + list($lo, $hi) = $x; + } + + return [ + ($hi << $shift) | (($lo >> (32 - $shift)) & (1 << $shift) - 1), + ($lo << $shift) | (($hi >> (32 - $shift)) & (1 << $shift) - 1) + ]; + } + + /** + * Pure-PHP 64-bit implementation of SHA3 + * + * @param string $p + * @param int $c + * @param int $r + * @param int $d + * @param int $padType + */ + private static function sha3_64($p, $c, $r, $d, $padType) + { + $block_size = $r >> 3; + $padLength = $block_size - (strlen($p) % $block_size); + $num_ints = $block_size >> 2; + + $p .= static::sha3_pad($padLength, $padType); + + $n = strlen($p) / $r; // number of blocks + + $s = [ + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0] + ]; + + $p = str_split($p, $block_size); + + foreach ($p as $pi) { + $pi = unpack('P*', $pi); + $x = $y = 0; + foreach ($pi as $subpi) { + $s[$x][$y++] ^= $subpi; + if ($y == 5) { + $y = 0; + $x++; + } + } + static::processSHA3Block64($s); + } + + $z = ''; + $i = $j = 0; + while (strlen($z) < $d) { + $z .= pack('P', $s[$i][$j++]); + if ($j == 5) { + $j = 0; + $i++; + if ($i == 5) { + $i = 0; + static::processSHA3Block64($s); + } + } + } + + return $z; + } + + /** + * 64-bit block processing method for SHA3 + * + * @param array $s + */ + private static function processSHA3Block64(&$s) + { + static $rotationOffsets = [ + [ 0, 1, 62, 28, 27], + [36, 44, 6, 55, 20], + [ 3, 10, 43, 25, 39], + [41, 45, 15, 21, 8], + [18, 2, 61, 56, 14] + ]; + + static $roundConstants = [ + 1, + 32898, + -9223372036854742902, + -9223372034707259392, + 32907, + 2147483649, + -9223372034707259263, + -9223372036854743031, + 138, + 136, + 2147516425, + 2147483658, + 2147516555, + -9223372036854775669, + -9223372036854742903, + -9223372036854743037, + -9223372036854743038, + -9223372036854775680, + 32778, + -9223372034707292150, + -9223372034707259263, + -9223372036854742912, + 2147483649, + -9223372034707259384 + ]; + + for ($round = 0; $round < 24; $round++) { + // theta step + $parity = []; + for ($i = 0; $i < 5; $i++) { + $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; + } + $temp = [ + $parity[4] ^ static::rotateLeft64($parity[1], 1), + $parity[0] ^ static::rotateLeft64($parity[2], 1), + $parity[1] ^ static::rotateLeft64($parity[3], 1), + $parity[2] ^ static::rotateLeft64($parity[4], 1), + $parity[3] ^ static::rotateLeft64($parity[0], 1) + ]; + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $s[$i][$j] ^= $temp[$j]; + } + } + + $st = $s; + + // rho and pi steps + for ($i = 0; $i < 5; $i++) { + for ($j = 0; $j < 5; $j++) { + $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); + } + } + + // chi step + for ($i = 0; $i < 5; $i++) { + $s[$i] = [ + $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), + $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), + $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), + $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), + $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) + ]; + } + + // iota step + $s[0][0] ^= $roundConstants[$round]; + } + } + + /** + * Rotate 64-bit int + * + * @param int $x + * @param int $shift + */ + private static function rotateLeft64($x, $shift) + { + return ($x << $shift) | (($x >> (64 - $shift)) & ((1 << $shift) - 1)); + } + + /** + * Pure-PHP implementation of SHA512 + * + * @param string $m + * @param array $hash + * @return string + */ + private static function sha512($m, $hash) + { + static $k; + + if (!isset($k)) { + // Initialize table of round constants + // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) + $k = [ + '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', + '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', + 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', + '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', + 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', + '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', + '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', + 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', + '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', + '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', + 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', + 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', + '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', + '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', + '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', + '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', + 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', + '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', + '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', + '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' + ]; + + for ($i = 0; $i < 80; $i++) { + $k[$i] = new BigInteger($k[$i], 16); + } + } + + // Pre-processing + $length = strlen($m); + // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 + $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); + $m[$length] = chr(0x80); + // we don't support hashing strings 512MB long + $m .= pack('N4', 0, 0, 0, $length << 3); + + // Process the message in successive 1024-bit chunks + $chunks = str_split($m, 128); + foreach ($chunks as $chunk) { + $w = []; + for ($i = 0; $i < 16; $i++) { + $temp = new BigInteger(Strings::shift($chunk, 8), 256); + $temp->setPrecision(64); + $w[] = $temp; + } + + // Extend the sixteen 32-bit words into eighty 32-bit words + for ($i = 16; $i < 80; $i++) { + $temp = [ + $w[$i - 15]->bitwise_rightRotate(1), + $w[$i - 15]->bitwise_rightRotate(8), + $w[$i - 15]->bitwise_rightShift(7) + ]; + $s0 = $temp[0]->bitwise_xor($temp[1]); + $s0 = $s0->bitwise_xor($temp[2]); + $temp = [ + $w[$i - 2]->bitwise_rightRotate(19), + $w[$i - 2]->bitwise_rightRotate(61), + $w[$i - 2]->bitwise_rightShift(6) + ]; + $s1 = $temp[0]->bitwise_xor($temp[1]); + $s1 = $s1->bitwise_xor($temp[2]); + $w[$i] = clone $w[$i - 16]; + $w[$i] = $w[$i]->add($s0); + $w[$i] = $w[$i]->add($w[$i - 7]); + $w[$i] = $w[$i]->add($s1); + } + + // Initialize hash value for this chunk + $a = clone $hash[0]; + $b = clone $hash[1]; + $c = clone $hash[2]; + $d = clone $hash[3]; + $e = clone $hash[4]; + $f = clone $hash[5]; + $g = clone $hash[6]; + $h = clone $hash[7]; + + // Main loop + for ($i = 0; $i < 80; $i++) { + $temp = [ + $a->bitwise_rightRotate(28), + $a->bitwise_rightRotate(34), + $a->bitwise_rightRotate(39) + ]; + $s0 = $temp[0]->bitwise_xor($temp[1]); + $s0 = $s0->bitwise_xor($temp[2]); + $temp = [ + $a->bitwise_and($b), + $a->bitwise_and($c), + $b->bitwise_and($c) + ]; + $maj = $temp[0]->bitwise_xor($temp[1]); + $maj = $maj->bitwise_xor($temp[2]); + $t2 = $s0->add($maj); + + $temp = [ + $e->bitwise_rightRotate(14), + $e->bitwise_rightRotate(18), + $e->bitwise_rightRotate(41) + ]; + $s1 = $temp[0]->bitwise_xor($temp[1]); + $s1 = $s1->bitwise_xor($temp[2]); + $temp = [ + $e->bitwise_and($f), + $g->bitwise_and($e->bitwise_not()) + ]; + $ch = $temp[0]->bitwise_xor($temp[1]); + $t1 = $h->add($s1); + $t1 = $t1->add($ch); + $t1 = $t1->add($k[$i]); + $t1 = $t1->add($w[$i]); + + $h = clone $g; + $g = clone $f; + $f = clone $e; + $e = $d->add($t1); + $d = clone $c; + $c = clone $b; + $b = clone $a; + $a = $t1->add($t2); + } + + // Add this chunk's hash to result so far + $hash = [ + $hash[0]->add($a), + $hash[1]->add($b), + $hash[2]->add($c), + $hash[3]->add($d), + $hash[4]->add($e), + $hash[5]->add($f), + $hash[6]->add($g), + $hash[7]->add($h) + ]; + } + + // Produce the final hash value (big-endian) + // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) + $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . + $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); + + return $temp; + } + + /** + * __toString() magic method + */ + public function __toString() + { + return $this->getHash(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php new file mode 100644 index 0000000..61afbae --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php @@ -0,0 +1,111 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Exception\NoKeyLoadedException; +use phpseclib3\File\X509; + +/** + * PublicKeyLoader + * + * @author Jim Wigginton + */ +abstract class PublicKeyLoader +{ + /** + * Loads a public or private key + * + * @return AsymmetricKey + * @param string|array $key + * @param string $password optional + */ + public static function load($key, $password = false) + { + try { + return EC::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + try { + return RSA::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + try { + return DSA::load($key, $password); + } catch (NoKeyLoadedException $e) { + } + + try { + $x509 = new X509(); + $x509->loadX509($key); + $key = $x509->getPublicKey(); + if ($key) { + return $key; + } + } catch (\Exception $e) { + } + + throw new NoKeyLoadedException('Unable to read key'); + } + + /** + * Loads a private key + * + * @return PrivateKey + * @param string|array $key + * @param string $password optional + */ + public static function loadPrivateKey($key, $password = false) + { + $key = self::load($key, $password); + if (!$key instanceof PrivateKey) { + throw new NoKeyLoadedException('The key that was loaded was not a private key'); + } + return $key; + } + + /** + * Loads a public key + * + * @return PublicKey + * @param string|array $key + */ + public static function loadPublicKey($key) + { + $key = self::load($key); + if (!$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a public key'); + } + return $key; + } + + /** + * Loads parameters + * + * @return AsymmetricKey + * @param string|array $key + */ + public static function loadParameters($key) + { + $key = self::load($key); + if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { + throw new NoKeyLoadedException('The key that was loaded was not a parameter'); + } + return $key; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php new file mode 100644 index 0000000..654c906 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php @@ -0,0 +1,640 @@ + + * setKey('abcdefgh'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $rc2->decrypt($rc2->encrypt($plaintext)); + * ?> + * + * + * @author Patrick Monnerat + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; + +/** + * Pure-PHP implementation of RC2. + * + */ +class RC2 extends BlockCipher +{ + /** + * Block Length of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size + * @var int + */ + protected $block_size = 8; + + /** + * The Key + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::key + * @see self::setKey() + * @var string + */ + protected $key; + + /** + * The Original (unpadded) Key + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::key + * @see self::setKey() + * @see self::encrypt() + * @see self::decrypt() + * @var string + */ + private $orig_key; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\RC2::setKeyLength() + * @var int + */ + protected $key_length = 16; // = 128 bits + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'rc2'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + */ + protected $cfb_init_len = 500; + + /** + * The key length in bits. + * + * {@internal Should be in range [1..1024].} + * + * {@internal Changing this value after setting the key has no effect.} + * + * @see self::setKeyLength() + * @see self::setKey() + * @var int + */ + private $default_key_length = 1024; + + /** + * The key length in bits. + * + * {@internal Should be in range [1..1024].} + * + * @see self::isValidEnine() + * @see self::setKey() + * @var int + */ + private $current_key_length; + + /** + * The Key Schedule + * + * @see self::setupKey() + * @var array + */ + private $keys; + + /** + * Key expansion randomization table. + * Twice the same 256-value sequence to save a modulus in key expansion. + * + * @see self::setKey() + * @var array + */ + private static $pitable = [ + 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, + 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, + 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, + 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, + 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, + 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, + 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, + 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, + 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, + 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, + 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, + 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, + 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, + 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, + 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, + 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, + 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, + 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, + 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, + 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, + 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, + 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, + 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, + 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, + 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, + 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, + 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, + 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, + 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, + 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, + 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, + 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD, + 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, + 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, + 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, + 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, + 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, + 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, + 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, + 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, + 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, + 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, + 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, + 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, + 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, + 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, + 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, + 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, + 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, + 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, + 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, + 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, + 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, + 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, + 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, + 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, + 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, + 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, + 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, + 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, + 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, + 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, + 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, + 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD + ]; + + /** + * Inverse key expansion randomization table. + * + * @see self::setKey() + * @var array + */ + private static $invpitable = [ + 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66, + 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4, + 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20, + 0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53, + 0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68, + 0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B, + 0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12, + 0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB, + 0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3, + 0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26, + 0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67, + 0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB, + 0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC, + 0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60, + 0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7, + 0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD, + 0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24, + 0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31, + 0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE, + 0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99, + 0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C, + 0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA, + 0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35, + 0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61, + 0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72, + 0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3, + 0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F, + 0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9, + 0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77, + 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75, + 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87, + 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 + ]; + + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_OPENSSL: + if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { + return false; + } + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } + $this->cipher_name_openssl_ecb = 'rc2-ecb'; + $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode(); + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the key length. + * + * Valid key lengths are 8 to 1024. + * Calling this function after setting the key has no effect until the next + * \phpseclib3\Crypt\RC2::setKey() call. + * + * @param int $length in bits + * @throws \LengthException if the key length isn't supported + */ + public function setKeyLength($length) + { + if ($length < 8 || $length > 1024) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); + } + + $this->default_key_length = $this->current_key_length = $length; + $this->explicit_key_length = $length >> 3; + } + + /** + * Returns the current key length + * + * @return int + */ + public function getKeyLength() + { + return $this->current_key_length; + } + + /** + * Sets the key. + * + * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg. + * strlen($key) <= 128), however, we only use the first 128 bytes if $key + * has more then 128 bytes in it, and set $key to a single null byte if + * it is empty. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @param string $key + * @param int|boolean $t1 optional Effective key length in bits. + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key, $t1 = false) + { + $this->orig_key = $key; + + if ($t1 === false) { + $t1 = $this->default_key_length; + } + + if ($t1 < 1 || $t1 > 1024) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); + } + + $this->current_key_length = $t1; + if (strlen($key) < 1 || strlen($key) > 128) { + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); + } + + $t = strlen($key); + + // The mcrypt RC2 implementation only supports effective key length + // of 1024 bits. It is however possible to handle effective key + // lengths in range 1..1024 by expanding the key and applying + // inverse pitable mapping to the first byte before submitting it + // to mcrypt. + + // Key expansion. + $l = array_values(unpack('C*', $key)); + $t8 = ($t1 + 7) >> 3; + $tm = 0xFF >> (8 * $t8 - $t1); + + // Expand key. + $pitable = self::$pitable; + for ($i = $t; $i < 128; $i++) { + $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]]; + } + $i = 128 - $t8; + $l[$i] = $pitable[$l[$i] & $tm]; + while ($i--) { + $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]]; + } + + // Prepare the key for mcrypt. + $l[0] = self::$invpitable[$l[0]]; + array_unshift($l, 'C*'); + + $this->key = pack(...$l); + $this->key_length = strlen($this->key); + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + } + + /** + * Encrypts a message. + * + * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code + * + * @see self::decrypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->engine == self::ENGINE_OPENSSL) { + $temp = $this->key; + $this->key = $this->orig_key; + $result = parent::encrypt($plaintext); + $this->key = $temp; + return $result; + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code + * + * @see self::encrypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if ($this->engine == self::ENGINE_OPENSSL) { + $temp = $this->key; + $this->key = $this->orig_key; + $result = parent::decrypt($ciphertext); + $this->key = $temp; + return $result; + } + + return parent::decrypt($ciphertext); + } + + /** + * Encrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); + $keys = $this->keys; + $limit = 20; + $actions = [$limit => 44, 44 => 64]; + $j = 0; + + for (;;) { + // Mixing round. + $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; + $r0 |= $r0 >> 16; + $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; + $r1 |= $r1 >> 16; + $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; + $r2 |= $r2 >> 16; + $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; + $r3 |= $r3 >> 16; + + if ($j === $limit) { + if ($limit === 64) { + break; + } + + // Mashing round. + $r0 += $keys[$r3 & 0x3F]; + $r1 += $keys[$r0 & 0x3F]; + $r2 += $keys[$r1 & 0x3F]; + $r3 += $keys[$r2 & 0x3F]; + $limit = $actions[$limit]; + } + } + + return pack('vvvv', $r0, $r1, $r2, $r3); + } + + /** + * Decrypts a block + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); + $keys = $this->keys; + $limit = 44; + $actions = [$limit => 20, 20 => 0]; + $j = 64; + + for (;;) { + // R-mixing round. + $r3 = ($r3 | ($r3 << 16)) >> 5; + $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; + $r2 = ($r2 | ($r2 << 16)) >> 3; + $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; + $r1 = ($r1 | ($r1 << 16)) >> 2; + $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; + $r0 = ($r0 | ($r0 << 16)) >> 1; + $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF; + + if ($j === $limit) { + if ($limit === 0) { + break; + } + + // R-mashing round. + $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; + $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; + $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; + $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF; + $limit = $actions[$limit]; + } + } + + return pack('vvvv', $r0, $r1, $r2, $r3); + } + + /** + * Creates the key schedule + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + */ + protected function setupKey() + { + if (!isset($this->key)) { + $this->setKey(''); + } + + // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey(): + // Only the first value must be altered. + $l = unpack('Ca/Cb/v*', $this->key); + array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8)); + unset($l['a']); + unset($l['b']); + $this->keys = $l; + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + // Init code for both, encrypt and decrypt. + $init_crypt = '$keys = $this->keys;'; + + $keys = $this->keys; + + // $in is the current 8 bytes block which has to be en/decrypt + $encrypt_block = $decrypt_block = ' + $in = unpack("v4", $in); + $r0 = $in[1]; + $r1 = $in[2]; + $r2 = $in[3]; + $r3 = $in[4]; + '; + + // Create code for encryption. + $limit = 20; + $actions = [$limit => 44, 44 => 64]; + $j = 0; + + for (;;) { + // Mixing round. + $encrypt_block .= ' + $r0 = (($r0 + ' . $keys[$j++] . ' + + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; + $r0 |= $r0 >> 16; + $r1 = (($r1 + ' . $keys[$j++] . ' + + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; + $r1 |= $r1 >> 16; + $r2 = (($r2 + ' . $keys[$j++] . ' + + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; + $r2 |= $r2 >> 16; + $r3 = (($r3 + ' . $keys[$j++] . ' + + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; + $r3 |= $r3 >> 16;'; + + if ($j === $limit) { + if ($limit === 64) { + break; + } + + // Mashing round. + $encrypt_block .= ' + $r0 += $keys[$r3 & 0x3F]; + $r1 += $keys[$r0 & 0x3F]; + $r2 += $keys[$r1 & 0x3F]; + $r3 += $keys[$r2 & 0x3F];'; + $limit = $actions[$limit]; + } + } + + $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Create code for decryption. + $limit = 44; + $actions = [$limit => 20, 20 => 0]; + $j = 64; + + for (;;) { + // R-mixing round. + $decrypt_block .= ' + $r3 = ($r3 | ($r3 << 16)) >> 5; + $r3 = ($r3 - ' . $keys[--$j] . ' - + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; + $r2 = ($r2 | ($r2 << 16)) >> 3; + $r2 = ($r2 - ' . $keys[--$j] . ' - + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; + $r1 = ($r1 | ($r1 << 16)) >> 2; + $r1 = ($r1 - ' . $keys[--$j] . ' - + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; + $r0 = ($r0 | ($r0 << 16)) >> 1; + $r0 = ($r0 - ' . $keys[--$j] . ' - + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; + + if ($j === $limit) { + if ($limit === 0) { + break; + } + + // R-mashing round. + $decrypt_block .= ' + $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; + $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; + $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; + $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; + $limit = $actions[$limit]; + } + } + + $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; + + // Creates the inline-crypt function + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php new file mode 100644 index 0000000..5f3bff2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php @@ -0,0 +1,280 @@ + + * setKey('abcdefgh'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rc4->decrypt($rc4->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\StreamCipher; + +/** + * Pure-PHP implementation of RC4. + * + * @author Jim Wigginton + */ +class RC4 extends StreamCipher +{ + /** + * @see \phpseclib3\Crypt\RC4::_crypt() + */ + const ENCRYPT = 0; + + /** + * @see \phpseclib3\Crypt\RC4::_crypt() + */ + const DECRYPT = 1; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\RC4::setKeyLength() + * @var int + */ + protected $key_length = 128; // = 1024 bits + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'arcfour'; + + /** + * The Key + * + * @see self::setKey() + * @var string + */ + protected $key; + + /** + * The Key Stream for decryption and encryption + * + * @see self::setKey() + * @var array + */ + private $stream; + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + if ($this->continuousBuffer) { + return false; + } + // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 + // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" + // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not + if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { + return false; + } + $this->cipher_name_openssl = 'rc4-40'; + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the key length + * + * Keys can be between 1 and 256 bytes long. + * + * @param int $length + * @throws \LengthException if the key length is invalid + */ + public function setKeyLength($length) + { + if ($length < 8 || $length > 2048) { + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); + } + + $this->key_length = $length >> 3; + + parent::setKeyLength($length); + } + + /** + * Sets the key length + * + * Keys can be between 1 and 256 bytes long. + * + * @param string $key + */ + public function setKey($key) + { + $length = strlen($key); + if ($length < 1 || $length > 256) { + throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); + } + + parent::setKey($key); + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + if ($this->engine != self::ENGINE_INTERNAL) { + return parent::encrypt($plaintext); + } + return $this->crypt($plaintext, self::ENCRYPT); + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if ($this->engine != self::ENGINE_INTERNAL) { + return parent::decrypt($ciphertext); + } + return $this->crypt($ciphertext, self::DECRYPT); + } + + /** + * Encrypts a block + * + * @param string $in + */ + protected function encryptBlock($in) + { + // RC4 does not utilize this method + } + + /** + * Decrypts a block + * + * @param string $in + */ + protected function decryptBlock($in) + { + // RC4 does not utilize this method + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + */ + protected function setupKey() + { + $key = $this->key; + $keyLength = strlen($key); + $keyStream = range(0, 255); + $j = 0; + for ($i = 0; $i < 256; $i++) { + $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255; + $temp = $keyStream[$i]; + $keyStream[$i] = $keyStream[$j]; + $keyStream[$j] = $temp; + } + + $this->stream = []; + $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = [ + 0, // index $i + 0, // index $j + $keyStream + ]; + } + + /** + * Encrypts or decrypts a message. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $text + * @param int $mode + * @return string $text + */ + private function crypt($text, $mode) + { + if ($this->changed) { + $this->setup(); + } + + $stream = &$this->stream[$mode]; + if ($this->continuousBuffer) { + $i = &$stream[0]; + $j = &$stream[1]; + $keyStream = &$stream[2]; + } else { + $i = $stream[0]; + $j = $stream[1]; + $keyStream = $stream[2]; + } + + $len = strlen($text); + for ($k = 0; $k < $len; ++$k) { + $i = ($i + 1) & 255; + $ksi = $keyStream[$i]; + $j = ($j + $ksi) & 255; + $ksj = $keyStream[$j]; + + $keyStream[$i] = $ksj; + $keyStream[$j] = $ksi; + $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]); + } + + return $text; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php new file mode 100644 index 0000000..19dcfea --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php @@ -0,0 +1,934 @@ + + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $ciphertext = $public->encrypt($plaintext); + * + * echo $private->decrypt($ciphertext); + * ?> + * + * + * Here's an example of how to create signatures and verify signatures with this library: + * + * getPublicKey(); + * + * $plaintext = 'terrafrost'; + * + * $signature = $private->sign($plaintext); + * + * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; + * ?> + * + * + * One thing to consider when using this: so phpseclib uses PSS mode by default. + * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So + * should phpseclib save to the id-RSASSA-PSS format by default or the + * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better + * because SSH doesn't use PSS and idk how many SSH servers would be able to + * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS + * format is used by default (unless you change it up to use PKCS1 instead) + * + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Crypt\RSA\PrivateKey; +use phpseclib3\Crypt\RSA\PublicKey; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP PKCS#1 compliant implementation of RSA. + * + * @author Jim Wigginton + */ +abstract class RSA extends AsymmetricKey +{ + /** + * Algorithm Name + * + * @var string + */ + const ALGORITHM = 'RSA'; + + /** + * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} + * (OAEP) for encryption / decryption. + * + * Uses sha256 by default + * + * @see self::setHash() + * @see self::setMGFHash() + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_OAEP = 1; + + /** + * Use PKCS#1 padding. + * + * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards + * compatibility with protocols (like SSH-1) written before OAEP's introduction. + * + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_PKCS1 = 2; + + /** + * Do not use any padding + * + * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy + * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. + * + * @see self::encrypt() + * @see self::decrypt() + */ + const ENCRYPTION_NONE = 4; + + /** + * Use the Probabilistic Signature Scheme for signing + * + * Uses sha256 and 0 as the salt length + * + * @see self::setSaltLength() + * @see self::setMGFHash() + * @see self::setHash() + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_PSS = 16; + + /** + * Use a relaxed version of PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_RELAXED_PKCS1 = 32; + + /** + * Use PKCS#1 padding for signature verification + * + * @see self::sign() + * @see self::verify() + * @see self::setHash() + */ + const SIGNATURE_PKCS1 = 64; + + /** + * Encryption padding mode + * + * @var int + */ + protected $encryptionPadding = self::ENCRYPTION_OAEP; + + /** + * Signature padding mode + * + * @var int + */ + protected $signaturePadding = self::SIGNATURE_PSS; + + /** + * Length of hash function output + * + * @var int + */ + protected $hLen; + + /** + * Length of salt + * + * @var int + */ + protected $sLen; + + /** + * Label + * + * @var string + */ + protected $label = ''; + + /** + * Hash function for the Mask Generation Function + * + * @var \phpseclib3\Crypt\Hash + */ + protected $mgfHash; + + /** + * Length of MGF hash function output + * + * @var int + */ + protected $mgfHLen; + + /** + * Modulus (ie. n) + * + * @var \phpseclib3\Math\BigInteger + */ + protected $modulus; + + /** + * Modulus length + * + * @var \phpseclib3\Math\BigInteger + */ + protected $k; + + /** + * Exponent (ie. e or d) + * + * @var \phpseclib3\Math\BigInteger + */ + protected $exponent; + + /** + * Default public exponent + * + * @var int + * @link http://en.wikipedia.org/wiki/65537_%28number%29 + */ + private static $defaultExponent = 65537; + + /** + * Enable Blinding? + * + * @var bool + */ + protected static $enableBlinding = true; + + /** + * OpenSSL configuration file name. + * + * @see self::createKey() + * @var ?string + */ + protected static $configFile; + + /** + * Smallest Prime + * + * Per , this number ought not result in primes smaller + * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime + * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if + * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is + * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's + * a chance neither gmp nor OpenSSL are installed) + * + * @var int + */ + private static $smallestPrime = 4096; + + /** + * Public Exponent + * + * @var \phpseclib3\Math\BigInteger + */ + protected $publicExponent; + + /** + * Sets the public exponent for key generation + * + * This will be 65537 unless changed. + * + * @param int $val + */ + public static function setExponent($val) + { + self::$defaultExponent = $val; + } + + /** + * Sets the smallest prime number in bits. Used for key generation + * + * This will be 4096 unless changed. + * + * @param int $val + */ + public static function setSmallestPrime($val) + { + self::$smallestPrime = $val; + } + + /** + * Sets the OpenSSL config file path + * + * Set to the empty string to use the default config file + * + * @param string $val + */ + public static function setOpenSSLConfigPath($val) + { + self::$configFile = $val; + } + + /** + * Create a private key + * + * The public key can be extracted from the private key + * + * @return RSA\PrivateKey + * @param int $bits + */ + public static function createKey($bits = 2048) + { + self::initialize_static_variables(); + + $class = new \ReflectionClass(static::class); + if ($class->isFinal()) { + throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); + } + + $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be + if ($regSize > self::$smallestPrime) { + $num_primes = floor($bits / self::$smallestPrime); + $regSize = self::$smallestPrime; + } else { + $num_primes = 2; + } + + if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + + // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum + if (self::$engines['OpenSSL']) { + $config = []; + if (self::$configFile) { + $config['config'] = self::$configFile; + } + $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config); + openssl_pkey_export($rsa, $privatekeystr, null, $config); + + // clear the buffer of error strings stemming from a minimalistic openssl.cnf + // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up + while (openssl_error_string() !== false) { + } + + return RSA::load($privatekeystr); + } + } + + static $e; + if (!isset($e)) { + $e = new BigInteger(self::$defaultExponent); + } + + $n = clone self::$one; + $exponents = $coefficients = $primes = []; + $lcm = [ + 'top' => clone self::$one, + 'bottom' => false + ]; + + do { + for ($i = 1; $i <= $num_primes; $i++) { + if ($i != $num_primes) { + $primes[$i] = BigInteger::randomPrime($regSize); + } else { + extract(BigInteger::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + list($min) = $min->divide($n); + $min = $min->add(self::$one); + list($max) = $max->divide($n); + $primes[$i] = BigInteger::randomRangePrime($min, $max); + } + + // the first coefficient is calculated differently from the rest + // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) + if ($i > 2) { + $coefficients[$i] = $n->modInverse($primes[$i]); + } + + $n = $n->multiply($primes[$i]); + + $temp = $primes[$i]->subtract(self::$one); + + // textbook RSA implementations use Euler's totient function instead of the least common multiple. + // see http://en.wikipedia.org/wiki/Euler%27s_totient_function + $lcm['top'] = $lcm['top']->multiply($temp); + $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); + } + + list($temp) = $lcm['top']->divide($lcm['bottom']); + $gcd = $temp->gcd($e); + $i0 = 1; + } while (!$gcd->equals(self::$one)); + + $coefficients[2] = $primes[2]->modInverse($primes[1]); + + $d = $e->modInverse($temp); + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $e->modInverse($temp); + } + + // from : + // RSAPrivateKey ::= SEQUENCE { + // version Version, + // modulus INTEGER, -- n + // publicExponent INTEGER, -- e + // privateExponent INTEGER, -- d + // prime1 INTEGER, -- p + // prime2 INTEGER, -- q + // exponent1 INTEGER, -- d mod (p-1) + // exponent2 INTEGER, -- d mod (q-1) + // coefficient INTEGER, -- (inverse of q) mod p + // otherPrimeInfos OtherPrimeInfos OPTIONAL + // } + $privatekey = new PrivateKey(); + $privatekey->modulus = $n; + $privatekey->k = $bits >> 3; + $privatekey->publicExponent = $e; + $privatekey->exponent = $d; + $privatekey->primes = $primes; + $privatekey->exponents = $exponents; + $privatekey->coefficients = $coefficients; + + /* + $publickey = new PublicKey; + $publickey->modulus = $n; + $publickey->k = $bits >> 3; + $publickey->exponent = $e; + $publickey->publicExponent = $e; + $publickey->isPublic = true; + */ + + return $privatekey; + } + + /** + * OnLoad Handler + * + * @return bool + */ + protected static function onLoad(array $components) + { + $key = $components['isPublicKey'] ? + new PublicKey() : + new PrivateKey(); + + $key->modulus = $components['modulus']; + $key->publicExponent = $components['publicExponent']; + $key->k = $key->modulus->getLengthInBytes(); + + if ($components['isPublicKey'] || !isset($components['privateExponent'])) { + $key->exponent = $key->publicExponent; + } else { + $key->privateExponent = $components['privateExponent']; + $key->exponent = $key->privateExponent; + $key->primes = $components['primes']; + $key->exponents = $components['exponents']; + $key->coefficients = $components['coefficients']; + } + + if ($components['format'] == PSS::class) { + // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is + // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib + // uses PSS padding by default. it assumes the more secure method by default and altho it provides + // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent + // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that + // not only does it defaults to the most secure methods - it doesn't even let you choose less + // secure methods + //$key = $key->withPadding(self::SIGNATURE_PSS); + if (isset($components['hash'])) { + $key = $key->withHash($components['hash']); + } + if (isset($components['MGFHash'])) { + $key = $key->withMGFHash($components['MGFHash']); + } + if (isset($components['saltLength'])) { + $key = $key->withSaltLength($components['saltLength']); + } + } + + return $key; + } + + /** + * Initialize static variables + */ + protected static function initialize_static_variables() + { + if (!isset(self::$configFile)) { + self::$configFile = dirname(__FILE__) . '/../openssl.cnf'; + } + + parent::initialize_static_variables(); + } + + /** + * Constructor + * + * PublicKey and PrivateKey objects can only be created from abstract RSA class + */ + protected function __construct() + { + parent::__construct(); + + $this->hLen = $this->hash->getLengthInBytes(); + $this->mgfHash = new Hash('sha256'); + $this->mgfHLen = $this->mgfHash->getLengthInBytes(); + } + + /** + * Integer-to-Octet-String primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. + * + * @param bool|\phpseclib3\Math\BigInteger $x + * @param int $xLen + * @return bool|string + */ + protected function i2osp($x, $xLen) + { + if ($x === false) { + return false; + } + $x = $x->toBytes(); + if (strlen($x) > $xLen) { + throw new \OutOfRangeException('Resultant string length out of range'); + } + return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); + } + + /** + * Octet-String-to-Integer primitive + * + * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. + * + * @param string $x + * @return \phpseclib3\Math\BigInteger + */ + protected function os2ip($x) + { + return new BigInteger($x, 256); + } + + /** + * EMSA-PKCS1-V1_5-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. + * + * @param string $m + * @param int $emLen + * @throws \LengthException if the intended encoded message length is too short + * @return string + */ + protected function emsa_pkcs1_v1_5_encode($m, $emLen) + { + $h = $this->hash->hash($m); + + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'md2': + $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10"; + break; + case 'md5': + $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; + break; + case 'sha1': + $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"; + break; + case 'sha256': + $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; + break; + case 'sha384': + $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"; + break; + case 'sha512': + $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"; + break; + case 'sha512/224': + $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c"; + break; + case 'sha512/256': + $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20"; + } + $t .= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + + /** + * EMSA-PKCS1-V1_5-ENCODE (without NULL) + * + * Quoting https://tools.ietf.org/html/rfc8017#page-65, + * + * "The parameters field associated with id-sha1, id-sha224, id-sha256, + * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should + * generally be omitted, but if present, it shall have a value of type + * NULL" + * + * @param string $m + * @param int $emLen + * @return string + */ + protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen) + { + $h = $this->hash->hash($m); + + // see http://tools.ietf.org/html/rfc3447#page-43 + switch ($this->hash->getHash()) { + case 'sha1': + $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14"; + break; + case 'sha256': + $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20"; + break; + case 'sha384': + $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30"; + break; + case 'sha512': + $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40"; + break; + // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 + case 'sha224': + $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c"; + break; + case 'sha512/224': + $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c"; + break; + case 'sha512/256': + $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20"; + break; + default: + throw new UnsupportedAlgorithmException('md2 and md5 require NULLs'); + } + $t .= $h; + $tLen = strlen($t); + + if ($emLen < $tLen + 11) { + throw new \LengthException('Intended encoded message length too short'); + } + + $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); + + $em = "\0\1$ps\0$t"; + + return $em; + } + + /** + * MGF1 + * + * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. + * + * @param string $mgfSeed + * @param int $maskLen + * @return string + */ + protected function mgf1($mgfSeed, $maskLen) + { + // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. + + $t = ''; + $count = ceil($maskLen / $this->mgfHLen); + for ($i = 0; $i < $count; $i++) { + $c = pack('N', $i); + $t .= $this->mgfHash->hash($mgfSeed . $c); + } + + return substr($t, 0, $maskLen); + } + + /** + * Returns the key size + * + * More specifically, this returns the size of the modulo in bits. + * + * @return int + */ + public function getLength() + { + return !isset($this->modulus) ? 0 : $this->modulus->getLength(); + } + + /** + * Determines which hashing function should be used + * + * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and + * decryption. + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->hash = new Hash($hash); + break; + default: + throw new UnsupportedAlgorithmException( + 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' + ); + } + $new->hLen = $new->hash->getLengthInBytes(); + + return $new; + } + + /** + * Determines which hashing function should be used for the mask generation function + * + * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's + * best if Hash and MGFHash are set to the same thing this is not a requirement. + * + * @param string $hash + */ + public function withMGFHash($hash) + { + $new = clone $this; + + // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. + switch (strtolower($hash)) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha256': + case 'sha384': + case 'sha512': + case 'sha224': + case 'sha512/224': + case 'sha512/256': + $new->mgfHash = new Hash($hash); + break; + default: + throw new UnsupportedAlgorithmException( + 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' + ); + } + $new->mgfHLen = $new->mgfHash->getLengthInBytes(); + + return $new; + } + + /** + * Returns the MGF hash algorithm currently being used + * + */ + public function getMGFHash() + { + return clone $this->mgfHash; + } + + /** + * Determines the salt length + * + * Used by RSA::PADDING_PSS + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: + * + * Typical salt lengths in octets are hLen (the length of the output + * of the hash function Hash) and 0. + * + * @param int $sLen + */ + public function withSaltLength($sLen) + { + $new = clone $this; + $new->sLen = $sLen; + return $new; + } + + /** + * Returns the salt length currently being used + * + */ + public function getSaltLength() + { + return $this->sLen !== null ? $this->sLen : $this->hLen; + } + + /** + * Determines the label + * + * Used by RSA::PADDING_OAEP + * + * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: + * + * Both the encryption and the decryption operations of RSAES-OAEP take + * the value of a label L as input. In this version of PKCS #1, L is + * the empty string; other uses of the label are outside the scope of + * this document. + * + * @param string $label + */ + public function withLabel($label) + { + $new = clone $this; + $new->label = $label; + return $new; + } + + /** + * Returns the label currently being used + * + */ + public function getLabel() + { + return $this->label; + } + + /** + * Determines the padding modes + * + * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); + * + * @param int $padding + */ + public function withPadding($padding) + { + $masks = [ + self::ENCRYPTION_OAEP, + self::ENCRYPTION_PKCS1, + self::ENCRYPTION_NONE + ]; + $encryptedCount = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $encryptedCount++; + } + } + if ($encryptedCount > 1) { + throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); + } + $encryptionPadding = $selected; + + $masks = [ + self::SIGNATURE_PSS, + self::SIGNATURE_RELAXED_PKCS1, + self::SIGNATURE_PKCS1 + ]; + $signatureCount = 0; + $selected = 0; + foreach ($masks as $mask) { + if ($padding & $mask) { + $selected = $mask; + $signatureCount++; + } + } + if ($signatureCount > 1) { + throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); + } + $signaturePadding = $selected; + + $new = clone $this; + if ($encryptedCount) { + $new->encryptionPadding = $encryptionPadding; + } + if ($signatureCount) { + $new->signaturePadding = $signaturePadding; + } + return $new; + } + + /** + * Returns the padding currently being used + * + */ + public function getPadding() + { + return $this->signaturePadding | $this->encryptionPadding; + } + + /** + * Returns the current engine being used + * + * OpenSSL is only used in this class (and it's subclasses) for key generation + * Even then it depends on the parameters you're using. It's not used for + * multi-prime RSA nor is it used if the key length is outside of the range + * supported by OpenSSL + * + * @see self::useInternalEngine() + * @see self::useBestEngine() + * @return string + */ + public function getEngine() + { + if (!isset(self::$engines['PHP'])) { + self::useBestEngine(); + } + return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ? + 'OpenSSL' : + 'PHP'; + } + + /** + * Enable RSA Blinding + * + */ + public static function enableBlinding() + { + static::$enableBlinding = true; + } + + /** + * Disable RSA Blinding + * + */ + public static function disableBlinding() + { + static::$enableBlinding = false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php new file mode 100644 index 0000000..87f543d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php @@ -0,0 +1,142 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * JWK Formatted RSA Handler + * + * @author Jim Wigginton + */ +abstract class JWK extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + if ($key->kty != 'RSA') { + throw new \RuntimeException('Only RSA JWK keys are supported'); + } + + $count = $publicCount = 0; + $vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']; + foreach ($vars as $var) { + if (!isset($key->$var) || !is_string($key->$var)) { + continue; + } + $count++; + $value = new BigInteger(Strings::base64url_decode($key->$var), 256); + switch ($var) { + case 'n': + $publicCount++; + $components['modulus'] = $value; + break; + case 'e': + $publicCount++; + $components['publicExponent'] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'qi': + $components['coefficients'][2] = $value; + } + } + + if ($count == count($vars)) { + return $components + ['isPublicKey' => false]; + } + + if ($count == 2 && $publicCount == 2) { + return $components + ['isPublicKey' => true]; + } + + throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys'); + } + + $key = [ + 'kty' => 'RSA', + 'n' => Strings::base64url_encode($n->toBytes()), + 'e' => Strings::base64url_encode($e->toBytes()), + 'd' => Strings::base64url_encode($d->toBytes()), + 'p' => Strings::base64url_encode($primes[1]->toBytes()), + 'q' => Strings::base64url_encode($primes[2]->toBytes()), + 'dp' => Strings::base64url_encode($exponents[1]->toBytes()), + 'dq' => Strings::base64url_encode($exponents[2]->toBytes()), + 'qi' => Strings::base64url_encode($coefficients[2]->toBytes()) + ]; + + return self::wrapKey($key, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $key = [ + 'kty' => 'RSA', + 'n' => Strings::base64url_encode($n->toBytes()), + 'e' => Strings::base64url_encode($e->toBytes()) + ]; + + return self::wrapKey($key, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php new file mode 100644 index 0000000..e9a0c4f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php @@ -0,0 +1,228 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Microsoft BLOB Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class MSBLOB +{ + /** + * Public/Private Key Pair + * + */ + const PRIVATEKEYBLOB = 0x7; + /** + * Public Key + * + */ + const PUBLICKEYBLOB = 0x6; + /** + * Public Key + * + */ + const PUBLICKEYBLOBEX = 0xA; + /** + * RSA public key exchange algorithm + * + */ + const CALG_RSA_KEYX = 0x0000A400; + /** + * RSA public key exchange algorithm + * + */ + const CALG_RSA_SIGN = 0x00002400; + /** + * Public Key + * + */ + const RSA1 = 0x31415352; + /** + * Private Key + * + */ + const RSA2 = 0x32415352; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $key = Strings::base64_decode($key); + + if (!is_string($key)) { + throw new \UnexpectedValueException('Base64 decoding produced an error'); + } + if (strlen($key) < 20) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + // PUBLICKEYSTRUC publickeystruc + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx + extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8))); + /** + * @var string $type + * @var string $version + * @var integer $reserved + * @var integer $algo + */ + switch (ord($type)) { + case self::PUBLICKEYBLOB: + case self::PUBLICKEYBLOBEX: + $publickey = true; + break; + case self::PRIVATEKEYBLOB: + $publickey = false; + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $components = ['isPublicKey' => $publickey]; + + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx + switch ($algo) { + case self::CALG_RSA_KEYX: + case self::CALG_RSA_SIGN: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + // RSAPUBKEY rsapubkey + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx + // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit + extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12))); + /** + * @var integer $magic + * @var integer $bitlen + * @var string $pubexp + */ + switch ($magic) { + case self::RSA2: + $components['isPublicKey'] = false; + // fall-through + case self::RSA1: + break; + default: + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $baseLength = $bitlen / 16; + if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + + $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); + // BYTE modulus[rsapubkey.bitlen/8] + $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); + + if ($publickey) { + return $components; + } + + $components['isPublicKey'] = false; + + // BYTE prime1[rsapubkey.bitlen/16] + $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE prime2[rsapubkey.bitlen/16] + $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); + // BYTE exponent1[rsapubkey.bitlen/16] + $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + // BYTE exponent2[rsapubkey.bitlen/16] + $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); + // BYTE coefficient[rsapubkey.bitlen/16] + $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; + if (isset($components['privateExponent'])) { + $components['publicExponent'] = $components['privateExponent']; + } + // BYTE privateExponent[rsapubkey.bitlen/8] + $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); + } + + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('MSBLOB private keys do not support encryption'); + } + + $n = strrev($n->toBytes()); + $e = str_pad(strrev($e->toBytes()), 4, "\0"); + $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); + $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e); + $key .= $n; + $key .= strrev($primes[1]->toBytes()); + $key .= strrev($primes[2]->toBytes()); + $key .= strrev($exponents[1]->toBytes()); + $key .= strrev($exponents[2]->toBytes()); + $key .= strrev($coefficients[2]->toBytes()); + $key .= strrev($d->toBytes()); + + return Strings::base64_encode($key); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + $n = strrev($n->toBytes()); + $e = str_pad(strrev($e->toBytes()), 4, "\0"); + $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); + $key .= pack('VVa*', self::RSA1, 8 * strlen($n), $e); + $key .= $n; + + return Strings::base64_encode($key); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php new file mode 100644 index 0000000..2367810 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php @@ -0,0 +1,132 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSH Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class OpenSSH extends Progenitor +{ + /** + * Supported Key Types + * + * @var array + */ + protected static $types = ['ssh-rsa']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $parsed = parent::load($key, $password); + + if (isset($parsed['paddedKey'])) { + list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); + if ($type != $parsed['type']) { + throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); + } + + $primes = $coefficients = []; + + list( + $modulus, + $publicExponent, + $privateExponent, + $coefficients[2], + $primes[1], + $primes[2], + $comment, + ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']); + + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + + $isPublicKey = false; + + return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + + list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']); + + return [ + 'isPublicKey' => true, + 'modulus' => $modulus, + 'publicExponent' => $publicExponent, + 'comment' => $parsed['comment'] + ]; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n); + + if (isset($options['binary']) ? $options['binary'] : self::$binary) { + return $RSAPublicKey; + } + + $comment = isset($options['comment']) ? $options['comment'] : self::$comment; + $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment; + + return $RSAPublicKey; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $publicKey = self::savePublicKey($n, $e, ['binary' => true]); + $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); + + return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php new file mode 100644 index 0000000..276c602 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php @@ -0,0 +1,160 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#1 Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS1 extends Progenitor +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (strpos($key, 'PUBLIC') !== false) { + $components = ['isPublicKey' => true]; + } elseif (strpos($key, 'PRIVATE') !== false) { + $components = ['isPublicKey' => false]; + } else { + $components = []; + } + + $key = parent::load($key, $password); + + $decoded = ASN1::decodeBER($key); + if (!$decoded) { + throw new \RuntimeException('Unable to decode BER'); + } + + $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); + if (is_array($key)) { + $components += [ + 'modulus' => $key['modulus'], + 'publicExponent' => $key['publicExponent'], + 'privateExponent' => $key['privateExponent'], + 'primes' => [1 => $key['prime1'], $key['prime2']], + 'exponents' => [1 => $key['exponent1'], $key['exponent2']], + 'coefficients' => [2 => $key['coefficient']] + ]; + if ($key['version'] == 'multi') { + foreach ($key['otherPrimeInfos'] as $primeInfo) { + $components['primes'][] = $primeInfo['prime']; + $components['exponents'][] = $primeInfo['exponent']; + $components['coefficients'][] = $primeInfo['coefficient']; + } + } + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = false; + } + return $components; + } + + $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); + + if (!is_array($key)) { + throw new \RuntimeException('Unable to perform ASN1 mapping'); + } + + if (!isset($components['isPublicKey'])) { + $components['isPublicKey'] = true; + } + + return $components + $key; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $num_primes = count($primes); + $key = [ + 'version' => $num_primes == 2 ? 'two-prime' : 'multi', + 'modulus' => $n, + 'publicExponent' => $e, + 'privateExponent' => $d, + 'prime1' => $primes[1], + 'prime2' => $primes[2], + 'exponent1' => $exponents[1], + 'exponent2' => $exponents[2], + 'coefficient' => $coefficients[2] + ]; + for ($i = 3; $i <= $num_primes; $i++) { + $key['otherPrimeInfos'][] = [ + 'prime' => $primes[$i], + 'exponent' => $exponents[$i], + 'coefficient' => $coefficients[$i] + ]; + } + + $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP); + + return self::wrapPrivateKey($key, 'RSA', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + $key = [ + 'modulus' => $n, + 'publicExponent' => $e + ]; + + $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP); + + return self::wrapPublicKey($key, 'RSA'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php new file mode 100644 index 0000000..1eaac6e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php @@ -0,0 +1,122 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PKCS8 extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'rsaEncryption'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.1.1'; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + $key = parent::load($key, $password); + + if (isset($key['privateKey'])) { + $components['isPublicKey'] = false; + $type = 'private'; + } else { + $components['isPublicKey'] = true; + $type = 'public'; + } + + $result = $components + PKCS1::load($key[$type . 'Key']); + + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + + return $result; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = ASN1::extractBER($key); + return self::wrapPrivateKey($key, [], null, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + $key = PKCS1::savePublicKey($n, $e); + $key = ASN1::extractBER($key); + return self::wrapPublicKey($key, null); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php new file mode 100644 index 0000000..ed75b9b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php @@ -0,0 +1,238 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * PKCS#8 Formatted RSA-PSS Key Handler + * + * @author Jim Wigginton + */ +abstract class PSS extends Progenitor +{ + /** + * OID Name + * + * @var string + */ + const OID_NAME = 'id-RSASSA-PSS'; + + /** + * OID Value + * + * @var string + */ + const OID_VALUE = '1.2.840.113549.1.1.10'; + + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = false; + + /** + * Child OIDs loaded + * + * @var bool + */ + protected static $childOIDsLoaded = false; + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!self::$oidsLoaded) { + ASN1::loadOIDs([ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + + 'id-mgf1' => '1.2.840.113549.1.1.8' + ]); + self::$oidsLoaded = true; + } + } + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + self::initialize_static_variables(); + + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; + + $key = parent::load($key, $password); + + $type = isset($key['privateKey']) ? 'private' : 'public'; + + $result = $components + PKCS1::load($key[$type . 'Key']); + + if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { + $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); + if ($decoded === false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); + } else { + $params = []; + } + + if (isset($params['maskGenAlgorithm']['parameters'])) { + $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); + if ($decoded === false) { + throw new \UnexpectedValueException('Unable to decode parameters'); + } + $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); + } else { + $params['maskGenAlgorithm'] = [ + 'algorithm' => 'id-mgf1', + 'parameters' => ['algorithm' => 'id-sha1'] + ]; + } + + if (!isset($params['hashAlgorithm']['algorithm'])) { + $params['hashAlgorithm']['algorithm'] = 'id-sha1'; + } + + $result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']); + $result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); + if (isset($params['saltLength'])) { + $result['saltLength'] = (int) $params['saltLength']->toString(); + } + + if (isset($key['meta'])) { + $result['meta'] = $key['meta']; + } + + return $result; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + self::initialize_static_variables(); + + $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); + $key = ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param array $options optional + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) + { + self::initialize_static_variables(); + + $key = PKCS1::savePublicKey($n, $e); + $key = ASN1::extractBER($key); + $params = self::savePSSParams($options); + return self::wrapPublicKey($key, $params); + } + + /** + * Encodes PSS parameters + * + * @param array $options + * @return string + */ + public static function savePSSParams(array $options) + { + /* + The trailerField field is an integer. It provides + compatibility with IEEE Std 1363a-2004 [P1363A]. The value + MUST be 1, which represents the trailer field with hexadecimal + value 0xBC. Other trailer fields, including the trailer field + composed of HashID concatenated with 0xCC that is specified in + IEEE Std 1363a, are not supported. Implementations that + perform signature generation MUST omit the trailerField field, + indicating that the default trailer field value was used. + Implementations that perform signature validation MUST + recognize both a present trailerField field with value 1 and an + absent trailerField field. + + source: https://tools.ietf.org/html/rfc4055#page-9 + */ + $params = [ + 'trailerField' => new BigInteger(1) + ]; + if (isset($options['hash'])) { + $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; + } + if (isset($options['MGFHash'])) { + $temp = ['algorithm' => 'id-' . $options['MGFHash']]; + $temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP); + $params['maskGenAlgorithm'] = [ + 'algorithm' => 'id-mgf1', + 'parameters' => new ASN1\Element($temp) + ]; + } + if (isset($options['saltLength'])) { + $params['saltLength'] = new BigInteger($options['saltLength']); + } + + return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php new file mode 100644 index 0000000..fe35717 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php @@ -0,0 +1,121 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; +use phpseclib3\Math\BigInteger; + +/** + * PuTTY Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class PuTTY extends Progenitor +{ + /** + * Public Handler + * + * @var string + */ + const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH'; + + /** + * Algorithm Identifier + * + * @var array + */ + protected static $types = ['ssh-rsa']; + + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + $components = parent::load($key, $password); + if (!isset($components['private'])) { + return $components; + } + extract($components); + unset($components['public'], $components['private']); + + $isPublicKey = false; + + $result = Strings::unpackSSH2('ii', $public); + if ($result === false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + list($publicExponent, $modulus) = $result; + + $result = Strings::unpackSSH2('iiii', $private); + if ($result === false) { + throw new \UnexpectedValueException('Key appears to be malformed'); + } + $primes = $coefficients = []; + list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; + + $temp = $primes[1]->subtract($one); + $exponents = [1 => $publicExponent->modInverse($temp)]; + $temp = $primes[2]->subtract($one); + $exponents[] = $publicExponent->modInverse($temp); + + return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); + } + + $public = Strings::packSSH2('ii', $e, $n); + $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); + + return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php new file mode 100644 index 0000000..db72878 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php @@ -0,0 +1,184 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class Raw +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!is_array($key)) { + throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); + } + + $key = array_change_key_case($key, CASE_LOWER); + + $components = ['isPublicKey' => false]; + + foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) { + if (isset($key[$index])) { + $components['publicExponent'] = $key[$index]; + break; + } + } + + foreach (['n', 'modulo', 'modulus', 1] as $index) { + if (isset($key[$index])) { + $components['modulus'] = $key[$index]; + break; + } + } + + if (!isset($components['publicExponent']) || !isset($components['modulus'])) { + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + + if (isset($key['primes'])) { + $components['primes'] = $key['primes']; + } elseif (isset($key['p']) && isset($key['q'])) { + $indices = [ + ['p', 'q'], + ['prime1', 'prime2'] + ]; + foreach ($indices as $index) { + list($i0, $i1) = $index; + if (isset($key[$i0]) && isset($key[$i1])) { + $components['primes'] = [1 => $key[$i0], $key[$i1]]; + } + } + } + + if (isset($key['exponents'])) { + $components['exponents'] = $key['exponents']; + } else { + $indices = [ + ['dp', 'dq'], + ['exponent1', 'exponent2'] + ]; + foreach ($indices as $index) { + list($i0, $i1) = $index; + if (isset($key[$i0]) && isset($key[$i1])) { + $components['exponents'] = [1 => $key[$i0], $key[$i1]]; + } + } + } + + if (isset($key['coefficients'])) { + $components['coefficients'] = $key['coefficients']; + } else { + foreach (['inverseq', 'q\'', 'coefficient'] as $index) { + if (isset($key[$index])) { + $components['coefficients'] = [2 => $key[$index]]; + } + } + } + + if (!isset($components['primes'])) { + $components['isPublicKey'] = true; + return $components; + } + + if (!isset($components['exponents'])) { + $one = new BigInteger(1); + $temp = $components['primes'][1]->subtract($one); + $exponents = [1 => $components['publicExponent']->modInverse($temp)]; + $temp = $components['primes'][2]->subtract($one); + $exponents[] = $components['publicExponent']->modInverse($temp); + $components['exponents'] = $exponents; + } + + if (!isset($components['coefficients'])) { + $components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])]; + } + + foreach (['privateexponent', 'd'] as $index) { + if (isset($key[$index])) { + $components['privateExponent'] = $key[$index]; + break; + } + } + + return $components; + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @param array $options optional + * @return array + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) + { + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('Raw private keys do not support encryption'); + } + + return [ + 'e' => clone $e, + 'n' => clone $n, + 'd' => clone $d, + 'primes' => array_map(function ($var) { + return clone $var; + }, $primes), + 'exponents' => array_map(function ($var) { + return clone $var; + }, $exponents), + 'coefficients' => array_map(function ($var) { + return clone $var; + }, $coefficients) + ]; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return array + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return ['e' => clone $e, 'n' => clone $n]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php new file mode 100644 index 0000000..280048c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php @@ -0,0 +1,171 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA\Formats\Keys; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * XML Formatted RSA Key Handler + * + * @author Jim Wigginton + */ +abstract class XML +{ + /** + * Break a public or private key down into its constituent components + * + * @param string $key + * @param string $password optional + * @return array + */ + public static function load($key, $password = '') + { + if (!Strings::is_stringable($key)) { + throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); + } + + if (!class_exists('DOMDocument')) { + throw new BadConfigurationException('The dom extension is not setup correctly on this system'); + } + + $components = [ + 'isPublicKey' => false, + 'primes' => [], + 'exponents' => [], + 'coefficients' => [] + ]; + + $use_errors = libxml_use_internal_errors(true); + + $dom = new \DOMDocument(); + if (substr($key, 0, 5) != '' . $key . ''; + } + if (!$dom->loadXML($key)) { + libxml_use_internal_errors($use_errors); + throw new \UnexpectedValueException('Key does not appear to contain XML'); + } + $xpath = new \DOMXPath($dom); + $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; + foreach ($keys as $key) { + // $dom->getElementsByTagName($key) is case-sensitive + $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); + if (!$temp->length) { + continue; + } + $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); + switch ($key) { + case 'modulus': + $components['modulus'] = $value; + break; + case 'exponent': + $components['publicExponent'] = $value; + break; + case 'p': + $components['primes'][1] = $value; + break; + case 'q': + $components['primes'][2] = $value; + break; + case 'dp': + $components['exponents'][1] = $value; + break; + case 'dq': + $components['exponents'][2] = $value; + break; + case 'inverseq': + $components['coefficients'][2] = $value; + break; + case 'd': + $components['privateExponent'] = $value; + } + } + + libxml_use_internal_errors($use_errors); + + foreach ($components as $key => $value) { + if (is_array($value) && !count($value)) { + unset($components[$key]); + } + } + + if (isset($components['modulus']) && isset($components['publicExponent'])) { + if (count($components) == 3) { + $components['isPublicKey'] = true; + } + return $components; + } + + throw new \UnexpectedValueException('Modulus / exponent not present'); + } + + /** + * Convert a private key to the appropriate format. + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @param \phpseclib3\Math\BigInteger $d + * @param array $primes + * @param array $exponents + * @param array $coefficients + * @param string $password optional + * @return string + */ + public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') + { + if (count($primes) != 2) { + throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); + } + + if (!empty($password) && is_string($password)) { + throw new UnsupportedFormatException('XML private keys do not support encryption'); + } + + return "\r\n" . + ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . + '

          ' . Strings::base64_encode($primes[1]->toBytes()) . "

          \r\n" . + ' ' . Strings::base64_encode($primes[2]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($exponents[1]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($exponents[2]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($coefficients[2]->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($d->toBytes()) . "\r\n" . + '
          '; + } + + /** + * Convert a public key to the appropriate format + * + * @param \phpseclib3\Math\BigInteger $n + * @param \phpseclib3\Math\BigInteger $e + * @return string + */ + public static function savePublicKey(BigInteger $n, BigInteger $e) + { + return "\r\n" . + ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . + ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . + ''; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php new file mode 100644 index 0000000..37dd09a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php @@ -0,0 +1,530 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA; + +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +final class PrivateKey extends RSA implements Common\PrivateKey +{ + use Common\Traits\PasswordProtected; + + /** + * Primes for Chinese Remainder Theorem (ie. p and q) + * + * @var array + */ + protected $primes; + + /** + * Exponents for Chinese Remainder Theorem (ie. dP and dQ) + * + * @var array + */ + protected $exponents; + + /** + * Coefficients for Chinese Remainder Theorem (ie. qInv) + * + * @var array + */ + protected $coefficients; + + /** + * Private Exponent + * + * @var \phpseclib3\Math\BigInteger + */ + protected $privateExponent; + + /** + * RSADP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. + * + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsadp(BigInteger $c) + { + if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Ciphertext representative out of range'); + } + return $this->exponentiate($c); + } + + /** + * RSASP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. + * + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsasp1(BigInteger $m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Signature representative out of range'); + } + return $this->exponentiate($m); + } + + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + protected function exponentiate(BigInteger $x) + { + switch (true) { + case empty($this->primes): + case $this->primes[1]->equals(self::$zero): + case empty($this->coefficients): + case $this->coefficients[2]->equals(self::$zero): + case empty($this->exponents): + case $this->exponents[1]->equals(self::$zero): + return $x->modPow($this->exponent, $this->modulus); + } + + $num_primes = count($this->primes); + + if (!static::$enableBlinding) { + $m_i = [ + 1 => $x->modPow($this->exponents[1], $this->primes[1]), + 2 => $x->modPow($this->exponents[2], $this->primes[2]) + ]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } else { + $smallest = $this->primes[1]; + for ($i = 2; $i <= $num_primes; $i++) { + if ($smallest->compare($this->primes[$i]) > 0) { + $smallest = $this->primes[$i]; + } + } + + $r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); + + $m_i = [ + 1 => $this->blind($x, $r, 1), + 2 => $this->blind($x, $r, 2) + ]; + $h = $m_i[1]->subtract($m_i[2]); + $h = $h->multiply($this->coefficients[2]); + list(, $h) = $h->divide($this->primes[1]); + $m = $m_i[2]->add($h->multiply($this->primes[2])); + + $r = $this->primes[1]; + for ($i = 3; $i <= $num_primes; $i++) { + $m_i = $this->blind($x, $r, $i); + + $r = $r->multiply($this->primes[$i - 1]); + + $h = $m_i->subtract($m); + $h = $h->multiply($this->coefficients[$i]); + list(, $h) = $h->divide($this->primes[$i]); + + $m = $m->add($r->multiply($h)); + } + } + + return $m; + } + + /** + * Performs RSA Blinding + * + * Protects against timing attacks by employing RSA Blinding. + * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) + * + * @param \phpseclib3\Math\BigInteger $x + * @param \phpseclib3\Math\BigInteger $r + * @param int $i + * @return \phpseclib3\Math\BigInteger + */ + private function blind(BigInteger $x, BigInteger $r, $i) + { + $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); + $x = $x->modPow($this->exponents[$i], $this->primes[$i]); + + $r = $r->modInverse($this->primes[$i]); + $x = $x->multiply($r); + list(, $x) = $x->divide($this->primes[$i]); + + return $x; + } + + /** + * EMSA-PSS-ENCODE + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. + * + * @return string + * @param string $m + * @throws \RuntimeException on encoding error + * @param int $emBits + */ + private function emsa_pss_encode($m, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + throw new \LengthException('RSA modulus too short'); + } + + $salt = Random::string($sLen); + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h = $this->hash->hash($m2); + $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); + $db = $ps . chr(1) . $salt; + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); // ie. stlren($db) + $maskedDB = $db ^ $dbMask; + $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; + $em = $maskedDB . $h . chr(0xBC); + + return $em; + } + + /** + * RSASSA-PSS-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. + * + * @param string $m + * @return bool|string + */ + private function rsassa_pss_sign($m) + { + // EMSA-PSS encoding + + $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); + + // RSA signature + + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + + // Output the signature S + + return $s; + } + + /** + * RSASSA-PKCS1-V1_5-SIGN + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. + * + * @param string $m + * @throws \LengthException if the RSA modulus is too short + * @return bool|string + */ + private function rsassa_pkcs1_v1_5_sign($m) + { + // EMSA-PKCS1-v1_5 encoding + + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + } catch (\LengthException $e) { + throw new \LengthException('RSA modulus too short'); + } + + // RSA signature + + $m = $this->os2ip($em); + $s = $this->rsasp1($m); + $s = $this->i2osp($s, $this->k); + + // Output the signature S + + return $s; + } + + /** + * Create a signature + * + * @see self::verify() + * @param string $message + * @return string + */ + public function sign($message) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_PKCS1: + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_sign($message); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_sign($message); + } + } + + /** + * RSAES-PKCS1-V1_5-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. + * + * @param string $c + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_decrypt($c) + { + // Length checking + + if (strlen($c) != $this->k) { // or if k < 11 + throw new \LengthException('Ciphertext representative too long'); + } + + // RSA decryption + + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + + // EME-PKCS1-v1_5 decoding + + if (ord($em[0]) != 0 || ord($em[1]) > 2) { + throw new \RuntimeException('Decryption error'); + } + + $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); + $m = substr($em, strlen($ps) + 3); + + if (strlen($ps) < 8) { + throw new \RuntimeException('Decryption error'); + } + + // Output M + + return $m; + } + + /** + * RSAES-OAEP-DECRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error + * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: + * + * Note. Care must be taken to ensure that an opponent cannot + * distinguish the different error conditions in Step 3.g, whether by + * error message or timing, or, more generally, learn partial + * information about the encoded message EM. Otherwise an opponent may + * be able to obtain useful information about the decryption of the + * ciphertext C, leading to a chosen-ciphertext attack such as the one + * observed by Manger [36]. + * + * @param string $c + * @return bool|string + */ + private function rsaes_oaep_decrypt($c) + { + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { + throw new \LengthException('Ciphertext representative too long'); + } + + // RSA decryption + + $c = $this->os2ip($c); + $m = $this->rsadp($c); + $em = $this->i2osp($m, $this->k); + + // EME-OAEP decoding + + $lHash = $this->hash->hash($this->label); + $y = ord($em[0]); + $maskedSeed = substr($em, 1, $this->hLen); + $maskedDB = substr($em, $this->hLen + 1); + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $seed = $maskedSeed ^ $seedMask; + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $lHash2 = substr($db, 0, $this->hLen); + $m = substr($db, $this->hLen); + $hashesMatch = hash_equals($lHash, $lHash2); + $leadingZeros = 1; + $patternMatch = 0; + $offset = 0; + for ($i = 0; $i < strlen($m); $i++) { + $patternMatch |= $leadingZeros & ($m[$i] === "\1"); + $leadingZeros &= $m[$i] === "\0"; + $offset += $patternMatch ? 0 : 1; + } + + // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation + // to protect against timing attacks + if (!$hashesMatch | !$patternMatch) { + throw new \RuntimeException('Decryption error'); + } + + // Output the message M + + return substr($m, $offset + 1); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (strlen($m) > $this->k) { + throw new \LengthException('Ciphertext representative too long'); + } + + $temp = $this->os2ip($m); + $temp = $this->rsadp($temp); + return $this->i2osp($temp, $this->k); + } + + /** + * Decryption + * + * @see self::encrypt() + * @param string $ciphertext + * @return bool|string + */ + public function decrypt($ciphertext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($ciphertext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_decrypt($ciphertext); + } + } + + /** + * Returns the public key + * + * @return mixed + */ + public function getPublicKey() + { + $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); + if (empty($this->modulus) || empty($this->publicExponent)) { + throw new \RuntimeException('Public key components not found'); + } + + $key = $type::savePublicKey($this->modulus, $this->publicExponent); + return RSA::loadFormat('PKCS8', $key) + ->withHash($this->hash->getHash()) + ->withMGFHash($this->mgfHash->getHash()) + ->withSaltLength($this->sLen) + ->withLabel($this->label) + ->withPadding($this->signaturePadding | $this->encryptionPadding); + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin( + 'Keys', + $type, + empty($this->primes) ? 'savePublicKey' : 'savePrivateKey' + ); + + if ($type == PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options += [ + 'hash' => $this->hash->getHash(), + 'MGFHash' => $this->mgfHash->getHash(), + 'saltLength' => $this->getSaltLength() + ]; + } else { + throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + + if (empty($this->primes)) { + return $type::savePublicKey($this->modulus, $this->exponent, $options); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + + /* + $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); + if ($key !== false || count($this->primes) == 2) { + return $key; + } + + $nSize = $this->getSize() >> 1; + + $primes = [1 => clone self::$one, clone self::$one]; + $i = 1; + foreach ($this->primes as $prime) { + $primes[$i] = $primes[$i]->multiply($prime); + if ($primes[$i]->getLength() >= $nSize) { + $i++; + } + } + + $exponents = []; + $coefficients = [2 => $primes[2]->modInverse($primes[1])]; + + foreach ($primes as $i => $prime) { + $temp = $prime->subtract(self::$one); + $exponents[$i] = $this->modulus->modInverse($temp); + } + + return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); + */ + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php new file mode 100644 index 0000000..58939a9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php @@ -0,0 +1,513 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt\RSA; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedFormatException; +use phpseclib3\File\ASN1; +use phpseclib3\File\ASN1\Maps\DigestInfo; +use phpseclib3\Math\BigInteger; + +/** + * Raw RSA Key Handler + * + * @author Jim Wigginton + */ +final class PublicKey extends RSA implements Common\PublicKey +{ + use Common\Traits\Fingerprint; + + /** + * Exponentiate + * + * @param \phpseclib3\Math\BigInteger $x + * @return \phpseclib3\Math\BigInteger + */ + private function exponentiate(BigInteger $x) + { + return $x->modPow($this->exponent, $this->modulus); + } + + /** + * RSAVP1 + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. + * + * @param \phpseclib3\Math\BigInteger $s + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsavp1($s) + { + if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { + return false; + } + return $this->exponentiate($s); + } + + /** + * RSASSA-PKCS1-V1_5-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. + * + * @param string $m + * @param string $s + * @throws \LengthException if the RSA modulus is too short + * @return bool + */ + private function rsassa_pkcs1_v1_5_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === false) { + return false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + // EMSA-PKCS1-v1_5 encoding + + $exception = false; + + // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus + // too short" and stop. + try { + $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); + $r1 = hash_equals($em, $em2); + } catch (\LengthException $e) { + $exception = true; + } + + try { + $em3 = $this->emsa_pkcs1_v1_5_encode_without_null($m, $this->k); + $r2 = hash_equals($em, $em3); + } catch (\LengthException $e) { + $exception = true; + } catch (UnsupportedAlgorithmException $e) { + $r2 = false; + } + + if ($exception) { + throw new \LengthException('RSA modulus too short'); + } + + // Compare + return $r1 || $r2; + } + + /** + * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) + * + * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 + * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. + * This means that under rare conditions you can have a perfectly valid v1.5 signature + * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends + * that if you're going to validate these types of signatures you "should indicate + * whether the underlying BER encoding is a DER encoding and hence whether the signature + * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do + * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of + * RSA::PADDING_PKCS1... that means BER encoding was used. + * + * @param string $m + * @param string $s + * @return bool + */ + private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $s = $this->os2ip($s); + $m2 = $this->rsavp1($s); + if ($m2 === false) { + return false; + } + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + if (Strings::shift($em, 2) != "\0\1") { + return false; + } + + $em = ltrim($em, "\xFF"); + if (Strings::shift($em) != "\0") { + return false; + } + + $decoded = ASN1::decodeBER($em); + if (!is_array($decoded) || empty($decoded[0]) || strlen($em) > $decoded[0]['length']) { + return false; + } + + static $oids; + if (!isset($oids)) { + $oids = [ + 'md2' => '1.2.840.113549.2.2', + 'md4' => '1.2.840.113549.2.4', // from PKCS1 v1.5 + 'md5' => '1.2.840.113549.2.5', + 'id-sha1' => '1.3.14.3.2.26', + 'id-sha256' => '2.16.840.1.101.3.4.2.1', + 'id-sha384' => '2.16.840.1.101.3.4.2.2', + 'id-sha512' => '2.16.840.1.101.3.4.2.3', + // from PKCS1 v2.2 + 'id-sha224' => '2.16.840.1.101.3.4.2.4', + 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', + 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', + ]; + ASN1::loadOIDs($oids); + } + + $decoded = ASN1::asn1map($decoded[0], DigestInfo::MAP); + if (!isset($decoded) || $decoded === false) { + return false; + } + + if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { + return false; + } + + if (isset($decoded['digestAlgorithm']['parameters']) && $decoded['digestAlgorithm']['parameters'] !== ['null' => '']) { + return false; + } + + $hash = $decoded['digestAlgorithm']['algorithm']; + $hash = substr($hash, 0, 3) == 'id-' ? + substr($hash, 3) : + $hash; + $hash = new Hash($hash); + $em = $hash->hash($m); + $em2 = $decoded['digest']; + + return hash_equals($em, $em2); + } + + /** + * EMSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. + * + * @param string $m + * @param string $em + * @param int $emBits + * @return string + */ + private function emsa_pss_verify($m, $em, $emBits) + { + // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); + $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; + + $mHash = $this->hash->hash($m); + if ($emLen < $this->hLen + $sLen + 2) { + return false; + } + + if ($em[strlen($em) - 1] != chr(0xBC)) { + return false; + } + + $maskedDB = substr($em, 0, -$this->hLen - 1); + $h = substr($em, -$this->hLen - 1, $this->hLen); + $temp = chr(0xFF << ($emBits & 7)); + if ((~$maskedDB[0] & $temp) != $temp) { + return false; + } + $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); + $db = $maskedDB ^ $dbMask; + $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; + $temp = $emLen - $this->hLen - $sLen - 2; + if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { + return false; + } + $salt = substr($db, $temp + 1); // should be $sLen long + $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; + $h2 = $this->hash->hash($m2); + return hash_equals($h, $h2); + } + + /** + * RSASSA-PSS-VERIFY + * + * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. + * + * @param string $m + * @param string $s + * @return bool|string + */ + private function rsassa_pss_verify($m, $s) + { + // Length checking + + if (strlen($s) != $this->k) { + return false; + } + + // RSA verification + + $modBits = strlen($this->modulus->toBits()); + + $s2 = $this->os2ip($s); + $m2 = $this->rsavp1($s2); + $em = $this->i2osp($m2, $this->k); + if ($em === false) { + return false; + } + + // EMSA-PSS verification + + return $this->emsa_pss_verify($m, $em, $modBits - 1); + } + + /** + * Verifies a signature + * + * @see self::sign() + * @param string $message + * @param string $signature + * @return bool + */ + public function verify($message, $signature) + { + switch ($this->signaturePadding) { + case self::SIGNATURE_RELAXED_PKCS1: + return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); + case self::SIGNATURE_PKCS1: + return $this->rsassa_pkcs1_v1_5_verify($message, $signature); + //case self::SIGNATURE_PSS: + default: + return $this->rsassa_pss_verify($message, $signature); + } + } + + /** + * RSAES-PKCS1-V1_5-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. + * + * @param string $m + * @param bool $pkcs15_compat optional + * @throws \LengthException if strlen($m) > $this->k - 11 + * @return bool|string + */ + private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = false) + { + $mLen = strlen($m); + + // Length checking + + if ($mLen > $this->k - 11) { + throw new \LengthException('Message too long'); + } + + // EME-PKCS1-v1_5 encoding + + $psLen = $this->k - $mLen - 3; + $ps = ''; + while (strlen($ps) != $psLen) { + $temp = Random::string($psLen - strlen($ps)); + $temp = str_replace("\x00", '', $temp); + $ps .= $temp; + } + $type = 2; + $em = chr(0) . chr($type) . $ps . chr(0) . $m; + + // RSA encryption + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAES-OAEP-ENCRYPT + * + * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and + * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. + * + * @param string $m + * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 + * @return string + */ + private function rsaes_oaep_encrypt($m) + { + $mLen = strlen($m); + + // Length checking + + // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error + // be output. + + if ($mLen > $this->k - 2 * $this->hLen - 2) { + throw new \LengthException('Message too long'); + } + + // EME-OAEP encoding + + $lHash = $this->hash->hash($this->label); + $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); + $db = $lHash . $ps . chr(1) . $m; + $seed = Random::string($this->hLen); + $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); + $maskedDB = $db ^ $dbMask; + $seedMask = $this->mgf1($maskedDB, $this->hLen); + $maskedSeed = $seed ^ $seedMask; + $em = chr(0) . $maskedSeed . $maskedDB; + + // RSA encryption + + $m = $this->os2ip($em); + $c = $this->rsaep($m); + $c = $this->i2osp($c, $this->k); + + // Output the ciphertext C + + return $c; + } + + /** + * RSAEP + * + * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. + * + * @param \phpseclib3\Math\BigInteger $m + * @return bool|\phpseclib3\Math\BigInteger + */ + private function rsaep($m) + { + if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { + throw new \OutOfRangeException('Message representative out of range'); + } + return $this->exponentiate($m); + } + + /** + * Raw Encryption / Decryption + * + * Doesn't use padding and is not recommended. + * + * @param string $m + * @return bool|string + * @throws \LengthException if strlen($m) > $this->k + */ + private function raw_encrypt($m) + { + if (strlen($m) > $this->k) { + throw new \LengthException('Message too long'); + } + + $temp = $this->os2ip($m); + $temp = $this->rsaep($temp); + return $this->i2osp($temp, $this->k); + } + + /** + * Encryption + * + * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. + * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will + * be concatenated together. + * + * @see self::decrypt() + * @param string $plaintext + * @return bool|string + * @throws \LengthException if the RSA modulus is too short + */ + public function encrypt($plaintext) + { + switch ($this->encryptionPadding) { + case self::ENCRYPTION_NONE: + return $this->raw_encrypt($plaintext); + case self::ENCRYPTION_PKCS1: + return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); + //case self::ENCRYPTION_OAEP: + default: + return $this->rsaes_oaep_encrypt($plaintext); + } + } + + /** + * Returns the public key + * + * The public key is only returned under two circumstances - if the private key had the public key embedded within it + * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this + * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. + * + * @param string $type + * @param array $options optional + * @return mixed + */ + public function toString($type, array $options = []) + { + $type = self::validatePlugin('Keys', $type, 'savePublicKey'); + + if ($type == PSS::class) { + if ($this->signaturePadding == self::SIGNATURE_PSS) { + $options += [ + 'hash' => $this->hash->getHash(), + 'MGFHash' => $this->mgfHash->getHash(), + 'saltLength' => $this->getSaltLength() + ]; + } else { + throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); + } + } + + return $type::savePublicKey($this->modulus, $this->publicExponent, $options); + } + + /** + * Converts a public key to a private key + * + * @return RSA + */ + public function asPrivateKey() + { + $new = new PrivateKey(); + $new->exponent = $this->exponent; + $new->modulus = $this->modulus; + $new->k = $this->k; + $new->format = $this->format; + return $new + ->withHash($this->hash->getHash()) + ->withMGFHash($this->mgfHash->getHash()) + ->withSaltLength($this->sLen) + ->withLabel($this->label) + ->withPadding($this->signaturePadding | $this->encryptionPadding); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php new file mode 100644 index 0000000..f813a2e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php @@ -0,0 +1,222 @@ + + * + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +/** + * Pure-PHP Random Number Generator + * + * @author Jim Wigginton + */ +abstract class Random +{ + /** + * Generate a random string. + * + * Although microoptimizations are generally discouraged as they impair readability this function is ripe with + * microoptimizations because this function has the potential of being called a huge number of times. + * eg. for RSA key generation. + * + * @param int $length + * @throws \RuntimeException if a symmetric cipher is needed but not loaded + * @return string + */ + public static function string($length) + { + if (!$length) { + return ''; + } + + try { + return random_bytes($length); + } catch (\Exception $e) { + // random_compat will throw an Exception, which in PHP 5 does not implement Throwable + } catch (\Throwable $e) { + // If a sufficient source of randomness is unavailable, random_bytes() will throw an + // object that implements the Throwable interface (Exception, TypeError, Error). + // We don't actually need to do anything here. The string() method should just continue + // as normal. Note, however, that if we don't have a sufficient source of randomness for + // random_bytes(), most of the other calls here will fail too, so we'll end up using + // the PHP implementation. + } + // at this point we have no choice but to use a pure-PHP CSPRNG + + // cascade entropy across multiple PHP instances by fixing the session and collecting all + // environmental variables, including the previous session data and the current session + // data. + // + // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively) + // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but + // PHP isn't low level to be able to use those as sources and on a web server there's not likely + // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use + // however, a ton of people visiting the website. obviously you don't want to base your seeding + // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled + // by the user and (2) this isn't just looking at the data sent by the current user - it's based + // on the data sent by all users. one user requests the page and a hash of their info is saved. + // another user visits the page and the serialization of their data is utilized along with the + // server environment stuff and a hash of the previous http request data (which itself utilizes + // a hash of the session data before that). certainly an attacker should be assumed to have + // full control over his own http requests. he, however, is not going to have control over + // everyone's http requests. + static $crypto = false, $v; + if ($crypto === false) { + // save old session data + $old_session_id = session_id(); + $old_use_cookies = ini_get('session.use_cookies'); + $old_session_cache_limiter = session_cache_limiter(); + $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false; + if ($old_session_id != '') { + session_write_close(); + } + + session_id(1); + ini_set('session.use_cookies', 0); + session_cache_limiter(''); + session_start(); + + $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . + (isset($_POST) ? self::safe_serialize($_POST) : '') . + (isset($_GET) ? self::safe_serialize($_GET) : '') . + (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . + // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates + // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage + // for more info + (version_compare(PHP_VERSION, '8.1.0', '>=') ? serialize($GLOBALS) : self::safe_serialize($GLOBALS)) . + self::safe_serialize($_SESSION) . + self::safe_serialize($_OLD_SESSION); + $v = $seed = $_SESSION['seed'] = sha1($v, true); + if (!isset($_SESSION['count'])) { + $_SESSION['count'] = 0; + } + $_SESSION['count']++; + + session_write_close(); + + // restore old session data + if ($old_session_id != '') { + session_id($old_session_id); + session_start(); + ini_set('session.use_cookies', $old_use_cookies); + session_cache_limiter($old_session_cache_limiter); + } else { + if ($_OLD_SESSION !== false) { + $_SESSION = $_OLD_SESSION; + unset($_OLD_SESSION); + } else { + unset($_SESSION); + } + } + + // in SSH2 a shared secret and an exchange hash are generated through the key exchange process. + // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C. + // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the + // original hash and the current hash. we'll be emulating that. for more info see the following URL: + // + // http://tools.ietf.org/html/rfc4253#section-7.2 + // + // see the is_string($crypto) part for an example of how to expand the keys + $key = sha1($seed . 'A', true); + $iv = sha1($seed . 'C', true); + + // ciphers are used as per the nist.gov link below. also, see this link: + // + // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives + switch (true) { + case class_exists('\phpseclib3\Crypt\AES'): + $crypto = new AES('ctr'); + break; + case class_exists('\phpseclib3\Crypt\Twofish'): + $crypto = new Twofish('ctr'); + break; + case class_exists('\phpseclib3\Crypt\Blowfish'): + $crypto = new Blowfish('ctr'); + break; + case class_exists('\phpseclib3\Crypt\TripleDES'): + $crypto = new TripleDES('ctr'); + break; + case class_exists('\phpseclib3\Crypt\DES'): + $crypto = new DES('ctr'); + break; + case class_exists('\phpseclib3\Crypt\RC4'): + $crypto = new RC4(); + break; + default: + throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); + } + + $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); + $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3)); + $crypto->enableContinuousBuffer(); + } + + //return $crypto->encrypt(str_repeat("\0", $length)); + + // the following is based off of ANSI X9.31: + // + // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf + // + // OpenSSL uses that same standard for it's random numbers: + // + // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c + // (do a search for "ANS X9.31 A.2.4") + $result = ''; + while (strlen($result) < $length) { + $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21 + $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20 + $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20 + $result .= $r; + } + + return substr($result, 0, $length); + } + + /** + * Safely serialize variables + * + * If a class has a private __sleep() it'll emit a warning + * @return mixed + * @param mixed $arr + */ + private static function safe_serialize(&$arr) + { + if (is_object($arr)) { + return ''; + } + if (!is_array($arr)) { + return serialize($arr); + } + // prevent circular array recursion + if (isset($arr['__phpseclib_marker'])) { + return ''; + } + $safearr = []; + $arr['__phpseclib_marker'] = true; + foreach (array_keys($arr) as $key) { + // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage + if ($key !== '__phpseclib_marker') { + $safearr[$key] = self::safe_serialize($arr[$key]); + } + } + unset($arr['__phpseclib_marker']); + return serialize($safearr); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php new file mode 100644 index 0000000..ff31f9c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php @@ -0,0 +1,1036 @@ + + * setKey('abcdefghijklmnop'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2008 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\BadModeException; +use phpseclib3\Exception\InconsistentSetupException; +use phpseclib3\Exception\InsufficientSetupException; + +/** + * Pure-PHP implementation of Rijndael. + * + * @author Jim Wigginton + */ +class Rijndael extends BlockCipher +{ + /** + * The mcrypt specific name of the cipher + * + * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. + * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable + * or not for the current $block_size/$key_length. + * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::engine + * @see self::isValidEngine() + * @var string + */ + protected $cipher_name_mcrypt = 'rijndael-128'; + + /** + * The Key Schedule + * + * @see self::setup() + * @var array + */ + private $w; + + /** + * The Inverse Key Schedule + * + * @see self::setup() + * @var array + */ + private $dw; + + /** + * The Block Length divided by 32 + * + * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size + * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could + * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see self::setBlockLength() + * @var int + */ + private $Nb = 4; + + /** + * The Key Length (in bytes) + * + * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk + * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could + * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu + * of that, we'll just precompute it once.} + * + * @see self::setKeyLength() + * @var int + */ + protected $key_length = 16; + + /** + * The Key Length divided by 32 + * + * @see self::setKeyLength() + * @var int + * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 + */ + private $Nk = 4; + + /** + * The Number of Rounds + * + * {@internal The max value is 14, the min value is 10.} + * + * @var int + */ + private $Nr; + + /** + * Shift offsets + * + * @var array + */ + private $c; + + /** + * Holds the last used key- and block_size information + * + * @var array + */ + private $kl; + + /** + * Default Constructor. + * + * @param string $mode + * @throws \InvalidArgumentException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Sets the key length. + * + * Valid key lengths are 128, 160, 192, 224, and 256. + * + * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined + * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to + * 192/256 bits as, for example, mcrypt will do. + * + * That said, if you want be compatible with other Rijndael and AES implementations, + * you should not setKeyLength(160) or setKeyLength(224). + * + * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use + * the mcrypt php extension, even if available. + * This results then in slower encryption. + * + * @throws \LengthException if the key length is invalid + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + $this->key_length = $length >> 3; + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); + } + + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 20: + case 24: + case 28: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); + } + + parent::setKey($key); + } + + /** + * Sets the block length + * + * Valid block lengths are 128, 160, 192, 224, and 256. + * + * @param int $length + */ + public function setBlockLength($length) + { + switch ($length) { + case 128: + case 160: + case 192: + case 224: + case 256: + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); + } + + $this->Nb = $length >> 5; + $this->block_size = $length >> 3; + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + switch ($engine) { + case self::ENGINE_LIBSODIUM: + return function_exists('sodium_crypto_aead_aes256gcm_is_available') && + sodium_crypto_aead_aes256gcm_is_available() && + $this->mode == self::MODE_GCM && + $this->key_length == 32 && + $this->nonce && strlen($this->nonce) == 12 && + $this->block_size == 16; + case self::ENGINE_OPENSSL_GCM: + if (!extension_loaded('openssl')) { + return false; + } + $methods = openssl_get_cipher_methods(); + return $this->mode == self::MODE_GCM && + version_compare(PHP_VERSION, '7.1.0', '>=') && + in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && + $this->block_size == 16; + case self::ENGINE_OPENSSL: + if ($this->block_size != 16) { + return false; + } + $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; + $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); + break; + case self::ENGINE_MCRYPT: + $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); + if ($this->key_length % 8) { // is it a 160/224-bit key? + // mcrypt is not usable for them, only for 128/192/256-bit keys + return false; + } + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Encrypts a block + * + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + static $tables; + if (empty($tables)) { + $tables = &$this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + + $state = []; + $words = unpack('N*', $in); + + $c = $this->c; + $w = $this->w; + $Nb = $this->Nb; + $Nr = $this->Nr; + + // addRoundKey + $wc = $Nb - 1; + foreach ($words as $word) { + $state[] = $word ^ $w[++$wc]; + } + + // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - + // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding + // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf. + // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization. + // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1], + // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. + + // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf + $temp = []; + for ($round = 1; $round < $Nr; ++$round) { + $i = 0; // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + + while ($i < $Nb) { + $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^ + $t1[$state[$j] >> 16 & 0x000000FF] ^ + $t2[$state[$k] >> 8 & 0x000000FF] ^ + $t3[$state[$l] & 0x000000FF] ^ + $w[++$wc]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + } + + // subWord + for ($i = 0; $i < $Nb; ++$i) { + $state[$i] = $sbox[$state[$i] & 0x000000FF] | + ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) | + ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) | + ($sbox[$state[$i] >> 24 & 0x000000FF] << 24); + } + + // shiftRows + addRoundKey + $i = 0; // $c[0] == 0 + $j = $c[1]; + $k = $c[2]; + $l = $c[3]; + while ($i < $Nb) { + $temp[$i] = ($state[$i] & intval(0xFF000000)) ^ + ($state[$j] & 0x00FF0000) ^ + ($state[$k] & 0x0000FF00) ^ + ($state[$l] & 0x000000FF) ^ + $w[$i]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + return pack('N*', ...$temp); + } + + /** + * Decrypts a block + * + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + static $invtables; + if (empty($invtables)) { + $invtables = &$this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + + $state = []; + $words = unpack('N*', $in); + + $c = $this->c; + $dw = $this->dw; + $Nb = $this->Nb; + $Nr = $this->Nr; + + // addRoundKey + $wc = $Nb - 1; + foreach ($words as $word) { + $state[] = $word ^ $dw[++$wc]; + } + + $temp = []; + for ($round = $Nr - 1; $round > 0; --$round) { + $i = 0; // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + + while ($i < $Nb) { + $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^ + $dt1[$state[$j] >> 16 & 0x000000FF] ^ + $dt2[$state[$k] >> 8 & 0x000000FF] ^ + $dt3[$state[$l] & 0x000000FF] ^ + $dw[++$wc]; + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + $state = $temp; + } + + // invShiftRows + invSubWord + addRoundKey + $i = 0; // $c[0] == 0 + $j = $Nb - $c[1]; + $k = $Nb - $c[2]; + $l = $Nb - $c[3]; + + while ($i < $Nb) { + $word = ($state[$i] & intval(0xFF000000)) | + ($state[$j] & 0x00FF0000) | + ($state[$k] & 0x0000FF00) | + ($state[$l] & 0x000000FF); + + $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] | + ($isbox[$word >> 8 & 0x000000FF] << 8) | + ($isbox[$word >> 16 & 0x000000FF] << 16) | + ($isbox[$word >> 24 & 0x000000FF] << 24)); + ++$i; + $j = ($j + 1) % $Nb; + $k = ($k + 1) % $Nb; + $l = ($l + 1) % $Nb; + } + + return pack('N*', ...$temp); + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine and flush all $buffers + * Used (only) if $engine == self::ENGINE_INTERNAL + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setIV() + * + * - disableContinuousBuffer() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * {@internal setup() is always called before en/decryption.} + * + * {@internal Could, but not must, extend by the child Crypt_* class} + * + * @see self::setKey() + * @see self::setIV() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + parent::setup(); + + if (is_string($this->iv) && strlen($this->iv) != $this->block_size) { + throw new InconsistentSetupException('The IV length (' . strlen($this->iv) . ') does not match the block size (' . $this->block_size . ')'); + } + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + */ + protected function setupKey() + { + // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. + // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse + static $rcon; + + if (!isset($rcon)) { + $rcon = [0, + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, + 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, + 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, + 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 + ]; + $rcon = array_map('intval', $rcon); + } + + if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; + + $this->Nk = $this->key_length >> 2; + // see Rijndael-ammended.pdf#page=44 + $this->Nr = max($this->Nk, $this->Nb) + 6; + + // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44, + // "Table 8: Shift offsets in Shiftrow for the alternative block lengths" + // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14, + // "Table 2: Shift offsets for different block lengths" + switch ($this->Nb) { + case 4: + case 5: + case 6: + $this->c = [0, 1, 2, 3]; + break; + case 7: + $this->c = [0, 1, 2, 4]; + break; + case 8: + $this->c = [0, 1, 3, 4]; + } + + $w = array_values(unpack('N*words', $this->key)); + + $length = $this->Nb * ($this->Nr + 1); + for ($i = $this->Nk; $i < $length; $i++) { + $temp = $w[$i - 1]; + if ($i % $this->Nk == 0) { + // according to , "the size of an integer is platform-dependent". + // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, + // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' + // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. + $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord + $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; + } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { + $temp = $this->subWord($temp); + } + $w[$i] = $w[$i - $this->Nk] ^ $temp; + } + + // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns + // and generate the inverse key schedule. more specifically, + // according to (section 5.3.3), + // "The key expansion for the Inverse Cipher is defined as follows: + // 1. Apply the Key Expansion. + // 2. Apply InvMixColumn to all Round Keys except the first and the last one." + // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" + list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); + $temp = $this->w = $this->dw = []; + for ($i = $row = $col = 0; $i < $length; $i++, $col++) { + if ($col == $this->Nb) { + if ($row == 0) { + $this->dw[0] = $this->w[0]; + } else { + // subWord + invMixColumn + invSubWord = invMixColumn + $j = 0; + while ($j < $this->Nb) { + $dw = $this->subWord($this->w[$row][$j]); + $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ + $dt1[$dw >> 16 & 0x000000FF] ^ + $dt2[$dw >> 8 & 0x000000FF] ^ + $dt3[$dw & 0x000000FF]; + $j++; + } + $this->dw[$row] = $temp; + } + + $col = 0; + $row++; + } + $this->w[$row][$col] = $w[$i]; + } + + $this->dw[$row] = $this->w[$row]; + + // Converting to 1-dim key arrays (both ascending) + $this->dw = array_reverse($this->dw); + $w = array_pop($this->w); + $dw = array_pop($this->dw); + foreach ($this->w as $r => $wr) { + foreach ($wr as $c => $wc) { + $w[] = $wc; + $dw[] = $this->dw[$r][$c]; + } + } + $this->w = $w; + $this->dw = $dw; + } + + /** + * Performs S-Box substitutions + * + * @return array + * @param int $word + */ + private function subWord($word) + { + static $sbox; + if (empty($sbox)) { + list(, , , , $sbox) = self::getTables(); + } + + return $sbox[$word & 0x000000FF] | + ($sbox[$word >> 8 & 0x000000FF] << 8) | + ($sbox[$word >> 16 & 0x000000FF] << 16) | + ($sbox[$word >> 24 & 0x000000FF] << 24); + } + + /** + * Provides the mixColumns and sboxes tables + * + * @see self::encryptBlock() + * @see self::setupInlineCrypt() + * @see self::subWord() + * @return array &$tables + */ + protected function &getTables() + { + static $tables; + if (empty($tables)) { + // according to (section 5.2.1), + // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so + // those are the names we'll use. + $t3 = array_map('intval', [ + // with array_map('intval', ...) we ensure we have only int's and not + // some slower floats converted by php automatically on high values + 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, + 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, + 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, + 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, + 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, + 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, + 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, + 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, + 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, + 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, + 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, + 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, + 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, + 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, + 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, + 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, + 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, + 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, + 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, + 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, + 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, + 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, + 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, + 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, + 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, + 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, + 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, + 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, + 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, + 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, + 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, + 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C + ]); + + foreach ($t3 as $t3i) { + $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF); + $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF); + $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF); + } + + $tables = [ + // The Precomputed mixColumns tables t0 - t3 + $t0, + $t1, + $t2, + $t3, + // The SubByte S-Box + [ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 + ] + ]; + } + return $tables; + } + + /** + * Provides the inverse mixColumns and inverse sboxes tables + * + * @see self::decryptBlock() + * @see self::setupInlineCrypt() + * @see self::setupKey() + * @return array &$tables + */ + protected function &getInvTables() + { + static $tables; + if (empty($tables)) { + $dt3 = array_map('intval', [ + 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, + 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, + 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, + 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, + 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, + 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, + 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, + 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, + 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, + 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, + 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, + 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, + 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, + 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, + 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, + 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, + 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, + 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, + 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, + 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, + 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, + 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, + 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, + 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, + 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, + 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, + 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, + 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, + 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, + 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, + 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, + 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 + ]); + + foreach ($dt3 as $dt3i) { + $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF); + $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF); + $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF); + }; + + $tables = [ + // The Precomputed inverse mixColumns tables dt0 - dt3 + $dt0, + $dt1, + $dt2, + $dt3, + // The inverse SubByte S-Box + [ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D + ] + ]; + } + return $tables; + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + $w = $this->w; + $dw = $this->dw; + $init_encrypt = ''; + $init_decrypt = ''; + + $Nr = $this->Nr; + $Nb = $this->Nb; + $c = $this->c; + + // Generating encrypt code: + $init_encrypt .= ' + if (empty($tables)) { + $tables = &$this->getTables(); + } + $t0 = $tables[0]; + $t1 = $tables[1]; + $t2 = $tables[2]; + $t3 = $tables[3]; + $sbox = $tables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $encrypt_block = '$in = unpack("N*", $in);' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ";\n"; + } + + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= + '$' . $e . $i . ' = + $t0[($' . $s . $i . ' >> 24) & 0xff] ^ + $t1[($' . $s . (($i + $c[1]) % $Nb) . ' >> 16) & 0xff] ^ + $t2[($' . $s . (($i + $c[2]) % $Nb) . ' >> 8) & 0xff] ^ + $t3[ $' . $s . (($i + $c[3]) % $Nb) . ' & 0xff] ^ + ' . $w[++$wc] . ";\n"; + } + } + + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= + '$' . $e . $i . ' = + $sbox[ $' . $e . $i . ' & 0xff] | + ($sbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | + ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | + ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; + } + $encrypt_block .= '$in = pack("N*"' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $encrypt_block .= ', + ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ + ($' . $e . (($i + $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ + ($' . $e . (($i + $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ + ($' . $e . (($i + $c[3]) % $Nb) . ' & 0x000000FF ) ^ + ' . $w[$i] . "\n"; + } + $encrypt_block .= ');'; + + // Generating decrypt code: + $init_decrypt .= ' + if (empty($invtables)) { + $invtables = &$this->getInvTables(); + } + $dt0 = $invtables[0]; + $dt1 = $invtables[1]; + $dt2 = $invtables[2]; + $dt3 = $invtables[3]; + $isbox = $invtables[4]; + '; + + $s = 'e'; + $e = 's'; + $wc = $Nb - 1; + + // Preround: addRoundKey + $decrypt_block = '$in = unpack("N*", $in);' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n"; + } + + // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey + for ($round = 1; $round < $Nr; ++$round) { + list($s, $e) = [$e, $s]; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= + '$' . $e . $i . ' = + $dt0[($' . $s . $i . ' >> 24) & 0xff] ^ + $dt1[($' . $s . (($Nb + $i - $c[1]) % $Nb) . ' >> 16) & 0xff] ^ + $dt2[($' . $s . (($Nb + $i - $c[2]) % $Nb) . ' >> 8) & 0xff] ^ + $dt3[ $' . $s . (($Nb + $i - $c[3]) % $Nb) . ' & 0xff] ^ + ' . $dw[++$wc] . ";\n"; + } + } + + // Finalround: subWord + shiftRows + addRoundKey + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= + '$' . $e . $i . ' = + $isbox[ $' . $e . $i . ' & 0xff] | + ($isbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | + ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | + ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; + } + $decrypt_block .= '$in = pack("N*"' . "\n"; + for ($i = 0; $i < $Nb; ++$i) { + $decrypt_block .= ', + ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ + ($' . $e . (($Nb + $i - $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ + ($' . $e . (($Nb + $i - $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ + ($' . $e . (($Nb + $i - $c[3]) % $Nb) . ' & 0x000000FF ) ^ + ' . $dw[$i] . "\n"; + } + $decrypt_block .= ');'; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => 'static $tables; static $invtables;', + 'init_encrypt' => $init_encrypt, + 'init_decrypt' => $init_decrypt, + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } + + /** + * Encrypts a message. + * + * @see self::decrypt() + * @see parent::encrypt() + * @param string $plaintext + * @return string + */ + public function encrypt($plaintext) + { + $this->setup(); + + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + $this->newtag = sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); + return Strings::shift($this->newtag, strlen($plaintext)); + case self::ENGINE_OPENSSL_GCM: + return openssl_encrypt( + $plaintext, + 'aes-' . $this->getKeyLength() . '-gcm', + $this->key, + OPENSSL_RAW_DATA, + $this->nonce, + $this->newtag, + $this->aad + ); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * @see self::encrypt() + * @see parent::decrypt() + * @param string $ciphertext + * @return string + */ + public function decrypt($ciphertext) + { + $this->setup(); + + switch ($this->engine) { + case self::ENGINE_LIBSODIUM: + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + if (strlen($this->oldtag) != 16) { + break; + } + $plaintext = sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); + if ($plaintext === false) { + $this->oldtag = false; + throw new BadDecryptionException('Error decrypting ciphertext with libsodium'); + } + return $plaintext; + case self::ENGINE_OPENSSL_GCM: + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + $plaintext = openssl_decrypt( + $ciphertext, + 'aes-' . $this->getKeyLength() . '-gcm', + $this->key, + OPENSSL_RAW_DATA, + $this->nonce, + $this->oldtag, + $this->aad + ); + if ($plaintext === false) { + $this->oldtag = false; + throw new BadDecryptionException('Error decrypting ciphertext with OpenSSL'); + } + return $plaintext; + } + + return parent::decrypt($ciphertext); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php new file mode 100644 index 0000000..0a35f47 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php @@ -0,0 +1,526 @@ + + * @copyright 2019 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\StreamCipher; +use phpseclib3\Exception\BadDecryptionException; +use phpseclib3\Exception\InsufficientSetupException; + +/** + * Pure-PHP implementation of Salsa20. + * + * @author Jim Wigginton + */ +class Salsa20 extends StreamCipher +{ + /** + * Part 1 of the state + * + * @var string|false + */ + protected $p1 = false; + + /** + * Part 2 of the state + * + * @var string|false + */ + protected $p2 = false; + + /** + * Key Length (in bytes) + * + * @var int + */ + protected $key_length = 32; // = 256 bits + + /** + * @see \phpseclib3\Crypt\Salsa20::crypt() + */ + const ENCRYPT = 0; + + /** + * @see \phpseclib3\Crypt\Salsa20::crypt() + */ + const DECRYPT = 1; + + /** + * Encryption buffer for continuous mode + * + * @var array + */ + protected $enbuffer; + + /** + * Decryption buffer for continuous mode + * + * @var array + */ + protected $debuffer; + + /** + * Counter + * + * @var int + */ + protected $counter = 0; + + /** + * Using Generated Poly1305 Key + * + * @var boolean + */ + protected $usingGeneratedPoly1305Key = false; + + /** + * Salsa20 uses a nonce + * + * @return bool + */ + public function usesNonce() + { + return true; + } + + /** + * Sets the key. + * + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); + } + + parent::setKey($key); + } + + /** + * Sets the nonce. + * + * @param string $nonce + */ + public function setNonce($nonce) + { + if (strlen($nonce) != 8) { + throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); + } + + $this->nonce = $nonce; + $this->changed = true; + $this->setEngine(); + } + + /** + * Sets the counter. + * + * @param int $counter + */ + public function setCounter($counter) + { + $this->counter = $counter; + $this->setEngine(); + } + + /** + * Creates a Poly1305 key using the method discussed in RFC8439 + * + * See https://tools.ietf.org/html/rfc8439#section-2.6.1 + */ + protected function createPoly1305Key() + { + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + $c = clone $this; + $c->setCounter(0); + $c->usePoly1305 = false; + $block = $c->encrypt(str_repeat("\0", 256)); + $this->setPoly1305Key(substr($block, 0, 32)); + + if ($this->counter == 0) { + $this->counter++; + } + } + + /** + * Setup the self::ENGINE_INTERNAL $engine + * + * (re)init, if necessary, the internal cipher $engine + * + * _setup() will be called each time if $changed === true + * typically this happens when using one or more of following public methods: + * + * - setKey() + * + * - setNonce() + * + * - First run of encrypt() / decrypt() with no init-settings + * + * @see self::setKey() + * @see self::setNonce() + * @see self::disableContinuousBuffer() + */ + protected function setup() + { + if (!$this->changed) { + return; + } + + $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; + + $this->changed = $this->nonIVChanged = false; + + if ($this->nonce === false) { + throw new InsufficientSetupException('No nonce has been defined'); + } + + if ($this->key === false) { + throw new InsufficientSetupException('No key has been defined'); + } + + if ($this->usePoly1305 && !isset($this->poly1305Key)) { + $this->usingGeneratedPoly1305Key = true; + $this->createPoly1305Key(); + } + + $key = $this->key; + if (strlen($key) == 16) { + $constant = 'expand 16-byte k'; + $key .= $key; + } else { + $constant = 'expand 32-byte k'; + } + + $this->p1 = substr($constant, 0, 4) . + substr($key, 0, 16) . + substr($constant, 4, 4) . + $this->nonce . + "\0\0\0\0"; + $this->p2 = substr($constant, 8, 4) . + substr($key, 16, 16) . + substr($constant, 12, 4); + } + + /** + * Setup the key (expansion) + */ + protected function setupKey() + { + // Salsa20 does not utilize this method + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @see self::crypt() + * @param string $plaintext + * @return string $ciphertext + */ + public function encrypt($plaintext) + { + $ciphertext = $this->crypt($plaintext, self::ENCRYPT); + if (isset($this->poly1305Key)) { + $this->newtag = $this->poly1305($ciphertext); + } + return $ciphertext; + } + + /** + * Decrypts a message. + * + * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). + * At least if the continuous buffer is disabled. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @see self::crypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if (isset($this->poly1305Key)) { + if ($this->oldtag === false) { + throw new InsufficientSetupException('Authentication Tag has not been set'); + } + $newtag = $this->poly1305($ciphertext); + if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { + $this->oldtag = false; + throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); + } + $this->oldtag = false; + } + + return $this->crypt($ciphertext, self::DECRYPT); + } + + /** + * Encrypts a block + * + * @param string $in + */ + protected function encryptBlock($in) + { + // Salsa20 does not utilize this method + } + + /** + * Decrypts a block + * + * @param string $in + */ + protected function decryptBlock($in) + { + // Salsa20 does not utilize this method + } + + /** + * Encrypts or decrypts a message. + * + * @see self::encrypt() + * @see self::decrypt() + * @param string $text + * @param int $mode + * @return string $text + */ + private function crypt($text, $mode) + { + $this->setup(); + if (!$this->continuousBuffer) { + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $this->counter) . $this->p2; + return openssl_encrypt( + $text, + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + } + $i = $this->counter; + $blocks = str_split($text, 64); + foreach ($blocks as &$block) { + $block ^= static::salsa20($this->p1 . pack('V', $i++) . $this->p2); + } + + return implode('', $blocks); + } + + if ($mode == self::ENCRYPT) { + $buffer = &$this->enbuffer; + } else { + $buffer = &$this->debuffer; + } + if (!strlen($buffer['ciphertext'])) { + $ciphertext = ''; + } else { + $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text)); + $text = substr($text, strlen($ciphertext)); + if (!strlen($text)) { + return $ciphertext; + } + } + + $overflow = strlen($text) % 64; // & 0x3F + if ($overflow) { + $text2 = Strings::pop($text, $overflow); + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $buffer['counter']) . $this->p2; + // at this point $text should be a multiple of 64 + $buffer['counter'] += (strlen($text) >> 6) + 1; // ie. divide by 64 + $encrypted = openssl_encrypt( + $text . str_repeat("\0", 64), + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + $temp = Strings::pop($encrypted, 64); + } else { + $blocks = str_split($text, 64); + if (strlen($text)) { + foreach ($blocks as &$block) { + $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + } + $encrypted = implode('', $blocks); + $temp = static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + $ciphertext .= $encrypted . ($text2 ^ $temp); + $buffer['ciphertext'] = substr($temp, $overflow); + } elseif (!strlen($buffer['ciphertext'])) { + if ($this->engine == self::ENGINE_OPENSSL) { + $iv = pack('V', $buffer['counter']) . $this->p2; + $buffer['counter'] += (strlen($text) >> 6); + $ciphertext .= openssl_encrypt( + $text, + $this->cipher_name_openssl, + $this->key, + OPENSSL_RAW_DATA, + $iv + ); + } else { + $blocks = str_split($text, 64); + foreach ($blocks as &$block) { + $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); + } + $ciphertext .= implode('', $blocks); + } + } + + return $ciphertext; + } + + /** + * Left Rotate + * + * @param int $x + * @param int $n + * @return int + */ + protected static function leftRotate($x, $n) + { + if (PHP_INT_SIZE == 8) { + $r1 = $x << $n; + $r1 &= 0xFFFFFFFF; + $r2 = ($x & 0xFFFFFFFF) >> (32 - $n); + } else { + $x = (int) $x; + $r1 = $x << $n; + $r2 = $x >> (32 - $n); + $r2 &= (1 << $n) - 1; + } + return $r1 | $r2; + } + + /** + * The quarterround function + * + * @param int $a + * @param int $b + * @param int $c + * @param int $d + */ + protected static function quarterRound(&$a, &$b, &$c, &$d) + { + $b ^= self::leftRotate($a + $d, 7); + $c ^= self::leftRotate($b + $a, 9); + $d ^= self::leftRotate($c + $b, 13); + $a ^= self::leftRotate($d + $c, 18); + } + + /** + * The doubleround function + * + * @param int $x0 (by reference) + * @param int $x1 (by reference) + * @param int $x2 (by reference) + * @param int $x3 (by reference) + * @param int $x4 (by reference) + * @param int $x5 (by reference) + * @param int $x6 (by reference) + * @param int $x7 (by reference) + * @param int $x8 (by reference) + * @param int $x9 (by reference) + * @param int $x10 (by reference) + * @param int $x11 (by reference) + * @param int $x12 (by reference) + * @param int $x13 (by reference) + * @param int $x14 (by reference) + * @param int $x15 (by reference) + */ + protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) + { + // columnRound + static::quarterRound($x0, $x4, $x8, $x12); + static::quarterRound($x5, $x9, $x13, $x1); + static::quarterRound($x10, $x14, $x2, $x6); + static::quarterRound($x15, $x3, $x7, $x11); + // rowRound + static::quarterRound($x0, $x1, $x2, $x3); + static::quarterRound($x5, $x6, $x7, $x4); + static::quarterRound($x10, $x11, $x8, $x9); + static::quarterRound($x15, $x12, $x13, $x14); + } + + /** + * The Salsa20 hash function function + * + * @param string $x + */ + protected static function salsa20($x) + { + $z = $x = unpack('V*', $x); + for ($i = 0; $i < 10; $i++) { + static::doubleRound($z[1], $z[2], $z[3], $z[4], $z[5], $z[6], $z[7], $z[8], $z[9], $z[10], $z[11], $z[12], $z[13], $z[14], $z[15], $z[16]); + } + + for ($i = 1; $i <= 16; $i++) { + $x[$i] += $z[$i]; + } + + return pack('V*', ...$x); + } + + /** + * Calculates Poly1305 MAC + * + * @see self::decrypt() + * @see self::encrypt() + * @param string $ciphertext + * @return string + */ + protected function poly1305($ciphertext) + { + if (!$this->usingGeneratedPoly1305Key) { + return parent::poly1305($this->aad . $ciphertext); + } else { + /* + sodium_crypto_aead_chacha20poly1305_encrypt does not calculate the poly1305 tag + the same way sodium_crypto_aead_chacha20poly1305_ietf_encrypt does. you can see + how the latter encrypts it in Salsa20::encrypt(). here's how the former encrypts + it: + + $this->newtag = $this->poly1305( + $this->aad . + pack('V', strlen($this->aad)) . "\0\0\0\0" . + $ciphertext . + pack('V', strlen($ciphertext)) . "\0\0\0\0" + ); + + phpseclib opts to use the IETF construction, even when the nonce is 64-bits + instead of 96-bits + */ + return parent::poly1305( + self::nullPad128($this->aad) . + self::nullPad128($ciphertext) . + pack('V', strlen($this->aad)) . "\0\0\0\0" . + pack('V', strlen($ciphertext)) . "\0\0\0\0" + ); + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php new file mode 100644 index 0000000..1ff5ed0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php @@ -0,0 +1,436 @@ + + * setKey('abcdefghijklmnopqrstuvwx'); + * + * $size = 10 * 1024; + * $plaintext = ''; + * for ($i = 0; $i < $size; $i++) { + * $plaintext.= 'a'; + * } + * + * echo $des->decrypt($des->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +/** + * Pure-PHP implementation of Triple DES. + * + * @author Jim Wigginton + */ +class TripleDES extends DES +{ + /** + * Encrypt / decrypt using inner chaining + * + * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3). + */ + const MODE_3CBC = -2; + + /** + * Encrypt / decrypt using outer chaining + * + * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC. + */ + const MODE_CBC3 = self::MODE_CBC; + + /** + * Key Length (in bytes) + * + * @see \phpseclib3\Crypt\TripleDES::setKeyLength() + * @var int + */ + protected $key_length = 24; + + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\DES::cipher_name_mcrypt + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'tripledes'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + */ + protected $cfb_init_len = 750; + + /** + * max possible size of $key + * + * @see self::setKey() + * @see \phpseclib3\Crypt\DES::setKey() + * @var string + */ + protected $key_length_max = 24; + + /** + * Internal flag whether using self::MODE_3CBC or not + * + * @var bool + */ + private $mode_3cbc; + + /** + * The \phpseclib3\Crypt\DES objects + * + * Used only if $mode_3cbc === true + * + * @var array + */ + private $des; + + /** + * Default Constructor. + * + * Determines whether or not the mcrypt or OpenSSL extensions should be used. + * + * $mode could be: + * + * - ecb + * + * - cbc + * + * - ctr + * + * - cfb + * + * - ofb + * + * - 3cbc + * + * - cbc3 (same as cbc) + * + * @see \phpseclib3\Crypt\DES::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param string $mode + */ + public function __construct($mode) + { + switch (strtolower($mode)) { + // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC + // and additional flag us internally as 3CBC + case '3cbc': + parent::__construct('cbc'); + $this->mode_3cbc = true; + + // This three $des'es will do the 3CBC work (if $key > 64bits) + $this->des = [ + new DES('cbc'), + new DES('cbc'), + new DES('cbc'), + ]; + + // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects + $this->des[0]->disablePadding(); + $this->des[1]->disablePadding(); + $this->des[2]->disablePadding(); + break; + case 'cbc3': + $mode = 'cbc'; + // fall-through + // If not 3CBC, we init as usual + default: + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + } + + /** + * Test for engine validity + * + * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @param int $engine + * @return bool + */ + protected function isValidEngineHelper($engine) + { + if ($engine == self::ENGINE_OPENSSL) { + $this->cipher_name_openssl_ecb = 'des-ede3'; + $mode = $this->openssl_translate_mode(); + $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; + } + + return parent::isValidEngineHelper($engine); + } + + /** + * Sets the initialization vector. + * + * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::setIV() + * @param string $iv + */ + public function setIV($iv) + { + parent::setIV($iv); + if ($this->mode_3cbc) { + $this->des[0]->setIV($iv); + $this->des[1]->setIV($iv); + $this->des[2]->setIV($iv); + } + } + + /** + * Sets the key length. + * + * Valid key lengths are 128 and 192 bits. + * + * If you want to use a 64-bit key use DES.php + * + * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength() + * @throws \LengthException if the key length is invalid + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + break; + default: + throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); + } + + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys. + * + * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. + * + * @see \phpseclib3\Crypt\DES::setKey() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() + * @throws \LengthException if the key length is invalid + * @param string $key + */ + public function setKey($key) + { + if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { + throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); + } + + switch (strlen($key)) { + case 16: + $key .= substr($key, 0, 8); + break; + case 24: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); + } + + // copied from self::setKey() + $this->key = $key; + $this->key_length = strlen($key); + $this->changed = $this->nonIVChanged = true; + $this->setEngine(); + + if ($this->mode_3cbc) { + $this->des[0]->setKey(substr($key, 0, 8)); + $this->des[1]->setKey(substr($key, 8, 8)); + $this->des[2]->setKey(substr($key, 16, 8)); + } + } + + /** + * Encrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() + * @param string $plaintext + * @return string $cipertext + */ + public function encrypt($plaintext) + { + // parent::en/decrypt() is able to do all the work for all modes and keylengths, + // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits + + // if the key is smaller then 8, do what we'd normally do + if ($this->mode_3cbc && strlen($this->key) > 8) { + return $this->des[2]->encrypt( + $this->des[1]->decrypt( + $this->des[0]->encrypt( + $this->pad($plaintext) + ) + ) + ); + } + + return parent::encrypt($plaintext); + } + + /** + * Decrypts a message. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() + * @param string $ciphertext + * @return string $plaintext + */ + public function decrypt($ciphertext) + { + if ($this->mode_3cbc && strlen($this->key) > 8) { + return $this->unpad( + $this->des[0]->decrypt( + $this->des[1]->encrypt( + $this->des[2]->decrypt( + str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0") + ) + ) + ) + ); + } + + return parent::decrypt($ciphertext); + } + + /** + * Treat consecutive "packets" as if they are a continuous buffer. + * + * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets + * will yield different outputs: + * + * + * echo $des->encrypt(substr($plaintext, 0, 8)); + * echo $des->encrypt(substr($plaintext, 8, 8)); + * + * + * echo $des->encrypt($plaintext); + * + * + * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates + * another, as demonstrated with the following: + * + * + * $des->encrypt(substr($plaintext, 0, 8)); + * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); + * + * + * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); + * + * + * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different + * outputs. The reason is due to the fact that the initialization vector's change after every encryption / + * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. + * + * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each + * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that + * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), + * however, they are also less intuitive and more likely to cause you problems. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::enableContinuousBuffer() + * @see self::disableContinuousBuffer() + */ + public function enableContinuousBuffer() + { + parent::enableContinuousBuffer(); + if ($this->mode_3cbc) { + $this->des[0]->enableContinuousBuffer(); + $this->des[1]->enableContinuousBuffer(); + $this->des[2]->enableContinuousBuffer(); + } + } + + /** + * Treat consecutive packets as if they are a discontinuous buffer. + * + * The default behavior. + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::disableContinuousBuffer() + * @see self::enableContinuousBuffer() + */ + public function disableContinuousBuffer() + { + parent::disableContinuousBuffer(); + if ($this->mode_3cbc) { + $this->des[0]->disableContinuousBuffer(); + $this->des[1]->disableContinuousBuffer(); + $this->des[2]->disableContinuousBuffer(); + } + } + + /** + * Creates the key schedule + * + * @see \phpseclib3\Crypt\DES::setupKey() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() + */ + protected function setupKey() + { + switch (true) { + // if $key <= 64bits we configure our internal pure-php cipher engine + // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. + case strlen($this->key) <= 8: + $this->des_rounds = 1; + break; + + // otherwise, if $key > 64bits, we configure our engine to work as 3DES. + default: + $this->des_rounds = 3; + + // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. + if ($this->mode_3cbc) { + $this->des[0]->setupKey(); + $this->des[1]->setupKey(); + $this->des[2]->setupKey(); + + // because $des[0-2] will, now, do all the work we can return here + // not need unnecessary stress parent::setupKey() with our, now unused, $key. + return; + } + } + // setup our key + parent::setupKey(); + } + + /** + * Sets the internal crypt engine + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() + * @see \phpseclib3\Crypt\Common\SymmetricKey::setPreferredEngine() + * @param int $engine + */ + public function setPreferredEngine($engine) + { + if ($this->mode_3cbc) { + $this->des[0]->setPreferredEngine($engine); + $this->des[1]->setPreferredEngine($engine); + $this->des[2]->setPreferredEngine($engine); + } + + parent::setPreferredEngine($engine); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php new file mode 100644 index 0000000..bf76563 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php @@ -0,0 +1,816 @@ + + * setKey('12345678901234567890123456789012'); + * + * $plaintext = str_repeat('a', 1024); + * + * echo $twofish->decrypt($twofish->encrypt($plaintext)); + * ?> + * + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Crypt; + +use phpseclib3\Crypt\Common\BlockCipher; +use phpseclib3\Exception\BadModeException; + +/** + * Pure-PHP implementation of Twofish. + * + * @author Jim Wigginton + * @author Hans-Juergen Petrich + */ +class Twofish extends BlockCipher +{ + /** + * The mcrypt specific name of the cipher + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt + * @var string + */ + protected $cipher_name_mcrypt = 'twofish'; + + /** + * Optimizing value while CFB-encrypting + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len + * @var int + */ + protected $cfb_init_len = 800; + + /** + * Q-Table + * + * @var array + */ + private static $q0 = [ + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, + 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, + 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, + 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, + 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, + 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, + 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, + 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, + 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, + 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, + 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, + 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, + 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, + 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, + 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, + 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, + 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, + 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, + 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, + 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, + 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, + 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 + ]; + + /** + * Q-Table + * + * @var array + */ + private static $q1 = [ + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, + 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, + 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, + 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, + 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, + 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, + 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, + 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, + 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, + 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, + 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, + 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, + 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, + 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, + 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, + 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, + 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, + 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, + 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, + 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, + 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, + 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 + ]; + + /** + * M-Table + * + * @var array + */ + private static $m0 = [ + 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, + 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, + 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, + 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F, + 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, + 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, + 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3, + 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, + 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, + 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C, + 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, + 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, + 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC, + 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, + 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, + 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17, + 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, + 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, + 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149, + 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, + 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, + 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48, + 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, + 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, + 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5, + 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, + 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, + 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC, + 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, + 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, + 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, + 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 + ]; + + /** + * M-Table + * + * @var array + */ + private static $m1 = [ + 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, + 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, + 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, + 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E, + 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, + 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, + 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D, + 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, + 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, + 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B, + 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, + 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, + 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D, + 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, + 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, + 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7, + 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, + 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, + 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E, + 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, + 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, + 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F, + 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, + 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, + 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7, + 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, + 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, + 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323, + 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, + 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, + 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, + 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 + ]; + + /** + * M-Table + * + * @var array + */ + private static $m2 = [ + 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, + 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, + 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, + 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE, + 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, + 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, + 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065, + 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, + 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, + 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF, + 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, + 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, + 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF, + 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, + 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, + 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC, + 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, + 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, + 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101, + 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, + 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, + 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A, + 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, + 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, + 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6, + 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, + 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, + 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB, + 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, + 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, + 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, + 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF + ]; + + /** + * M-Table + * + * @var array + */ + private static $m3 = [ + 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, + 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, + 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, + 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A, + 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, + 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, + 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63, + 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, + 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, + 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197, + 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, + 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, + 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20, + 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, + 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, + 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730, + 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, + 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, + 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F, + 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, + 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, + 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D, + 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, + 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, + 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6, + 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, + 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, + 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439, + 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, + 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, + 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, + 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 + ]; + + /** + * The Key Schedule Array + * + * @var array + */ + private $K = []; + + /** + * The Key depended S-Table 0 + * + * @var array + */ + private $S0 = []; + + /** + * The Key depended S-Table 1 + * + * @var array + */ + private $S1 = []; + + /** + * The Key depended S-Table 2 + * + * @var array + */ + private $S2 = []; + + /** + * The Key depended S-Table 3 + * + * @var array + */ + private $S3 = []; + + /** + * Holds the last used key + * + * @var array + */ + private $kl; + + /** + * The Key Length (in bytes) + * + * @see Crypt_Twofish::setKeyLength() + * @var int + */ + protected $key_length = 16; + + /** + * Default Constructor. + * + * @param string $mode + * @throws BadModeException if an invalid / unsupported mode is provided + */ + public function __construct($mode) + { + parent::__construct($mode); + + if ($this->mode == self::MODE_STREAM) { + throw new BadModeException('Block ciphers cannot be ran in stream mode'); + } + } + + /** + * Initialize Static Variables + */ + protected static function initialize_static_variables() + { + if (is_float(self::$m3[0])) { + self::$m0 = array_map('intval', self::$m0); + self::$m1 = array_map('intval', self::$m1); + self::$m2 = array_map('intval', self::$m2); + self::$m3 = array_map('intval', self::$m3); + self::$q0 = array_map('intval', self::$q0); + self::$q1 = array_map('intval', self::$q1); + } + + parent::initialize_static_variables(); + } + + /** + * Sets the key length. + * + * Valid key lengths are 128, 192 or 256 bits + * + * @param int $length + */ + public function setKeyLength($length) + { + switch ($length) { + case 128: + case 192: + case 256: + break; + default: + throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKeyLength($length); + } + + /** + * Sets the key. + * + * Rijndael supports five different key lengths + * + * @see setKeyLength() + * @param string $key + * @throws \LengthException if the key length isn't supported + */ + public function setKey($key) + { + switch (strlen($key)) { + case 16: + case 24: + case 32: + break; + default: + throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); + } + + parent::setKey($key); + } + + /** + * Setup the key (expansion) + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() + */ + protected function setupKey() + { + if (isset($this->kl['key']) && $this->key === $this->kl['key']) { + // already expanded + return; + } + $this->kl = ['key' => $this->key]; + + /* Key expanding and generating the key-depended s-boxes */ + $le_longs = unpack('V*', $this->key); + $key = unpack('C*', $this->key); + $m0 = self::$m0; + $m1 = self::$m1; + $m2 = self::$m2; + $m3 = self::$m3; + $q0 = self::$q0; + $q1 = self::$q1; + + $K = $S0 = $S1 = $S2 = $S3 = []; + + switch (strlen($this->key)) { + case 16: + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[3], $le_longs[4]); + for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { + $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ + $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ + $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^ + $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]]; + $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^ + $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^ + $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^ + $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]]; + $B = ($B << 8) | ($B >> 24 & 0xff); + $A = self::safe_intval($A + $B); + $K[] = $A; + $A = self::safe_intval($A + $B); + $K[] = ($A << 9 | $A >> 23 & 0x1ff); + } + for ($i = 0; $i < 256; ++$i) { + $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0]; + $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1]; + $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2]; + $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3]; + } + break; + case 24: + list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[5], $le_longs[6]); + for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { + $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ + $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ + $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ + $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]]; + $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ + $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ + $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ + $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]]; + $B = ($B << 8) | ($B >> 24 & 0xff); + $A = self::safe_intval($A + $B); + $K[] = $A; + $A = self::safe_intval($A + $B); + $K[] = ($A << 9 | $A >> 23 & 0x1ff); + } + for ($i = 0; $i < 256; ++$i) { + $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0]; + $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1]; + $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2]; + $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3]; + } + break; + default: // 32 + list($sf, $se, $sd, $sc) = $this->mdsrem($le_longs[1], $le_longs[2]); + list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[3], $le_longs[4]); + list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[5], $le_longs[6]); + list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[7], $le_longs[8]); + for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { + $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ + $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ + $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ + $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]]; + $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ + $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ + $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ + $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]]; + $B = ($B << 8) | ($B >> 24 & 0xff); + $A = self::safe_intval($A + $B); + $K[] = $A; + $A = self::safe_intval($A + $B); + $K[] = ($A << 9 | $A >> 23 & 0x1ff); + } + for ($i = 0; $i < 256; ++$i) { + $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0]; + $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1]; + $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2]; + $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3]; + } + } + + $this->K = $K; + $this->S0 = $S0; + $this->S1 = $S1; + $this->S2 = $S2; + $this->S3 = $S3; + } + + /** + * _mdsrem function using by the twofish cipher algorithm + * + * @param string $A + * @param string $B + * @return array + */ + private function mdsrem($A, $B) + { + // No gain by unrolling this loop. + for ($i = 0; $i < 8; ++$i) { + // Get most significant coefficient. + $t = 0xff & ($B >> 24); + + // Shift the others up. + $B = ($B << 8) | (0xff & ($A >> 24)); + $A <<= 8; + + $u = $t << 1; + + // Subtract the modular polynomial on overflow. + if ($t & 0x80) { + $u ^= 0x14d; + } + + // Remove t * (a * x^2 + 1). + $B ^= $t ^ ($u << 16); + + // Form u = a*t + t/a = t*(a + 1/a). + $u ^= 0x7fffffff & ($t >> 1); + + // Add the modular polynomial on underflow. + if ($t & 0x01) { + $u ^= 0xa6 ; + } + + // Remove t * (a + 1/a) * (x^3 + x). + $B ^= ($u << 24) | ($u << 8); + } + + return [ + 0xff & $B >> 24, + 0xff & $B >> 16, + 0xff & $B >> 8, + 0xff & $B]; + } + + /** + * Encrypts a block + * + * @param string $in + * @return string + */ + protected function encryptBlock($in) + { + $S0 = $this->S0; + $S1 = $this->S1; + $S2 = $this->S2; + $S3 = $this->S3; + $K = $this->K; + + $in = unpack("V4", $in); + $R0 = $K[0] ^ $in[1]; + $R1 = $K[1] ^ $in[2]; + $R2 = $K[2] ^ $in[3]; + $R3 = $K[3] ^ $in[4]; + + $ki = 7; + while ($ki < 39) { + $t0 = $S0[ $R0 & 0xff] ^ + $S1[($R0 >> 8) & 0xff] ^ + $S2[($R0 >> 16) & 0xff] ^ + $S3[($R0 >> 24) & 0xff]; + $t1 = $S0[($R1 >> 24) & 0xff] ^ + $S1[ $R1 & 0xff] ^ + $S2[($R1 >> 8) & 0xff] ^ + $S3[($R1 >> 16) & 0xff]; + $R2 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); + $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + + $t0 = $S0[ $R2 & 0xff] ^ + $S1[($R2 >> 8) & 0xff] ^ + $S2[($R2 >> 16) & 0xff] ^ + $S3[($R2 >> 24) & 0xff]; + $t1 = $S0[($R3 >> 24) & 0xff] ^ + $S1[ $R3 & 0xff] ^ + $S2[($R3 >> 8) & 0xff] ^ + $S3[($R3 >> 16) & 0xff]; + $R0 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); + $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); + } + + // @codingStandardsIgnoreStart + return pack("V4", $K[4] ^ $R2, + $K[5] ^ $R3, + $K[6] ^ $R0, + $K[7] ^ $R1); + // @codingStandardsIgnoreEnd + } + + /** + * Decrypts a block + * + * @param string $in + * @return string + */ + protected function decryptBlock($in) + { + $S0 = $this->S0; + $S1 = $this->S1; + $S2 = $this->S2; + $S3 = $this->S3; + $K = $this->K; + + $in = unpack("V4", $in); + $R0 = $K[4] ^ $in[1]; + $R1 = $K[5] ^ $in[2]; + $R2 = $K[6] ^ $in[3]; + $R3 = $K[7] ^ $in[4]; + + $ki = 40; + while ($ki > 8) { + $t0 = $S0[$R0 & 0xff] ^ + $S1[$R0 >> 8 & 0xff] ^ + $S2[$R0 >> 16 & 0xff] ^ + $S3[$R0 >> 24 & 0xff]; + $t1 = $S0[$R1 >> 24 & 0xff] ^ + $S1[$R1 & 0xff] ^ + $S2[$R1 >> 8 & 0xff] ^ + $S3[$R1 >> 16 & 0xff]; + $R3 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); + + $t0 = $S0[$R2 & 0xff] ^ + $S1[$R2 >> 8 & 0xff] ^ + $S2[$R2 >> 16 & 0xff] ^ + $S3[$R2 >> 24 & 0xff]; + $t1 = $S0[$R3 >> 24 & 0xff] ^ + $S1[$R3 & 0xff] ^ + $S2[$R3 >> 8 & 0xff] ^ + $S3[$R3 >> 16 & 0xff]; + $R1 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); + $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); + } + + // @codingStandardsIgnoreStart + return pack("V4", $K[0] ^ $R2, + $K[1] ^ $R3, + $K[2] ^ $R0, + $K[3] ^ $R1); + // @codingStandardsIgnoreEnd + } + + /** + * Setup the performance-optimized function for de/encrypt() + * + * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() + */ + protected function setupInlineCrypt() + { + $K = $this->K; + $init_crypt = ' + static $S0, $S1, $S2, $S3; + if (!$S0) { + for ($i = 0; $i < 256; ++$i) { + $S0[] = (int)$this->S0[$i]; + $S1[] = (int)$this->S1[$i]; + $S2[] = (int)$this->S2[$i]; + $S3[] = (int)$this->S3[$i]; + } + } + '; + + $safeint = self::safe_intval_inline(); + + // Generating encrypt code: + $encrypt_block = ' + $in = unpack("V4", $in); + $R0 = ' . $K[0] . ' ^ $in[1]; + $R1 = ' . $K[1] . ' ^ $in[2]; + $R2 = ' . $K[2] . ' ^ $in[3]; + $R3 = ' . $K[3] . ' ^ $in[4]; + '; + for ($ki = 7, $i = 0; $i < 8; ++$i) { + $encrypt_block .= ' + $t0 = $S0[ $R0 & 0xff] ^ + $S1[($R0 >> 8) & 0xff] ^ + $S2[($R0 >> 16) & 0xff] ^ + $S3[($R0 >> 24) & 0xff]; + $t1 = $S0[($R1 >> 24) & 0xff] ^ + $S1[ $R1 & 0xff] ^ + $S2[($R1 >> 8) & 0xff] ^ + $S3[($R1 >> 16) & 0xff]; + $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . '; + $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); + $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + + $t0 = $S0[ $R2 & 0xff] ^ + $S1[($R2 >> 8) & 0xff] ^ + $S2[($R2 >> 16) & 0xff] ^ + $S3[($R2 >> 24) & 0xff]; + $t1 = $S0[($R3 >> 24) & 0xff] ^ + $S1[ $R3 & 0xff] ^ + $S2[($R3 >> 8) & 0xff] ^ + $S3[($R3 >> 16) & 0xff]; + $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; + $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); + $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; + '; + } + $encrypt_block .= ' + $in = pack("V4", ' . $K[4] . ' ^ $R2, + ' . $K[5] . ' ^ $R3, + ' . $K[6] . ' ^ $R0, + ' . $K[7] . ' ^ $R1); + '; + + // Generating decrypt code: + $decrypt_block = ' + $in = unpack("V4", $in); + $R0 = ' . $K[4] . ' ^ $in[1]; + $R1 = ' . $K[5] . ' ^ $in[2]; + $R2 = ' . $K[6] . ' ^ $in[3]; + $R3 = ' . $K[7] . ' ^ $in[4]; + '; + for ($ki = 40, $i = 0; $i < 8; ++$i) { + $decrypt_block .= ' + $t0 = $S0[$R0 & 0xff] ^ + $S1[$R0 >> 8 & 0xff] ^ + $S2[$R0 >> 16 & 0xff] ^ + $S3[$R0 >> 24 & 0xff]; + $t1 = $S0[$R1 >> 24 & 0xff] ^ + $S1[$R1 & 0xff] ^ + $S2[$R1 >> 8 & 0xff] ^ + $S3[$R1 >> 16 & 0xff]; + $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; + $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; + + $t0 = $S0[$R2 & 0xff] ^ + $S1[$R2 >> 8 & 0xff] ^ + $S2[$R2 >> 16 & 0xff] ^ + $S3[$R2 >> 24 & 0xff]; + $t1 = $S0[$R3 >> 24 & 0xff] ^ + $S1[$R3 & 0xff] ^ + $S2[$R3 >> 8 & 0xff] ^ + $S3[$R3 >> 16 & 0xff]; + $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; + $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; + $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; + '; + } + $decrypt_block .= ' + $in = pack("V4", ' . $K[0] . ' ^ $R2, + ' . $K[1] . ' ^ $R3, + ' . $K[2] . ' ^ $R0, + ' . $K[3] . ' ^ $R1); + '; + + $this->inline_crypt = $this->createInlineCryptFunction( + [ + 'init_crypt' => $init_crypt, + 'init_encrypt' => '', + 'init_decrypt' => '', + 'encrypt_block' => $encrypt_block, + 'decrypt_block' => $decrypt_block + ] + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php new file mode 100644 index 0000000..1aabcae --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadConfigurationException + * + * @author Jim Wigginton + */ +class BadConfigurationException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php new file mode 100644 index 0000000..88331dc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadDecryptionException + * + * @author Jim Wigginton + */ +class BadDecryptionException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php new file mode 100644 index 0000000..87689b2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * BadModeException + * + * @author Jim Wigginton + */ +class BadModeException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php new file mode 100644 index 0000000..6aaccba --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * ConnectionClosedException + * + * @author Jim Wigginton + */ +class ConnectionClosedException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php new file mode 100644 index 0000000..66e7270 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * FileNotFoundException + * + * @author Jim Wigginton + */ +class FileNotFoundException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php new file mode 100644 index 0000000..23c38fb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * InconsistentSetupException + * + * @author Jim Wigginton + */ +class InconsistentSetupException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php new file mode 100644 index 0000000..4f4114d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * InsufficientSetupException + * + * @author Jim Wigginton + */ +class InsufficientSetupException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php new file mode 100644 index 0000000..7ec2fe9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * NoKeyLoadedException + * + * @author Jim Wigginton + */ +class NoKeyLoadedException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php new file mode 100644 index 0000000..b3ea8f3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * NoSupportedAlgorithmsException + * + * @author Jim Wigginton + */ +class NoSupportedAlgorithmsException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php new file mode 100644 index 0000000..bfa005b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnableToConnectException + * + * @author Jim Wigginton + */ +class UnableToConnectException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php new file mode 100644 index 0000000..210a9a5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedAlgorithmException + * + * @author Jim Wigginton + */ +class UnsupportedAlgorithmException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php new file mode 100644 index 0000000..9915215 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedCurveException + * + * @author Jim Wigginton + */ +class UnsupportedCurveException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php new file mode 100644 index 0000000..e207d7e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedFormatException + * + * @author Jim Wigginton + */ +class UnsupportedFormatException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php new file mode 100644 index 0000000..9a11544 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php @@ -0,0 +1,23 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Exception; + +/** + * UnsupportedOperationException + * + * @author Jim Wigginton + */ +class UnsupportedOperationException extends \RuntimeException +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php new file mode 100644 index 0000000..5803a37 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php @@ -0,0 +1,551 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File; + +/** + * Pure-PHP ANSI Decoder + * + * @author Jim Wigginton + */ +class ANSI +{ + /** + * Max Width + * + * @var int + */ + private $max_x; + + /** + * Max Height + * + * @var int + */ + private $max_y; + + /** + * Max History + * + * @var int + */ + private $max_history; + + /** + * History + * + * @var array + */ + private $history; + + /** + * History Attributes + * + * @var array + */ + private $history_attrs; + + /** + * Current Column + * + * @var int + */ + private $x; + + /** + * Current Row + * + * @var int + */ + private $y; + + /** + * Old Column + * + * @var int + */ + private $old_x; + + /** + * Old Row + * + * @var int + */ + private $old_y; + + /** + * An empty attribute cell + * + * @var object + */ + private $base_attr_cell; + + /** + * The current attribute cell + * + * @var object + */ + private $attr_cell; + + /** + * An empty attribute row + * + * @var array + */ + private $attr_row; + + /** + * The current screen text + * + * @var list + */ + private $screen; + + /** + * The current screen attributes + * + * @var array + */ + private $attrs; + + /** + * Current ANSI code + * + * @var string + */ + private $ansi; + + /** + * Tokenization + * + * @var array + */ + private $tokenization; + + /** + * Default Constructor. + * + * @return \phpseclib3\File\ANSI + */ + public function __construct() + { + $attr_cell = new \stdClass(); + $attr_cell->bold = false; + $attr_cell->underline = false; + $attr_cell->blink = false; + $attr_cell->background = 'black'; + $attr_cell->foreground = 'white'; + $attr_cell->reverse = false; + $this->base_attr_cell = clone $attr_cell; + $this->attr_cell = clone $attr_cell; + + $this->setHistory(200); + $this->setDimensions(80, 24); + } + + /** + * Set terminal width and height + * + * Resets the screen as well + * + * @param int $x + * @param int $y + */ + public function setDimensions($x, $y) + { + $this->max_x = $x - 1; + $this->max_y = $y - 1; + $this->x = $this->y = 0; + $this->history = $this->history_attrs = []; + $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell); + $this->screen = array_fill(0, $this->max_y + 1, ''); + $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row); + $this->ansi = ''; + } + + /** + * Set the number of lines that should be logged past the terminal height + * + * @param int $history + */ + public function setHistory($history) + { + $this->max_history = $history; + } + + /** + * Load a string + * + * @param string $source + */ + public function loadString($source) + { + $this->setDimensions($this->max_x + 1, $this->max_y + 1); + $this->appendString($source); + } + + /** + * Appdend a string + * + * @param string $source + */ + public function appendString($source) + { + $this->tokenization = ['']; + for ($i = 0; $i < strlen($source); $i++) { + if (strlen($this->ansi)) { + $this->ansi .= $source[$i]; + $chr = ord($source[$i]); + // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements + // single character CSI's not currently supported + switch (true) { + case $this->ansi == "\x1B=": + $this->ansi = ''; + continue 2; + case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['): + case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126: + break; + default: + continue 2; + } + $this->tokenization[] = $this->ansi; + $this->tokenization[] = ''; + // http://ascii-table.com/ansi-escape-sequences-vt-100.php + switch ($this->ansi) { + case "\x1B[H": // Move cursor to upper left corner + $this->old_x = $this->x; + $this->old_y = $this->y; + $this->x = $this->y = 0; + break; + case "\x1B[J": // Clear screen from cursor down + $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y)); + $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, '')); + + $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y)); + $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row)); + + if (count($this->history) == $this->max_history) { + array_shift($this->history); + array_shift($this->history_attrs); + } + // fall-through + case "\x1B[K": // Clear screen from cursor right + $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); + + array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell)); + break; + case "\x1B[2K": // Clear entire line + $this->screen[$this->y] = str_repeat(' ', $this->x); + $this->attrs[$this->y] = $this->attr_row; + break; + case "\x1B[?1h": // set cursor key to application + case "\x1B[?25h": // show the cursor + case "\x1B(B": // set united states g0 character set + break; + case "\x1BE": // Move to next line + $this->newLine(); + $this->x = 0; + break; + default: + switch (true) { + case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines + $this->old_y = $this->y; + $this->y += (int) $match[1]; + break; + case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h + $this->old_x = $this->x; + $this->old_y = $this->y; + $this->x = $match[2] - 1; + $this->y = (int) $match[1] - 1; + break; + case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines + $this->old_x = $this->x; + $this->x += $match[1]; + break; + case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines + $this->old_x = $this->x; + $this->x -= $match[1]; + if ($this->x < 0) { + $this->x = 0; + } + break; + case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window + break; + case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes + $attr_cell = &$this->attr_cell; + $mods = explode(';', $match[1]); + foreach ($mods as $mod) { + switch ($mod) { + case '': + case '0': // Turn off character attributes + $attr_cell = clone $this->base_attr_cell; + break; + case '1': // Turn bold mode on + $attr_cell->bold = true; + break; + case '4': // Turn underline mode on + $attr_cell->underline = true; + break; + case '5': // Turn blinking mode on + $attr_cell->blink = true; + break; + case '7': // Turn reverse video on + $attr_cell->reverse = !$attr_cell->reverse; + $temp = $attr_cell->background; + $attr_cell->background = $attr_cell->foreground; + $attr_cell->foreground = $temp; + break; + default: // set colors + //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground; + $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' }; + //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background; + $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; + switch ($mod) { + // @codingStandardsIgnoreStart + case '30': $front = 'black'; break; + case '31': $front = 'red'; break; + case '32': $front = 'green'; break; + case '33': $front = 'yellow'; break; + case '34': $front = 'blue'; break; + case '35': $front = 'magenta'; break; + case '36': $front = 'cyan'; break; + case '37': $front = 'white'; break; + + case '40': $back = 'black'; break; + case '41': $back = 'red'; break; + case '42': $back = 'green'; break; + case '43': $back = 'yellow'; break; + case '44': $back = 'blue'; break; + case '45': $back = 'magenta'; break; + case '46': $back = 'cyan'; break; + case '47': $back = 'white'; break; + // @codingStandardsIgnoreEnd + + default: + //user_error('Unsupported attribute: ' . $mod); + $this->ansi = ''; + break 2; + } + } + } + break; + default: + //user_error("{$this->ansi} is unsupported\r\n"); + } + } + $this->ansi = ''; + continue; + } + + $this->tokenization[count($this->tokenization) - 1] .= $source[$i]; + switch ($source[$i]) { + case "\r": + $this->x = 0; + break; + case "\n": + $this->newLine(); + break; + case "\x08": // backspace + if ($this->x) { + $this->x--; + $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell; + $this->screen[$this->y] = substr_replace( + $this->screen[$this->y], + $source[$i], + $this->x, + 1 + ); + } + break; + case "\x0F": // shift + break; + case "\x1B": // start ANSI escape code + $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1); + //if (!strlen($this->tokenization[count($this->tokenization) - 1])) { + // array_pop($this->tokenization); + //} + $this->ansi .= "\x1B"; + break; + default: + $this->attrs[$this->y][$this->x] = clone $this->attr_cell; + if ($this->x > strlen($this->screen[$this->y])) { + $this->screen[$this->y] = str_repeat(' ', $this->x); + } + $this->screen[$this->y] = substr_replace( + $this->screen[$this->y], + $source[$i], + $this->x, + 1 + ); + + if ($this->x > $this->max_x) { + $this->x = 0; + $this->newLine(); + } else { + $this->x++; + } + } + } + } + + /** + * Add a new line + * + * Also update the $this->screen and $this->history buffers + * + */ + private function newLine() + { + //if ($this->y < $this->max_y) { + // $this->y++; + //} + + while ($this->y >= $this->max_y) { + $this->history = array_merge($this->history, [array_shift($this->screen)]); + $this->screen[] = ''; + + $this->history_attrs = array_merge($this->history_attrs, [array_shift($this->attrs)]); + $this->attrs[] = $this->attr_row; + + if (count($this->history) >= $this->max_history) { + array_shift($this->history); + array_shift($this->history_attrs); + } + + $this->y--; + } + $this->y++; + } + + /** + * Returns the current coordinate without preformating + * + * @param \stdClass $last_attr + * @param \stdClass $cur_attr + * @param string $char + * @return string + */ + private function processCoordinate(\stdClass $last_attr, \stdClass $cur_attr, $char) + { + $output = ''; + + if ($last_attr != $cur_attr) { + $close = $open = ''; + if ($last_attr->foreground != $cur_attr->foreground) { + if ($cur_attr->foreground != 'white') { + $open .= ''; + } + if ($last_attr->foreground != 'white') { + $close = '' . $close; + } + } + if ($last_attr->background != $cur_attr->background) { + if ($cur_attr->background != 'black') { + $open .= ''; + } + if ($last_attr->background != 'black') { + $close = '' . $close; + } + } + if ($last_attr->bold != $cur_attr->bold) { + if ($cur_attr->bold) { + $open .= ''; + } else { + $close = '' . $close; + } + } + if ($last_attr->underline != $cur_attr->underline) { + if ($cur_attr->underline) { + $open .= ''; + } else { + $close = '' . $close; + } + } + if ($last_attr->blink != $cur_attr->blink) { + if ($cur_attr->blink) { + $open .= ''; + } else { + $close = '' . $close; + } + } + $output .= $close . $open; + } + + $output .= htmlspecialchars($char); + + return $output; + } + + /** + * Returns the current screen without preformating + * + * @return string + */ + private function getScreenHelper() + { + $output = ''; + $last_attr = $this->base_attr_cell; + for ($i = 0; $i <= $this->max_y; $i++) { + for ($j = 0; $j <= $this->max_x; $j++) { + $cur_attr = $this->attrs[$i][$j]; + $output .= $this->processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); + $last_attr = $this->attrs[$i][$j]; + } + $output .= "\r\n"; + } + $output = substr($output, 0, -2); + // close any remaining open tags + $output .= $this->processCoordinate($last_attr, $this->base_attr_cell, ''); + return rtrim($output); + } + + /** + * Returns the current screen + * + * @return string + */ + public function getScreen() + { + return '
          ' . $this->getScreenHelper() . '
          '; + } + + /** + * Returns the current screen and the x previous lines + * + * @return string + */ + public function getHistory() + { + $scrollback = ''; + $last_attr = $this->base_attr_cell; + for ($i = 0; $i < count($this->history); $i++) { + for ($j = 0; $j <= $this->max_x + 1; $j++) { + $cur_attr = $this->history_attrs[$i][$j]; + $scrollback .= $this->processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); + $last_attr = $this->history_attrs[$i][$j]; + } + $scrollback .= "\r\n"; + } + $base_attr_cell = $this->base_attr_cell; + $this->base_attr_cell = $last_attr; + $scrollback .= $this->getScreen(); + $this->base_attr_cell = $base_attr_cell; + + return '
          ' . $scrollback . '
          '; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php new file mode 100644 index 0000000..3096ff1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php @@ -0,0 +1,1508 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\File\ASN1\Element; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP ASN.1 Parser + * + * @author Jim Wigginton + */ +abstract class ASN1 +{ + // Tag Classes + // http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 + const CLASS_UNIVERSAL = 0; + const CLASS_APPLICATION = 1; + const CLASS_CONTEXT_SPECIFIC = 2; + const CLASS_PRIVATE = 3; + + // Tag Classes + // http://www.obj-sys.com/asn1tutorial/node124.html + const TYPE_BOOLEAN = 1; + const TYPE_INTEGER = 2; + const TYPE_BIT_STRING = 3; + const TYPE_OCTET_STRING = 4; + const TYPE_NULL = 5; + const TYPE_OBJECT_IDENTIFIER = 6; + //const TYPE_OBJECT_DESCRIPTOR = 7; + //const TYPE_INSTANCE_OF = 8; // EXTERNAL + const TYPE_REAL = 9; + const TYPE_ENUMERATED = 10; + //const TYPE_EMBEDDED = 11; + const TYPE_UTF8_STRING = 12; + //const TYPE_RELATIVE_OID = 13; + const TYPE_SEQUENCE = 16; // SEQUENCE OF + const TYPE_SET = 17; // SET OF + + // More Tag Classes + // http://www.obj-sys.com/asn1tutorial/node10.html + const TYPE_NUMERIC_STRING = 18; + const TYPE_PRINTABLE_STRING = 19; + const TYPE_TELETEX_STRING = 20; // T61String + const TYPE_VIDEOTEX_STRING = 21; + const TYPE_IA5_STRING = 22; + const TYPE_UTC_TIME = 23; + const TYPE_GENERALIZED_TIME = 24; + const TYPE_GRAPHIC_STRING = 25; + const TYPE_VISIBLE_STRING = 26; // ISO646String + const TYPE_GENERAL_STRING = 27; + const TYPE_UNIVERSAL_STRING = 28; + //const TYPE_CHARACTER_STRING = 29; + const TYPE_BMP_STRING = 30; + + // Tag Aliases + // These tags are kinda place holders for other tags. + const TYPE_CHOICE = -1; + const TYPE_ANY = -2; + + /** + * ASN.1 object identifiers + * + * @var array + * @link http://en.wikipedia.org/wiki/Object_identifier + */ + private static $oids = []; + + /** + * ASN.1 object identifier reverse mapping + * + * @var array + */ + private static $reverseOIDs = []; + + /** + * Default date format + * + * @var string + * @link http://php.net/class.datetime + */ + private static $format = 'D, d M Y H:i:s O'; + + /** + * Filters + * + * If the mapping type is self::TYPE_ANY what do we actually encode it as? + * + * @var array + * @see self::encode_der() + */ + private static $filters; + + /** + * Current Location of most recent ASN.1 encode process + * + * Useful for debug purposes + * + * @var array + * @see self::encode_der() + */ + private static $location; + + /** + * DER Encoded String + * + * In case we need to create ASN1\Element object's.. + * + * @var string + * @see self::decodeDER() + */ + private static $encoded; + + /** + * Type mapping table for the ANY type. + * + * Structured or unknown types are mapped to a \phpseclib3\File\ASN1\Element. + * Unambiguous types get the direct mapping (int/real/bool). + * Others are mapped as a choice, with an extra indexing level. + * + * @var array + */ + const ANY_MAP = [ + self::TYPE_BOOLEAN => true, + self::TYPE_INTEGER => true, + self::TYPE_BIT_STRING => 'bitString', + self::TYPE_OCTET_STRING => 'octetString', + self::TYPE_NULL => 'null', + self::TYPE_OBJECT_IDENTIFIER => 'objectIdentifier', + self::TYPE_REAL => true, + self::TYPE_ENUMERATED => 'enumerated', + self::TYPE_UTF8_STRING => 'utf8String', + self::TYPE_NUMERIC_STRING => 'numericString', + self::TYPE_PRINTABLE_STRING => 'printableString', + self::TYPE_TELETEX_STRING => 'teletexString', + self::TYPE_VIDEOTEX_STRING => 'videotexString', + self::TYPE_IA5_STRING => 'ia5String', + self::TYPE_UTC_TIME => 'utcTime', + self::TYPE_GENERALIZED_TIME => 'generalTime', + self::TYPE_GRAPHIC_STRING => 'graphicString', + self::TYPE_VISIBLE_STRING => 'visibleString', + self::TYPE_GENERAL_STRING => 'generalString', + self::TYPE_UNIVERSAL_STRING => 'universalString', + //self::TYPE_CHARACTER_STRING => 'characterString', + self::TYPE_BMP_STRING => 'bmpString' + ]; + + /** + * String type to character size mapping table. + * + * Non-convertable types are absent from this table. + * size == 0 indicates variable length encoding. + * + * @var array + */ + const STRING_TYPE_SIZE = [ + self::TYPE_UTF8_STRING => 0, + self::TYPE_BMP_STRING => 2, + self::TYPE_UNIVERSAL_STRING => 4, + self::TYPE_PRINTABLE_STRING => 1, + self::TYPE_TELETEX_STRING => 1, + self::TYPE_IA5_STRING => 1, + self::TYPE_VISIBLE_STRING => 1, + ]; + + /** + * Parse BER-encoding + * + * Serves a similar purpose to openssl's asn1parse + * + * @param Element|string $encoded + * @return ?array + */ + public static function decodeBER($encoded) + { + if ($encoded instanceof Element) { + $encoded = $encoded->element; + } + + self::$encoded = $encoded; + + $decoded = self::decode_ber($encoded); + if ($decoded === false) { + return null; + } + + return [$decoded]; + } + + /** + * Parse BER-encoding (Helper function) + * + * Sometimes we want to get the BER encoding of a particular tag. $start lets us do that without having to reencode. + * $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and + * self::TYPE_OCTET_STRING. In those cases, the indefinite length is used. + * + * @param string $encoded + * @param int $start + * @param int $encoded_pos + * @return array|bool + */ + private static function decode_ber($encoded, $start = 0, $encoded_pos = 0) + { + $current = ['start' => $start]; + + if (!isset($encoded[$encoded_pos])) { + return false; + } + $type = ord($encoded[$encoded_pos++]); + $startOffset = 1; + + $constructed = ($type >> 5) & 1; + + $tag = $type & 0x1F; + if ($tag == 0x1F) { + $tag = 0; + // process septets (since the eighth bit is ignored, it's not an octet) + do { + if (!isset($encoded[$encoded_pos])) { + return false; + } + $temp = ord($encoded[$encoded_pos++]); + $startOffset++; + $loop = $temp >> 7; + $tag <<= 7; + $temp &= 0x7F; + // "bits 7 to 1 of the first subsequent octet shall not all be zero" + if ($startOffset == 2 && $temp == 0) { + return false; + } + $tag |= $temp; + } while ($loop); + } + + $start += $startOffset; + + // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 + if (!isset($encoded[$encoded_pos])) { + return false; + } + $length = ord($encoded[$encoded_pos++]); + $start++; + if ($length == 0x80) { // indefinite length + // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all + // immediately available." -- paragraph 8.1.3.2.c + $length = strlen($encoded) - $encoded_pos; + } elseif ($length & 0x80) { // definite length, long form + // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only + // support it up to four. + $length &= 0x7F; + $temp = substr($encoded, $encoded_pos, $length); + $encoded_pos += $length; + // tags of indefinte length don't really have a header length; this length includes the tag + $current += ['headerlength' => $length + 2]; + $start += $length; + extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); + /** @var integer $length */ + } else { + $current += ['headerlength' => 2]; + } + + if ($length > (strlen($encoded) - $encoded_pos)) { + return false; + } + + $content = substr($encoded, $encoded_pos, $length); + $content_pos = 0; + + // at this point $length can be overwritten. it's only accurate for definite length things as is + + /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1 + built-in types. It defines an application-independent data type that must be distinguishable from all other + data types. The other three classes are user defined. The APPLICATION class distinguishes data types that + have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within + a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the + alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this + data type; the term CONTEXT-SPECIFIC does not appear. + + -- http://www.obj-sys.com/asn1tutorial/node12.html */ + $class = ($type >> 6) & 3; + switch ($class) { + case self::CLASS_APPLICATION: + case self::CLASS_PRIVATE: + case self::CLASS_CONTEXT_SPECIFIC: + if (!$constructed) { + return [ + 'type' => $class, + 'constant' => $tag, + 'content' => $content, + 'length' => $length + $start - $current['start'] + ] + $current; + } + + $newcontent = []; + $remainingLength = $length; + while ($remainingLength > 0) { + $temp = self::decode_ber($content, $start, $content_pos); + if ($temp === false) { + break; + } + $length = $temp['length']; + // end-of-content octets - see paragraph 8.1.5 + if (substr($content, $content_pos + $length, 2) == "\0\0") { + $length += 2; + $start += $length; + $newcontent[] = $temp; + break; + } + $start += $length; + $remainingLength -= $length; + $newcontent[] = $temp; + $content_pos += $length; + } + + return [ + 'type' => $class, + 'constant' => $tag, + // the array encapsulation is for BC with the old format + 'content' => $newcontent, + // the only time when $content['headerlength'] isn't defined is when the length is indefinite. + // the absence of $content['headerlength'] is how we know if something is indefinite or not. + // technically, it could be defined to be 2 and then another indicator could be used but whatever. + 'length' => $start - $current['start'] + ] + $current; + } + + $current += ['type' => $tag]; + + // decode UNIVERSAL tags + switch ($tag) { + case self::TYPE_BOOLEAN: + // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 + if ($constructed || strlen($content) != 1) { + return false; + } + $current['content'] = (bool) ord($content[$content_pos]); + break; + case self::TYPE_INTEGER: + case self::TYPE_ENUMERATED: + if ($constructed) { + return false; + } + $current['content'] = new BigInteger(substr($content, $content_pos), -256); + break; + case self::TYPE_REAL: // not currently supported + return false; + case self::TYPE_BIT_STRING: + // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, + // the number of unused bits in the final subsequent octet. The number shall be in the range zero to + // seven. + if (!$constructed) { + $current['content'] = substr($content, $content_pos); + } else { + $temp = self::decode_ber($content, $start, $content_pos); + if ($temp === false) { + return false; + } + $length -= (strlen($content) - $content_pos); + $last = count($temp) - 1; + for ($i = 0; $i < $last; $i++) { + // all subtags should be bit strings + if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { + return false; + } + $current['content'] .= substr($temp[$i]['content'], 1); + } + // all subtags should be bit strings + if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { + return false; + } + $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); + } + break; + case self::TYPE_OCTET_STRING: + if (!$constructed) { + $current['content'] = substr($content, $content_pos); + } else { + $current['content'] = ''; + $length = 0; + while (substr($content, $content_pos, 2) != "\0\0") { + $temp = self::decode_ber($content, $length + $start, $content_pos); + if ($temp === false) { + return false; + } + $content_pos += $temp['length']; + // all subtags should be octet strings + if ($temp['type'] != self::TYPE_OCTET_STRING) { + return false; + } + $current['content'] .= $temp['content']; + $length += $temp['length']; + } + if (substr($content, $content_pos, 2) == "\0\0") { + $length += 2; // +2 for the EOC + } + } + break; + case self::TYPE_NULL: + // "The contents octets shall not contain any octets." -- paragraph 8.8.2 + if ($constructed || strlen($content)) { + return false; + } + break; + case self::TYPE_SEQUENCE: + case self::TYPE_SET: + if (!$constructed) { + return false; + } + $offset = 0; + $current['content'] = []; + $content_len = strlen($content); + while ($content_pos < $content_len) { + // if indefinite length construction was used and we have an end-of-content string next + // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2 + if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") { + $length = $offset + 2; // +2 for the EOC + break 2; + } + $temp = self::decode_ber($content, $start + $offset, $content_pos); + if ($temp === false) { + return false; + } + $content_pos += $temp['length']; + $current['content'][] = $temp; + $offset += $temp['length']; + } + break; + case self::TYPE_OBJECT_IDENTIFIER: + if ($constructed) { + return false; + } + $current['content'] = self::decodeOID(substr($content, $content_pos)); + if ($current['content'] === false) { + return false; + } + break; + /* Each character string type shall be encoded as if it had been declared: + [UNIVERSAL x] IMPLICIT OCTET STRING + + -- X.690-0207.pdf#page=23 (paragraph 8.21.3) + + Per that, we're not going to do any validation. If there are any illegal characters in the string, + we don't really care */ + case self::TYPE_NUMERIC_STRING: + // 0,1,2,3,4,5,6,7,8,9, and space + case self::TYPE_PRINTABLE_STRING: + // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma, + // hyphen, full stop, solidus, colon, equal sign, question mark + case self::TYPE_TELETEX_STRING: + // The Teletex character set in CCITT's T61, space, and delete + // see http://en.wikipedia.org/wiki/Teletex#Character_sets + case self::TYPE_VIDEOTEX_STRING: + // The Videotex character set in CCITT's T.100 and T.101, space, and delete + case self::TYPE_VISIBLE_STRING: + // Printing character sets of international ASCII, and space + case self::TYPE_IA5_STRING: + // International Alphabet 5 (International ASCII) + case self::TYPE_GRAPHIC_STRING: + // All registered G sets, and space + case self::TYPE_GENERAL_STRING: + // All registered C and G sets, space and delete + case self::TYPE_UTF8_STRING: + // ???? + case self::TYPE_BMP_STRING: + if ($constructed) { + return false; + } + $current['content'] = substr($content, $content_pos); + break; + case self::TYPE_UTC_TIME: + case self::TYPE_GENERALIZED_TIME: + if ($constructed) { + return false; + } + $current['content'] = self::decodeTime(substr($content, $content_pos), $tag); + break; + default: + return false; + } + + $start += $length; + + // ie. length is the length of the full TLV encoding - it's not just the length of the value + return $current + ['length' => $start - $current['start']]; + } + + /** + * ASN.1 Map + * + * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format. + * + * "Special" mappings may be applied on a per tag-name basis via $special. + * + * @param array $decoded + * @param array $mapping + * @param array $special + * @return array|bool|Element|string|null + */ + public static function asn1map(array $decoded, $mapping, $special = []) + { + if (isset($mapping['explicit']) && is_array($decoded['content'])) { + $decoded = $decoded['content'][0]; + } + + switch (true) { + case $mapping['type'] == self::TYPE_ANY: + $intype = $decoded['type']; + // !isset(self::ANY_MAP[$intype]) produces a fatal error on PHP 5.6 + if (isset($decoded['constant']) || !array_key_exists($intype, self::ANY_MAP) || (ord(self::$encoded[$decoded['start']]) & 0x20)) { + return new Element(substr(self::$encoded, $decoded['start'], $decoded['length'])); + } + $inmap = self::ANY_MAP[$intype]; + if (is_string($inmap)) { + return [$inmap => self::asn1map($decoded, ['type' => $intype] + $mapping, $special)]; + } + break; + case $mapping['type'] == self::TYPE_CHOICE: + foreach ($mapping['children'] as $key => $option) { + switch (true) { + case isset($option['constant']) && $option['constant'] == $decoded['constant']: + case !isset($option['constant']) && $option['type'] == $decoded['type']: + $value = self::asn1map($decoded, $option, $special); + break; + case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE: + $v = self::asn1map($decoded, $option, $special); + if (isset($v)) { + $value = $v; + } + } + if (isset($value)) { + if (isset($special[$key])) { + $value = $special[$key]($value); + } + return [$key => $value]; + } + } + return null; + case isset($mapping['implicit']): + case isset($mapping['explicit']): + case $decoded['type'] == $mapping['type']: + break; + default: + // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings, + // let it through + switch (true) { + case $decoded['type'] < 18: // self::TYPE_NUMERIC_STRING == 18 + case $decoded['type'] > 30: // self::TYPE_BMP_STRING == 30 + case $mapping['type'] < 18: + case $mapping['type'] > 30: + return null; + } + } + + if (isset($mapping['implicit'])) { + $decoded['type'] = $mapping['type']; + } + + switch ($decoded['type']) { + case self::TYPE_SEQUENCE: + $map = []; + + // ignore the min and max + if (isset($mapping['min']) && isset($mapping['max'])) { + $child = $mapping['children']; + foreach ($decoded['content'] as $content) { + if (($map[] = self::asn1map($content, $child, $special)) === null) { + return null; + } + } + + return $map; + } + + $n = count($decoded['content']); + $i = 0; + + foreach ($mapping['children'] as $key => $child) { + $maymatch = $i < $n; // Match only existing input. + if ($maymatch) { + $temp = $decoded['content'][$i]; + + if ($child['type'] != self::TYPE_CHOICE) { + // Get the mapping and input class & constant. + $childClass = $tempClass = self::CLASS_UNIVERSAL; + $constant = null; + if (isset($temp['constant'])) { + $tempClass = $temp['type']; + } + if (isset($child['class'])) { + $childClass = $child['class']; + $constant = $child['cast']; + } elseif (isset($child['constant'])) { + $childClass = self::CLASS_CONTEXT_SPECIFIC; + $constant = $child['constant']; + } + + if (isset($constant) && isset($temp['constant'])) { + // Can only match if constants and class match. + $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; + } else { + // Can only match if no constant expected and type matches or is generic. + $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; + } + } + } + + if ($maymatch) { + // Attempt submapping. + $candidate = self::asn1map($temp, $child, $special); + $maymatch = $candidate !== null; + } + + if ($maymatch) { + // Got the match: use it. + if (isset($special[$key])) { + $candidate = $special[$key]($candidate); + } + $map[$key] = $candidate; + $i++; + } elseif (isset($child['default'])) { + $map[$key] = $child['default']; + } elseif (!isset($child['optional'])) { + return null; // Syntax error. + } + } + + // Fail mapping if all input items have not been consumed. + return $i < $n ? null : $map; + + // the main diff between sets and sequences is the encapsulation of the foreach in another for loop + case self::TYPE_SET: + $map = []; + + // ignore the min and max + if (isset($mapping['min']) && isset($mapping['max'])) { + $child = $mapping['children']; + foreach ($decoded['content'] as $content) { + if (($map[] = self::asn1map($content, $child, $special)) === null) { + return null; + } + } + + return $map; + } + + for ($i = 0; $i < count($decoded['content']); $i++) { + $temp = $decoded['content'][$i]; + $tempClass = self::CLASS_UNIVERSAL; + if (isset($temp['constant'])) { + $tempClass = $temp['type']; + } + + foreach ($mapping['children'] as $key => $child) { + if (isset($map[$key])) { + continue; + } + $maymatch = true; + if ($child['type'] != self::TYPE_CHOICE) { + $childClass = self::CLASS_UNIVERSAL; + $constant = null; + if (isset($child['class'])) { + $childClass = $child['class']; + $constant = $child['cast']; + } elseif (isset($child['constant'])) { + $childClass = self::CLASS_CONTEXT_SPECIFIC; + $constant = $child['constant']; + } + + if (isset($constant) && isset($temp['constant'])) { + // Can only match if constants and class match. + $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; + } else { + // Can only match if no constant expected and type matches or is generic. + $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; + } + } + + if ($maymatch) { + // Attempt submapping. + $candidate = self::asn1map($temp, $child, $special); + $maymatch = $candidate !== null; + } + + if (!$maymatch) { + break; + } + + // Got the match: use it. + if (isset($special[$key])) { + $candidate = $special[$key]($candidate); + } + $map[$key] = $candidate; + break; + } + } + + foreach ($mapping['children'] as $key => $child) { + if (!isset($map[$key])) { + if (isset($child['default'])) { + $map[$key] = $child['default']; + } elseif (!isset($child['optional'])) { + return null; + } + } + } + return $map; + case self::TYPE_OBJECT_IDENTIFIER: + return isset(self::$oids[$decoded['content']]) ? self::$oids[$decoded['content']] : $decoded['content']; + case self::TYPE_UTC_TIME: + case self::TYPE_GENERALIZED_TIME: + // for explicitly tagged optional stuff + if (is_array($decoded['content'])) { + $decoded['content'] = $decoded['content'][0]['content']; + } + // for implicitly tagged optional stuff + // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist + // in the wild that OpenSSL decodes without issue so we'll support them as well + if (!is_object($decoded['content'])) { + $decoded['content'] = self::decodeTime($decoded['content'], $decoded['type']); + } + return $decoded['content'] ? $decoded['content']->format(self::$format) : false; + case self::TYPE_BIT_STRING: + if (isset($mapping['mapping'])) { + $offset = ord($decoded['content'][0]); + $size = (strlen($decoded['content']) - 1) * 8 - $offset; + /* + From X.680-0207.pdf#page=46 (21.7): + + "When a "NamedBitList" is used in defining a bitstring type ASN.1 encoding rules are free to add (or remove) + arbitrarily any trailing 0 bits to (or from) values that are being encoded or decoded. Application designers should + therefore ensure that different semantics are not associated with such values which differ only in the number of trailing + 0 bits." + */ + $bits = count($mapping['mapping']) == $size ? [] : array_fill(0, count($mapping['mapping']) - $size, false); + for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) { + $current = ord($decoded['content'][$i]); + for ($j = $offset; $j < 8; $j++) { + $bits[] = (bool) ($current & (1 << $j)); + } + $offset = 0; + } + $values = []; + $map = array_reverse($mapping['mapping']); + foreach ($map as $i => $value) { + if ($bits[$i]) { + $values[] = $value; + } + } + return $values; + } + // fall-through + case self::TYPE_OCTET_STRING: + return $decoded['content']; + case self::TYPE_NULL: + return ''; + case self::TYPE_BOOLEAN: + case self::TYPE_NUMERIC_STRING: + case self::TYPE_PRINTABLE_STRING: + case self::TYPE_TELETEX_STRING: + case self::TYPE_VIDEOTEX_STRING: + case self::TYPE_IA5_STRING: + case self::TYPE_GRAPHIC_STRING: + case self::TYPE_VISIBLE_STRING: + case self::TYPE_GENERAL_STRING: + case self::TYPE_UNIVERSAL_STRING: + case self::TYPE_UTF8_STRING: + case self::TYPE_BMP_STRING: + return $decoded['content']; + case self::TYPE_INTEGER: + case self::TYPE_ENUMERATED: + $temp = $decoded['content']; + if (isset($mapping['implicit'])) { + $temp = new BigInteger($decoded['content'], -256); + } + if (isset($mapping['mapping'])) { + $temp = (int) $temp->toString(); + return isset($mapping['mapping'][$temp]) ? + $mapping['mapping'][$temp] : + false; + } + return $temp; + } + } + + /** + * DER-decode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @param string $string + * @return int + */ + public static function decodeLength(&$string) + { + $length = ord(Strings::shift($string)); + if ($length & 0x80) { // definite length, long form + $length &= 0x7F; + $temp = Strings::shift($string, $length); + list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); + } + return $length; + } + + /** + * ASN.1 Encode + * + * DER-encodes an ASN.1 semantic mapping ($mapping). Some libraries would probably call this function + * an ASN.1 compiler. + * + * "Special" mappings can be applied via $special. + * + * @param Element|string|array $source + * @param array $mapping + * @param array $special + * @return string + */ + public static function encodeDER($source, $mapping, $special = []) + { + self::$location = []; + return self::encode_der($source, $mapping, null, $special); + } + + /** + * ASN.1 Encode (Helper function) + * + * @param Element|string|array|null $source + * @param array $mapping + * @param int $idx + * @param array $special + * @return string + */ + private static function encode_der($source, array $mapping, $idx = null, array $special = []) + { + if ($source instanceof Element) { + return $source->element; + } + + // do not encode (implicitly optional) fields with value set to default + if (isset($mapping['default']) && $source === $mapping['default']) { + return ''; + } + + if (isset($idx)) { + if (isset($special[$idx])) { + $source = $special[$idx]($source); + } + self::$location[] = $idx; + } + + $tag = $mapping['type']; + + switch ($tag) { + case self::TYPE_SET: // Children order is not important, thus process in sequence. + case self::TYPE_SEQUENCE: + $tag |= 0x20; // set the constructed bit + + // ignore the min and max + if (isset($mapping['min']) && isset($mapping['max'])) { + $value = []; + $child = $mapping['children']; + + foreach ($source as $content) { + $temp = self::encode_der($content, $child, null, $special); + if ($temp === false) { + return false; + } + $value[] = $temp; + } + /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared + as octet strings with the shorter components being padded at their trailing end with 0-octets. + NOTE - The padding octets are for comparison purposes only and do not appear in the encodings." + + -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ + if ($mapping['type'] == self::TYPE_SET) { + sort($value); + } + $value = implode('', $value); + break; + } + + $value = ''; + foreach ($mapping['children'] as $key => $child) { + if (!array_key_exists($key, $source)) { + if (!isset($child['optional'])) { + return false; + } + continue; + } + + $temp = self::encode_der($source[$key], $child, $key, $special); + if ($temp === false) { + return false; + } + + // An empty child encoding means it has been optimized out. + // Else we should have at least one tag byte. + if ($temp === '') { + continue; + } + + // if isset($child['constant']) is true then isset($child['optional']) should be true as well + if (isset($child['constant'])) { + /* + From X.680-0207.pdf#page=58 (30.6): + + "The tagging construction specifies explicit tagging if any of the following holds: + ... + c) the "Tag Type" alternative is used and the value of "TagDefault" for the module is IMPLICIT TAGS or + AUTOMATIC TAGS, but the type defined by "Type" is an untagged choice type, an untagged open type, or + an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)." + */ + if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); + $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; + } else { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); + $temp = $subtag . substr($temp, 1); + } + } + $value .= $temp; + } + break; + case self::TYPE_CHOICE: + $temp = false; + + foreach ($mapping['children'] as $key => $child) { + if (!isset($source[$key])) { + continue; + } + + $temp = self::encode_der($source[$key], $child, $key, $special); + if ($temp === false) { + return false; + } + + // An empty child encoding means it has been optimized out. + // Else we should have at least one tag byte. + if ($temp === '') { + continue; + } + + $tag = ord($temp[0]); + + // if isset($child['constant']) is true then isset($child['optional']) should be true as well + if (isset($child['constant'])) { + if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); + $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; + } else { + $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); + $temp = $subtag . substr($temp, 1); + } + } + } + + if (isset($idx)) { + array_pop(self::$location); + } + + if ($temp && isset($mapping['cast'])) { + $temp[0] = chr(($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']); + } + + return $temp; + case self::TYPE_INTEGER: + case self::TYPE_ENUMERATED: + if (!isset($mapping['mapping'])) { + if (is_numeric($source)) { + $source = new BigInteger($source); + } + $value = $source->toBytes(true); + } else { + $value = array_search($source, $mapping['mapping']); + if ($value === false) { + return false; + } + $value = new BigInteger($value); + $value = $value->toBytes(true); + } + if (!strlen($value)) { + $value = chr(0); + } + break; + case self::TYPE_UTC_TIME: + case self::TYPE_GENERALIZED_TIME: + $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y'; + $format .= 'mdHis'; + // if $source does _not_ include timezone information within it then assume that the timezone is GMT + $date = new \DateTime($source, new \DateTimeZone('GMT')); + // if $source _does_ include timezone information within it then convert the time to GMT + $date->setTimezone(new \DateTimeZone('GMT')); + $value = $date->format($format) . 'Z'; + break; + case self::TYPE_BIT_STRING: + if (isset($mapping['mapping'])) { + $bits = array_fill(0, count($mapping['mapping']), 0); + $size = 0; + for ($i = 0; $i < count($mapping['mapping']); $i++) { + if (in_array($mapping['mapping'][$i], $source)) { + $bits[$i] = 1; + $size = $i; + } + } + + if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) { + $size = $mapping['min'] - 1; + } + + $offset = 8 - (($size + 1) & 7); + $offset = $offset !== 8 ? $offset : 0; + + $value = chr($offset); + + for ($i = $size + 1; $i < count($mapping['mapping']); $i++) { + unset($bits[$i]); + } + + $bits = implode('', array_pad($bits, $size + $offset + 1, 0)); + $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' '))); + foreach ($bytes as $byte) { + $value .= chr(bindec($byte)); + } + + break; + } + // fall-through + case self::TYPE_OCTET_STRING: + /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, + the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. + + -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ + $value = $source; + break; + case self::TYPE_OBJECT_IDENTIFIER: + $value = self::encodeOID($source); + break; + case self::TYPE_ANY: + $loc = self::$location; + if (isset($idx)) { + array_pop(self::$location); + } + + switch (true) { + case !isset($source): + return self::encode_der(null, ['type' => self::TYPE_NULL] + $mapping, null, $special); + case is_int($source): + case $source instanceof BigInteger: + return self::encode_der($source, ['type' => self::TYPE_INTEGER] + $mapping, null, $special); + case is_float($source): + return self::encode_der($source, ['type' => self::TYPE_REAL] + $mapping, null, $special); + case is_bool($source): + return self::encode_der($source, ['type' => self::TYPE_BOOLEAN] + $mapping, null, $special); + case is_array($source) && count($source) == 1: + $typename = implode('', array_keys($source)); + $outtype = array_search($typename, self::ANY_MAP, true); + if ($outtype !== false) { + return self::encode_der($source[$typename], ['type' => $outtype] + $mapping, null, $special); + } + } + + $filters = self::$filters; + foreach ($loc as $part) { + if (!isset($filters[$part])) { + $filters = false; + break; + } + $filters = $filters[$part]; + } + if ($filters === false) { + throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); + } + return self::encode_der($source, $filters + $mapping, null, $special); + case self::TYPE_NULL: + $value = ''; + break; + case self::TYPE_NUMERIC_STRING: + case self::TYPE_TELETEX_STRING: + case self::TYPE_PRINTABLE_STRING: + case self::TYPE_UNIVERSAL_STRING: + case self::TYPE_UTF8_STRING: + case self::TYPE_BMP_STRING: + case self::TYPE_IA5_STRING: + case self::TYPE_VISIBLE_STRING: + case self::TYPE_VIDEOTEX_STRING: + case self::TYPE_GRAPHIC_STRING: + case self::TYPE_GENERAL_STRING: + $value = $source; + break; + case self::TYPE_BOOLEAN: + $value = $source ? "\xFF" : "\x00"; + break; + default: + throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); + } + + if (isset($idx)) { + array_pop(self::$location); + } + + if (isset($mapping['cast'])) { + if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) { + $value = chr($tag) . self::encodeLength(strlen($value)) . $value; + $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; + } else { + $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; + } + } + + return chr($tag) . self::encodeLength(strlen($value)) . $value; + } + + /** + * BER-decode the OID + * + * Called by _decode_ber() + * + * @param string $content + * @return string + */ + public static function decodeOID($content) + { + static $eighty; + if (!$eighty) { + $eighty = new BigInteger(80); + } + + $oid = []; + $pos = 0; + $len = strlen($content); + + if (ord($content[$len - 1]) & 0x80) { + return false; + } + + $n = new BigInteger(); + while ($pos < $len) { + $temp = ord($content[$pos++]); + $n = $n->bitwise_leftShift(7); + $n = $n->bitwise_or(new BigInteger($temp & 0x7F)); + if (~$temp & 0x80) { + $oid[] = $n; + $n = new BigInteger(); + } + } + $part1 = array_shift($oid); + $first = floor(ord($content[0]) / 40); + /* + "This packing of the first two object identifier components recognizes that only three values are allocated from the root + node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1." + + -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22 + */ + if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78) + array_unshift($oid, ord($content[0]) % 40); + array_unshift($oid, $first); + } else { + array_unshift($oid, $part1->subtract($eighty)); + array_unshift($oid, 2); + } + + return implode('.', $oid); + } + + /** + * DER-encode the OID + * + * Called by _encode_der() + * + * @param string $source + * @return string + */ + public static function encodeOID($source) + { + static $mask, $zero, $forty; + if (!$mask) { + $mask = new BigInteger(0x7F); + $zero = new BigInteger(); + $forty = new BigInteger(40); + } + + if (!preg_match('#(?:\d+\.)+#', $source)) { + $oid = isset(self::$reverseOIDs[$source]) ? self::$reverseOIDs[$source] : false; + } else { + $oid = $source; + } + if ($oid === false) { + throw new \RuntimeException('Invalid OID'); + } + + $parts = explode('.', $oid); + $part1 = array_shift($parts); + $part2 = array_shift($parts); + + $first = new BigInteger($part1); + $first = $first->multiply($forty); + $first = $first->add(new BigInteger($part2)); + + array_unshift($parts, $first->toString()); + + $value = ''; + foreach ($parts as $part) { + if (!$part) { + $temp = "\0"; + } else { + $temp = ''; + $part = new BigInteger($part); + while (!$part->equals($zero)) { + $submask = $part->bitwise_and($mask); + $submask->setPrecision(8); + $temp = (chr(0x80) | $submask->toBytes()) . $temp; + $part = $part->bitwise_rightShift(7); + } + $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F); + } + $value .= $temp; + } + + return $value; + } + + /** + * BER-decode the time + * + * Called by _decode_ber() and in the case of implicit tags asn1map(). + * + * @param string $content + * @param int $tag + * @return \DateTime|false + */ + private static function decodeTime($content, $tag) + { + /* UTCTime: + http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 + http://www.obj-sys.com/asn1tutorial/node15.html + + GeneralizedTime: + http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2 + http://www.obj-sys.com/asn1tutorial/node14.html */ + + $format = 'YmdHis'; + + if ($tag == self::TYPE_UTC_TIME) { + // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds + // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the + // browsers parse it phpseclib ought to too + if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) { + $content = $matches[1] . '00' . $matches[2]; + } + $prefix = substr($content, 0, 2) >= 50 ? '19' : '20'; + $content = $prefix . $content; + } elseif (strpos($content, '.') !== false) { + $format .= '.u'; + } + + if ($content[strlen($content) - 1] == 'Z') { + $content = substr($content, 0, -1) . '+0000'; + } + + if (strpos($content, '-') !== false || strpos($content, '+') !== false) { + $format .= 'O'; + } + + // error supression isn't necessary as of PHP 7.0: + // http://php.net/manual/en/migration70.other-changes.php + return @\DateTime::createFromFormat($format, $content); + } + + /** + * Set the time format + * + * Sets the time / date format for asn1map(). + * + * @param string $format + */ + public static function setTimeFormat($format) + { + self::$format = $format; + } + + /** + * Load OIDs + * + * Load the relevant OIDs for a particular ASN.1 semantic mapping. + * Previously loaded OIDs are retained. + * + * @param array $oids + */ + public static function loadOIDs(array $oids) + { + self::$reverseOIDs += $oids; + self::$oids = array_flip(self::$reverseOIDs); + } + + /** + * Set filters + * + * See \phpseclib3\File\X509, etc, for an example. + * Previously loaded filters are not retained. + * + * @param array $filters + */ + public static function setFilters(array $filters) + { + self::$filters = $filters; + } + + /** + * String type conversion + * + * This is a lazy conversion, dealing only with character size. + * No real conversion table is used. + * + * @param string $in + * @param int $from + * @param int $to + * @return string + */ + public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) + { + // isset(self::STRING_TYPE_SIZE[$from] returns a fatal error on PHP 5.6 + if (!array_key_exists($from, self::STRING_TYPE_SIZE) || !array_key_exists($to, self::STRING_TYPE_SIZE)) { + return false; + } + $insize = self::STRING_TYPE_SIZE[$from]; + $outsize = self::STRING_TYPE_SIZE[$to]; + $inlength = strlen($in); + $out = ''; + + for ($i = 0; $i < $inlength;) { + if ($inlength - $i < $insize) { + return false; + } + + // Get an input character as a 32-bit value. + $c = ord($in[$i++]); + switch (true) { + case $insize == 4: + $c = ($c << 8) | ord($in[$i++]); + $c = ($c << 8) | ord($in[$i++]); + // fall-through + case $insize == 2: + $c = ($c << 8) | ord($in[$i++]); + // fall-through + case $insize == 1: + break; + case ($c & 0x80) == 0x00: + break; + case ($c & 0x40) == 0x00: + return false; + default: + $bit = 6; + do { + if ($bit > 25 || $i >= $inlength || (ord($in[$i]) & 0xC0) != 0x80) { + return false; + } + $c = ($c << 6) | (ord($in[$i++]) & 0x3F); + $bit += 5; + $mask = 1 << $bit; + } while ($c & $bit); + $c &= $mask - 1; + break; + } + + // Convert and append the character to output string. + $v = ''; + switch (true) { + case $outsize == 4: + $v .= chr($c & 0xFF); + $c >>= 8; + $v .= chr($c & 0xFF); + $c >>= 8; + // fall-through + case $outsize == 2: + $v .= chr($c & 0xFF); + $c >>= 8; + // fall-through + case $outsize == 1: + $v .= chr($c & 0xFF); + $c >>= 8; + if ($c) { + return false; + } + break; + case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0: + return false; + case $c >= 0x04000000: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x04000000; + // fall-through + case $c >= 0x00200000: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x00200000; + // fall-through + case $c >= 0x00010000: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x00010000; + // fall-through + case $c >= 0x00000800: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x00000800; + // fall-through + case $c >= 0x00000080: + $v .= chr(0x80 | ($c & 0x3F)); + $c = ($c >> 6) | 0x000000C0; + // fall-through + default: + $v .= chr($c); + break; + } + $out .= strrev($v); + } + return $out; + } + + /** + * Extract raw BER from Base64 encoding + * + * @param string $str + * @return string + */ + public static function extractBER($str) + { + /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them + * above and beyond the ceritificate. + * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: + * + * Bag Attributes + * localKeyID: 01 00 00 00 + * subject=/O=organization/OU=org unit/CN=common name + * issuer=/O=organization/CN=common name + */ + if (strlen($str) > ini_get('pcre.backtrack_limit')) { + $temp = $str; + } else { + $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); + $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1); + } + // remove new lines + $temp = str_replace(["\r", "\n", ' '], '', $temp); + // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff + $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; + return $temp != false ? $temp : $str; + } + + /** + * DER-encode the length + * + * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See + * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. + * + * @param int $length + * @return string + */ + public static function encodeLength($length) + { + if ($length <= 0x7F) { + return chr($length); + } + + $temp = ltrim(pack('N', $length), chr(0)); + return pack('Ca*', 0x80 | strlen($temp), $temp); + } + + /** + * Returns the OID corresponding to a name + * + * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if + * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version + * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able + * to work from version to version. + * + * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that + * what's being passed to it already is an OID and return that instead. A few examples. + * + * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' + * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' + * getOID('zzz') == 'zzz' + * + * @param string $name + * @return string + */ + public static function getOID($name) + { + return isset(self::$reverseOIDs[$name]) ? self::$reverseOIDs[$name] : $name; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php new file mode 100644 index 0000000..6540b42 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php @@ -0,0 +1,43 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1; + +/** + * ASN.1 Raw Element + * + * An ASN.1 ANY mapping will return an ASN1\Element object. Use of this object + * will also bypass the normal encoding rules in ASN1::encodeDER() + * + * @author Jim Wigginton + */ +class Element +{ + /** + * Raw element value + * + * @var string + */ + public $element; + + /** + * Constructor + * + * @param string $encoded + * @return \phpseclib3\File\ASN1\Element + */ + public function __construct($encoded) + { + $this->element = $encoded; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php new file mode 100644 index 0000000..1cbc5a5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AccessDescription + * + * @author Jim Wigginton + */ +abstract class AccessDescription +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'accessMethod' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'accessLocation' => GeneralName::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php new file mode 100644 index 0000000..04183a1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AdministrationDomainName + * + * @author Jim Wigginton + */ +abstract class AdministrationDomainName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 2, + 'children' => [ + 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php new file mode 100644 index 0000000..0da7eb1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AlgorithmIdentifier + * + * @author Jim Wigginton + */ +abstract class AlgorithmIdentifier +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'algorithm' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php new file mode 100644 index 0000000..d96c170 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AnotherName + * + * @author Jim Wigginton + */ +abstract class AnotherName +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type-id' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'value' => [ + 'type' => ASN1::TYPE_ANY, + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php new file mode 100644 index 0000000..38a6aee --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Attribute + * + * @author Jim Wigginton + */ +abstract class Attribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => AttributeType::MAP, + 'value' => [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => AttributeValue::MAP + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php new file mode 100644 index 0000000..5cbc2bc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeType + * + * @author Jim Wigginton + */ +abstract class AttributeType +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php new file mode 100644 index 0000000..fe414f1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeTypeAndValue + * + * @author Jim Wigginton + */ +abstract class AttributeTypeAndValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => AttributeType::MAP, + 'value' => AttributeValue::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php new file mode 100644 index 0000000..3b3b6d2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AttributeValue + * + * @author Jim Wigginton + */ +abstract class AttributeValue +{ + const MAP = ['type' => ASN1::TYPE_ANY]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php new file mode 100644 index 0000000..cd53ecf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Attributes + * + * @author Jim Wigginton + */ +abstract class Attributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => Attribute::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php new file mode 100644 index 0000000..3e80a55 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AuthorityInfoAccessSyntax + * + * @author Jim Wigginton + */ +abstract class AuthorityInfoAccessSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => AccessDescription::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php new file mode 100644 index 0000000..e7ec5b2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * AuthorityKeyIdentifier + * + * @author Jim Wigginton + */ +abstract class AuthorityKeyIdentifier +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyIdentifier' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + KeyIdentifier::MAP, + 'authorityCertIssuer' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP, + 'authorityCertSerialNumber' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + CertificateSerialNumber::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php new file mode 100644 index 0000000..e59668a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BaseDistance + * + * @author Jim Wigginton + */ +abstract class BaseDistance +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php new file mode 100644 index 0000000..587ef1b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BasicConstraints + * + * @author Jim Wigginton + */ +abstract class BasicConstraints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'cA' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ], + 'pathLenConstraint' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php new file mode 100644 index 0000000..e81bc78 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInDomainDefinedAttribute + * + * @author Jim Wigginton + */ +abstract class BuiltInDomainDefinedAttribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'type' => ['type' => ASN1::TYPE_PRINTABLE_STRING], + 'value' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php new file mode 100644 index 0000000..471e88f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInDomainDefinedAttributes + * + * @author Jim Wigginton + */ +abstract class BuiltInDomainDefinedAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-domain-defined-attributes + 'children' => BuiltInDomainDefinedAttribute::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php new file mode 100644 index 0000000..752f400 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php @@ -0,0 +1,67 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * BuiltInStandardAttributes + * + * @author Jim Wigginton + */ +abstract class BuiltInStandardAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'country-name' => ['optional' => true] + CountryName::MAP, + 'administration-domain-name' => ['optional' => true] + AdministrationDomainName::MAP, + 'network-address' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + NetworkAddress::MAP, + 'terminal-identifier' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + TerminalIdentifier::MAP, + 'private-domain-name' => [ + 'constant' => 2, + 'optional' => true, + 'explicit' => true + ] + PrivateDomainName::MAP, + 'organization-name' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + OrganizationName::MAP, + 'numeric-user-identifier' => [ + 'constant' => 4, + 'optional' => true, + 'implicit' => true + ] + NumericUserIdentifier::MAP, + 'personal-name' => [ + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ] + PersonalName::MAP, + 'organizational-unit-names' => [ + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ] + OrganizationalUnitNames::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php new file mode 100644 index 0000000..56e5888 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CPSuri + * + * @author Jim Wigginton + */ +abstract class CPSuri +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php new file mode 100644 index 0000000..79860b2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLDistributionPoints + * + * @author Jim Wigginton + */ +abstract class CRLDistributionPoints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => DistributionPoint::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php new file mode 100644 index 0000000..f6cb956 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLNumber + * + * @author Jim Wigginton + */ +abstract class CRLNumber +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php new file mode 100644 index 0000000..d373652 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CRLReason + * + * @author Jim Wigginton + */ +abstract class CRLReason +{ + const MAP = [ + 'type' => ASN1::TYPE_ENUMERATED, + 'mapping' => [ + 'unspecified', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + // Value 7 is not used. + 8 => 'removeFromCRL', + 'privilegeWithdrawn', + 'aACompromise' + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php new file mode 100644 index 0000000..d7e7776 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertPolicyId + * + * @author Jim Wigginton + */ +abstract class CertPolicyId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php new file mode 100644 index 0000000..01943a0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Certificate + * + * @author Jim Wigginton + */ +abstract class Certificate +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'tbsCertificate' => TBSCertificate::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php new file mode 100644 index 0000000..ccd68dd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * CertificateIssuer + * + * @author Jim Wigginton + */ +abstract class CertificateIssuer +{ + const MAP = GeneralNames::MAP; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php new file mode 100644 index 0000000..d54ed6d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateList + * + * @author Jim Wigginton + */ +abstract class CertificateList +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'tbsCertList' => TBSCertList::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php new file mode 100644 index 0000000..ec0fa6b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificatePolicies + * + * @author Jim Wigginton + */ +abstract class CertificatePolicies +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => PolicyInformation::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php new file mode 100644 index 0000000..06ec944 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificateSerialNumber + * + * @author Jim Wigginton + */ +abstract class CertificateSerialNumber +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php new file mode 100644 index 0000000..2da70ed --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificationRequest + * + * @author Jim Wigginton + */ +abstract class CertificationRequest +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'certificationRequestInfo' => CertificationRequestInfo::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php new file mode 100644 index 0000000..ce6dc88 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CertificationRequestInfo + * + * @author Jim Wigginton + */ +abstract class CertificationRequestInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1'] + ], + 'subject' => Name::MAP, + 'subjectPKInfo' => SubjectPublicKeyInfo::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP, + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php new file mode 100644 index 0000000..5bf59bb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Characteristic_two + * + * @author Jim Wigginton + */ +abstract class Characteristic_two +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'm' => ['type' => ASN1::TYPE_INTEGER], // field size 2**m + 'basis' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php new file mode 100644 index 0000000..737d844 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * CountryName + * + * @author Jim Wigginton + */ +abstract class CountryName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or + // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC + 'class' => ASN1::CLASS_APPLICATION, + 'cast' => 1, + 'children' => [ + 'x121-dcc-code' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'iso-3166-alpha2-code' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php new file mode 100644 index 0000000..621f103 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Curve + * + * @author Jim Wigginton + */ +abstract class Curve +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'a' => FieldElement::MAP, + 'b' => FieldElement::MAP, + 'seed' => [ + 'type' => ASN1::TYPE_BIT_STRING, + 'optional' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php new file mode 100644 index 0000000..26863db --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DHParameter + * + * @author Jim Wigginton + */ +abstract class DHParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'prime' => ['type' => ASN1::TYPE_INTEGER], + 'base' => ['type' => ASN1::TYPE_INTEGER], + 'privateValueLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php new file mode 100644 index 0000000..7af397b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAParams + * + * @author Jim Wigginton + */ +abstract class DSAParams +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'p' => ['type' => ASN1::TYPE_INTEGER], + 'q' => ['type' => ASN1::TYPE_INTEGER], + 'g' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php new file mode 100644 index 0000000..d97cd02 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php @@ -0,0 +1,36 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAPrivateKey + * + * @author Jim Wigginton + */ +abstract class DSAPrivateKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => ['type' => ASN1::TYPE_INTEGER], + 'p' => ['type' => ASN1::TYPE_INTEGER], + 'q' => ['type' => ASN1::TYPE_INTEGER], + 'g' => ['type' => ASN1::TYPE_INTEGER], + 'y' => ['type' => ASN1::TYPE_INTEGER], + 'x' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php new file mode 100644 index 0000000..f795747 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DSAPublicKey + * + * @author Jim Wigginton + */ +abstract class DSAPublicKey +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php new file mode 100644 index 0000000..b38ff3c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DigestInfo + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class DigestInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'digestAlgorithm' => AlgorithmIdentifier::MAP, + 'digest' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php new file mode 100644 index 0000000..45218e3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DirectoryString + * + * @author Jim Wigginton + */ +abstract class DirectoryString +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'teletexString' => ['type' => ASN1::TYPE_TELETEX_STRING], + 'printableString' => ['type' => ASN1::TYPE_PRINTABLE_STRING], + 'universalString' => ['type' => ASN1::TYPE_UNIVERSAL_STRING], + 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING], + 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php new file mode 100644 index 0000000..a13e6a6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DisplayText + * + * @author Jim Wigginton + */ +abstract class DisplayText +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], + 'visibleString' => ['type' => ASN1::TYPE_VISIBLE_STRING], + 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING], + 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php new file mode 100644 index 0000000..4d9af6b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DistributionPoint + * + * @author Jim Wigginton + */ +abstract class DistributionPoint +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'distributionPoint' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + DistributionPointName::MAP, + 'reasons' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + ReasonFlags::MAP, + 'cRLIssuer' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php new file mode 100644 index 0000000..bc0cec8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DistributionPointName + * + * @author Jim Wigginton + */ +abstract class DistributionPointName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'fullName' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + GeneralNames::MAP, + 'nameRelativeToCRLIssuer' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + RelativeDistinguishedName::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php new file mode 100644 index 0000000..2af7408 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * DssSigValue + * + * @author Jim Wigginton + */ +abstract class DssSigValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'r' => ['type' => ASN1::TYPE_INTEGER], + 's' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php new file mode 100644 index 0000000..f25f6fa --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECParameters + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * -- implicitCurve NULL + * -- specifiedCurve SpecifiedECDomain + * } + * -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. + * -- Details for SpecifiedECDomain can be found in [X9.62]. + * -- Any future additions to this CHOICE should be coordinated + * -- with ANSI X9. + * + * @author Jim Wigginton + */ +abstract class ECParameters +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'namedCurve' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'implicitCurve' => ['type' => ASN1::TYPE_NULL], + 'specifiedCurve' => SpecifiedECDomain::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php new file mode 100644 index 0000000..fb11db8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECPoint + * + * @author Jim Wigginton + */ +abstract class ECPoint +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php new file mode 100644 index 0000000..7454f38 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php @@ -0,0 +1,48 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ECPrivateKey + * + * @author Jim Wigginton + */ +abstract class ECPrivateKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => [1 => 'ecPrivkeyVer1'] + ], + 'privateKey' => ['type' => ASN1::TYPE_OCTET_STRING], + 'parameters' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + ECParameters::MAP, + 'publicKey' => [ + 'type' => ASN1::TYPE_BIT_STRING, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php new file mode 100644 index 0000000..ea7dcf1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EDIPartyName + * + * @author Jim Wigginton + */ +abstract class EDIPartyName +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'nameAssigner' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + DirectoryString::MAP, + // partyName is technically required but \phpseclib3\File\ASN1 doesn't currently support non-optional constants and + // setting it to optional gets the job done in any event. + 'partyName' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + DirectoryString::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php new file mode 100644 index 0000000..8ab9ff1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EcdsaSigValue + * + * @author Jim Wigginton + */ +abstract class EcdsaSigValue +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'r' => ['type' => ASN1::TYPE_INTEGER], + 's' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php new file mode 100644 index 0000000..8d8739e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EncryptedData + * + * @author Jim Wigginton + */ +abstract class EncryptedData +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php new file mode 100644 index 0000000..2c93567 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * EncryptedPrivateKeyInfo + * + * @author Jim Wigginton + */ +abstract class EncryptedPrivateKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'encryptionAlgorithm' => AlgorithmIdentifier::MAP, + 'encryptedData' => EncryptedData::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php new file mode 100644 index 0000000..f9bc5de --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtKeyUsageSyntax + * + * @author Jim Wigginton + */ +abstract class ExtKeyUsageSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => KeyPurposeId::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php new file mode 100644 index 0000000..e32668f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php @@ -0,0 +1,43 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Extension + * + * A certificate using system MUST reject the certificate if it encounters + * a critical extension it does not recognize; however, a non-critical + * extension may be ignored if it is not recognized. + * + * http://tools.ietf.org/html/rfc5280#section-4.2 + * + * @author Jim Wigginton + */ +abstract class Extension +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'extnId' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'critical' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'optional' => true, + 'default' => false + ], + 'extnValue' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php new file mode 100644 index 0000000..565b36d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtensionAttribute + * + * @author Jim Wigginton + */ +abstract class ExtensionAttribute +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'extension-attribute-type' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ], + 'extension-attribute-value' => [ + 'type' => ASN1::TYPE_ANY, + 'constant' => 1, + 'optional' => true, + 'explicit' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php new file mode 100644 index 0000000..a2e9bfa --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ExtensionAttributes + * + * @author Jim Wigginton + */ +abstract class ExtensionAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => 256, // ub-extension-attributes + 'children' => ExtensionAttribute::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php new file mode 100644 index 0000000..5015c97 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Extensions + * + * @author Jim Wigginton + */ +abstract class Extensions +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + // technically, it's MAX, but we'll assume anything < 0 is MAX + 'max' => -1, + // if 'children' isn't an array then 'min' and 'max' must be defined + 'children' => Extension::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php new file mode 100644 index 0000000..3173407 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * FieldElement + * + * @author Jim Wigginton + */ +abstract class FieldElement +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php new file mode 100644 index 0000000..e32a9c0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * FieldID + * + * @author Jim Wigginton + */ +abstract class FieldID +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'fieldType' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], + 'parameters' => [ + 'type' => ASN1::TYPE_ANY, + 'optional' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php new file mode 100644 index 0000000..57d86da --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php @@ -0,0 +1,80 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralName + * + * @author Jim Wigginton + */ +abstract class GeneralName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'otherName' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + AnotherName::MAP, + 'rfc822Name' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ], + 'dNSName' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ], + 'x400Address' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ORAddress::MAP, + 'directoryName' => [ + 'constant' => 4, + 'optional' => true, + 'explicit' => true + ] + Name::MAP, + 'ediPartyName' => [ + 'constant' => 5, + 'optional' => true, + 'implicit' => true + ] + EDIPartyName::MAP, + 'uniformResourceIdentifier' => [ + 'type' => ASN1::TYPE_IA5_STRING, + 'constant' => 6, + 'optional' => true, + 'implicit' => true + ], + 'iPAddress' => [ + 'type' => ASN1::TYPE_OCTET_STRING, + 'constant' => 7, + 'optional' => true, + 'implicit' => true + ], + 'registeredID' => [ + 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, + 'constant' => 8, + 'optional' => true, + 'implicit' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php new file mode 100644 index 0000000..5d93153 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralNames + * + * @author Jim Wigginton + */ +abstract class GeneralNames +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => GeneralName::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php new file mode 100644 index 0000000..5388db5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php @@ -0,0 +1,42 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralSubtree + * + * @author Jim Wigginton + */ +abstract class GeneralSubtree +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'base' => GeneralName::MAP, + 'minimum' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'default' => '0' + ] + BaseDistance::MAP, + 'maximum' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + ] + BaseDistance::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php new file mode 100644 index 0000000..27548cf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * GeneralSubtrees + * + * @author Jim Wigginton + */ +abstract class GeneralSubtrees +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => GeneralSubtree::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php new file mode 100644 index 0000000..deb13ca --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * HashAglorithm + * + * @author Jim Wigginton + */ +abstract class HashAlgorithm +{ + const MAP = AlgorithmIdentifier::MAP; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php new file mode 100644 index 0000000..88d6ff3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * HoldInstructionCode + * + * @author Jim Wigginton + */ +abstract class HoldInstructionCode +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php new file mode 100644 index 0000000..f34b5f7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * InvalidityDate + * + * @author Jim Wigginton + */ +abstract class InvalidityDate +{ + const MAP = ['type' => ASN1::TYPE_GENERALIZED_TIME]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php new file mode 100644 index 0000000..e9d0324 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * IssuerAltName + * + * @author Jim Wigginton + */ +abstract class IssuerAltName +{ + const MAP = GeneralNames::MAP; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php new file mode 100644 index 0000000..415996f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php @@ -0,0 +1,68 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * IssuingDistributionPoint + * + * @author Jim Wigginton + */ +abstract class IssuingDistributionPoint +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'distributionPoint' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + DistributionPointName::MAP, + 'onlyContainsUserCerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 1, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlyContainsCACerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 2, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlySomeReasons' => [ + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ReasonFlags::MAP, + 'indirectCRL' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 4, + 'optional' => true, + 'default' => false, + 'implicit' => true + ], + 'onlyContainsAttributeCerts' => [ + 'type' => ASN1::TYPE_BOOLEAN, + 'constant' => 5, + 'optional' => true, + 'default' => false, + 'implicit' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php new file mode 100644 index 0000000..82a4151 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyIdentifier + * + * @author Jim Wigginton + */ +abstract class KeyIdentifier +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php new file mode 100644 index 0000000..b8509f1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyPurposeId + * + * @author Jim Wigginton + */ +abstract class KeyPurposeId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php new file mode 100644 index 0000000..827ce03 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * KeyUsage + * + * @author Jim Wigginton + */ +abstract class KeyUsage +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'digitalSignature', + 'nonRepudiation', + 'keyEncipherment', + 'dataEncipherment', + 'keyAgreement', + 'keyCertSign', + 'cRLSign', + 'encipherOnly', + 'decipherOnly' + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php new file mode 100644 index 0000000..ea3f998 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * MaskGenAglorithm + * + * @author Jim Wigginton + */ +abstract class MaskGenAlgorithm +{ + const MAP = AlgorithmIdentifier::MAP; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php new file mode 100644 index 0000000..a6a9009 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Name + * + * @author Jim Wigginton + */ +abstract class Name +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'rdnSequence' => RDNSequence::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php new file mode 100644 index 0000000..80486f9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NameConstraints + * + * @author Jim Wigginton + */ +abstract class NameConstraints +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'permittedSubtrees' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + GeneralSubtrees::MAP, + 'excludedSubtrees' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + GeneralSubtrees::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php new file mode 100644 index 0000000..6c68df0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NetworkAddress + * + * @author Jim Wigginton + */ +abstract class NetworkAddress +{ + const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php new file mode 100644 index 0000000..9eec123 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NoticeReference + * + * @author Jim Wigginton + */ +abstract class NoticeReference +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'organization' => DisplayText::MAP, + 'noticeNumbers' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 200, + 'children' => ['type' => ASN1::TYPE_INTEGER] + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php new file mode 100644 index 0000000..635a89d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * NumericUserIdentifier + * + * @author Jim Wigginton + */ +abstract class NumericUserIdentifier +{ + const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php new file mode 100644 index 0000000..b853abe --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ORAddress + * + * @author Jim Wigginton + */ +abstract class ORAddress +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'built-in-standard-attributes' => BuiltInStandardAttributes::MAP, + 'built-in-domain-defined-attributes' => ['optional' => true] + BuiltInDomainDefinedAttributes::MAP, + 'extension-attributes' => ['optional' => true] + ExtensionAttributes::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php new file mode 100644 index 0000000..5953024 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php @@ -0,0 +1,48 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OneAsymmetricKey + * + * @author Jim Wigginton + */ +abstract class OneAsymmetricKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1', 'v2'] + ], + 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, + 'privateKey' => PrivateKey::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP, + 'publicKey' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + PublicKey::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php new file mode 100644 index 0000000..b5cc949 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OrganizationName + * + * @author Jim Wigginton + */ +abstract class OrganizationName +{ + const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php new file mode 100644 index 0000000..b3e5780 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OrganizationalUnitNames + * + * @author Jim Wigginton + */ +abstract class OrganizationalUnitNames +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => 4, // ub-organizational-units + 'children' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php new file mode 100644 index 0000000..5d56560 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OtherPrimeInfo + * + * @author Jim Wigginton + */ +abstract class OtherPrimeInfo +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'prime' => ['type' => ASN1::TYPE_INTEGER], // ri + 'exponent' => ['type' => ASN1::TYPE_INTEGER], // di + 'coefficient' => ['type' => ASN1::TYPE_INTEGER] // ti + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php new file mode 100644 index 0000000..9802a80 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * OtherPrimeInfos + * + * @author Jim Wigginton + */ +abstract class OtherPrimeInfos +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => OtherPrimeInfo::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php new file mode 100644 index 0000000..8eb27cf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBEParameter + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBEParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], + 'iterationCount' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php new file mode 100644 index 0000000..bd31699 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBES2params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBES2params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyDerivationFunc' => AlgorithmIdentifier::MAP, + 'encryptionScheme' => AlgorithmIdentifier::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php new file mode 100644 index 0000000..2dafed9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBKDF2params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBKDF2params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + // technically, this is a CHOICE in RFC2898 but the other "choice" is, currently, more of a placeholder + // in the RFC + 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], + 'iterationCount' => ['type' => ASN1::TYPE_INTEGER], + 'keyLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'prf' => AlgorithmIdentifier::MAP + ['optional' => true] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php new file mode 100644 index 0000000..91319f5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php @@ -0,0 +1,34 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PBMAC1params + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class PBMAC1params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'keyDerivationFunc' => AlgorithmIdentifier::MAP, + 'messageAuthScheme' => AlgorithmIdentifier::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php new file mode 100644 index 0000000..87d0862 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PKCS9String + * + * @author Jim Wigginton + */ +abstract class PKCS9String +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], + 'directoryString' => DirectoryString::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php new file mode 100644 index 0000000..b8c8c02 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Pentanomial + * + * @author Jim Wigginton + */ +abstract class Pentanomial +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'k1' => ['type' => ASN1::TYPE_INTEGER], // k1 > 0 + 'k2' => ['type' => ASN1::TYPE_INTEGER], // k2 > k1 + 'k3' => ['type' => ASN1::TYPE_INTEGER], // k3 > h2 + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php new file mode 100644 index 0000000..14e2860 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php @@ -0,0 +1,54 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PersonalName + * + * @author Jim Wigginton + */ +abstract class PersonalName +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'children' => [ + 'surname' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ], + 'given-name' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ], + 'initials' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ], + 'generation-qualifier' => [ + 'type' => ASN1::TYPE_PRINTABLE_STRING, + 'constant' => 3, + 'optional' => true, + 'implicit' => true + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php new file mode 100644 index 0000000..1625d19 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyInformation + * + * @author Jim Wigginton + */ +abstract class PolicyInformation +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'policyIdentifier' => CertPolicyId::MAP, + 'policyQualifiers' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 0, + 'max' => -1, + 'optional' => true, + 'children' => PolicyQualifierInfo::MAP + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php new file mode 100644 index 0000000..d30b852 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyMappings + * + * @author Jim Wigginton + */ +abstract class PolicyMappings +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'issuerDomainPolicy' => CertPolicyId::MAP, + 'subjectDomainPolicy' => CertPolicyId::MAP + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php new file mode 100644 index 0000000..7b7cd6a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyQualifierId + * + * @author Jim Wigginton + */ +abstract class PolicyQualifierId +{ + const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php new file mode 100644 index 0000000..d227702 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PolicyQualifierInfo + * + * @author Jim Wigginton + */ +abstract class PolicyQualifierInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'policyQualifierId' => PolicyQualifierId::MAP, + 'qualifier' => ['type' => ASN1::TYPE_ANY] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php new file mode 100644 index 0000000..142b309 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PostalAddress + * + * @author Jim Wigginton + */ +abstract class PostalAddress +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 1, + 'max' => -1, + 'children' => DirectoryString::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php new file mode 100644 index 0000000..7743034 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Prime_p + * + * @author Jim Wigginton + */ +abstract class Prime_p +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php new file mode 100644 index 0000000..195dcaa --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateDomainName + * + * @author Jim Wigginton + */ +abstract class PrivateDomainName +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], + 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php new file mode 100644 index 0000000..3c89594 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKey + * + * @author Jim Wigginton + */ +abstract class PrivateKey +{ + const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php new file mode 100644 index 0000000..b440b78 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php @@ -0,0 +1,41 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKeyInfo + * + * @author Jim Wigginton + */ +abstract class PrivateKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1'] + ], + 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, + 'privateKey' => PrivateKey::MAP, + 'attributes' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true + ] + Attributes::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php new file mode 100644 index 0000000..5b87036 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PrivateKeyUsagePeriod + * + * @author Jim Wigginton + */ +abstract class PrivateKeyUsagePeriod +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => [ + 'constant' => 0, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME], + 'notAfter' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true, + 'type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php new file mode 100644 index 0000000..4840920 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKey + * + * @author Jim Wigginton + */ +abstract class PublicKey +{ + const MAP = ['type' => ASN1::TYPE_BIT_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php new file mode 100644 index 0000000..432581e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKeyAndChallenge + * + * @author Jim Wigginton + */ +abstract class PublicKeyAndChallenge +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'spki' => SubjectPublicKeyInfo::MAP, + 'challenge' => ['type' => ASN1::TYPE_IA5_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php new file mode 100644 index 0000000..b39a341 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * PublicKeyInfo + * + * this format is not formally defined anywhere but is none-the-less the form you + * get when you do "openssl rsa -in private.pem -outform PEM -pubout" + * + * @author Jim Wigginton + */ +abstract class PublicKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'publicKeyAlgorithm' => AlgorithmIdentifier::MAP, + 'publicKey' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php new file mode 100644 index 0000000..48649ab --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RC2CBCParameter + * + * from https://tools.ietf.org/html/rfc2898#appendix-A.3 + * + * @author Jim Wigginton + */ +abstract class RC2CBCParameter +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'rc2ParametersVersion' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'iv' => ['type' => ASN1::TYPE_OCTET_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php new file mode 100644 index 0000000..04b071c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RDNSequence + * + * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + * but they can be useful at times when either there is no unique attribute in the entry or you + * want to ensure that the entry's DN contains some useful identifying information. + * + * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + * + * @author Jim Wigginton + */ +abstract class RDNSequence +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + // RDNSequence does not define a min or a max, which means it doesn't have one + 'min' => 0, + 'max' => -1, + 'children' => RelativeDistinguishedName::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php new file mode 100644 index 0000000..8c19c65 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php @@ -0,0 +1,44 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSAPrivateKey + * + * @author Jim Wigginton + */ +abstract class RSAPrivateKey +{ + // version must be multi if otherPrimeInfos present + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['two-prime', 'multi'] + ], + 'modulus' => ['type' => ASN1::TYPE_INTEGER], // n + 'publicExponent' => ['type' => ASN1::TYPE_INTEGER], // e + 'privateExponent' => ['type' => ASN1::TYPE_INTEGER], // d + 'prime1' => ['type' => ASN1::TYPE_INTEGER], // p + 'prime2' => ['type' => ASN1::TYPE_INTEGER], // q + 'exponent1' => ['type' => ASN1::TYPE_INTEGER], // d mod (p-1) + 'exponent2' => ['type' => ASN1::TYPE_INTEGER], // d mod (q-1) + 'coefficient' => ['type' => ASN1::TYPE_INTEGER], // (inverse of q) mod p + 'otherPrimeInfos' => OtherPrimeInfos::MAP + ['optional' => true] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php new file mode 100644 index 0000000..b14c32c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSAPublicKey + * + * @author Jim Wigginton + */ +abstract class RSAPublicKey +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'modulus' => ['type' => ASN1::TYPE_INTEGER], + 'publicExponent' => ['type' => ASN1::TYPE_INTEGER] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php new file mode 100644 index 0000000..1a784bf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php @@ -0,0 +1,58 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RSASSA_PSS_params + * + * @author Jim Wigginton + */ +abstract class RSASSA_PSS_params +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'hashAlgorithm' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + //'default' => 'sha1Identifier' + ] + HashAlgorithm::MAP, + 'maskGenAlgorithm' => [ + 'constant' => 1, + 'optional' => true, + 'explicit' => true, + //'default' => 'mgf1SHA1Identifier' + ] + MaskGenAlgorithm::MAP, + 'saltLength' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 2, + 'optional' => true, + 'explicit' => true, + 'default' => 20 + ], + 'trailerField' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 3, + 'optional' => true, + 'explicit' => true, + 'default' => 1 + ] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php new file mode 100644 index 0000000..2e62fcd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php @@ -0,0 +1,39 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * ReasonFlags + * + * @author Jim Wigginton + */ +abstract class ReasonFlags +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'unused', + 'keyCompromise', + 'cACompromise', + 'affiliationChanged', + 'superseded', + 'cessationOfOperation', + 'certificateHold', + 'privilegeWithdrawn', + 'aACompromise' + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php new file mode 100644 index 0000000..a0421f7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php @@ -0,0 +1,37 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RelativeDistinguishedName + * + * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, + * but they can be useful at times when either there is no unique attribute in the entry or you + * want to ensure that the entry's DN contains some useful identifying information. + * + * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName + * + * @author Jim Wigginton + */ +abstract class RelativeDistinguishedName +{ + const MAP = [ + 'type' => ASN1::TYPE_SET, + 'min' => 1, + 'max' => -1, + 'children' => AttributeTypeAndValue::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php new file mode 100644 index 0000000..ff759eb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php @@ -0,0 +1,35 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * RevokedCertificate + * + * @author Jim Wigginton + */ +abstract class RevokedCertificate +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'userCertificate' => CertificateSerialNumber::MAP, + 'revocationDate' => Time::MAP, + 'crlEntryExtensions' => [ + 'optional' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php new file mode 100644 index 0000000..0f482a2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php @@ -0,0 +1,33 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SignedPublicKeyAndChallenge + * + * @author Jim Wigginton + */ +abstract class SignedPublicKeyAndChallenge +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'publicKeyAndChallenge' => PublicKeyAndChallenge::MAP, + 'signatureAlgorithm' => AlgorithmIdentifier::MAP, + 'signature' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php new file mode 100644 index 0000000..7408a56 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php @@ -0,0 +1,45 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SpecifiedECDomain + * + * @author Jim Wigginton + */ +abstract class SpecifiedECDomain +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => [1 => 'ecdpVer1', 'ecdpVer2', 'ecdpVer3'] + ], + 'fieldID' => FieldID::MAP, + 'curve' => Curve::MAP, + 'base' => ECPoint::MAP, + 'order' => ['type' => ASN1::TYPE_INTEGER], + 'cofactor' => [ + 'type' => ASN1::TYPE_INTEGER, + 'optional' => true + ], + 'hash' => ['optional' => true] + HashAlgorithm::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php new file mode 100644 index 0000000..39138a9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php @@ -0,0 +1,24 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +/** + * SubjectAltName + * + * @author Jim Wigginton + */ +abstract class SubjectAltName +{ + const MAP = GeneralNames::MAP; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php new file mode 100644 index 0000000..f2e206f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectDirectoryAttributes + * + * @author Jim Wigginton + */ +abstract class SubjectDirectoryAttributes +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => Attribute::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php new file mode 100644 index 0000000..1ff241f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php @@ -0,0 +1,31 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectInfoAccessSyntax + * + * @author Jim Wigginton + */ +abstract class SubjectInfoAccessSyntax +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'min' => 1, + 'max' => -1, + 'children' => AccessDescription::MAP + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php new file mode 100644 index 0000000..0d53d54 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * SubjectPublicKeyInfo + * + * @author Jim Wigginton + */ +abstract class SubjectPublicKeyInfo +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'algorithm' => AlgorithmIdentifier::MAP, + 'subjectPublicKey' => ['type' => ASN1::TYPE_BIT_STRING] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php new file mode 100644 index 0000000..49b3cfc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php @@ -0,0 +1,54 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TBSCertList + * + * @author Jim Wigginton + */ +abstract class TBSCertList +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'mapping' => ['v1', 'v2', 'v3'], + 'optional' => true, + 'default' => 'v2' + ], + 'signature' => AlgorithmIdentifier::MAP, + 'issuer' => Name::MAP, + 'thisUpdate' => Time::MAP, + 'nextUpdate' => [ + 'optional' => true + ] + Time::MAP, + 'revokedCertificates' => [ + 'type' => ASN1::TYPE_SEQUENCE, + 'optional' => true, + 'min' => 0, + 'max' => -1, + 'children' => RevokedCertificate::MAP + ], + 'crlExtensions' => [ + 'constant' => 0, + 'optional' => true, + 'explicit' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php new file mode 100644 index 0000000..007360c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php @@ -0,0 +1,65 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TBSCertificate + * + * @author Jim Wigginton + */ +abstract class TBSCertificate +{ + // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + // technically, default implies optional, but we'll define it as being optional, none-the-less, just to + // reenforce that fact + 'version' => [ + 'type' => ASN1::TYPE_INTEGER, + 'constant' => 0, + 'optional' => true, + 'explicit' => true, + 'mapping' => ['v1', 'v2', 'v3'], + 'default' => 'v1' + ], + 'serialNumber' => CertificateSerialNumber::MAP, + 'signature' => AlgorithmIdentifier::MAP, + 'issuer' => Name::MAP, + 'validity' => Validity::MAP, + 'subject' => Name::MAP, + 'subjectPublicKeyInfo' => SubjectPublicKeyInfo::MAP, + // implicit means that the T in the TLV structure is to be rewritten, regardless of the type + 'issuerUniqueID' => [ + 'constant' => 1, + 'optional' => true, + 'implicit' => true + ] + UniqueIdentifier::MAP, + 'subjectUniqueID' => [ + 'constant' => 2, + 'optional' => true, + 'implicit' => true + ] + UniqueIdentifier::MAP, + // doesn't use the EXPLICIT keyword but if + // it's not IMPLICIT, it's EXPLICIT + 'extensions' => [ + 'constant' => 3, + 'optional' => true, + 'explicit' => true + ] + Extensions::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php new file mode 100644 index 0000000..7f6d9d2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * TerminalIdentifier + * + * @author Jim Wigginton + */ +abstract class TerminalIdentifier +{ + const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php new file mode 100644 index 0000000..744ee70 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Time + * + * @author Jim Wigginton + */ +abstract class Time +{ + const MAP = [ + 'type' => ASN1::TYPE_CHOICE, + 'children' => [ + 'utcTime' => ['type' => ASN1::TYPE_UTC_TIME], + 'generalTime' => ['type' => ASN1::TYPE_GENERALIZED_TIME] + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php new file mode 100644 index 0000000..33baa91 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Trinomial + * + * @author Jim Wigginton + */ +abstract class Trinomial +{ + const MAP = ['type' => ASN1::TYPE_INTEGER]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php new file mode 100644 index 0000000..f4c954b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * UniqueIdentifier + * + * @author Jim Wigginton + */ +abstract class UniqueIdentifier +{ + const MAP = ['type' => ASN1::TYPE_BIT_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php new file mode 100644 index 0000000..98d527b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php @@ -0,0 +1,38 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * UserNotice + * + * @author Jim Wigginton + */ +abstract class UserNotice +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'noticeRef' => [ + 'optional' => true, + 'implicit' => true + ] + NoticeReference::MAP, + 'explicitText' => [ + 'optional' => true, + 'implicit' => true + ] + DisplayText::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php new file mode 100644 index 0000000..8ef64cf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php @@ -0,0 +1,32 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * Validity + * + * @author Jim Wigginton + */ +abstract class Validity +{ + const MAP = [ + 'type' => ASN1::TYPE_SEQUENCE, + 'children' => [ + 'notBefore' => Time::MAP, + 'notAfter' => Time::MAP + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php new file mode 100644 index 0000000..2ab1572 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_ca_policy_url + * + * @author Jim Wigginton + */ +abstract class netscape_ca_policy_url +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php new file mode 100644 index 0000000..49e8da4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php @@ -0,0 +1,40 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_cert_type + * + * mapping is from + * + * @author Jim Wigginton + */ +abstract class netscape_cert_type +{ + const MAP = [ + 'type' => ASN1::TYPE_BIT_STRING, + 'mapping' => [ + 'SSLClient', + 'SSLServer', + 'Email', + 'ObjectSigning', + 'Reserved', + 'SSLCA', + 'EmailCA', + 'ObjectSigningCA' + ] + ]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php new file mode 100644 index 0000000..d3ff4dd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php @@ -0,0 +1,26 @@ + + * @copyright 2016 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File\ASN1\Maps; + +use phpseclib3\File\ASN1; + +/** + * netscape_comment + * + * @author Jim Wigginton + */ +abstract class netscape_comment +{ + const MAP = ['type' => ASN1::TYPE_IA5_STRING]; +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php new file mode 100644 index 0000000..5e2f073 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php @@ -0,0 +1,4006 @@ + + * @copyright 2012 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\File; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\RSA\Formats\Keys\PSS; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\File\ASN1\Element; +use phpseclib3\File\ASN1\Maps; +use phpseclib3\Math\BigInteger; + +/** + * Pure-PHP X.509 Parser + * + * @author Jim Wigginton + */ +class X509 +{ + /** + * Flag to only accept signatures signed by certificate authorities + * + * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs + * + */ + const VALIDATE_SIGNATURE_BY_CA = 1; + + /** + * Return internal array representation + * + * @see \phpseclib3\File\X509::getDN() + */ + const DN_ARRAY = 0; + /** + * Return string + * + * @see \phpseclib3\File\X509::getDN() + */ + const DN_STRING = 1; + /** + * Return ASN.1 name string + * + * @see \phpseclib3\File\X509::getDN() + */ + const DN_ASN1 = 2; + /** + * Return OpenSSL compatible array + * + * @see \phpseclib3\File\X509::getDN() + */ + const DN_OPENSSL = 3; + /** + * Return canonical ASN.1 RDNs string + * + * @see \phpseclib3\File\X509::getDN() + */ + const DN_CANON = 4; + /** + * Return name hash for file indexing + * + * @see \phpseclib3\File\X509::getDN() + */ + const DN_HASH = 5; + + /** + * Save as PEM + * + * ie. a base64-encoded PEM with a header and a footer + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + const FORMAT_PEM = 0; + /** + * Save as DER + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + const FORMAT_DER = 1; + /** + * Save as a SPKAC + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + * + * Only works on CSRs. Not currently supported. + */ + const FORMAT_SPKAC = 2; + /** + * Auto-detect the format + * + * Used only by the load*() functions + * + * @see \phpseclib3\File\X509::saveX509() + * @see \phpseclib3\File\X509::saveCSR() + * @see \phpseclib3\File\X509::saveCRL() + */ + const FORMAT_AUTO_DETECT = 3; + + /** + * Attribute value disposition. + * If disposition is >= 0, this is the index of the target value. + */ + const ATTR_ALL = -1; // All attribute values (array). + const ATTR_APPEND = -2; // Add a value. + const ATTR_REPLACE = -3; // Clear first, then add a value. + + /** + * Distinguished Name + * + * @var array + */ + private $dn; + + /** + * Public key + * + * @var string|PublicKey + */ + private $publicKey; + + /** + * Private key + * + * @var string|PrivateKey + */ + private $privateKey; + + /** + * The certificate authorities + * + * @var array + */ + private $CAs = []; + + /** + * The currently loaded certificate + * + * @var array + */ + private $currentCert; + + /** + * The signature subject + * + * There's no guarantee \phpseclib3\File\X509 is going to re-encode an X.509 cert in the same way it was originally + * encoded so we take save the portion of the original cert that the signature would have made for. + * + * @var string + */ + private $signatureSubject; + + /** + * Certificate Start Date + * + * @var string + */ + private $startDate; + + /** + * Certificate End Date + * + * @var string|Element + */ + private $endDate; + + /** + * Serial Number + * + * @var string + */ + private $serialNumber; + + /** + * Key Identifier + * + * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and + * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}. + * + * @var string + */ + private $currentKeyIdentifier; + + /** + * CA Flag + * + * @var bool + */ + private $caFlag = false; + + /** + * SPKAC Challenge + * + * @var string + */ + private $challenge; + + /** + * @var array + */ + private $extensionValues = []; + + /** + * OIDs loaded + * + * @var bool + */ + private static $oidsLoaded = false; + + /** + * Recursion Limit + * + * @var int + */ + private static $recur_limit = 5; + + /** + * URL fetch flag + * + * @var bool + */ + private static $disable_url_fetch = false; + + /** + * @var array + */ + private static $extensions = []; + + /** + * @var ?array + */ + private $ipAddresses = null; + + /** + * @var ?array + */ + private $domains = null; + + /** + * Default Constructor. + * + * @return \phpseclib3\File\X509 + */ + public function __construct() + { + // Explicitly Tagged Module, 1988 Syntax + // http://tools.ietf.org/html/rfc5280#appendix-A.1 + + if (!self::$oidsLoaded) { + // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 + ASN1::loadOIDs([ + //'id-pkix' => '1.3.6.1.5.5.7', + //'id-pe' => '1.3.6.1.5.5.7.1', + //'id-qt' => '1.3.6.1.5.5.7.2', + //'id-kp' => '1.3.6.1.5.5.7.3', + //'id-ad' => '1.3.6.1.5.5.7.48', + 'id-qt-cps' => '1.3.6.1.5.5.7.2.1', + 'id-qt-unotice' => '1.3.6.1.5.5.7.2.2', + 'id-ad-ocsp' => '1.3.6.1.5.5.7.48.1', + 'id-ad-caIssuers' => '1.3.6.1.5.5.7.48.2', + 'id-ad-timeStamping' => '1.3.6.1.5.5.7.48.3', + 'id-ad-caRepository' => '1.3.6.1.5.5.7.48.5', + //'id-at' => '2.5.4', + 'id-at-name' => '2.5.4.41', + 'id-at-surname' => '2.5.4.4', + 'id-at-givenName' => '2.5.4.42', + 'id-at-initials' => '2.5.4.43', + 'id-at-generationQualifier' => '2.5.4.44', + 'id-at-commonName' => '2.5.4.3', + 'id-at-localityName' => '2.5.4.7', + 'id-at-stateOrProvinceName' => '2.5.4.8', + 'id-at-organizationName' => '2.5.4.10', + 'id-at-organizationalUnitName' => '2.5.4.11', + 'id-at-title' => '2.5.4.12', + 'id-at-description' => '2.5.4.13', + 'id-at-dnQualifier' => '2.5.4.46', + 'id-at-countryName' => '2.5.4.6', + 'id-at-serialNumber' => '2.5.4.5', + 'id-at-pseudonym' => '2.5.4.65', + 'id-at-postalCode' => '2.5.4.17', + 'id-at-streetAddress' => '2.5.4.9', + 'id-at-uniqueIdentifier' => '2.5.4.45', + 'id-at-role' => '2.5.4.72', + 'id-at-postalAddress' => '2.5.4.16', + 'jurisdictionOfIncorporationCountryName' => '1.3.6.1.4.1.311.60.2.1.3', + 'jurisdictionOfIncorporationStateOrProvinceName' => '1.3.6.1.4.1.311.60.2.1.2', + 'jurisdictionLocalityName' => '1.3.6.1.4.1.311.60.2.1.1', + 'id-at-businessCategory' => '2.5.4.15', + + //'id-domainComponent' => '0.9.2342.19200300.100.1.25', + //'pkcs-9' => '1.2.840.113549.1.9', + 'pkcs-9-at-emailAddress' => '1.2.840.113549.1.9.1', + //'id-ce' => '2.5.29', + 'id-ce-authorityKeyIdentifier' => '2.5.29.35', + 'id-ce-subjectKeyIdentifier' => '2.5.29.14', + 'id-ce-keyUsage' => '2.5.29.15', + 'id-ce-privateKeyUsagePeriod' => '2.5.29.16', + 'id-ce-certificatePolicies' => '2.5.29.32', + //'anyPolicy' => '2.5.29.32.0', + + 'id-ce-policyMappings' => '2.5.29.33', + + 'id-ce-subjectAltName' => '2.5.29.17', + 'id-ce-issuerAltName' => '2.5.29.18', + 'id-ce-subjectDirectoryAttributes' => '2.5.29.9', + 'id-ce-basicConstraints' => '2.5.29.19', + 'id-ce-nameConstraints' => '2.5.29.30', + 'id-ce-policyConstraints' => '2.5.29.36', + 'id-ce-cRLDistributionPoints' => '2.5.29.31', + 'id-ce-extKeyUsage' => '2.5.29.37', + //'anyExtendedKeyUsage' => '2.5.29.37.0', + 'id-kp-serverAuth' => '1.3.6.1.5.5.7.3.1', + 'id-kp-clientAuth' => '1.3.6.1.5.5.7.3.2', + 'id-kp-codeSigning' => '1.3.6.1.5.5.7.3.3', + 'id-kp-emailProtection' => '1.3.6.1.5.5.7.3.4', + 'id-kp-timeStamping' => '1.3.6.1.5.5.7.3.8', + 'id-kp-OCSPSigning' => '1.3.6.1.5.5.7.3.9', + 'id-ce-inhibitAnyPolicy' => '2.5.29.54', + 'id-ce-freshestCRL' => '2.5.29.46', + 'id-pe-authorityInfoAccess' => '1.3.6.1.5.5.7.1.1', + 'id-pe-subjectInfoAccess' => '1.3.6.1.5.5.7.1.11', + 'id-ce-cRLNumber' => '2.5.29.20', + 'id-ce-issuingDistributionPoint' => '2.5.29.28', + 'id-ce-deltaCRLIndicator' => '2.5.29.27', + 'id-ce-cRLReasons' => '2.5.29.21', + 'id-ce-certificateIssuer' => '2.5.29.29', + 'id-ce-holdInstructionCode' => '2.5.29.23', + //'holdInstruction' => '1.2.840.10040.2', + 'id-holdinstruction-none' => '1.2.840.10040.2.1', + 'id-holdinstruction-callissuer' => '1.2.840.10040.2.2', + 'id-holdinstruction-reject' => '1.2.840.10040.2.3', + 'id-ce-invalidityDate' => '2.5.29.24', + + 'rsaEncryption' => '1.2.840.113549.1.1.1', + 'md2WithRSAEncryption' => '1.2.840.113549.1.1.2', + 'md5WithRSAEncryption' => '1.2.840.113549.1.1.4', + 'sha1WithRSAEncryption' => '1.2.840.113549.1.1.5', + 'sha224WithRSAEncryption' => '1.2.840.113549.1.1.14', + 'sha256WithRSAEncryption' => '1.2.840.113549.1.1.11', + 'sha384WithRSAEncryption' => '1.2.840.113549.1.1.12', + 'sha512WithRSAEncryption' => '1.2.840.113549.1.1.13', + + 'id-ecPublicKey' => '1.2.840.10045.2.1', + 'ecdsa-with-SHA1' => '1.2.840.10045.4.1', + // from https://tools.ietf.org/html/rfc5758#section-3.2 + 'ecdsa-with-SHA224' => '1.2.840.10045.4.3.1', + 'ecdsa-with-SHA256' => '1.2.840.10045.4.3.2', + 'ecdsa-with-SHA384' => '1.2.840.10045.4.3.3', + 'ecdsa-with-SHA512' => '1.2.840.10045.4.3.4', + + 'id-dsa' => '1.2.840.10040.4.1', + 'id-dsa-with-sha1' => '1.2.840.10040.4.3', + // from https://tools.ietf.org/html/rfc5758#section-3.1 + 'id-dsa-with-sha224' => '2.16.840.1.101.3.4.3.1', + 'id-dsa-with-sha256' => '2.16.840.1.101.3.4.3.2', + + // from https://tools.ietf.org/html/rfc8410: + 'id-Ed25519' => '1.3.101.112', + 'id-Ed448' => '1.3.101.113', + + 'id-RSASSA-PSS' => '1.2.840.113549.1.1.10', + + //'id-sha224' => '2.16.840.1.101.3.4.2.4', + //'id-sha256' => '2.16.840.1.101.3.4.2.1', + //'id-sha384' => '2.16.840.1.101.3.4.2.2', + //'id-sha512' => '2.16.840.1.101.3.4.2.3', + //'id-GostR3411-94-with-GostR3410-94' => '1.2.643.2.2.4', + //'id-GostR3411-94-with-GostR3410-2001' => '1.2.643.2.2.3', + //'id-GostR3410-2001' => '1.2.643.2.2.20', + //'id-GostR3410-94' => '1.2.643.2.2.19', + // Netscape Object Identifiers from "Netscape Certificate Extensions" + 'netscape' => '2.16.840.1.113730', + 'netscape-cert-extension' => '2.16.840.1.113730.1', + 'netscape-cert-type' => '2.16.840.1.113730.1.1', + 'netscape-comment' => '2.16.840.1.113730.1.13', + 'netscape-ca-policy-url' => '2.16.840.1.113730.1.8', + // the following are X.509 extensions not supported by phpseclib + 'id-pe-logotype' => '1.3.6.1.5.5.7.1.12', + 'entrustVersInfo' => '1.2.840.113533.7.65.0', + 'verisignPrivate' => '2.16.840.1.113733.1.6.9', + // for Certificate Signing Requests + // see http://tools.ietf.org/html/rfc2985 + 'pkcs-9-at-unstructuredName' => '1.2.840.113549.1.9.2', // PKCS #9 unstructured name + 'pkcs-9-at-challengePassword' => '1.2.840.113549.1.9.7', // Challenge password for certificate revocations + 'pkcs-9-at-extensionRequest' => '1.2.840.113549.1.9.14' // Certificate extension request + ]); + } + } + + /** + * Load X.509 certificate + * + * Returns an associative array describing the X.509 cert or a false if the cert failed to load + * + * @param array|string $cert + * @param int $mode + * @return mixed + */ + public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) + { + if (is_array($cert) && isset($cert['tbsCertificate'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + $this->dn = $cert['tbsCertificate']['subject']; + if (!isset($this->dn)) { + return false; + } + $this->currentCert = $cert; + + $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); + $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; + + unset($this->signatureSubject); + + return $cert; + } + + if ($mode != self::FORMAT_DER) { + $newcert = ASN1::extractBER($cert); + if ($mode == self::FORMAT_PEM && $cert == $newcert) { + return false; + } + $cert = $newcert; + } + + if ($cert === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($cert); + + if ($decoded) { + $x509 = ASN1::asn1map($decoded[0], Maps\Certificate::MAP); + } + if (!isset($x509) || $x509 === false) { + $this->currentCert = false; + return false; + } + + $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + if ($this->isSubArrayValid($x509, 'tbsCertificate/extensions')) { + $this->mapInExtensions($x509, 'tbsCertificate/extensions'); + } + $this->mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence'); + $this->mapInDNs($x509, 'tbsCertificate/subject/rdnSequence'); + + $key = $x509['tbsCertificate']['subjectPublicKeyInfo']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + + $this->currentCert = $x509; + $this->dn = $x509['tbsCertificate']['subject']; + + $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); + $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; + + return $x509; + } + + /** + * Save X.509 certificate + * + * @param array $cert + * @param int $format optional + * @return string + */ + public function saveX509(array $cert, $format = self::FORMAT_PEM) + { + if (!is_array($cert) || !isset($cert['tbsCertificate'])) { + return false; + } + + switch (true) { + // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" + case !($algorithm = $this->subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): + case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): + break; + default: + $cert['tbsCertificate']['subjectPublicKeyInfo'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])) + ); + } + + if ($algorithm == 'rsaEncryption') { + $cert['signatureAlgorithm']['parameters'] = null; + $cert['tbsCertificate']['signature']['parameters'] = null; + } + + $filters = []; + $type_utf8_string = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string; + $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string; + $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string; + $filters['tbsCertificate']['subject']['rdnSequence']['value'] = $type_utf8_string; + $filters['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = $type_utf8_string; + $filters['signatureAlgorithm']['parameters'] = $type_utf8_string; + $filters['authorityCertIssuer']['directoryName']['rdnSequence']['value'] = $type_utf8_string; + //$filters['policyQualifiers']['qualifier'] = $type_utf8_string; + $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string; + $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string; + + foreach (self::$extensions as $extension) { + $filters['tbsCertificate']['extensions'][] = $extension; + } + + /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib3\File\ASN1::TYPE_IA5_STRING. + \phpseclib3\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random + characters. + */ + $filters['policyQualifiers']['qualifier'] + = ['type' => ASN1::TYPE_IA5_STRING]; + + ASN1::setFilters($filters); + + $this->mapOutExtensions($cert, 'tbsCertificate/extensions'); + $this->mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence'); + $this->mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence'); + + $cert = ASN1::encodeDER($cert, Maps\Certificate::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $cert; + // case self::FORMAT_PEM: + default: + return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Strings::base64_encode($cert), 64) . '-----END CERTIFICATE-----'; + } + } + + /** + * Map extension values from octet string to extension-specific internal + * format. + * + * @param array $root (by reference) + * @param string $path + */ + private function mapInExtensions(array &$root, $path) + { + $extensions = &$this->subArrayUnchecked($root, $path); + + if ($extensions) { + for ($i = 0; $i < count($extensions); $i++) { + $id = $extensions[$i]['extnId']; + $value = &$extensions[$i]['extnValue']; + /* [extnValue] contains the DER encoding of an ASN.1 value + corresponding to the extension type identified by extnID */ + $map = $this->getMapping($id); + if (!is_bool($map)) { + $decoder = $id == 'id-ce-nameConstraints' ? + [static::class, 'decodeNameConstraintIP'] : + [static::class, 'decodeIP']; + $decoded = ASN1::decodeBER($value); + if (!$decoded) { + continue; + } + $mapped = ASN1::asn1map($decoded[0], $map, ['iPAddress' => $decoder]); + $value = $mapped === false ? $decoded[0] : $mapped; + + if ($id == 'id-ce-certificatePolicies') { + for ($j = 0; $j < count($value); $j++) { + if (!isset($value[$j]['policyQualifiers'])) { + continue; + } + for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { + $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; + $map = $this->getMapping($subid); + $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; + if ($map !== false) { + $decoded = ASN1::decodeBER($subvalue); + if (!$decoded) { + continue; + } + $mapped = ASN1::asn1map($decoded[0], $map); + $subvalue = $mapped === false ? $decoded[0] : $mapped; + } + } + } + } + } + } + } + } + + /** + * Map extension values from extension-specific internal format to + * octet string. + * + * @param array $root (by reference) + * @param string $path + */ + private function mapOutExtensions(array &$root, $path) + { + $extensions = &$this->subArray($root, $path, !empty($this->extensionValues)); + + foreach ($this->extensionValues as $id => $data) { + extract($data); + $newext = [ + 'extnId' => $id, + 'extnValue' => $value, + 'critical' => $critical + ]; + if ($replace) { + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + $extensions[$key] = $newext; + continue 2; + } + } + } + $extensions[] = $newext; + } + + if (is_array($extensions)) { + $size = count($extensions); + for ($i = 0; $i < $size; $i++) { + if ($extensions[$i] instanceof Element) { + continue; + } + + $id = $extensions[$i]['extnId']; + $value = &$extensions[$i]['extnValue']; + + switch ($id) { + case 'id-ce-certificatePolicies': + for ($j = 0; $j < count($value); $j++) { + if (!isset($value[$j]['policyQualifiers'])) { + continue; + } + for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { + $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; + $map = $this->getMapping($subid); + $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; + if ($map !== false) { + // by default \phpseclib3\File\ASN1 will try to render qualifier as a \phpseclib3\File\ASN1::TYPE_IA5_STRING since it's + // actual type is \phpseclib3\File\ASN1::TYPE_ANY + $subvalue = new Element(ASN1::encodeDER($subvalue, $map)); + } + } + } + break; + case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string + if (isset($value['authorityCertSerialNumber'])) { + if ($value['authorityCertSerialNumber']->toBytes() == '') { + $temp = chr((ASN1::CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0"; + $value['authorityCertSerialNumber'] = new Element($temp); + } + } + } + + /* [extnValue] contains the DER encoding of an ASN.1 value + corresponding to the extension type identified by extnID */ + $map = $this->getMapping($id); + if (is_bool($map)) { + if (!$map) { + //user_error($id . ' is not a currently supported extension'); + unset($extensions[$i]); + } + } else { + $value = ASN1::encodeDER($value, $map, ['iPAddress' => [static::class, 'encodeIP']]); + } + } + } + } + + /** + * Map attribute values from ANY type to attribute-specific internal + * format. + * + * @param array $root (by reference) + * @param string $path + */ + private function mapInAttributes(&$root, $path) + { + $attributes = &$this->subArray($root, $path); + + if (is_array($attributes)) { + for ($i = 0; $i < count($attributes); $i++) { + $id = $attributes[$i]['type']; + /* $value contains the DER encoding of an ASN.1 value + corresponding to the attribute type identified by type */ + $map = $this->getMapping($id); + if (is_array($attributes[$i]['value'])) { + $values = &$attributes[$i]['value']; + for ($j = 0; $j < count($values); $j++) { + $value = ASN1::encodeDER($values[$j], Maps\AttributeValue::MAP); + $decoded = ASN1::decodeBER($value); + if (!is_bool($map)) { + if (!$decoded) { + continue; + } + $mapped = ASN1::asn1map($decoded[0], $map); + if ($mapped !== false) { + $values[$j] = $mapped; + } + if ($id == 'pkcs-9-at-extensionRequest' && $this->isSubArrayValid($values, $j)) { + $this->mapInExtensions($values, $j); + } + } elseif ($map) { + $values[$j] = $value; + } + } + } + } + } + } + + /** + * Map attribute values from attribute-specific internal format to + * ANY type. + * + * @param array $root (by reference) + * @param string $path + */ + private function mapOutAttributes(&$root, $path) + { + $attributes = &$this->subArray($root, $path); + + if (is_array($attributes)) { + $size = count($attributes); + for ($i = 0; $i < $size; $i++) { + /* [value] contains the DER encoding of an ASN.1 value + corresponding to the attribute type identified by type */ + $id = $attributes[$i]['type']; + $map = $this->getMapping($id); + if ($map === false) { + //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); + unset($attributes[$i]); + } elseif (is_array($attributes[$i]['value'])) { + $values = &$attributes[$i]['value']; + for ($j = 0; $j < count($values); $j++) { + switch ($id) { + case 'pkcs-9-at-extensionRequest': + $this->mapOutExtensions($values, $j); + break; + } + + if (!is_bool($map)) { + $temp = ASN1::encodeDER($values[$j], $map); + $decoded = ASN1::decodeBER($temp); + if (!$decoded) { + continue; + } + $values[$j] = ASN1::asn1map($decoded[0], Maps\AttributeValue::MAP); + } + } + } + } + } + } + + /** + * Map DN values from ANY type to DN-specific internal + * format. + * + * @param array $root (by reference) + * @param string $path + */ + private function mapInDNs(array &$root, $path) + { + $dns = &$this->subArray($root, $path); + + if (is_array($dns)) { + for ($i = 0; $i < count($dns); $i++) { + for ($j = 0; $j < count($dns[$i]); $j++) { + $type = $dns[$i][$j]['type']; + $value = &$dns[$i][$j]['value']; + if (is_object($value) && $value instanceof Element) { + $map = $this->getMapping($type); + if (!is_bool($map)) { + $decoded = ASN1::decodeBER($value); + if (!$decoded) { + continue; + } + $value = ASN1::asn1map($decoded[0], $map); + } + } + } + } + } + } + + /** + * Map DN values from DN-specific internal format to + * ANY type. + * + * @param array $root (by reference) + * @param string $path + */ + private function mapOutDNs(array &$root, $path) + { + $dns = &$this->subArray($root, $path); + + if (is_array($dns)) { + $size = count($dns); + for ($i = 0; $i < $size; $i++) { + for ($j = 0; $j < count($dns[$i]); $j++) { + $type = $dns[$i][$j]['type']; + $value = &$dns[$i][$j]['value']; + if (is_object($value) && $value instanceof Element) { + continue; + } + + $map = $this->getMapping($type); + if (!is_bool($map)) { + $value = new Element(ASN1::encodeDER($value, $map)); + } + } + } + } + } + + /** + * Associate an extension ID to an extension mapping + * + * @param string $extnId + * @return mixed + */ + private function getMapping($extnId) + { + if (!is_string($extnId)) { // eg. if it's a \phpseclib3\File\ASN1\Element object + return true; + } + + if (isset(self::$extensions[$extnId])) { + return self::$extensions[$extnId]; + } + + switch ($extnId) { + case 'id-ce-keyUsage': + return Maps\KeyUsage::MAP; + case 'id-ce-basicConstraints': + return Maps\BasicConstraints::MAP; + case 'id-ce-subjectKeyIdentifier': + return Maps\KeyIdentifier::MAP; + case 'id-ce-cRLDistributionPoints': + return Maps\CRLDistributionPoints::MAP; + case 'id-ce-authorityKeyIdentifier': + return Maps\AuthorityKeyIdentifier::MAP; + case 'id-ce-certificatePolicies': + return Maps\CertificatePolicies::MAP; + case 'id-ce-extKeyUsage': + return Maps\ExtKeyUsageSyntax::MAP; + case 'id-pe-authorityInfoAccess': + return Maps\AuthorityInfoAccessSyntax::MAP; + case 'id-ce-subjectAltName': + return Maps\SubjectAltName::MAP; + case 'id-ce-subjectDirectoryAttributes': + return Maps\SubjectDirectoryAttributes::MAP; + case 'id-ce-privateKeyUsagePeriod': + return Maps\PrivateKeyUsagePeriod::MAP; + case 'id-ce-issuerAltName': + return Maps\IssuerAltName::MAP; + case 'id-ce-policyMappings': + return Maps\PolicyMappings::MAP; + case 'id-ce-nameConstraints': + return Maps\NameConstraints::MAP; + + case 'netscape-cert-type': + return Maps\netscape_cert_type::MAP; + case 'netscape-comment': + return Maps\netscape_comment::MAP; + case 'netscape-ca-policy-url': + return Maps\netscape_ca_policy_url::MAP; + + // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets + // back around to asn1map() and we don't want it decoded again. + //case 'id-qt-cps': + // return Maps\CPSuri::MAP; + case 'id-qt-unotice': + return Maps\UserNotice::MAP; + + // the following OIDs are unsupported but we don't want them to give notices when calling saveX509(). + case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt + case 'entrustVersInfo': + // http://support.microsoft.com/kb/287547 + case '1.3.6.1.4.1.311.20.2': // szOID_ENROLL_CERTTYPE_EXTENSION + case '1.3.6.1.4.1.311.21.1': // szOID_CERTSRV_CA_VERSION + // "SET Secure Electronic Transaction Specification" + // http://www.maithean.com/docs/set_bk3.pdf + case '2.23.42.7.0': // id-set-hashedRootKey + // "Certificate Transparency" + // https://tools.ietf.org/html/rfc6962 + case '1.3.6.1.4.1.11129.2.4.2': + // "Qualified Certificate statements" + // https://tools.ietf.org/html/rfc3739#section-3.2.6 + case '1.3.6.1.5.5.7.1.3': + return true; + + // CSR attributes + case 'pkcs-9-at-unstructuredName': + return Maps\PKCS9String::MAP; + case 'pkcs-9-at-challengePassword': + return Maps\DirectoryString::MAP; + case 'pkcs-9-at-extensionRequest': + return Maps\Extensions::MAP; + + // CRL extensions. + case 'id-ce-cRLNumber': + return Maps\CRLNumber::MAP; + case 'id-ce-deltaCRLIndicator': + return Maps\CRLNumber::MAP; + case 'id-ce-issuingDistributionPoint': + return Maps\IssuingDistributionPoint::MAP; + case 'id-ce-freshestCRL': + return Maps\CRLDistributionPoints::MAP; + case 'id-ce-cRLReasons': + return Maps\CRLReason::MAP; + case 'id-ce-invalidityDate': + return Maps\InvalidityDate::MAP; + case 'id-ce-certificateIssuer': + return Maps\CertificateIssuer::MAP; + case 'id-ce-holdInstructionCode': + return Maps\HoldInstructionCode::MAP; + case 'id-at-postalAddress': + return Maps\PostalAddress::MAP; + } + + return false; + } + + /** + * Load an X.509 certificate as a certificate authority + * + * @param string $cert + * @return bool + */ + public function loadCA($cert) + { + $olddn = $this->dn; + $oldcert = $this->currentCert; + $oldsigsubj = $this->signatureSubject; + $oldkeyid = $this->currentKeyIdentifier; + + $cert = $this->loadX509($cert); + if (!$cert) { + $this->dn = $olddn; + $this->currentCert = $oldcert; + $this->signatureSubject = $oldsigsubj; + $this->currentKeyIdentifier = $oldkeyid; + + return false; + } + + /* From RFC5280 "PKIX Certificate and CRL Profile": + + If the keyUsage extension is present, then the subject public key + MUST NOT be used to verify signatures on certificates or CRLs unless + the corresponding keyCertSign or cRLSign bit is set. */ + //$keyUsage = $this->getExtension('id-ce-keyUsage'); + //if ($keyUsage && !in_array('keyCertSign', $keyUsage)) { + // return false; + //} + + /* From RFC5280 "PKIX Certificate and CRL Profile": + + The cA boolean indicates whether the certified public key may be used + to verify certificate signatures. If the cA boolean is not asserted, + then the keyCertSign bit in the key usage extension MUST NOT be + asserted. If the basic constraints extension is not present in a + version 3 certificate, or the extension is present but the cA boolean + is not asserted, then the certified public key MUST NOT be used to + verify certificate signatures. */ + //$basicConstraints = $this->getExtension('id-ce-basicConstraints'); + //if (!$basicConstraints || !$basicConstraints['cA']) { + // return false; + //} + + $this->CAs[] = $cert; + + $this->dn = $olddn; + $this->currentCert = $oldcert; + $this->signatureSubject = $oldsigsubj; + + return true; + } + + /** + * Validate an X.509 certificate against a URL + * + * From RFC2818 "HTTP over TLS": + * + * Matching is performed using the matching rules specified by + * [RFC2459]. If more than one identity of a given type is present in + * the certificate (e.g., more than one dNSName name, a match in any one + * of the set is considered acceptable.) Names may contain the wildcard + * character * which is considered to match any single domain name + * component or component fragment. E.g., *.a.com matches foo.a.com but + * not bar.foo.a.com. f*.com matches foo.com but not bar.com. + * + * @param string $url + * @return bool + */ + public function validateURL($url) + { + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + + $components = parse_url($url); + if (!isset($components['host'])) { + return false; + } + + if ($names = $this->getExtension('id-ce-subjectAltName')) { + foreach ($names as $name) { + foreach ($name as $key => $value) { + $value = preg_quote($value); + $value = str_replace('\*', '[^.]*', $value); + switch ($key) { + case 'dNSName': + /* From RFC2818 "HTTP over TLS": + + If a subjectAltName extension of type dNSName is present, that MUST + be used as the identity. Otherwise, the (most specific) Common Name + field in the Subject field of the certificate MUST be used. Although + the use of the Common Name is existing practice, it is deprecated and + Certification Authorities are encouraged to use the dNSName instead. */ + if (preg_match('#^' . $value . '$#', $components['host'])) { + return true; + } + break; + case 'iPAddress': + /* From RFC2818 "HTTP over TLS": + + In some cases, the URI is specified as an IP address rather than a + hostname. In this case, the iPAddress subjectAltName must be present + in the certificate and must exactly match the IP in the URI. */ + if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) { + return true; + } + } + } + } + return false; + } + + if ($value = $this->getDNProp('id-at-commonName')) { + $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value[0]); + return preg_match('#^' . $value . '$#', $components['host']) === 1; + } + + return false; + } + + /** + * Validate a date + * + * If $date isn't defined it is assumed to be the current date. + * + * @param \DateTimeInterface|string $date optional + * @return bool + */ + public function validateDate($date = null) + { + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + + if (!isset($date)) { + $date = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); + } + + $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore']; + $notBefore = isset($notBefore['generalTime']) ? $notBefore['generalTime'] : $notBefore['utcTime']; + + $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter']; + $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime']; + + if (is_string($date)) { + $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); + } + + $notBefore = new \DateTimeImmutable($notBefore, new \DateTimeZone(@date_default_timezone_get())); + $notAfter = new \DateTimeImmutable($notAfter, new \DateTimeZone(@date_default_timezone_get())); + + return $date >= $notBefore && $date <= $notAfter; + } + + /** + * Fetches a URL + * + * @param string $url + * @return bool|string + */ + private static function fetchURL($url) + { + if (self::$disable_url_fetch) { + return false; + } + + $parts = parse_url($url); + $data = ''; + switch ($parts['scheme']) { + case 'http': + $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80); + if (!$fsock) { + return false; + } + $path = $parts['path']; + if (isset($parts['query'])) { + $path .= '?' . $parts['query']; + } + fputs($fsock, "GET $path HTTP/1.0\r\n"); + fputs($fsock, "Host: $parts[host]\r\n\r\n"); + $line = fgets($fsock, 1024); + if (strlen($line) < 3) { + return false; + } + preg_match('#HTTP/1.\d (\d{3})#', $line, $temp); + if ($temp[1] != '200') { + return false; + } + + // skip the rest of the headers in the http response + while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") { + } + + while (!feof($fsock)) { + $temp = fread($fsock, 1024); + if ($temp === false) { + return false; + } + $data .= $temp; + } + + break; + //case 'ftp': + //case 'ldap': + //default: + } + + return $data; + } + + /** + * Validates an intermediate cert as identified via authority info access extension + * + * See https://tools.ietf.org/html/rfc4325 for more info + * + * @param bool $caonly + * @param int $count + * @return bool + */ + private function testForIntermediate($caonly, $count) + { + $opts = $this->getExtension('id-pe-authorityInfoAccess'); + if (!is_array($opts)) { + return false; + } + foreach ($opts as $opt) { + if ($opt['accessMethod'] == 'id-ad-caIssuers') { + // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP, + // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325 + // discusses + if (isset($opt['accessLocation']['uniformResourceIdentifier'])) { + $url = $opt['accessLocation']['uniformResourceIdentifier']; + break; + } + } + } + + if (!isset($url)) { + return false; + } + + $cert = static::fetchURL($url); + if (!is_string($cert)) { + return false; + } + + $parent = new static(); + $parent->CAs = $this->CAs; + /* + "Conforming applications that support HTTP or FTP for accessing + certificates MUST be able to accept .cer files and SHOULD be able + to accept .p7c files." -- https://tools.ietf.org/html/rfc4325 + + A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797" + + These are currently unsupported + */ + if (!is_array($parent->loadX509($cert))) { + return false; + } + + if (!$parent->validateSignatureCountable($caonly, ++$count)) { + return false; + } + + $this->CAs[] = $parent->currentCert; + //$this->loadCA($cert); + + return true; + } + + /** + * Validate a signature + * + * Works on X.509 certs, CSR's and CRL's. + * Returns true if the signature is verified, false if it is not correct or null on error + * + * By default returns false for self-signed certs. Call validateSignature(false) to make this support + * self-signed. + * + * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}. + * + * @param bool $caonly optional + * @return mixed + */ + public function validateSignature($caonly = true) + { + return $this->validateSignatureCountable($caonly, 0); + } + + /** + * Validate a signature + * + * Performs said validation whilst keeping track of how many times validation method is called + * + * @param bool $caonly + * @param int $count + * @return mixed + */ + private function validateSignatureCountable($caonly, $count) + { + if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { + return null; + } + + if ($count == self::$recur_limit) { + return false; + } + + /* TODO: + "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")." + -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6 + + implement pathLenConstraint in the id-ce-basicConstraints extension */ + + switch (true) { + case isset($this->currentCert['tbsCertificate']): + // self-signed cert + switch (true) { + case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']: + case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING): + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier'); + switch (true) { + case !is_array($authorityKey): + case !$subjectKeyID: + case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + $signingCert = $this->currentCert; // working cert + } + } + + if (!empty($this->CAs)) { + for ($i = 0; $i < count($this->CAs); $i++) { + // even if the cert is a self-signed one we still want to see if it's a CA; + // if not, we'll conditionally return an error + $ca = $this->CAs[$i]; + switch (true) { + case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']: + case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case !$subjectKeyID: + case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { + break 2; // serial mismatch - check other ca + } + $signingCert = $ca; // working cert + break 3; + } + } + } + if (count($this->CAs) == $i && $caonly) { + return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + } + } elseif (!isset($signingCert) || $caonly) { + return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); + } + return $this->validateSignatureHelper( + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + case isset($this->currentCert['certificationRequestInfo']): + return $this->validateSignatureHelper( + $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], + $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + case isset($this->currentCert['publicKeyAndChallenge']): + return $this->validateSignatureHelper( + $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], + $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + case isset($this->currentCert['tbsCertList']): + if (!empty($this->CAs)) { + for ($i = 0; $i < count($this->CAs); $i++) { + $ca = $this->CAs[$i]; + switch (true) { + case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']: + case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case !$subjectKeyID: + case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { + break 2; // serial mismatch - check other ca + } + $signingCert = $ca; // working cert + break 3; + } + } + } + } + if (!isset($signingCert)) { + return false; + } + return $this->validateSignatureHelper( + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], + $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], + $this->currentCert['signatureAlgorithm']['algorithm'], + substr($this->currentCert['signature'], 1), + $this->signatureSubject + ); + default: + return false; + } + } + + /** + * Validates a signature + * + * Returns true if the signature is verified and false if it is not correct. + * If the algorithms are unsupposed an exception is thrown. + * + * @param string $publicKeyAlgorithm + * @param string $publicKey + * @param string $signatureAlgorithm + * @param string $signature + * @param string $signatureSubject + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return bool + */ + private function validateSignatureHelper($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) + { + switch ($publicKeyAlgorithm) { + case 'id-RSASSA-PSS': + $key = RSA::loadFormat('PSS', $publicKey); + break; + case 'rsaEncryption': + $key = RSA::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'id-RSASSA-PSS': + break; + case 'md2WithRSAEncryption': + case 'md5WithRSAEncryption': + case 'sha1WithRSAEncryption': + case 'sha224WithRSAEncryption': + case 'sha256WithRSAEncryption': + case 'sha384WithRSAEncryption': + case 'sha512WithRSAEncryption': + $key = $key + ->withHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)) + ->withPadding(RSA::SIGNATURE_PKCS1); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + case 'id-Ed25519': + case 'id-Ed448': + $key = EC::loadFormat('PKCS8', $publicKey); + break; + case 'id-ecPublicKey': + $key = EC::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'ecdsa-with-SHA1': + case 'ecdsa-with-SHA224': + case 'ecdsa-with-SHA256': + case 'ecdsa-with-SHA384': + case 'ecdsa-with-SHA512': + $key = $key + ->withHash(preg_replace('#^ecdsa-with-#', '', strtolower($signatureAlgorithm))); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + case 'id-dsa': + $key = DSA::loadFormat('PKCS8', $publicKey); + switch ($signatureAlgorithm) { + case 'id-dsa-with-sha1': + case 'id-dsa-with-sha224': + case 'id-dsa-with-sha256': + $key = $key + ->withHash(preg_replace('#^id-dsa-with-#', '', strtolower($signatureAlgorithm))); + break; + default: + throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); + } + break; + default: + throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); + } + + return $key->verify($signatureSubject, $signature); + } + + /** + * Sets the recursion limit + * + * When validating a signature it may be necessary to download intermediate certs from URI's. + * An intermediate cert that linked to itself would result in an infinite loop so to prevent + * that we set a recursion limit. A negative number means that there is no recursion limit. + * + * @param int $count + */ + public static function setRecurLimit($count) + { + self::$recur_limit = $count; + } + + /** + * Prevents URIs from being automatically retrieved + * + */ + public static function disableURLFetch() + { + self::$disable_url_fetch = true; + } + + /** + * Allows URIs to be automatically retrieved + * + */ + public static function enableURLFetch() + { + self::$disable_url_fetch = false; + } + + /** + * Decodes an IP address + * + * Takes in a base64 encoded "blob" and returns a human readable IP address + * + * @param string $ip + * @return string + */ + public static function decodeIP($ip) + { + return inet_ntop($ip); + } + + /** + * Decodes an IP address in a name constraints extension + * + * Takes in a base64 encoded "blob" and returns a human readable IP address / mask + * + * @param string $ip + * @return array + */ + public static function decodeNameConstraintIP($ip) + { + $size = strlen($ip) >> 1; + $mask = substr($ip, $size); + $ip = substr($ip, 0, $size); + return [inet_ntop($ip), inet_ntop($mask)]; + } + + /** + * Encodes an IP address + * + * Takes a human readable IP address into a base64-encoded "blob" + * + * @param string|array $ip + * @return string + */ + public static function encodeIP($ip) + { + return is_string($ip) ? + inet_pton($ip) : + inet_pton($ip[0]) . inet_pton($ip[1]); + } + + /** + * "Normalizes" a Distinguished Name property + * + * @param string $propName + * @return mixed + */ + private function translateDNProp($propName) + { + switch (strtolower($propName)) { + case 'jurisdictionofincorporationcountryname': + case 'jurisdictioncountryname': + case 'jurisdictionc': + return 'jurisdictionOfIncorporationCountryName'; + case 'jurisdictionofincorporationstateorprovincename': + case 'jurisdictionstateorprovincename': + case 'jurisdictionst': + return 'jurisdictionOfIncorporationStateOrProvinceName'; + case 'jurisdictionlocalityname': + case 'jurisdictionl': + return 'jurisdictionLocalityName'; + case 'id-at-businesscategory': + case 'businesscategory': + return 'id-at-businessCategory'; + case 'id-at-countryname': + case 'countryname': + case 'c': + return 'id-at-countryName'; + case 'id-at-organizationname': + case 'organizationname': + case 'o': + return 'id-at-organizationName'; + case 'id-at-dnqualifier': + case 'dnqualifier': + return 'id-at-dnQualifier'; + case 'id-at-commonname': + case 'commonname': + case 'cn': + return 'id-at-commonName'; + case 'id-at-stateorprovincename': + case 'stateorprovincename': + case 'state': + case 'province': + case 'provincename': + case 'st': + return 'id-at-stateOrProvinceName'; + case 'id-at-localityname': + case 'localityname': + case 'l': + return 'id-at-localityName'; + case 'id-emailaddress': + case 'emailaddress': + return 'pkcs-9-at-emailAddress'; + case 'id-at-serialnumber': + case 'serialnumber': + return 'id-at-serialNumber'; + case 'id-at-postalcode': + case 'postalcode': + return 'id-at-postalCode'; + case 'id-at-streetaddress': + case 'streetaddress': + return 'id-at-streetAddress'; + case 'id-at-name': + case 'name': + return 'id-at-name'; + case 'id-at-givenname': + case 'givenname': + return 'id-at-givenName'; + case 'id-at-surname': + case 'surname': + case 'sn': + return 'id-at-surname'; + case 'id-at-initials': + case 'initials': + return 'id-at-initials'; + case 'id-at-generationqualifier': + case 'generationqualifier': + return 'id-at-generationQualifier'; + case 'id-at-organizationalunitname': + case 'organizationalunitname': + case 'ou': + return 'id-at-organizationalUnitName'; + case 'id-at-pseudonym': + case 'pseudonym': + return 'id-at-pseudonym'; + case 'id-at-title': + case 'title': + return 'id-at-title'; + case 'id-at-description': + case 'description': + return 'id-at-description'; + case 'id-at-role': + case 'role': + return 'id-at-role'; + case 'id-at-uniqueidentifier': + case 'uniqueidentifier': + case 'x500uniqueidentifier': + return 'id-at-uniqueIdentifier'; + case 'postaladdress': + case 'id-at-postaladdress': + return 'id-at-postalAddress'; + default: + return false; + } + } + + /** + * Set a Distinguished Name property + * + * @param string $propName + * @param mixed $propValue + * @param string $type optional + * @return bool + */ + public function setDNProp($propName, $propValue, $type = 'utf8String') + { + if (empty($this->dn)) { + $this->dn = ['rdnSequence' => []]; + } + + if (($propName = $this->translateDNProp($propName)) === false) { + return false; + } + + foreach ((array) $propValue as $v) { + if (!is_array($v) && isset($type)) { + $v = [$type => $v]; + } + $this->dn['rdnSequence'][] = [ + [ + 'type' => $propName, + 'value' => $v + ] + ]; + } + + return true; + } + + /** + * Remove Distinguished Name properties + * + * @param string $propName + */ + public function removeDNProp($propName) + { + if (empty($this->dn)) { + return; + } + + if (($propName = $this->translateDNProp($propName)) === false) { + return; + } + + $dn = &$this->dn['rdnSequence']; + $size = count($dn); + for ($i = 0; $i < $size; $i++) { + if ($dn[$i][0]['type'] == $propName) { + unset($dn[$i]); + } + } + + $dn = array_values($dn); + // fix for https://bugs.php.net/75433 affecting PHP 7.2 + if (!isset($dn[0])) { + $dn = array_splice($dn, 0, 0); + } + } + + /** + * Get Distinguished Name properties + * + * @param string $propName + * @param array $dn optional + * @param bool $withType optional + * @return mixed + */ + public function getDNProp($propName, array $dn = null, $withType = false) + { + if (!isset($dn)) { + $dn = $this->dn; + } + + if (empty($dn)) { + return false; + } + + if (($propName = $this->translateDNProp($propName)) === false) { + return false; + } + + $filters = []; + $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + $dn = $dn['rdnSequence']; + $result = []; + for ($i = 0; $i < count($dn); $i++) { + if ($dn[$i][0]['type'] == $propName) { + $v = $dn[$i][0]['value']; + if (!$withType) { + if (is_array($v)) { + foreach ($v as $type => $s) { + $type = array_search($type, ASN1::ANY_MAP); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $s = ASN1::convert($s, $type); + if ($s !== false) { + $v = $s; + break; + } + } + } + if (is_array($v)) { + $v = array_pop($v); // Always strip data type. + } + } elseif (is_object($v) && $v instanceof Element) { + $map = $this->getMapping($propName); + if (!is_bool($map)) { + $decoded = ASN1::decodeBER($v); + if (!$decoded) { + return false; + } + $v = ASN1::asn1map($decoded[0], $map); + } + } + } + $result[] = $v; + } + } + + return $result; + } + + /** + * Set a Distinguished Name + * + * @param mixed $dn + * @param bool $merge optional + * @param string $type optional + * @return bool + */ + public function setDN($dn, $merge = false, $type = 'utf8String') + { + if (!$merge) { + $this->dn = null; + } + + if (is_array($dn)) { + if (isset($dn['rdnSequence'])) { + $this->dn = $dn; // No merge here. + return true; + } + + // handles stuff generated by openssl_x509_parse() + foreach ($dn as $prop => $value) { + if (!$this->setDNProp($prop, $value, $type)) { + return false; + } + } + return true; + } + + // handles everything else + $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE); + for ($i = 1; $i < count($results); $i += 2) { + $prop = trim($results[$i], ', =/'); + $value = $results[$i + 1]; + if (!$this->setDNProp($prop, $value, $type)) { + return false; + } + } + + return true; + } + + /** + * Get the Distinguished Name for a certificates subject + * + * @param mixed $format optional + * @param array $dn optional + * @return array|bool|string + */ + public function getDN($format = self::DN_ARRAY, array $dn = null) + { + if (!isset($dn)) { + $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; + } + + switch ((int) $format) { + case self::DN_ARRAY: + return $dn; + case self::DN_ASN1: + $filters = []; + $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + return ASN1::encodeDER($dn, Maps\Name::MAP); + case self::DN_CANON: + // No SEQUENCE around RDNs and all string values normalized as + // trimmed lowercase UTF-8 with all spacing as one blank. + // constructed RDNs will not be canonicalized + $filters = []; + $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $result = ''; + $this->mapOutDNs($dn, 'rdnSequence'); + foreach ($dn['rdnSequence'] as $rdn) { + foreach ($rdn as $i => $attr) { + $attr = &$rdn[$i]; + if (is_array($attr['value'])) { + foreach ($attr['value'] as $type => $v) { + $type = array_search($type, ASN1::ANY_MAP, true); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $v = ASN1::convert($v, $type); + if ($v !== false) { + $v = preg_replace('/\s+/', ' ', $v); + $attr['value'] = strtolower(trim($v)); + break; + } + } + } + } + } + $result .= ASN1::encodeDER($rdn, Maps\RelativeDistinguishedName::MAP); + } + return $result; + case self::DN_HASH: + $dn = $this->getDN(self::DN_CANON, $dn); + $hash = new Hash('sha1'); + $hash = $hash->hash($dn); + extract(unpack('Vhash', $hash)); + return strtolower(Strings::bin2hex(pack('N', $hash))); + } + + // Default is to return a string. + $start = true; + $output = ''; + + $result = []; + $filters = []; + $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; + ASN1::setFilters($filters); + $this->mapOutDNs($dn, 'rdnSequence'); + + foreach ($dn['rdnSequence'] as $field) { + $prop = $field[0]['type']; + $value = $field[0]['value']; + + $delim = ', '; + switch ($prop) { + case 'id-at-countryName': + $desc = 'C'; + break; + case 'id-at-stateOrProvinceName': + $desc = 'ST'; + break; + case 'id-at-organizationName': + $desc = 'O'; + break; + case 'id-at-organizationalUnitName': + $desc = 'OU'; + break; + case 'id-at-commonName': + $desc = 'CN'; + break; + case 'id-at-localityName': + $desc = 'L'; + break; + case 'id-at-surname': + $desc = 'SN'; + break; + case 'id-at-uniqueIdentifier': + $delim = '/'; + $desc = 'x500UniqueIdentifier'; + break; + case 'id-at-postalAddress': + $delim = '/'; + $desc = 'postalAddress'; + break; + default: + $delim = '/'; + $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop); + } + + if (!$start) { + $output .= $delim; + } + if (is_array($value)) { + foreach ($value as $type => $v) { + $type = array_search($type, ASN1::ANY_MAP, true); + if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { + $v = ASN1::convert($v, $type); + if ($v !== false) { + $value = $v; + break; + } + } + } + if (is_array($value)) { + $value = array_pop($value); // Always strip data type. + } + } elseif (is_object($value) && $value instanceof Element) { + $callback = function ($x) { + return '\x' . bin2hex($x[0]); + }; + $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); + } + $output .= $desc . '=' . $value; + $result[$desc] = isset($result[$desc]) ? + array_merge((array) $result[$desc], [$value]) : + $value; + $start = false; + } + + return $format == self::DN_OPENSSL ? $result : $output; + } + + /** + * Get the Distinguished Name for a certificate/crl issuer + * + * @param int $format optional + * @return mixed + */ + public function getIssuerDN($format = self::DN_ARRAY) + { + switch (true) { + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDN($format, $this->currentCert['tbsCertificate']['issuer']); + case isset($this->currentCert['tbsCertList']): + return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']); + } + + return false; + } + + /** + * Get the Distinguished Name for a certificate/csr subject + * Alias of getDN() + * + * @param int $format optional + * @return mixed + */ + public function getSubjectDN($format = self::DN_ARRAY) + { + switch (true) { + case !empty($this->dn): + return $this->getDN($format); + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDN($format, $this->currentCert['tbsCertificate']['subject']); + case isset($this->currentCert['certificationRequestInfo']): + return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']); + } + + return false; + } + + /** + * Get an individual Distinguished Name property for a certificate/crl issuer + * + * @param string $propName + * @param bool $withType optional + * @return mixed + */ + public function getIssuerDNProp($propName, $withType = false) + { + switch (true) { + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType); + case isset($this->currentCert['tbsCertList']): + return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType); + } + + return false; + } + + /** + * Get an individual Distinguished Name property for a certificate/csr subject + * + * @param string $propName + * @param bool $withType optional + * @return mixed + */ + public function getSubjectDNProp($propName, $withType = false) + { + switch (true) { + case !empty($this->dn): + return $this->getDNProp($propName, null, $withType); + case !isset($this->currentCert) || !is_array($this->currentCert): + break; + case isset($this->currentCert['tbsCertificate']): + return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType); + case isset($this->currentCert['certificationRequestInfo']): + return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType); + } + + return false; + } + + /** + * Get the certificate chain for the current cert + * + * @return mixed + */ + public function getChain() + { + $chain = [$this->currentCert]; + + if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { + return false; + } + while (true) { + $currentCert = $chain[count($chain) - 1]; + for ($i = 0; $i < count($this->CAs); $i++) { + $ca = $this->CAs[$i]; + if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) { + $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert); + $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); + switch (true) { + case !is_array($authorityKey): + case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: + if ($currentCert === $ca) { + break 3; + } + $chain[] = $ca; + break 2; + } + } + } + if ($i == count($this->CAs)) { + break; + } + } + foreach ($chain as $key => $value) { + $chain[$key] = new X509(); + $chain[$key]->loadX509($value); + } + return $chain; + } + + /** + * Returns the current cert + * + * @return array|bool + */ + public function &getCurrentCert() + { + return $this->currentCert; + } + + /** + * Set public key + * + * Key needs to be a \phpseclib3\Crypt\RSA object + * + * @param PublicKey $key + * @return void + */ + public function setPublicKey(PublicKey $key) + { + $this->publicKey = $key; + } + + /** + * Set private key + * + * Key needs to be a \phpseclib3\Crypt\RSA object + * + * @param PrivateKey $key + */ + public function setPrivateKey(PrivateKey $key) + { + $this->privateKey = $key; + } + + /** + * Set challenge + * + * Used for SPKAC CSR's + * + * @param string $challenge + */ + public function setChallenge($challenge) + { + $this->challenge = $challenge; + } + + /** + * Gets the public key + * + * Returns a \phpseclib3\Crypt\RSA object or a false. + * + * @return mixed + */ + public function getPublicKey() + { + if (isset($this->publicKey)) { + return $this->publicKey; + } + + if (isset($this->currentCert) && is_array($this->currentCert)) { + $paths = [ + 'tbsCertificate/subjectPublicKeyInfo', + 'certificationRequestInfo/subjectPKInfo', + 'publicKeyAndChallenge/spki' + ]; + foreach ($paths as $path) { + $keyinfo = $this->subArray($this->currentCert, $path); + if (!empty($keyinfo)) { + break; + } + } + } + if (empty($keyinfo)) { + return false; + } + + $key = $keyinfo['subjectPublicKey']; + + switch ($keyinfo['algorithm']['algorithm']) { + case 'id-RSASSA-PSS': + return RSA::loadFormat('PSS', $key); + case 'rsaEncryption': + return RSA::loadFormat('PKCS8', $key)->withPadding(RSA::SIGNATURE_PKCS1); + case 'id-ecPublicKey': + case 'id-Ed25519': + case 'id-Ed448': + return EC::loadFormat('PKCS8', $key); + case 'id-dsa': + return DSA::loadFormat('PKCS8', $key); + } + + return false; + } + + /** + * Load a Certificate Signing Request + * + * @param string $csr + * @param int $mode + * @return mixed + */ + public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) + { + if (is_array($csr) && isset($csr['certificationRequestInfo'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + unset($this->signatureSubject); + $this->dn = $csr['certificationRequestInfo']['subject']; + if (!isset($this->dn)) { + return false; + } + + $this->currentCert = $csr; + return $csr; + } + + // see http://tools.ietf.org/html/rfc2986 + + if ($mode != self::FORMAT_DER) { + $newcsr = ASN1::extractBER($csr); + if ($mode == self::FORMAT_PEM && $csr == $newcsr) { + return false; + } + $csr = $newcsr; + } + $orig = $csr; + + if ($csr === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($csr); + + if (!$decoded) { + $this->currentCert = false; + return false; + } + + $csr = ASN1::asn1map($decoded[0], Maps\CertificationRequest::MAP); + if (!isset($csr) || $csr === false) { + $this->currentCert = false; + return false; + } + + $this->mapInAttributes($csr, 'certificationRequestInfo/attributes'); + $this->mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); + + $this->dn = $csr['certificationRequestInfo']['subject']; + + $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + $key = $csr['certificationRequestInfo']['subjectPKInfo']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + + $this->currentKeyIdentifier = null; + $this->currentCert = $csr; + + $this->publicKey = null; + $this->publicKey = $this->getPublicKey(); + + return $csr; + } + + /** + * Save CSR request + * + * @param array $csr + * @param int $format optional + * @return string + */ + public function saveCSR(array $csr, $format = self::FORMAT_PEM) + { + if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { + return false; + } + + switch (true) { + case !($algorithm = $this->subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): + case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): + break; + default: + $csr['certificationRequestInfo']['subjectPKInfo'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])) + ); + } + + $filters = []; + $filters['certificationRequestInfo']['subject']['rdnSequence']['value'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + + ASN1::setFilters($filters); + + $this->mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); + $this->mapOutAttributes($csr, 'certificationRequestInfo/attributes'); + $csr = ASN1::encodeDER($csr, Maps\CertificationRequest::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $csr; + // case self::FORMAT_PEM: + default: + return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Strings::base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; + } + } + + /** + * Load a SPKAC CSR + * + * SPKAC's are produced by the HTML5 keygen element: + * + * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen + * + * @param string $spkac + * @return mixed + */ + public function loadSPKAC($spkac) + { + if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) { + unset($this->currentCert); + unset($this->currentKeyIdentifier); + unset($this->signatureSubject); + $this->currentCert = $spkac; + return $spkac; + } + + // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge + + // OpenSSL produces SPKAC's that are preceded by the string SPKAC= + $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); + $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; + if ($temp != false) { + $spkac = $temp; + } + $orig = $spkac; + + if ($spkac === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($spkac); + + if (!$decoded) { + $this->currentCert = false; + return false; + } + + $spkac = ASN1::asn1map($decoded[0], Maps\SignedPublicKeyAndChallenge::MAP); + + if (!isset($spkac) || !is_array($spkac)) { + $this->currentCert = false; + return false; + } + + $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + $key = $spkac['publicKeyAndChallenge']['spki']; + $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); + $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = + "-----BEGIN PUBLIC KEY-----\r\n" . + chunk_split(base64_encode($key), 64) . + "-----END PUBLIC KEY-----"; + + $this->currentKeyIdentifier = null; + $this->currentCert = $spkac; + + $this->publicKey = null; + $this->publicKey = $this->getPublicKey(); + + return $spkac; + } + + /** + * Save a SPKAC CSR request + * + * @param array $spkac + * @param int $format optional + * @return string + */ + public function saveSPKAC(array $spkac, $format = self::FORMAT_PEM) + { + if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { + return false; + } + + $algorithm = $this->subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); + switch (true) { + case !$algorithm: + case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): + break; + default: + $spkac['publicKeyAndChallenge']['spki'] = new Element( + base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])) + ); + } + + $spkac = ASN1::encodeDER($spkac, Maps\SignedPublicKeyAndChallenge::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $spkac; + // case self::FORMAT_PEM: + default: + // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much + // no other SPKAC decoders phpseclib will use that same format + return 'SPKAC=' . Strings::base64_encode($spkac); + } + } + + /** + * Load a Certificate Revocation List + * + * @param string $crl + * @param int $mode + * @return mixed + */ + public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) + { + if (is_array($crl) && isset($crl['tbsCertList'])) { + $this->currentCert = $crl; + unset($this->signatureSubject); + return $crl; + } + + if ($mode != self::FORMAT_DER) { + $newcrl = ASN1::extractBER($crl); + if ($mode == self::FORMAT_PEM && $crl == $newcrl) { + return false; + } + $crl = $newcrl; + } + $orig = $crl; + + if ($crl === false) { + $this->currentCert = false; + return false; + } + + $decoded = ASN1::decodeBER($crl); + + if (!$decoded) { + $this->currentCert = false; + return false; + } + + $crl = ASN1::asn1map($decoded[0], Maps\CertificateList::MAP); + if (!isset($crl) || $crl === false) { + $this->currentCert = false; + return false; + } + + $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); + + $this->mapInDNs($crl, 'tbsCertList/issuer/rdnSequence'); + if ($this->isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { + $this->mapInExtensions($crl, 'tbsCertList/crlExtensions'); + } + if ($this->isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { + $rclist_ref = &$this->subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); + if ($rclist_ref) { + $rclist = $crl['tbsCertList']['revokedCertificates']; + foreach ($rclist as $i => $extension) { + if ($this->isSubArrayValid($rclist, "$i/crlEntryExtensions")) { + $this->mapInExtensions($rclist_ref, "$i/crlEntryExtensions"); + } + } + } + } + + $this->currentKeyIdentifier = null; + $this->currentCert = $crl; + + return $crl; + } + + /** + * Save Certificate Revocation List. + * + * @param array $crl + * @param int $format optional + * @return string + */ + public function saveCRL(array $crl, $format = self::FORMAT_PEM) + { + if (!is_array($crl) || !isset($crl['tbsCertList'])) { + return false; + } + + $filters = []; + $filters['tbsCertList']['issuer']['rdnSequence']['value'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters['tbsCertList']['signature']['parameters'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + $filters['signatureAlgorithm']['parameters'] + = ['type' => ASN1::TYPE_UTF8_STRING]; + + if (empty($crl['tbsCertList']['signature']['parameters'])) { + $filters['tbsCertList']['signature']['parameters'] + = ['type' => ASN1::TYPE_NULL]; + } + + if (empty($crl['signatureAlgorithm']['parameters'])) { + $filters['signatureAlgorithm']['parameters'] + = ['type' => ASN1::TYPE_NULL]; + } + + ASN1::setFilters($filters); + + $this->mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence'); + $this->mapOutExtensions($crl, 'tbsCertList/crlExtensions'); + $rclist = &$this->subArray($crl, 'tbsCertList/revokedCertificates'); + if (is_array($rclist)) { + foreach ($rclist as $i => $extension) { + $this->mapOutExtensions($rclist, "$i/crlEntryExtensions"); + } + } + + $crl = ASN1::encodeDER($crl, Maps\CertificateList::MAP); + + switch ($format) { + case self::FORMAT_DER: + return $crl; + // case self::FORMAT_PEM: + default: + return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Strings::base64_encode($crl), 64) . '-----END X509 CRL-----'; + } + } + + /** + * Helper function to build a time field according to RFC 3280 section + * - 4.1.2.5 Validity + * - 5.1.2.4 This Update + * - 5.1.2.5 Next Update + * - 5.1.2.6 Revoked Certificates + * by choosing utcTime iff year of date given is before 2050 and generalTime else. + * + * @param string $date in format date('D, d M Y H:i:s O') + * @return array|Element + */ + private function timeField($date) + { + if ($date instanceof Element) { + return $date; + } + $dateObj = new \DateTimeImmutable($date, new \DateTimeZone('GMT')); + $year = $dateObj->format('Y'); // the same way ASN1.php parses this + if ($year < 2050) { + return ['utcTime' => $date]; + } else { + return ['generalTime' => $date]; + } + } + + /** + * Sign an X.509 certificate + * + * $issuer's private key needs to be loaded. + * $subject can be either an existing X.509 cert (if you want to resign it), + * a CSR or something with the DN and public key explicitly set. + * + * @return mixed + */ + public function sign(X509 $issuer, X509 $subject) + { + if (!is_object($issuer->privateKey) || empty($issuer->dn)) { + return false; + } + + if (isset($subject->publicKey) && !($subjectPublicKey = $subject->formatSubjectPublicKey())) { + return false; + } + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); + + if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) { + $this->currentCert = $subject->currentCert; + $this->currentCert['tbsCertificate']['signature'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; + + if (!empty($this->startDate)) { + $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->timeField($this->startDate); + } + if (!empty($this->endDate)) { + $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->timeField($this->endDate); + } + if (!empty($this->serialNumber)) { + $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber; + } + if (!empty($subject->dn)) { + $this->currentCert['tbsCertificate']['subject'] = $subject->dn; + } + if (!empty($subject->publicKey)) { + $this->currentCert['tbsCertificate']['subjectPublicKeyInfo'] = $subjectPublicKey; + } + $this->removeExtension('id-ce-authorityKeyIdentifier'); + if (isset($subject->domains)) { + $this->removeExtension('id-ce-subjectAltName'); + } + } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) { + return false; + } else { + if (!isset($subject->publicKey)) { + return false; + } + + $startDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); + $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O'); + + $endDate = new \DateTimeImmutable('+1 year', new \DateTimeZone(@date_default_timezone_get())); + $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O'); + + /* "The serial number MUST be a positive integer" + "Conforming CAs MUST NOT use serialNumber values longer than 20 octets." + -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2 + + for the integer to be positive the leading bit needs to be 0 hence the + application of a bitmap + */ + $serialNumber = !empty($this->serialNumber) ? + $this->serialNumber : + new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256); + + $this->currentCert = [ + 'tbsCertificate' => + [ + 'version' => 'v3', + 'serialNumber' => $serialNumber, // $this->setSerialNumber() + 'signature' => $signatureAlgorithm, + 'issuer' => false, // this is going to be overwritten later + 'validity' => [ + 'notBefore' => $this->timeField($startDate), // $this->setStartDate() + 'notAfter' => $this->timeField($endDate) // $this->setEndDate() + ], + 'subject' => $subject->dn, + 'subjectPublicKeyInfo' => $subjectPublicKey + ], + 'signatureAlgorithm' => $signatureAlgorithm, + 'signature' => false // this is going to be overwritten later + ]; + + // Copy extensions from CSR. + $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0); + + if (!empty($csrexts)) { + $this->currentCert['tbsCertificate']['extensions'] = $csrexts; + } + } + + $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; + + if (isset($issuer->currentKeyIdentifier)) { + $this->setExtension('id-ce-authorityKeyIdentifier', [ + //'authorityCertIssuer' => array( + // array( + // 'directoryName' => $issuer->dn + // ) + //), + 'keyIdentifier' => $issuer->currentKeyIdentifier + ]); + //$extensions = &$this->currentCert['tbsCertificate']['extensions']; + //if (isset($issuer->serialNumber)) { + // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; + //} + //unset($extensions); + } + + if (isset($subject->currentKeyIdentifier)) { + $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier); + } + + $altName = []; + + if (isset($subject->domains) && count($subject->domains)) { + $altName = array_map(['\phpseclib3\File\X509', 'dnsName'], $subject->domains); + } + + if (isset($subject->ipAddresses) && count($subject->ipAddresses)) { + // should an IP address appear as the CN if no domain name is specified? idk + //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1); + $ipAddresses = []; + foreach ($subject->ipAddresses as $ipAddress) { + $encoded = $subject->ipAddress($ipAddress); + if ($encoded !== false) { + $ipAddresses[] = $encoded; + } + } + if (count($ipAddresses)) { + $altName = array_merge($altName, $ipAddresses); + } + } + + if (!empty($altName)) { + $this->setExtension('id-ce-subjectAltName', $altName); + } + + if ($this->caFlag) { + $keyUsage = $this->getExtension('id-ce-keyUsage'); + if (!$keyUsage) { + $keyUsage = []; + } + + $this->setExtension( + 'id-ce-keyUsage', + array_values(array_unique(array_merge($keyUsage, ['cRLSign', 'keyCertSign']))) + ); + + $basicConstraints = $this->getExtension('id-ce-basicConstraints'); + if (!$basicConstraints) { + $basicConstraints = []; + } + + $this->setExtension( + 'id-ce-basicConstraints', + array_merge(['cA' => true], $basicConstraints), + true + ); + + if (!isset($subject->currentKeyIdentifier)) { + $this->setExtension('id-ce-subjectKeyIdentifier', $this->computeKeyIdentifier($this->currentCert), false, false); + } + } + + // resync $this->signatureSubject + // save $tbsCertificate in case there are any \phpseclib3\File\ASN1\Element objects in it + $tbsCertificate = $this->currentCert['tbsCertificate']; + $this->loadX509($this->saveX509($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); + $result['tbsCertificate'] = $tbsCertificate; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Sign a CSR + * + * @return mixed + */ + public function signCSR() + { + if (!is_object($this->privateKey) || empty($this->dn)) { + return false; + } + + $origPublicKey = $this->publicKey; + $this->publicKey = $this->privateKey->getPublicKey(); + $publicKey = $this->formatSubjectPublicKey(); + $this->publicKey = $origPublicKey; + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); + + if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) { + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; + if (!empty($this->dn)) { + $this->currentCert['certificationRequestInfo']['subject'] = $this->dn; + } + $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey; + } else { + $this->currentCert = [ + 'certificationRequestInfo' => + [ + 'version' => 'v1', + 'subject' => $this->dn, + 'subjectPKInfo' => $publicKey + ], + 'signatureAlgorithm' => $signatureAlgorithm, + 'signature' => false // this is going to be overwritten later + ]; + } + + // resync $this->signatureSubject + // save $certificationRequestInfo in case there are any \phpseclib3\File\ASN1\Element objects in it + $certificationRequestInfo = $this->currentCert['certificationRequestInfo']; + $this->loadCSR($this->saveCSR($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); + $result['certificationRequestInfo'] = $certificationRequestInfo; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Sign a SPKAC + * + * @return mixed + */ + public function signSPKAC() + { + if (!is_object($this->privateKey)) { + return false; + } + + $origPublicKey = $this->publicKey; + $this->publicKey = $this->privateKey->getPublicKey(); + $publicKey = $this->formatSubjectPublicKey(); + $this->publicKey = $origPublicKey; + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); + + // re-signing a SPKAC seems silly but since everything else supports re-signing why not? + if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) { + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; + $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey; + if (!empty($this->challenge)) { + // the bitwise AND ensures that the output is a valid IA5String + $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge)); + } + } else { + $this->currentCert = [ + 'publicKeyAndChallenge' => + [ + 'spki' => $publicKey, + // quoting , + // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified." + // both Firefox and OpenSSL ("openssl spkac -key private.key") behave this way + // we could alternatively do this instead if we ignored the specs: + // Random::string(8) & str_repeat("\x7F", 8) + 'challenge' => !empty($this->challenge) ? $this->challenge : '' + ], + 'signatureAlgorithm' => $signatureAlgorithm, + 'signature' => false // this is going to be overwritten later + ]; + } + + // resync $this->signatureSubject + // save $publicKeyAndChallenge in case there are any \phpseclib3\File\ASN1\Element objects in it + $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge']; + $this->loadSPKAC($this->saveSPKAC($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); + $result['publicKeyAndChallenge'] = $publicKeyAndChallenge; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Sign a CRL + * + * $issuer's private key needs to be loaded. + * + * @return mixed + */ + public function signCRL(X509 $issuer, X509 $crl) + { + if (!is_object($issuer->privateKey) || empty($issuer->dn)) { + return false; + } + + $currentCert = isset($this->currentCert) ? $this->currentCert : null; + $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; + $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); + + $thisUpdate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); + $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O'); + + if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) { + $this->currentCert = $crl->currentCert; + $this->currentCert['tbsCertList']['signature'] = $signatureAlgorithm; + $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; + } else { + $this->currentCert = [ + 'tbsCertList' => + [ + 'version' => 'v2', + 'signature' => $signatureAlgorithm, + 'issuer' => false, // this is going to be overwritten later + 'thisUpdate' => $this->timeField($thisUpdate) // $this->setStartDate() + ], + 'signatureAlgorithm' => $signatureAlgorithm, + 'signature' => false // this is going to be overwritten later + ]; + } + + $tbsCertList = &$this->currentCert['tbsCertList']; + $tbsCertList['issuer'] = $issuer->dn; + $tbsCertList['thisUpdate'] = $this->timeField($thisUpdate); + + if (!empty($this->endDate)) { + $tbsCertList['nextUpdate'] = $this->timeField($this->endDate); // $this->setEndDate() + } else { + unset($tbsCertList['nextUpdate']); + } + + if (!empty($this->serialNumber)) { + $crlNumber = $this->serialNumber; + } else { + $crlNumber = $this->getExtension('id-ce-cRLNumber'); + // "The CRL number is a non-critical CRL extension that conveys a + // monotonically increasing sequence number for a given CRL scope and + // CRL issuer. This extension allows users to easily determine when a + // particular CRL supersedes another CRL." + // -- https://tools.ietf.org/html/rfc5280#section-5.2.3 + $crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null; + } + + $this->removeExtension('id-ce-authorityKeyIdentifier'); + $this->removeExtension('id-ce-issuerAltName'); + + // Be sure version >= v2 if some extension found. + $version = isset($tbsCertList['version']) ? $tbsCertList['version'] : 0; + if (!$version) { + if (!empty($tbsCertList['crlExtensions'])) { + $version = 1; // v2. + } elseif (!empty($tbsCertList['revokedCertificates'])) { + foreach ($tbsCertList['revokedCertificates'] as $cert) { + if (!empty($cert['crlEntryExtensions'])) { + $version = 1; // v2. + } + } + } + + if ($version) { + $tbsCertList['version'] = $version; + } + } + + // Store additional extensions. + if (!empty($tbsCertList['version'])) { // At least v2. + if (!empty($crlNumber)) { + $this->setExtension('id-ce-cRLNumber', $crlNumber); + } + + if (isset($issuer->currentKeyIdentifier)) { + $this->setExtension('id-ce-authorityKeyIdentifier', [ + //'authorityCertIssuer' => array( + // ] + // 'directoryName' => $issuer->dn + // ] + //), + 'keyIdentifier' => $issuer->currentKeyIdentifier + ]); + //$extensions = &$tbsCertList['crlExtensions']; + //if (isset($issuer->serialNumber)) { + // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; + //} + //unset($extensions); + } + + $issuerAltName = $this->getExtension('id-ce-subjectAltName', $issuer->currentCert); + + if ($issuerAltName !== false) { + $this->setExtension('id-ce-issuerAltName', $issuerAltName); + } + } + + if (empty($tbsCertList['revokedCertificates'])) { + unset($tbsCertList['revokedCertificates']); + } + + unset($tbsCertList); + + // resync $this->signatureSubject + // save $tbsCertList in case there are any \phpseclib3\File\ASN1\Element objects in it + $tbsCertList = $this->currentCert['tbsCertList']; + $this->loadCRL($this->saveCRL($this->currentCert)); + + $result = $this->currentCert; + $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); + $result['tbsCertList'] = $tbsCertList; + + $this->currentCert = $currentCert; + $this->signatureSubject = $signatureSubject; + + return $result; + } + + /** + * Identify signature algorithm from key settings + * + * @param PrivateKey $key + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + * @return array + */ + private static function identifySignatureAlgorithm(PrivateKey $key) + { + if ($key instanceof RSA) { + if ($key->getPadding() & RSA::SIGNATURE_PSS) { + $r = PSS::load($key->withPassword()->toString('PSS')); + return [ + 'algorithm' => 'id-RSASSA-PSS', + 'parameters' => PSS::savePSSParams($r) + ]; + } + switch ($key->getHash()) { + case 'md2': + case 'md5': + case 'sha1': + case 'sha224': + case 'sha256': + case 'sha384': + case 'sha512': + return ['algorithm' => $key->getHash() . 'WithRSAEncryption']; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for RSA are: md2, md5, sha1, sha224, sha256, sha384, sha512'); + } + + if ($key instanceof DSA) { + switch ($key->getHash()) { + case 'sha1': + case 'sha224': + case 'sha256': + return ['algorithm' => 'id-dsa-with-' . $key->getHash()]; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for DSA are: sha1, sha224, sha256'); + } + + if ($key instanceof EC) { + switch ($key->getCurve()) { + case 'Ed25519': + case 'Ed448': + return ['algorithm' => 'id-' . $key->getCurve()]; + } + switch ($key->getHash()) { + case 'sha1': + case 'sha224': + case 'sha256': + case 'sha384': + case 'sha512': + return ['algorithm' => 'ecdsa-with-' . strtoupper($key->getHash())]; + } + throw new UnsupportedAlgorithmException('The only supported hash algorithms for EC are: sha1, sha224, sha256, sha384, sha512'); + } + + throw new UnsupportedAlgorithmException('The only supported public key classes are: RSA, DSA, EC'); + } + + /** + * Set certificate start date + * + * @param \DateTimeInterface|string $date + */ + public function setStartDate($date) + { + if (!is_object($date) || !($date instanceof \DateTimeInterface)) { + $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); + } + + $this->startDate = $date->format('D, d M Y H:i:s O'); + } + + /** + * Set certificate end date + * + * @param \DateTimeInterface|string $date + */ + public function setEndDate($date) + { + /* + To indicate that a certificate has no well-defined expiration date, + the notAfter SHOULD be assigned the GeneralizedTime value of + 99991231235959Z. + + -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5 + */ + if (is_string($date) && strtolower($date) === 'lifetime') { + $temp = '99991231235959Z'; + $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . ASN1::encodeLength(strlen($temp)) . $temp; + $this->endDate = new Element($temp); + } else { + if (!is_object($date) || !($date instanceof \DateTimeInterface)) { + $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); + } + + $this->endDate = $date->format('D, d M Y H:i:s O'); + } + } + + /** + * Set Serial Number + * + * @param string $serial + * @param int $base optional + */ + public function setSerialNumber($serial, $base = -256) + { + $this->serialNumber = new BigInteger($serial, $base); + } + + /** + * Turns the certificate into a certificate authority + * + */ + public function makeCA() + { + $this->caFlag = true; + } + + /** + * Check for validity of subarray + * + * This is intended for use in conjunction with _subArrayUnchecked(), + * implementing the checks included in _subArray() but without copying + * a potentially large array by passing its reference by-value to is_array(). + * + * @param array $root + * @param string $path + * @return boolean + */ + private function isSubArrayValid(array $root, $path) + { + if (!is_array($root)) { + return false; + } + + foreach (explode('/', $path) as $i) { + if (!is_array($root)) { + return false; + } + + if (!isset($root[$i])) { + return true; + } + + $root = $root[$i]; + } + + return true; + } + + /** + * Get a reference to a subarray + * + * This variant of _subArray() does no is_array() checking, + * so $root should be checked with _isSubArrayValid() first. + * + * This is here for performance reasons: + * Passing a reference (i.e. $root) by-value (i.e. to is_array()) + * creates a copy. If $root is an especially large array, this is expensive. + * + * @param array $root + * @param string $path absolute path with / as component separator + * @param bool $create optional + * @return array|false + */ + private function &subArrayUnchecked(array &$root, $path, $create = false) + { + $false = false; + + foreach (explode('/', $path) as $i) { + if (!isset($root[$i])) { + if (!$create) { + return $false; + } + + $root[$i] = []; + } + + $root = &$root[$i]; + } + + return $root; + } + + /** + * Get a reference to a subarray + * + * @param array $root + * @param string $path absolute path with / as component separator + * @param bool $create optional + * @return array|false + */ + private function &subArray(array &$root = null, $path, $create = false) + { + $false = false; + + if (!is_array($root)) { + return $false; + } + + foreach (explode('/', $path) as $i) { + if (!is_array($root)) { + return $false; + } + + if (!isset($root[$i])) { + if (!$create) { + return $false; + } + + $root[$i] = []; + } + + $root = &$root[$i]; + } + + return $root; + } + + /** + * Get a reference to an extension subarray + * + * @param array $root + * @param string $path optional absolute path with / as component separator + * @param bool $create optional + * @return array|false + */ + private function &extensions(array &$root = null, $path = null, $create = false) + { + if (!isset($root)) { + $root = $this->currentCert; + } + + switch (true) { + case !empty($path): + case !is_array($root): + break; + case isset($root['tbsCertificate']): + $path = 'tbsCertificate/extensions'; + break; + case isset($root['tbsCertList']): + $path = 'tbsCertList/crlExtensions'; + break; + case isset($root['certificationRequestInfo']): + $pth = 'certificationRequestInfo/attributes'; + $attributes = &$this->subArray($root, $pth, $create); + + if (is_array($attributes)) { + foreach ($attributes as $key => $value) { + if ($value['type'] == 'pkcs-9-at-extensionRequest') { + $path = "$pth/$key/value/0"; + break 2; + } + } + if ($create) { + $key = count($attributes); + $attributes[] = ['type' => 'pkcs-9-at-extensionRequest', 'value' => []]; + $path = "$pth/$key/value/0"; + } + } + break; + } + + $extensions = &$this->subArray($root, $path, $create); + + if (!is_array($extensions)) { + $false = false; + return $false; + } + + return $extensions; + } + + /** + * Remove an Extension + * + * @param string $id + * @param string $path optional + * @return bool + */ + private function removeExtensionHelper($id, $path = null) + { + $extensions = &$this->extensions($this->currentCert, $path); + + if (!is_array($extensions)) { + return false; + } + + $result = false; + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + unset($extensions[$key]); + $result = true; + } + } + + $extensions = array_values($extensions); + // fix for https://bugs.php.net/75433 affecting PHP 7.2 + if (!isset($extensions[0])) { + $extensions = array_splice($extensions, 0, 0); + } + return $result; + } + + /** + * Get an Extension + * + * Returns the extension if it exists and false if not + * + * @param string $id + * @param array $cert optional + * @param string $path optional + * @return mixed + */ + private function getExtensionHelper($id, array $cert = null, $path = null) + { + $extensions = $this->extensions($cert, $path); + + if (!is_array($extensions)) { + return false; + } + + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + return $value['extnValue']; + } + } + + return false; + } + + /** + * Returns a list of all extensions in use + * + * @param array $cert optional + * @param string $path optional + * @return array + */ + private function getExtensionsHelper(array $cert = null, $path = null) + { + $exts = $this->extensions($cert, $path); + $extensions = []; + + if (is_array($exts)) { + foreach ($exts as $extension) { + $extensions[] = $extension['extnId']; + } + } + + return $extensions; + } + + /** + * Set an Extension + * + * @param string $id + * @param mixed $value + * @param bool $critical optional + * @param bool $replace optional + * @param string $path optional + * @return bool + */ + private function setExtensionHelper($id, $value, $critical = false, $replace = true, $path = null) + { + $extensions = &$this->extensions($this->currentCert, $path, true); + + if (!is_array($extensions)) { + return false; + } + + $newext = ['extnId' => $id, 'critical' => $critical, 'extnValue' => $value]; + + foreach ($extensions as $key => $value) { + if ($value['extnId'] == $id) { + if (!$replace) { + return false; + } + + $extensions[$key] = $newext; + return true; + } + } + + $extensions[] = $newext; + return true; + } + + /** + * Remove a certificate, CSR or CRL Extension + * + * @param string $id + * @return bool + */ + public function removeExtension($id) + { + return $this->removeExtensionHelper($id); + } + + /** + * Get a certificate, CSR or CRL Extension + * + * Returns the extension if it exists and false if not + * + * @param string $id + * @param array $cert optional + * @param string $path + * @return mixed + */ + public function getExtension($id, array $cert = null, $path = null) + { + return $this->getExtensionHelper($id, $cert, $path); + } + + /** + * Returns a list of all extensions in use in certificate, CSR or CRL + * + * @param array $cert optional + * @param string $path optional + * @return array + */ + public function getExtensions(array $cert = null, $path = null) + { + return $this->getExtensionsHelper($cert, $path); + } + + /** + * Set a certificate, CSR or CRL Extension + * + * @param string $id + * @param mixed $value + * @param bool $critical optional + * @param bool $replace optional + * @return bool + */ + public function setExtension($id, $value, $critical = false, $replace = true) + { + return $this->setExtensionHelper($id, $value, $critical, $replace); + } + + /** + * Remove a CSR attribute. + * + * @param string $id + * @param int $disposition optional + * @return bool + */ + public function removeAttribute($id, $disposition = self::ATTR_ALL) + { + $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes'); + + if (!is_array($attributes)) { + return false; + } + + $result = false; + foreach ($attributes as $key => $attribute) { + if ($attribute['type'] == $id) { + $n = count($attribute['value']); + switch (true) { + case $disposition == self::ATTR_APPEND: + case $disposition == self::ATTR_REPLACE: + return false; + case $disposition >= $n: + $disposition -= $n; + break; + case $disposition == self::ATTR_ALL: + case $n == 1: + unset($attributes[$key]); + $result = true; + break; + default: + unset($attributes[$key]['value'][$disposition]); + $attributes[$key]['value'] = array_values($attributes[$key]['value']); + $result = true; + break; + } + if ($result && $disposition != self::ATTR_ALL) { + break; + } + } + } + + $attributes = array_values($attributes); + return $result; + } + + /** + * Get a CSR attribute + * + * Returns the attribute if it exists and false if not + * + * @param string $id + * @param int $disposition optional + * @param array $csr optional + * @return mixed + */ + public function getAttribute($id, $disposition = self::ATTR_ALL, array $csr = null) + { + if (empty($csr)) { + $csr = $this->currentCert; + } + + $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); + + if (!is_array($attributes)) { + return false; + } + + foreach ($attributes as $key => $attribute) { + if ($attribute['type'] == $id) { + $n = count($attribute['value']); + switch (true) { + case $disposition == self::ATTR_APPEND: + case $disposition == self::ATTR_REPLACE: + return false; + case $disposition == self::ATTR_ALL: + return $attribute['value']; + case $disposition >= $n: + $disposition -= $n; + break; + default: + return $attribute['value'][$disposition]; + } + } + } + + return false; + } + + /** + * Returns a list of all CSR attributes in use + * + * @param array $csr optional + * @return array + */ + public function getAttributes(array $csr = null) + { + if (empty($csr)) { + $csr = $this->currentCert; + } + + $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); + $attrs = []; + + if (is_array($attributes)) { + foreach ($attributes as $attribute) { + $attrs[] = $attribute['type']; + } + } + + return $attrs; + } + + /** + * Set a CSR attribute + * + * @param string $id + * @param mixed $value + * @param int $disposition optional + * @return bool + */ + public function setAttribute($id, $value, $disposition = self::ATTR_ALL) + { + $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes', true); + + if (!is_array($attributes)) { + return false; + } + + switch ($disposition) { + case self::ATTR_REPLACE: + $disposition = self::ATTR_APPEND; + // fall-through + case self::ATTR_ALL: + $this->removeAttribute($id); + break; + } + + foreach ($attributes as $key => $attribute) { + if ($attribute['type'] == $id) { + $n = count($attribute['value']); + switch (true) { + case $disposition == self::ATTR_APPEND: + $last = $key; + break; + case $disposition >= $n: + $disposition -= $n; + break; + default: + $attributes[$key]['value'][$disposition] = $value; + return true; + } + } + } + + switch (true) { + case $disposition >= 0: + return false; + case isset($last): + $attributes[$last]['value'][] = $value; + break; + default: + $attributes[] = ['type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value : [$value]]; + break; + } + + return true; + } + + /** + * Sets the subject key identifier + * + * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions. + * + * @param string $value + */ + public function setKeyIdentifier($value) + { + if (empty($value)) { + unset($this->currentKeyIdentifier); + } else { + $this->currentKeyIdentifier = $value; + } + } + + /** + * Compute a public key identifier. + * + * Although key identifiers may be set to any unique value, this function + * computes key identifiers from public key according to the two + * recommended methods (4.2.1.2 RFC 3280). + * Highly polymorphic: try to accept all possible forms of key: + * - Key object + * - \phpseclib3\File\X509 object with public or private key defined + * - Certificate or CSR array + * - \phpseclib3\File\ASN1\Element object + * - PEM or DER string + * + * @param mixed $key optional + * @param int $method optional + * @return string binary key identifier + */ + public function computeKeyIdentifier($key = null, $method = 1) + { + if (is_null($key)) { + $key = $this; + } + + switch (true) { + case is_string($key): + break; + case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): + return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method); + case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): + return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method); + case !is_object($key): + return false; + case $key instanceof Element: + // Assume the element is a bitstring-packed key. + $decoded = ASN1::decodeBER($key->element); + if (!$decoded) { + return false; + } + $raw = ASN1::asn1map($decoded[0], ['type' => ASN1::TYPE_BIT_STRING]); + if (empty($raw)) { + return false; + } + // If the key is private, compute identifier from its corresponding public key. + $key = PublicKeyLoader::load($raw); + if ($key instanceof PrivateKey) { // If private. + return $this->computeKeyIdentifier($key, $method); + } + $key = $raw; // Is a public key. + break; + case $key instanceof X509: + if (isset($key->publicKey)) { + return $this->computeKeyIdentifier($key->publicKey, $method); + } + if (isset($key->privateKey)) { + return $this->computeKeyIdentifier($key->privateKey, $method); + } + if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) { + return $this->computeKeyIdentifier($key->currentCert, $method); + } + return false; + default: // Should be a key object (i.e.: \phpseclib3\Crypt\RSA). + $key = $key->getPublicKey(); + break; + } + + // If in PEM format, convert to binary. + $key = ASN1::extractBER($key); + + // Now we have the key string: compute its sha-1 sum. + $hash = new Hash('sha1'); + $hash = $hash->hash($key); + + if ($method == 2) { + $hash = substr($hash, -8); + $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40); + } + + return $hash; + } + + /** + * Format a public key as appropriate + * + * @return array|false + */ + private function formatSubjectPublicKey() + { + $format = $this->publicKey instanceof RSA && ($this->publicKey->getPadding() & RSA::SIGNATURE_PSS) ? + 'PSS' : + 'PKCS8'; + + $publicKey = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->toString($format))); + + $decoded = ASN1::decodeBER($publicKey); + if (!$decoded) { + return false; + } + $mapped = ASN1::asn1map($decoded[0], Maps\SubjectPublicKeyInfo::MAP); + if (!is_array($mapped)) { + return false; + } + + $mapped['subjectPublicKey'] = $this->publicKey->toString($format); + + return $mapped; + } + + /** + * Set the domain name's which the cert is to be valid for + * + * @param mixed ...$domains + * @return void + */ + public function setDomain(...$domains) + { + $this->domains = $domains; + $this->removeDNProp('id-at-commonName'); + $this->setDNProp('id-at-commonName', $this->domains[0]); + } + + /** + * Set the IP Addresses's which the cert is to be valid for + * + * @param mixed[] ...$ipAddresses + */ + public function setIPAddress(...$ipAddresses) + { + $this->ipAddresses = $ipAddresses; + /* + if (!isset($this->domains)) { + $this->removeDNProp('id-at-commonName'); + $this->setDNProp('id-at-commonName', $this->ipAddresses[0]); + } + */ + } + + /** + * Helper function to build domain array + * + * @param string $domain + * @return array + */ + private static function dnsName($domain) + { + return ['dNSName' => $domain]; + } + + /** + * Helper function to build IP Address array + * + * (IPv6 is not currently supported) + * + * @param string $address + * @return array + */ + private function iPAddress($address) + { + return ['iPAddress' => $address]; + } + + /** + * Get the index of a revoked certificate. + * + * @param array $rclist + * @param string $serial + * @param bool $create optional + * @return int|false + */ + private function revokedCertificate(array &$rclist, $serial, $create = false) + { + $serial = new BigInteger($serial); + + foreach ($rclist as $i => $rc) { + if (!($serial->compare($rc['userCertificate']))) { + return $i; + } + } + + if (!$create) { + return false; + } + + $i = count($rclist); + $revocationDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); + $rclist[] = ['userCertificate' => $serial, + 'revocationDate' => $this->timeField($revocationDate->format('D, d M Y H:i:s O'))]; + return $i; + } + + /** + * Revoke a certificate. + * + * @param string $serial + * @param string $date optional + * @return bool + */ + public function revoke($serial, $date = null) + { + if (isset($this->currentCert['tbsCertList'])) { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if ($this->revokedCertificate($rclist, $serial) === false) { // If not yet revoked + if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { + if (!empty($date)) { + $rclist[$i]['revocationDate'] = $this->timeField($date); + } + + return true; + } + } + } + } + + return false; + } + + /** + * Unrevoke a certificate. + * + * @param string $serial + * @return bool + */ + public function unrevoke($serial) + { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + unset($rclist[$i]); + $rclist = array_values($rclist); + return true; + } + } + + return false; + } + + /** + * Get a revoked certificate. + * + * @param string $serial + * @return mixed + */ + public function getRevoked($serial) + { + if (is_array($rclist = $this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $rclist[$i]; + } + } + + return false; + } + + /** + * List revoked certificates + * + * @param array $crl optional + * @return array|bool + */ + public function listRevoked(array $crl = null) + { + if (!isset($crl)) { + $crl = $this->currentCert; + } + + if (!isset($crl['tbsCertList'])) { + return false; + } + + $result = []; + + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + foreach ($rclist as $rc) { + $result[] = $rc['userCertificate']->toString(); + } + } + + return $result; + } + + /** + * Remove a Revoked Certificate Extension + * + * @param string $serial + * @param string $id + * @return bool + */ + public function removeRevokedCertificateExtension($serial, $id) + { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->removeExtensionHelper($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + + return false; + } + + /** + * Get a Revoked Certificate Extension + * + * Returns the extension if it exists and false if not + * + * @param string $serial + * @param string $id + * @param array $crl optional + * @return mixed + */ + public function getRevokedCertificateExtension($serial, $id, array $crl = null) + { + if (!isset($crl)) { + $crl = $this->currentCert; + } + + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + + return false; + } + + /** + * Returns a list of all extensions in use for a given revoked certificate + * + * @param string $serial + * @param array $crl optional + * @return array|bool + */ + public function getRevokedCertificateExtensions($serial, array $crl = null) + { + if (!isset($crl)) { + $crl = $this->currentCert; + } + + if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { + if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { + return $this->getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + + return false; + } + + /** + * Set a Revoked Certificate Extension + * + * @param string $serial + * @param string $id + * @param mixed $value + * @param bool $critical optional + * @param bool $replace optional + * @return bool + */ + public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) + { + if (isset($this->currentCert['tbsCertList'])) { + if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { + if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { + return $this->setExtensionHelper($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); + } + } + } + + return false; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * @param array $mapping + */ + public static function registerExtension($id, array $mapping) + { + if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { + throw new \RuntimeException( + 'Extension ' . $id . ' has already been defined with a different mapping.' + ); + } + + self::$extensions[$id] = $mapping; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * + * @return array|null + */ + public static function getRegisteredExtension($id) + { + return isset(self::$extensions[$id]) ? self::$extensions[$id] : null; + } + + /** + * Register the mapping for a custom/unsupported extension. + * + * @param string $id + * @param mixed $value + * @param bool $critical + * @param bool $replace + */ + public function setExtensionValue($id, $value, $critical = false, $replace = false) + { + $this->extensionValues[$id] = compact('critical', 'replace', 'value'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php new file mode 100644 index 0000000..67d4788 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php @@ -0,0 +1,892 @@ + + * add($b); + * + * echo $c->toString(); // outputs 5 + * ?> + * + * + * @author Jim Wigginton + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math; + +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger\Engines\Engine; + +/** + * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 + * numbers. + * + * @author Jim Wigginton + */ +class BigInteger implements \JsonSerializable +{ + /** + * Main Engine + * + * @var class-string + */ + private static $mainEngine; + + /** + * Selected Engines + * + * @var list + */ + private static $engines; + + /** + * The actual BigInteger object + * + * @var object + */ + private $value; + + /** + * Mode independent value used for serialization. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + */ + private $hex; + + /** + * Precision (used only for serialization) + * + * @see self::__sleep() + * @see self::__wakeup() + * @var int + */ + private $precision; + + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param string $main + * @param list $modexps optional + * @return void + */ + public static function setEngine($main, array $modexps = ['DefaultEngine']) + { + self::$engines = []; + + $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; + if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { + throw new \InvalidArgumentException("$main is not a valid engine"); + } + if (!$fqmain::isValidEngine()) { + throw new BadConfigurationException("$main is not setup correctly on this system"); + } + /** @var class-string $fqmain */ + self::$mainEngine = $fqmain; + + $found = false; + foreach ($modexps as $modexp) { + try { + $fqmain::setModExpEngine($modexp); + $found = true; + break; + } catch (\Exception $e) { + } + } + + if (!$found) { + throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); + } + + self::$engines = [$main, $modexp]; + } + + /** + * Returns the engine type + * + * @return string[] + */ + public static function getEngine() + { + self::initialize_static_variables(); + + return self::$engines; + } + + /** + * Initialize static variables + */ + private static function initialize_static_variables() + { + if (!isset(self::$mainEngine)) { + $engines = [ + ['GMP', ['DefaultEngine']], + ['PHP64', ['OpenSSL']], + ['BCMath', ['OpenSSL']], + ['PHP32', ['OpenSSL']], + ['PHP64', ['DefaultEngine']], + ['PHP32', ['DefaultEngine']] + ]; + + foreach ($engines as $engine) { + try { + self::setEngine($engine[0], $engine[1]); + return; + } catch (\Exception $e) { + } + } + + throw new \UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath'); + } + } + + /** + * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. + * + * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using + * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. + * + * @param string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x = 0, $base = 10) + { + self::initialize_static_variables(); + + if ($x instanceof self::$mainEngine) { + $this->value = clone $x; + } elseif ($x instanceof BigInteger\Engines\Engine) { + $this->value = new static("$x"); + $this->value->setPrecision($x->getPrecision()); + } else { + $this->value = new self::$mainEngine($x, $base); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return $this->value->toString(); + } + + /** + * __toString() magic method + */ + public function __toString() + { + return (string)$this->value; + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + */ + public function __debugInfo() + { + return $this->value->__debugInfo(); + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + return $this->value->toBytes($twos_compliment); + } + + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = false) + { + return $this->value->toHex($twos_compliment); + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + return $this->value->toBits($twos_compliment); + } + + /** + * Adds two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function add(BigInteger $y) + { + return new static($this->value->add($y->value)); + } + + /** + * Subtracts two BigIntegers. + * + * @param BigInteger $y + * @return BigInteger + */ + public function subtract(BigInteger $y) + { + return new static($this->value->subtract($y->value)); + } + + /** + * Multiplies two BigIntegers + * + * @param BigInteger $x + * @return BigInteger + */ + public function multiply(BigInteger $x) + { + return new static($this->value->multiply($x->value)); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * Here's an example: + * + * divide($b); + * + * echo $quotient->toString(); // outputs 0 + * echo "\r\n"; + * echo $remainder->toString(); // outputs 10 + * ?> + * + * + * @param BigInteger $y + * @return BigInteger[] + */ + public function divide(BigInteger $y) + { + list($q, $r) = $this->value->divide($y->value); + return [ + new static($q), + new static($r) + ]; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BigInteger $n + * @return BigInteger + */ + public function modInverse(BigInteger $n) + { + return new static($this->value->modInverse($n->value)); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BigInteger $n + * @return BigInteger[] + */ + public function extendedGCD(BigInteger $n) + { + extract($this->value->extendedGCD($n->value)); + /** + * @var BigInteger $gcd + * @var BigInteger $x + * @var BigInteger $y + */ + return [ + 'gcd' => new static($gcd), + 'x' => new static($x), + 'y' => new static($y) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BigInteger $n + * @return BigInteger + */ + public function gcd(BigInteger $n) + { + return new static($this->value->gcd($n->value)); + } + + /** + * Absolute value. + * + * @return BigInteger + */ + public function abs() + { + return new static($this->value->abs()); + } + + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + $this->value->setPrecision($bits); + } + + /** + * Get Precision + * + * Returns the precision if it exists, false if it doesn't + * + * @return int|bool + */ + public function getPrecision() + { + return $this->value->getPrecision(); + } + + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * __sleep() / __wakeup() have been around since PHP 4.0 + * + * \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1: + * https://wiki.php.net/rfc/phase_out_serializable + * + * __serialize() / __unserialize() were introduced in PHP 7.4: + * https://wiki.php.net/rfc/custom_object_serialization + * + * @return array + */ + public function __sleep() + { + $this->hex = $this->toHex(true); + $vars = ['hex']; + if ($this->getPrecision() > 0) { + $vars[] = 'precision'; + } + return $vars; + } + + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + */ + public function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * @return array{hex: string, precision?: int] + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $result = ['hex' => $this->toHex(true)]; + if ($this->precision > 0) { + $result['precision'] = $this->getPrecision(); + } + return $result; + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function powMod(BigInteger $e, BigInteger $n) + { + return new static($this->value->powMod($e->value, $n->value)); + } + + /** + * Performs modular exponentiation. + * + * @param BigInteger $e + * @param BigInteger $n + * @return BigInteger + */ + public function modPow(BigInteger $e, BigInteger $n) + { + return new static($this->value->modPow($e->value, $n->value)); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BigInteger $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(BigInteger $y) + { + return $this->value->compare($y->value); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BigInteger $x + * @return bool + */ + public function equals(BigInteger $x) + { + return $this->value->equals($x->value); + } + + /** + * Logical Not + * + * @return BigInteger + */ + public function bitwise_not() + { + return new static($this->value->bitwise_not()); + } + + /** + * Logical And + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_and(BigInteger $x) + { + return new static($this->value->bitwise_and($x->value)); + } + + /** + * Logical Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_or(BigInteger $x) + { + return new static($this->value->bitwise_or($x->value)); + } + + /** + * Logical Exclusive Or + * + * @param BigInteger $x + * @return BigInteger + */ + public function bitwise_xor(BigInteger $x) + { + return new static($this->value->bitwise_xor($x->value)); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightShift($shift) + { + return new static($this->value->bitwise_rightShift($shift)); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftShift($shift) + { + return new static($this->value->bitwise_leftShift($shift)); + } + + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_leftRotate($shift) + { + return new static($this->value->bitwise_leftRotate($shift)); + } + + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return BigInteger + */ + public function bitwise_rightRotate($shift) + { + return new static($this->value->bitwise_rightRotate($shift)); + } + + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return BigInteger[] + */ + public static function minMaxBits($bits) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + extract($class::minMaxBits($bits)); + /** @var BigInteger $min + * @var BigInteger $max + */ + return [ + 'min' => new static($min), + 'max' => new static($max) + ]; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return $this->value->getLength(); + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return $this->value->getLengthInBytes(); + } + + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function random($size) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + return new static($class::random($size)); + } + + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return BigInteger + */ + public static function randomPrime($size) + { + self::initialize_static_variables(); + + $class = self::$mainEngine; + return new static($class::randomPrime($size)); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BigInteger $min + * @param BigInteger $max + * @return false|BigInteger + */ + public static function randomRangePrime(BigInteger $min, BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRangePrime($min->value, $max->value)); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BigInteger $min + * @param BigInteger $max + * @return BigInteger + */ + public static function randomRange(BigInteger $min, BigInteger $max) + { + $class = self::$mainEngine; + return new static($class::randomRange($min->value, $max->value)); + } + + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = false) + { + return $this->value->isPrime($t); + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n optional + * @return BigInteger + */ + public function root($n = 2) + { + return new static($this->value->root($n)); + } + + /** + * Performs exponentiation. + * + * @param BigInteger $n + * @return BigInteger + */ + public function pow(BigInteger $n) + { + return new static($this->value->pow($n->value)); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function min(BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = array_map(function ($num) { + return $num->value; + }, $nums); + return new static($class::min(...$nums)); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BigInteger ...$nums + * @return BigInteger + */ + public static function max(BigInteger ...$nums) + { + $class = self::$mainEngine; + $nums = array_map(function ($num) { + return $num->value; + }, $nums); + return new static($class::max(...$nums)); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BigInteger $min + * @param BigInteger $max + * @return bool + */ + public function between(BigInteger $min, BigInteger $max) + { + return $this->value->between($min->value, $max->value); + } + + /** + * Clone + */ + public function __clone() + { + $this->value = clone $this->value; + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value->isOdd(); + } + + /** + * Tests if a bit is set + * + * @param int $x + * @return bool + */ + public function testBit($x) + { + return $this->value->testBit($x); + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return $this->value->isNegative(); + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BigInteger + */ + public function negate() + { + return new static($this->value->negate()); + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BigInteger $r + * @return int + */ + public static function scan1divide(BigInteger $r) + { + $class = self::$mainEngine; + return $class::scan1divide($r->value); + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $func = $this->value->createRecurringModuloFunction(); + return function (BigInteger $x) use ($func) { + return new static($func($x->value)); + }; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return BigInteger[] + */ + public function bitwise_split($split) + { + return array_map(function ($val) { + return new static($val); + }, $this->value->bitwise_split($split)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php new file mode 100644 index 0000000..7c5ca9f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php @@ -0,0 +1,697 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; + +/** + * BCMath Engine. + * + * @author Jim Wigginton + */ +class BCMath extends Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = false; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'BCMath'; + + /** + * Test for engine validity + * + * @return bool + * @see parent::__construct() + */ + public static function isValidEngine() + { + return extension_loaded('bcmath'); + } + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new BadConfigurationException('BCMath is not setup correctly on this system'); + } + + $this->value = '0'; + + parent::__construct($x, $base); + } + + /** + * Initialize a BCMath BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 256: + // round $len to the nearest 4 + $len = (strlen($this->value) + 3) & ~3; + + $x = str_pad($this->value, $len, chr(0), STR_PAD_LEFT); + + $this->value = '0'; + for ($i = 0; $i < $len; $i += 4) { + $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 + $this->value = bcadd( + $this->value, + 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord( + $x[$i + 2] + ) << 8) | ord($x[$i + 3])), + 0 + ); + } + + if ($this->is_negative) { + $this->value = '-' . $this->value; + } + break; + case 16: + $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; + $temp = new self(Strings::hex2bin($x), 256); + $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; + $this->is_negative = false; + break; + case 10: + // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different + // results then doing it on '-1' does (modInverse does $x[0]) + $this->value = $this->value === '-' ? '0' : (string)$this->value; + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if ($this->value === '0') { + return '0'; + } + + return ltrim($this->value, '0'); + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + $value = ''; + $current = $this->value; + + if ($current[0] == '-') { + $current = substr($current, 1); + } + + while (bccomp($current, '0', 0) > 0) { + $temp = bcmod($current, '16777216'); + $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; + $current = bcdiv($current, '16777216', 0); + } + + return $this->precision > 0 ? + substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($value, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function add(BCMath $y) + { + $temp = new self(); + $temp->value = bcadd($this->value, $y->value); + + return $this->normalize($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param BCMath $y + * @return BCMath + */ + public function subtract(BCMath $y) + { + $temp = new self(); + $temp->value = bcsub($this->value, $y->value); + + return $this->normalize($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param BCMath $x + * @return BCMath + */ + public function multiply(BCMath $x) + { + $temp = new self(); + $temp->value = bcmul($this->value, $x->value); + + return $this->normalize($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param BCMath $y + * @return array{static, static} + */ + public function divide(BCMath $y) + { + $quotient = new self(); + $remainder = new self(); + + $quotient->value = bcdiv($this->value, $y->value, 0); + $remainder->value = bcmod($this->value, $y->value); + + if ($remainder->value[0] == '-') { + $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); + } + + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param BCMath $n + * @return false|BCMath + */ + public function modInverse(BCMath $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param BCMath $n + * @return array{gcd: static, x: static, y: static} + */ + public function extendedGCD(BCMath $n) + { + // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works + // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, + // the basic extended euclidean algorithim is what we're using. + + $u = $this->value; + $v = $n->value; + + $a = '1'; + $b = '0'; + $c = '0'; + $d = '1'; + + while (bccomp($v, '0', 0) != 0) { + $q = bcdiv($u, $v, 0); + + $temp = $u; + $u = $v; + $v = bcsub($temp, bcmul($v, $q, 0), 0); + + $temp = $a; + $a = $c; + $c = bcsub($temp, bcmul($a, $q, 0), 0); + + $temp = $b; + $b = $d; + $d = bcsub($temp, bcmul($b, $q, 0), 0); + } + + return [ + 'gcd' => $this->normalize(new static($u)), + 'x' => $this->normalize(new static($a)), + 'y' => $this->normalize(new static($b)) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param BCMath $n + * @return BCMath + */ + public function gcd(BCMath $n) + { + extract($this->extendedGCD($n)); + /** @var BCMath $gcd */ + return $gcd; + } + + /** + * Absolute value. + * + * @return BCMath + */ + public function abs() + { + $temp = new static(); + $temp->value = strlen($this->value) && $this->value[0] == '-' ? + substr($this->value, 1) : + $this->value; + + return $temp; + } + + /** + * Logical And + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_and(BCMath $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_or(BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param BCMath $x + * @return BCMath + */ + public function bitwise_xor(BCMath $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return BCMath + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return BCMath + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); + + return $this->normalize($temp); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param BCMath $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(BCMath $y) + { + return bccomp($this->value, $y->value, 0); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param BCMath $x + * @return bool + */ + public function equals(BCMath $x) + { + return $this->value == $x->value; + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function modPow(BCMath $e, BCMath $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + public function powMod(BCMath $e, BCMath $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected function powModInner(BCMath $e, BCMath $n) + { + try { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param BCMath $result + * @return BCMath + */ + protected function normalize(BCMath $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + if ($result->bitmask !== false) { + $result->value = bcmod($result->value, $result->bitmask->value); + } + + return $result; + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param BCMath $min + * @param BCMath $max + * @return false|BCMath + */ + public static function randomRangePrime(BCMath $min, BCMath $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param BCMath $min + * @param BCMath $max + * @return BCMath + */ + public static function randomRange(BCMath $min, BCMath $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + if (!$this->isOdd()) { + $this->value = bcadd($this->value, '1'); + } + } + + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value === '1') { + return false; + } + if ($this->value === '2') { + return true; + } + if ($this->value[strlen($this->value) - 1] % 2 == 0) { + return false; + } + + $value = $this->value; + + foreach (self::PRIMES as $prime) { + $r = bcmod($this->value, $prime); + if ($r == '0') { + return $this->value == $prime; + } + } + + return true; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param BCMath $r + * @return int + * @see self::isPrime() + */ + public static function scan1divide(BCMath $r) + { + $r_value = &$r->value; + $s = 0; + // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one[static::class]) check earlier + while ($r_value[strlen($r_value) - 1] % 2 == 0) { + $r_value = bcdiv($r_value, '2', 0); + ++$s; + } + + return $s; + } + + /** + * Performs exponentiation. + * + * @param BCMath $n + * @return BCMath + */ + public function pow(BCMath $n) + { + $temp = new self(); + $temp->value = bcpow($this->value, $n->value); + + return $this->normalize($temp); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function min(BCMath ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param BCMath ...$nums + * @return BCMath + */ + public static function max(BCMath ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param BCMath $min + * @param BCMath $max + * @return bool + */ + public function between(BCMath $min, BCMath $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + + /** + * Set Bitmask + * + * @param int $bits + * @return Engine + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + $temp = parent::setBitmask($bits); + return $temp->add(static::$one[static::class]); + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value[strlen($this->value) - 1] % 2 == 1; + } + + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + return bccomp( + bcmod($this->value, bcpow('2', $x + 1, 0)), + bcpow('2', $x, 0), + 0 + ) >= 0; + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return strlen($this->value) && $this->value[0] == '-'; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return BCMath + */ + public function negate() + { + $temp = clone $this; + + if (!strlen($temp->value)) { + return $temp; + } + + $temp->value = $temp->value[0] == '-' ? + substr($this->value, 1) : + '-' . $this->value; + + return $temp; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php new file mode 100644 index 0000000..fe21e04 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php @@ -0,0 +1,110 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * Sliding Window Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Base extends BCMath +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @param string $class + * @return BCMath + */ + protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = '1'; + return $x->normalize($temp); + } + + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + + /** + * Modular reduction preparation + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function prepareReduce($x, $n, $class) + { + return static::reduce($x, $n); + } + + /** + * Modular multiply + * + * @param string $x + * @param string $y + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function multiplyReduce($x, $y, $n, $class) + { + return static::reduce(bcmul($x, $y), $n); + } + + /** + * Modular square + * + * @param string $x + * @param string $n + * @param string $class + * @see self::slidingWindow() + * @return string + */ + protected static function squareReduce($x, $n, $class) + { + return static::reduce(bcmul($x, $x), $n); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php new file mode 100644 index 0000000..b7ca8a2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath; + +/** + * Built-In BCMath Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class BuiltIn extends BCMath +{ + /** + * Performs modular exponentiation. + * + * @param BCMath $x + * @param BCMath $e + * @param BCMath $n + * @return BCMath + */ + protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n) + { + $temp = new BCMath(); + $temp->value = bcpowmod($x->value, $e->value, $n->value); + + return $x->normalize($temp); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php new file mode 100644 index 0000000..b2d9fa9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; + +/** + * PHP Default Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends Barrett +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php new file mode 100644 index 0000000..aed9494 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath; + +use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL extends Progenitor +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php new file mode 100644 index 0000000..0fb7eae --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php @@ -0,0 +1,187 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use phpseclib3\Math\BigInteger\Engines\BCMath\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Barrett extends Base +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $m_length = strlen($m); + + if (strlen($n) > 2 * $m_length) { + return bcmod($n, $m); + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m); + } + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); + $u = bcdiv($lhs, $m, 0); + $m1 = bcsub($lhs, bcmul($u, $m)); + + $cache[self::DATA][] = [ + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1' => $m1 // m.length + ]; + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + + $lsd = substr($n, -$cutoff); + $msd = substr($n, 0, -$cutoff); + + $temp = bcmul($msd, $m1); // m.length + (m.length >> 1) + $n = bcadd($lsd, $temp); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n, $m); + //} + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = substr($n, 0, -$m_length + 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = bcmul($temp, $u); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = substr($temp, 0, -($m_length >> 1) - 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = bcmul($temp, $m); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = bcsub($n, $temp); + + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $temp = '1' . str_repeat('0', $m_length + 1); + $result = bcadd($result, $temp); + } + + while (bccomp($result, $m) >= 0) { + $result = bcsub($result, $m); + } + + return $result; + } + + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param string $x + * @param string $n + * @return string + */ + private static function regularBarrett($x, $n) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $n_length = strlen($n); + + if (strlen($x) > 2 * $n_length) { + return bcmod($x, $n); + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = '1' . str_repeat('0', 2 * $n_length); + $cache[self::DATA][] = bcdiv($lhs, $n, 0); + } + + $temp = substr($x, 0, -$n_length + 1); + $temp = bcmul($temp, $cache[self::DATA][$key]); + $temp = substr($temp, 0, -$n_length - 1); + + $r1 = substr($x, -$n_length - 1); + $r2 = substr(bcmul($temp, $n), -$n_length - 1); + $result = bcsub($r1, $r2); + + //if (bccomp($result, '0') < 0) { + if ($result[0] == '-') { + $q = '1' . str_repeat('0', $n_length + 1); + $result = bcadd($result, $q); + } + + while (bccomp($result, $n) >= 0) { + $result = bcsub($result, $n); + } + + return $result; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php new file mode 100644 index 0000000..e033ba5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php @@ -0,0 +1,108 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; + +use phpseclib3\Math\BigInteger\Engines\BCMath; +use phpseclib3\Math\BigInteger\Engines\BCMath\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class EvalBarrett extends Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param string $n + * @param string $m + * @return string + */ + protected static function reduce($n, $m) + { + $inline = self::$custom_reduction; + return $inline($n); + } + + /** + * Generate Custom Reduction + * + * @param BCMath $m + * @param string $class + * @return callable|void + */ + protected static function generateCustomReduction(BCMath $m, $class) + { + $m_length = strlen($m); + + if ($m_length < 5) { + $code = 'return bcmod($x, $n);'; + eval('$func = function ($n) { ' . $code . '};'); + self::$custom_reduction = $func; + return; + } + + $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); + $u = bcdiv($lhs, $m, 0); + $m1 = bcsub($lhs, bcmul($u, $m)); + + $cutoff = $m_length + ($m_length >> 1); + + $m = "'$m'"; + $u = "'$u'"; + $m1 = "'$m1'"; + + $code = ' + $lsd = substr($n, -' . $cutoff . '); + $msd = substr($n, 0, -' . $cutoff . '); + + $temp = bcmul($msd, ' . $m1 . '); + $n = bcadd($lsd, $temp); + + $temp = substr($n, 0, ' . (-$m_length + 1) . '); + $temp = bcmul($temp, ' . $u . '); + $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); + $temp = bcmul($temp, ' . $m . '); + + $result = bcsub($n, $temp); + + if ($result[0] == \'-\') { + $temp = \'1' . str_repeat('0', $m_length + 1) . '\'; + $result = bcadd($result, $temp); + } + + while (bccomp($result, ' . $m . ') >= 0) { + $result = bcsub($result, ' . $m . '); + } + + return $result;'; + + eval('$func = function ($n) { ' . $code . '};'); + + self::$custom_reduction = $func; + + return $func; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php new file mode 100644 index 0000000..abdf3b4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php @@ -0,0 +1,1285 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Random; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Math\BigInteger; + +/** + * Base Engine. + * + * @author Jim Wigginton + */ +abstract class Engine implements \JsonSerializable +{ + /* final protected */ const PRIMES = [ + 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, + ]; + + /** + * BigInteger(0) + * + * @var array, static> + */ + protected static $zero = []; + + /** + * BigInteger(1) + * + * @var array, static> + */ + protected static $one = []; + + /** + * BigInteger(2) + * + * @var array, static> + */ + protected static $two = []; + + /** + * Modular Exponentiation Engine + * + * @var array, class-string> + */ + protected static $modexpEngine; + + /** + * Engine Validity Flag + * + * @var array, bool> + */ + protected static $isValidEngine; + + /** + * Holds the BigInteger's value + * + * @var \GMP|string|array|int + */ + protected $value; + + /** + * Holds the BigInteger's sign + * + * @var bool + */ + protected $is_negative; + + /** + * Precision + * + * @see static::setPrecision() + * @var int + */ + protected $precision = -1; + + /** + * Precision Bitmask + * + * @see static::setPrecision() + * @var static|false + */ + protected $bitmask = false; + + /** + * Recurring Modulo Function + * + * @var callable + */ + protected $reduce; + + /** + * Mode independent value used for serialization. + * + * @see self::__sleep() + * @see self::__wakeup() + * @var string + */ + protected $hex; + + /** + * Default constructor + * + * @param int|numeric-string $x integer Base-10 number or base-$base number if $base set. + * @param int $base + */ + public function __construct($x = 0, $base = 10) + { + if (!array_key_exists(static::class, static::$zero)) { + static::$zero[static::class] = null; // Placeholder to prevent infinite loop. + static::$zero[static::class] = new static(0); + static::$one[static::class] = new static(1); + static::$two[static::class] = new static(2); + } + + // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 + // '0' is the only value like this per http://php.net/empty + if (empty($x) && (abs($base) != 256 || $x !== '0')) { + return; + } + + switch ($base) { + case -256: + case 256: + if ($base == -256 && (ord($x[0]) & 0x80)) { + $this->value = ~$x; + $this->is_negative = true; + } else { + $this->value = $x; + $this->is_negative = false; + } + + $this->initialize($base); + + if ($this->is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -16: + case 16: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#s', '$1', $x); + + $is_negative = false; + if ($base < 0 && hexdec($x[0]) >= 8) { + $this->is_negative = $is_negative = true; + $x = Strings::bin2hex(~Strings::hex2bin($x)); + } + + $this->value = $x; + $this->initialize($base); + + if ($is_negative) { + $temp = $this->add(new static('-1')); + $this->value = $temp->value; + } + break; + case -10: + case 10: + // (?value = preg_replace('#(?value) || $this->value == '-') { + $this->value = '0'; + } + $this->initialize($base); + break; + case -2: + case 2: + if ($base > 0 && $x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = preg_replace('#^([01]*).*#s', '$1', $x); + + $temp = new static(Strings::bits2bin($x), 128 * $base); // ie. either -16 or +16 + $this->value = $temp->value; + if ($temp->is_negative) { + $this->is_negative = true; + } + + break; + default: + // base not supported, so we'll let $this == 0 + } + } + + /** + * Sets engine type. + * + * Throws an exception if the type is invalid + * + * @param class-string $engine + */ + public static function setModExpEngine($engine) + { + $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; + if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { + throw new \InvalidArgumentException("$engine is not a valid engine"); + } + if (!$fqengine::isValidEngine()) { + throw new BadConfigurationException("$engine is not setup correctly on this system"); + } + static::$modexpEngine[static::class] = $fqengine; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * @return string + */ + protected function toBytesHelper() + { + $comparison = $this->compare(new static()); + if ($comparison == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = $comparison < 0 ? $this->add(new static(1)) : $this; + $bytes = $temp->toBytes(); + + if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 + $bytes = chr(0); + } + + if (ord($bytes[0]) & 0x80) { + $bytes = chr(0) . $bytes; + } + + return $comparison < 0 ? ~$bytes : $bytes; + } + + /** + * Converts a BigInteger to a hex string (eg. base-16). + * + * @param bool $twos_compliment + * @return string + */ + public function toHex($twos_compliment = false) + { + return Strings::bin2hex($this->toBytes($twos_compliment)); + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + $hex = $this->toBytes($twos_compliment); + $bits = Strings::bin2bits($hex); + + $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $result; + } + + return $result; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} + * + * @param Engine $n + * @return static|false + */ + protected function modInverseHelper(Engine $n) + { + // $x mod -$n == $x mod $n. + $n = $n->abs(); + + if ($this->compare(static::$zero[static::class]) < 0) { + $temp = $this->abs(); + $temp = $temp->modInverse($n); + return $this->normalize($n->subtract($temp)); + } + + extract($this->extendedGCD($n)); + /** + * @var Engine $gcd + * @var Engine $x + */ + + if (!$gcd->equals(static::$one[static::class])) { + return false; + } + + $x = $x->compare(static::$zero[static::class]) < 0 ? $x->add($n) : $x; + + return $this->compare(static::$zero[static::class]) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); + } + + /** + * Serialize + * + * Will be called, automatically, when serialize() is called on a BigInteger object. + * + * @return array + */ + public function __sleep() + { + $this->hex = $this->toHex(true); + $vars = ['hex']; + if ($this->precision > 0) { + $vars[] = 'precision'; + } + return $vars; + } + + /** + * Serialize + * + * Will be called, automatically, when unserialize() is called on a BigInteger object. + * + * @return void + */ + public function __wakeup() + { + $temp = new static($this->hex, -16); + $this->value = $temp->value; + $this->is_negative = $temp->is_negative; + if ($this->precision > 0) { + // recalculate $this->bitmask + $this->setPrecision($this->precision); + } + } + + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * @return array{hex: string, precision?: int] + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + $result = ['hex' => $this->toHex(true)]; + if ($this->precision > 0) { + $result['precision'] = $this->precision; + } + return $result; + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * __debugInfo() magic method + * + * Will be called, automatically, when print_r() or var_dump() are called + * + * @return array + */ + public function __debugInfo() + { + $result = [ + 'value' => '0x' . $this->toHex(true), + 'engine' => basename(static::class) + ]; + return $this->precision > 0 ? $result + ['precision' => $this->precision] : $result; + } + + /** + * Set Precision + * + * Some bitwise operations give different results depending on the precision being used. Examples include left + * shift, not, and rotates. + * + * @param int $bits + */ + public function setPrecision($bits) + { + if ($bits < 1) { + $this->precision = -1; + $this->bitmask = false; + + return; + } + $this->precision = $bits; + $this->bitmask = static::setBitmask($bits); + + $temp = $this->normalize($this); + $this->value = $temp->value; + } + + /** + * Get Precision + * + * Returns the precision if it exists, -1 if it doesn't + * + * @return int + */ + public function getPrecision() + { + return $this->precision; + } + + /** + * Set Bitmask + * @return static + * @param int $bits + * @see self::setPrecision() + */ + protected static function setBitmask($bits) + { + return new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); + } + + /** + * Logical Not + * + * @return Engine|string + */ + public function bitwise_not() + { + // calculuate "not" without regard to $this->precision + // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) + $temp = $this->toBytes(); + if ($temp == '') { + return $this->normalize(static::$zero[static::class]); + } + $pre_msb = decbin(ord($temp[0])); + $temp = ~$temp; + $msb = decbin(ord($temp[0])); + if (strlen($msb) == 8) { + $msb = substr($msb, strpos($msb, '0')); + } + $temp[0] = chr(bindec($msb)); + + // see if we need to add extra leading 1's + $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; + $new_bits = $this->precision - $current_bits; + if ($new_bits <= 0) { + return $this->normalize(new static($temp, 256)); + } + + // generate as many leading 1's as we need to. + $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); + + self::base256_lshift($leading_ones, $current_bits); + + $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($leading_ones | $temp, 256)); + } + + /** + * Logical Left Shift + * + * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. + * + * @param string $x + * @param int $shift + * @return void + */ + protected static function base256_lshift(&$x, $shift) + { + if ($shift == 0) { + return; + } + + $num_bytes = $shift >> 3; // eg. floor($shift/8) + $shift &= 7; // eg. $shift % 8 + + $carry = 0; + for ($i = strlen($x) - 1; $i >= 0; --$i) { + $temp = ord($x[$i]) << $shift | $carry; + $x[$i] = chr($temp); + $carry = $temp >> 8; + } + $carry = ($carry != 0) ? chr($carry) : ''; + $x = $carry . $x . str_repeat(chr(0), $num_bytes); + } + + /** + * Logical Left Rotate + * + * Instead of the top x bits being dropped they're appended to the shifted bit string. + * + * @param int $shift + * @return Engine + */ + public function bitwise_leftRotate($shift) + { + $bits = $this->toBytes(); + + if ($this->precision > 0) { + $precision = $this->precision; + if (static::FAST_BITWISE) { + $mask = $this->bitmask->toBytes(); + } else { + $mask = $this->bitmask->subtract(new static(1)); + $mask = $mask->toBytes(); + } + } else { + $temp = ord($bits[0]); + for ($i = 0; $temp >> $i; ++$i) { + } + $precision = 8 * strlen($bits) - 8 + $i; + $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); + } + + if ($shift < 0) { + $shift += $precision; + } + $shift %= $precision; + + if (!$shift) { + return clone $this; + } + + $left = $this->bitwise_leftShift($shift); + $left = $left->bitwise_and(new static($mask, 256)); + $right = $this->bitwise_rightShift($precision - $shift); + $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); + return $this->normalize($result); + } + + /** + * Logical Right Rotate + * + * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. + * + * @param int $shift + * @return Engine + */ + public function bitwise_rightRotate($shift) + { + return $this->bitwise_leftRotate(-$shift); + } + + /** + * Returns the smallest and largest n-bit number + * + * @param int $bits + * @return array{min: static, max: static} + */ + public static function minMaxBits($bits) + { + $bytes = $bits >> 3; + $min = str_repeat(chr(0), $bytes); + $max = str_repeat(chr(0xFF), $bytes); + $msb = $bits & 7; + if ($msb) { + $min = chr(1 << ($msb - 1)) . $min; + $max = chr((1 << $msb) - 1) . $max; + } else { + $min[0] = chr(0x80); + } + return [ + 'min' => new static($min, 256), + 'max' => new static($max, 256) + ]; + } + + /** + * Return the size of a BigInteger in bits + * + * @return int + */ + public function getLength() + { + return strlen($this->toBits()); + } + + /** + * Return the size of a BigInteger in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return strlen($this->toBytes()); + } + + /** + * Performs some pre-processing for powMod + * + * @param Engine $e + * @param Engine $n + * @return static|false + */ + protected function powModOuter(Engine $e, Engine $n) + { + $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); + + if ($e->compare(new static()) < 0) { + $e = $e->abs(); + + $temp = $this->modInverse($n); + if ($temp === false) { + return false; + } + + return $this->normalize($temp->powModInner($e, $n)); + } + + if ($this->compare($n) > 0) { + list(, $temp) = $this->divide($n); + return $temp->powModInner($e, $n); + } + + return $this->powModInner($e, $n); + } + + /** + * Sliding Window k-ary Modular Exponentiation + * + * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, + * however, this function performs a modular reduction after every multiplication and squaring operation. + * As such, this function has the same preconditions that the reductions being used do. + * + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T + */ + protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) + { + static $window_ranges = [7, 25, 81, 241, 673, 1793]; // from BigInteger.java's oddModPow function + //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 + + $e_bits = $e->toBits(); + $e_length = strlen($e_bits); + + // calculate the appropriate window size. + // $window_size == 3 if $window_ranges is between 25 and 81, for example. + for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { + } + + $n_value = $n->value; + + if (method_exists(static::class, 'generateCustomReduction')) { + static::generateCustomReduction($n, $class); + } + + // precompute $this^0 through $this^$window_size + $powers = []; + $powers[1] = static::prepareReduce($x->value, $n_value, $class); + $powers[2] = static::squareReduce($powers[1], $n_value, $class); + + // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end + // in a 1. ie. it's supposed to be odd. + $temp = 1 << ($window_size - 1); + for ($i = 1; $i < $temp; ++$i) { + $i2 = $i << 1; + $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); + } + + $result = new $class(1); + $result = static::prepareReduce($result->value, $n_value, $class); + + for ($i = 0; $i < $e_length;) { + if (!$e_bits[$i]) { + $result = static::squareReduce($result, $n_value, $class); + ++$i; + } else { + for ($j = $window_size - 1; $j > 0; --$j) { + if (!empty($e_bits[$i + $j])) { + break; + } + } + + // eg. the length of substr($e_bits, $i, $j + 1) + for ($k = 0; $k <= $j; ++$k) { + $result = static::squareReduce($result, $n_value, $class); + } + + $result = static::multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $class); + + $i += $j + 1; + } + } + + $temp = new $class(); + $temp->value = static::reduce($result, $n_value, $class); + + return $temp; + } + + /** + * Generates a random number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return Engine + */ + public static function random($size) + { + extract(static::minMaxBits($size)); + /** + * @var BigInteger $min + * @var BigInteger $max + */ + return static::randomRange($min, $max); + } + + /** + * Generates a random prime number of a certain size + * + * Bit length is equal to $size + * + * @param int $size + * @return Engine + */ + public static function randomPrime($size) + { + extract(static::minMaxBits($size)); + /** + * @var static $min + * @var static $max + */ + return static::randomRangePrime($min, $max); + } + + /** + * Performs some pre-processing for randomRangePrime + * + * @param Engine $min + * @param Engine $max + * @return static|false + */ + protected static function randomRangePrimeOuter(Engine $min, Engine $max) + { + $compare = $max->compare($min); + + if (!$compare) { + return $min->isPrime() ? $min : false; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + $x = static::randomRange($min, $max); + + return static::randomRangePrimeInner($x, $min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param Engine $min + * @param Engine $max + * @return Engine + */ + protected static function randomRangeHelper(Engine $min, Engine $max) + { + $compare = $max->compare($min); + + if (!$compare) { + return $min; + } elseif ($compare < 0) { + // if $min is bigger then $max, swap $min and $max + $temp = $max; + $max = $min; + $min = $temp; + } + + if (!isset(static::$one[static::class])) { + static::$one[static::class] = new static(1); + } + + $max = $max->subtract($min->subtract(static::$one[static::class])); + + $size = strlen(ltrim($max->toBytes(), chr(0))); + + /* + doing $random % $max doesn't work because some numbers will be more likely to occur than others. + eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 + would produce 5 whereas the only value of random that could produce 139 would be 139. ie. + not all numbers would be equally likely. some would be more likely than others. + + creating a whole new random number until you find one that is within the range doesn't work + because, for sufficiently small ranges, the likelihood that you'd get a number within that range + would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability + would be pretty high that $random would be greater than $max. + + phpseclib works around this using the technique described here: + + http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string + */ + $random_max = new static(chr(1) . str_repeat("\0", $size), 256); + $random = new static(Random::string($size), 256); + + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + + while ($random->compare($max_multiple) >= 0) { + $random = $random->subtract($max_multiple); + $random_max = $random_max->subtract($max_multiple); + $random = $random->bitwise_leftShift(8); + $random = $random->add(new static(Random::string(1), 256)); + $random_max = $random_max->bitwise_leftShift(8); + list($max_multiple) = $random_max->divide($max); + $max_multiple = $max_multiple->multiply($max); + } + list(, $random) = $random->divide($max); + + return $random->add($min); + } + + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return static|false + */ + protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) + { + if (!isset(static::$two[static::class])) { + static::$two[static::class] = new static('2'); + } + + $x->make_odd(); + if ($x->compare($max) > 0) { + // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range + if ($min->equals($max)) { + return false; + } + $x = clone $min; + $x->make_odd(); + } + + $initial_x = clone $x; + + while (true) { + if ($x->isPrime()) { + return $x; + } + + $x = $x->add(static::$two[static::class]); + + if ($x->compare($max) > 0) { + $x = clone $min; + if ($x->equals(static::$two[static::class])) { + return $x; + } + $x->make_odd(); + } + + if ($x->equals($initial_x)) { + return false; + } + } + } + + /** + * Sets the $t parameter for primality testing + * + * @return int + */ + protected function setupIsPrime() + { + $length = $this->getLengthInBytes(); + + // see HAC 4.49 "Note (controlling the error probability)" + // @codingStandardsIgnoreStart + if ($length >= 163) { $t = 2; } // floor(1300 / 8) + else if ($length >= 106) { $t = 3; } // floor( 850 / 8) + else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) + else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) + else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) + else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) + else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) + else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) + else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) + else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) + else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) + else { $t = 27; } + // @codingStandardsIgnoreEnd + + return $t; + } + + /** + * Tests Primality + * + * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + if (!$this->testSmallPrimes()) { + return false; + } + + $n = clone $this; + $n_1 = $n->subtract(static::$one[static::class]); + $n_2 = $n->subtract(static::$two[static::class]); + + $r = clone $n_1; + $s = static::scan1divide($r); + + for ($i = 0; $i < $t; ++$i) { + $a = static::randomRange(static::$two[static::class], $n_2); + $y = $a->modPow($r, $n); + + if (!$y->equals(static::$one[static::class]) && !$y->equals($n_1)) { + for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { + $y = $y->modPow(static::$two[static::class], $n); + if ($y->equals(static::$one[static::class])) { + return false; + } + } + + if (!$y->equals($n_1)) { + return false; + } + } + } + + return true; + } + + /** + * Checks a numer to see if it's prime + * + * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the + * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads + * on a website instead of just one. + * + * @param int|bool $t + * @return bool + */ + public function isPrime($t = false) + { + if (!$t) { + $t = $this->setupIsPrime(); + } + return $this->testPrimality($t); + } + + /** + * Performs a few preliminary checks on root + * + * @param int $n + * @return Engine + */ + protected function rootHelper($n) + { + if ($n < 1) { + return clone static::$zero[static::class]; + } // we want positive exponents + if ($this->compare(static::$one[static::class]) < 0) { + return clone static::$zero[static::class]; + } // we want positive numbers + if ($this->compare(static::$two[static::class]) < 0) { + return clone static::$one[static::class]; + } // n-th root of 1 or 2 is 1 + + return $this->rootInner($n); + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} + * + * @param int $n + * @return Engine + */ + protected function rootInner($n) + { + $n = new static($n); + + // g is our guess number + $g = static::$two[static::class]; + // while (g^n < num) g=g*2 + while ($g->pow($n)->compare($this) < 0) { + $g = $g->multiply(static::$two[static::class]); + } + // if (g^n==num) num is a power of 2, we're lucky, end of job + // == 0 bccomp(bcpow($g, $n), $n->value)==0 + if ($g->pow($n)->equals($this) > 0) { + $root = $g; + return $this->normalize($root); + } + + // if we're here num wasn't a power of 2 :( + $og = $g; // og means original guess and here is our upper bound + $g = $g->divide(static::$two[static::class])[0]; // g is set to be our lower bound + $step = $og->subtract($g)->divide(static::$two[static::class])[0]; // step is the half of upper bound - lower bound + $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval + + // while step>1 + + while ($step->compare(static::$one[static::class]) == 1) { + $guess = $g->pow($n); + $step = $step->divide(static::$two[static::class])[0]; + $comp = $guess->compare($this); // compare our guess with real number + switch ($comp) { + case -1: // if guess is lower we add the new step + $g = $g->add($step); + break; + case 1: // if guess is higher we sub the new step + $g = $g->subtract($step); + break; + case 0: // if guess is exactly the num we're done, we return the value + $root = $g; + break 2; + } + } + + if ($comp == 1) { + $g = $g->subtract($step); + } + + // whatever happened, g is the closest guess we can make so return it + $root = $g; + + return $this->normalize($root); + } + + /** + * Calculates the nth root of a biginteger. + * + * @param int $n + * @return Engine + */ + public function root($n = 2) + { + return $this->rootHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function minHelper(array $nums) + { + if (count($nums) == 1) { + return $nums[0]; + } + $min = $nums[0]; + for ($i = 1; $i < count($nums); $i++) { + $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; + } + return $min; + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param array $nums + * @return Engine + */ + protected static function maxHelper(array $nums) + { + if (count($nums) == 1) { + return $nums[0]; + } + $max = $nums[0]; + for ($i = 1; $i < count($nums); $i++) { + $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; + } + return $max; + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $class = static::class; + + $fqengine = !method_exists(static::$modexpEngine[static::class], 'reduce') ? + '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : + static::$modexpEngine[static::class]; + if (method_exists($fqengine, 'generateCustomReduction')) { + $func = $fqengine::generateCustomReduction($this, static::class); + return eval('return function(' . static::class . ' $x) use ($func, $class) { + $r = new $class(); + $r->value = $func($x->value); + return $r; + };'); + } + $n = $this->value; + return eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { + $r = new $class(); + $r->value = $fqengine::reduce($x->value, $n, $class); + return $r; + };'); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * @param Engine $n + * @return array{gcd: Engine, x: Engine, y: Engine} + */ + protected function extendedGCDHelper(Engine $n) + { + $u = clone $this; + $v = clone $n; + + $one = new static(1); + $zero = new static(); + + $a = clone $one; + $b = clone $zero; + $c = clone $zero; + $d = clone $one; + + while (!$v->equals($zero)) { + list($q) = $u->divide($v); + + $temp = $u; + $u = $v; + $v = $temp->subtract($v->multiply($q)); + + $temp = $a; + $a = $c; + $c = $temp->subtract($a->multiply($q)); + + $temp = $b; + $b = $d; + $d = $temp->subtract($b->multiply($q)); + } + + return [ + 'gcd' => $u, + 'x' => $a, + 'y' => $b + ]; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return Engine[] + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + + $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); + + $num = clone $this; + + $vals = []; + while (!$num->equals(static::$zero[static::class])) { + $vals[] = $num->bitwise_and($mask); + $num = $num->bitwise_rightShift($split); + } + + return array_reverse($vals); + } + + /** + * Logical And + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseAndHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($left & $right, -256)); + } + + /** + * Logical Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseOrHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + + return $this->normalize(new static($left | $right, -256)); + } + + /** + * Logical Exclusive Or + * + * @param Engine $x + * @return Engine + */ + protected function bitwiseXorHelper(Engine $x) + { + $left = $this->toBytes(true); + $right = $x->toBytes(true); + + $length = max(strlen($left), strlen($right)); + + + $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); + $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); + return $this->normalize(new static($left ^ $right, -256)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php new file mode 100644 index 0000000..f616362 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php @@ -0,0 +1,694 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Exception\BadConfigurationException; + +/** + * GMP Engine. + * + * @author Jim Wigginton + */ +class GMP extends Engine +{ + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = true; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'GMP'; + + /** + * Test for engine validity + * + * @return bool + * @see parent::__construct() + */ + public static function isValidEngine() + { + return extension_loaded('gmp'); + } + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = self::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new BadConfigurationException('GMP is not setup correctly on this system'); + } + + if ($x instanceof \GMP) { + $this->value = $x; + return; + } + + $this->value = gmp_init(0); + + parent::__construct($x, $base); + } + + /** + * Initialize a GMP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 256: + $this->value = gmp_import($this->value); + if ($this->is_negative) { + $this->value = -$this->value; + } + break; + case 16: + $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; + $this->value = gmp_init($temp); + break; + case 10: + $this->value = gmp_init(isset($this->value) ? $this->value : '0'); + } + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + return (string)$this->value; + } + + /** + * Converts a BigInteger to a bit string (eg. base-2). + * + * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're + * saved as two's compliment. + * + * @param bool $twos_compliment + * @return string + */ + public function toBits($twos_compliment = false) + { + $hex = $this->toHex($twos_compliment); + + $bits = gmp_strval(gmp_init($hex, 16), 2); + + if ($this->precision > 0) { + $bits = substr($bits, -$this->precision); + } + + if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { + return '0' . $bits; + } + + return $bits; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + if (gmp_cmp($this->value, gmp_init(0)) == 0) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $temp = gmp_export($this->value); + + return $this->precision > 0 ? + substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : + ltrim($temp, chr(0)); + } + + /** + * Adds two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function add(GMP $y) + { + $temp = new self(); + $temp->value = $this->value + $y->value; + + return $this->normalize($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param GMP $y + * @return GMP + */ + public function subtract(GMP $y) + { + $temp = new self(); + $temp->value = $this->value - $y->value; + + return $this->normalize($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param GMP $x + * @return GMP + */ + public function multiply(GMP $x) + { + $temp = new self(); + $temp->value = $this->value * $x->value; + + return $this->normalize($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param GMP $y + * @return array{GMP, GMP} + */ + public function divide(GMP $y) + { + $quotient = new self(); + $remainder = new self(); + + list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); + + if (gmp_sign($remainder->value) < 0) { + $remainder->value = $remainder->value + gmp_abs($y->value); + } + + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this + * is demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param GMP $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(GMP $y) + { + $r = gmp_cmp($this->value, $y->value); + if ($r < -1) { + $r = -1; + } + if ($r > 1) { + $r = 1; + } + return $r; + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param GMP $x + * @return bool + */ + public function equals(GMP $x) + { + return $this->value == $x->value; + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * + * @param GMP $n + * @return false|GMP + */ + public function modInverse(GMP $n) + { + $temp = new self(); + $temp->value = gmp_invert($this->value, $n->value); + + return $temp->value === false ? false : $this->normalize($temp); + } + + /** + * Calculates the greatest common divisor and Bezout's identity. + * + * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that + * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which + * combination is returned is dependent upon which mode is in use. See + * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. + * + * @param GMP $n + * @return GMP[] + */ + public function extendedGCD(GMP $n) + { + extract(gmp_gcdext($this->value, $n->value)); + + return [ + 'gcd' => $this->normalize(new self($g)), + 'x' => $this->normalize(new self($s)), + 'y' => $this->normalize(new self($t)) + ]; + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param GMP $n + * @return GMP + */ + public function gcd(GMP $n) + { + $r = gmp_gcd($this->value, $n->value); + return $this->normalize(new self($r)); + } + + /** + * Absolute value. + * + * @return GMP + */ + public function abs() + { + $temp = new self(); + $temp->value = gmp_abs($this->value); + + return $temp; + } + + /** + * Logical And + * + * @param GMP $x + * @return GMP + */ + public function bitwise_and(GMP $x) + { + $temp = new self(); + $temp->value = $this->value & $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_or(GMP $x) + { + $temp = new self(); + $temp->value = $this->value | $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Exclusive Or + * + * @param GMP $x + * @return GMP + */ + public function bitwise_xor(GMP $x) + { + $temp = new self(); + $temp->value = $this->value ^ $x->value; + + return $this->normalize($temp); + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return GMP + */ + public function bitwise_rightShift($shift) + { + // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) + // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') + + $temp = new self(); + $temp->value = $this->value >> $shift; + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return GMP + */ + public function bitwise_leftShift($shift) + { + $temp = new self(); + $temp->value = $this->value << $shift; + + return $this->normalize($temp); + } + + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function modPow(GMP $e, GMP $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + public function powMod(GMP $e, GMP $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected function powModInner(GMP $e, GMP $n) + { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n); + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param GMP $result + * @return GMP + */ + protected function normalize(GMP $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + if ($result->bitmask !== false) { + $flip = $result->value < 0; + if ($flip) { + $result->value = -$result->value; + } + $result->value = $result->value & $result->bitmask->value; + if ($flip) { + $result->value = -$result->value; + } + } + + return $result; + } + + /** + * Performs some post-processing for randomRangePrime + * + * @param Engine $x + * @param Engine $min + * @param Engine $max + * @return GMP + */ + protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) + { + $p = gmp_nextprime($x->value); + + if ($p <= $max->value) { + return new self($p); + } + + if ($min->value != $x->value) { + $x = new self($x->value - 1); + } + + return self::randomRangePrime($min, $x); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param GMP $min + * @param GMP $max + * @return false|GMP + */ + public static function randomRangePrime(GMP $min, GMP $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param GMP $min + * @param GMP $max + * @return GMP + */ + public static function randomRange(GMP $min, GMP $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + gmp_setbit($this->value, 0); + } + + /** + * Tests Primality + * + * @param int $t + * @return bool + */ + protected function testPrimality($t) + { + return gmp_prob_prime($this->value, $t) != 0; + } + + /** + * Calculates the nth root of a biginteger. + * + * Returns the nth root of a positive biginteger, where n defaults to 2 + * + * @param int $n + * @return GMP + */ + protected function rootInner($n) + { + $root = new self(); + $root->value = gmp_root($this->value, $n); + return $this->normalize($root); + } + + /** + * Performs exponentiation. + * + * @param GMP $n + * @return GMP + */ + public function pow(GMP $n) + { + $temp = new self(); + $temp->value = $this->value ** $n->value; + + return $this->normalize($temp); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function min(GMP ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param GMP ...$nums + * @return GMP + */ + public static function max(GMP ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param GMP $min + * @param GMP $max + * @return bool + */ + public function between(GMP $min, GMP $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } + + /** + * Create Recurring Modulo Function + * + * Sometimes it may be desirable to do repeated modulos with the same number outside of + * modular exponentiation + * + * @return callable + */ + public function createRecurringModuloFunction() + { + $temp = $this->value; + return function (GMP $x) use ($temp) { + return new GMP($x->value % $temp); + }; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param GMP $r + * @return int + */ + public static function scan1divide(GMP $r) + { + $s = gmp_scan1($r->value, 0); + $r->value >>= $s; + return $s; + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return gmp_testbit($this->value, 0); + } + + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + return gmp_testbit($this->value, $x); + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return gmp_sign($this->value) == -1; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return GMP + */ + public function negate() + { + $temp = clone $this; + $temp->value = -$this->value; + + return $temp; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php new file mode 100644 index 0000000..bc219fb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php @@ -0,0 +1,40 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\GMP; + +use phpseclib3\Math\BigInteger\Engines\GMP; + +/** + * GMP Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends GMP +{ + /** + * Performs modular exponentiation. + * + * @param GMP $x + * @param GMP $e + * @param GMP $n + * @return GMP + */ + protected static function powModHelper(GMP $x, GMP $e, GMP $n) + { + $temp = new GMP(); + $temp->value = gmp_powm($x->value, $e->value, $n->value); + + return $x->normalize($temp); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php new file mode 100644 index 0000000..e33a9f1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php @@ -0,0 +1,68 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; +use phpseclib3\Math\BigInteger; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return extension_loaded('openssl') && static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @return Engine + */ + public static function powModHelper(Engine $x, Engine $e, Engine $n) + { + if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { + throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); + } + + $key = PKCS8::savePublicKey( + new BigInteger($n), + new BigInteger($e) + ); + + $plaintext = str_pad($x->toBytes(), $n->getLengthInBytes(), "\0", STR_PAD_LEFT); + + // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it + // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" + // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what + // about odd numbers divisible by 3, by 5, etc? + if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) { + throw new \UnexpectedValueException(openssl_error_string()); + } + + $class = get_class($x); + return new $class($result, 256); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php new file mode 100644 index 0000000..7e85783 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php @@ -0,0 +1,1344 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\BadConfigurationException; + +/** + * Pure-PHP Engine. + * + * @author Jim Wigginton + */ +abstract class PHP extends Engine +{ + /**#@+ + * Array constants + * + * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and + * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. + * + */ + /** + * $result[self::VALUE] contains the value. + */ + const VALUE = 0; + /** + * $result[self::SIGN] contains the sign. + */ + const SIGN = 1; + /**#@-*/ + + /** + * Karatsuba Cutoff + * + * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? + * + */ + const KARATSUBA_CUTOFF = 25; + + /** + * Can Bitwise operations be done fast? + * + * @see parent::bitwise_leftRotate() + * @see parent::bitwise_rightRotate() + */ + const FAST_BITWISE = true; + + /** + * Engine Directory + * + * @see parent::setModExpEngine + */ + const ENGINE_DIR = 'PHP'; + + /** + * Default constructor + * + * @param mixed $x integer Base-10 number or base-$base number if $base set. + * @param int $base + * @return PHP + * @see parent::__construct() + */ + public function __construct($x = 0, $base = 10) + { + if (!isset(static::$isValidEngine[static::class])) { + static::$isValidEngine[static::class] = static::isValidEngine(); + } + if (!static::$isValidEngine[static::class]) { + throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); + } + + $this->value = []; + parent::__construct($x, $base); + } + + /** + * Initialize a PHP BigInteger Engine instance + * + * @param int $base + * @see parent::__construct() + */ + protected function initialize($base) + { + switch (abs($base)) { + case 16: + $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; + $temp = new static(Strings::hex2bin($x), 256); + $this->value = $temp->value; + break; + case 10: + $temp = new static(); + + $multiplier = new static(); + $multiplier->value = [static::MAX10]; + + $x = $this->value; + + if ($x[0] == '-') { + $this->is_negative = true; + $x = substr($x, 1); + } + + $x = str_pad( + $x, + strlen($x) + ((static::MAX10LEN - 1) * strlen($x)) % static::MAX10LEN, + 0, + STR_PAD_LEFT + ); + while (strlen($x)) { + $temp = $temp->multiply($multiplier); + $temp = $temp->add(new static($this->int2bytes(substr($x, 0, static::MAX10LEN)), 256)); + $x = substr($x, static::MAX10LEN); + } + + $this->value = $temp->value; + } + } + + /** + * Pads strings so that unpack may be used on them + * + * @param string $str + * @return string + */ + protected function pad($str) + { + $length = strlen($str); + + $pad = 4 - (strlen($str) % 4); + + return str_pad($str, $length + $pad, "\0", STR_PAD_LEFT); + } + + /** + * Converts a BigInteger to a base-10 number. + * + * @return string + */ + public function toString() + { + if (!count($this->value)) { + return '0'; + } + + $temp = clone $this; + $temp->bitmask = false; + $temp->is_negative = false; + + $divisor = new static(); + $divisor->value = [static::MAX10]; + $result = ''; + while (count($temp->value)) { + list($temp, $mod) = $temp->divide($divisor); + $result = str_pad( + isset($mod->value[0]) ? $mod->value[0] : '', + static::MAX10LEN, + '0', + STR_PAD_LEFT + ) . $result; + } + $result = ltrim($result, '0'); + if (empty($result)) { + $result = '0'; + } + + if ($this->is_negative) { + $result = '-' . $result; + } + + return $result; + } + + /** + * Converts a BigInteger to a byte string (eg. base-256). + * + * @param bool $twos_compliment + * @return string + */ + public function toBytes($twos_compliment = false) + { + if ($twos_compliment) { + return $this->toBytesHelper(); + } + + if (!count($this->value)) { + return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; + } + + $result = $this->bitwise_small_split(8); + $result = implode('', array_map('chr', $result)); + + return $this->precision > 0 ? + str_pad( + substr($result, -(($this->precision + 7) >> 3)), + ($this->precision + 7) >> 3, + chr(0), + STR_PAD_LEFT + ) : + $result; + } + + /** + * Performs addition. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return [ + self::VALUE => $y_value, + self::SIGN => $y_negative + ]; + } elseif ($y_size == 0) { + return [ + self::VALUE => $x_value, + self::SIGN => $x_negative + ]; + } + + // subtract, if appropriate + if ($x_negative != $y_negative) { + if ($x_value == $y_value) { + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + $temp = self::subtractHelper($x_value, false, $y_value, false); + $temp[self::SIGN] = self::compareHelper($x_value, false, $y_value, false) > 0 ? + $x_negative : $y_negative; + + return $temp; + } + + if ($x_size < $y_size) { + $size = $x_size; + $value = $y_value; + } else { + $size = $y_size; + $value = $x_value; + } + + $value[count($value)] = 0; // just in case the carry adds an extra digit + + $carry = 0; + for ($i = 0, $j = 1; $j < $size; $i += 2, $j += 2) { + //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; + $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; + + $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $value[$i] = (int)($sum - static::BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) + $value[$j] = $temp; + } + + if ($j == $size) { // ie. if $y_size is odd + $sum = $x_value[$i] + $y_value[$i] + $carry; + $carry = $sum >= static::BASE_FULL; + $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; + ++$i; // ie. let $i = $j since we've just done $value[$i] + } + + if ($carry) { + for (; $value[$i] == static::MAX_DIGIT; ++$i) { + $value[$i] = 0; + } + ++$value[$i]; + } + + return [ + self::VALUE => self::trim($value), + self::SIGN => $x_negative + ]; + } + + /** + * Performs subtraction. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + public static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + $x_size = count($x_value); + $y_size = count($y_value); + + if ($x_size == 0) { + return [ + self::VALUE => $y_value, + self::SIGN => !$y_negative + ]; + } elseif ($y_size == 0) { + return [ + self::VALUE => $x_value, + self::SIGN => $x_negative + ]; + } + + // add, if appropriate (ie. -$x - +$y or +$x - -$y) + if ($x_negative != $y_negative) { + $temp = self::addHelper($x_value, false, $y_value, false); + $temp[self::SIGN] = $x_negative; + + return $temp; + } + + $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); + + if (!$diff) { + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + // switch $x and $y around, if appropriate. + if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_negative = !$x_negative; + + $x_size = count($x_value); + $y_size = count($y_value); + } + + // at this point, $x_value should be at least as big as - if not bigger than - $y_value + + $carry = 0; + for ($i = 0, $j = 1; $j < $y_size; $i += 2, $j += 2) { + $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; + + $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 + $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; + + $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); + + $x_value[$i] = (int)($sum - static::BASE_FULL * $temp); + $x_value[$j] = $temp; + } + + if ($j == $y_size) { // ie. if $y_size is odd + $sum = $x_value[$i] - $y_value[$i] - $carry; + $carry = $sum < 0; + $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; + ++$i; + } + + if ($carry) { + for (; !$x_value[$i]; ++$i) { + $x_value[$i] = static::MAX_DIGIT; + } + --$x_value[$i]; + } + + return [ + self::VALUE => self::trim($x_value), + self::SIGN => $x_negative + ]; + } + + /** + * Performs multiplication. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return array + */ + protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + //if ( $x_value == $y_value ) { + // return [ + // self::VALUE => self::square($x_value), + // self::SIGN => $x_sign != $y_value + // ]; + //} + + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + return [ + self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? + self::trim(self::regularMultiply($x_value, $y_value)) : + self::trim(self::karatsuba($x_value, $y_value)), + self::SIGN => $x_negative != $y_negative + ]; + } + + /** + * Performs Karatsuba multiplication on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + private static function karatsuba(array $x_value, array $y_value) + { + $m = min(count($x_value) >> 1, count($y_value) >> 1); + + if ($m < self::KARATSUBA_CUTOFF) { + return self::regularMultiply($x_value, $y_value); + } + + $x1 = array_slice($x_value, $m); + $x0 = array_slice($x_value, 0, $m); + $y1 = array_slice($y_value, $m); + $y0 = array_slice($y_value, 0, $m); + + $z2 = self::karatsuba($x1, $y1); + $z0 = self::karatsuba($x0, $y0); + + $z1 = self::addHelper($x1, false, $x0, false); + $temp = self::addHelper($y1, false, $y0, false); + $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); + $temp = self::addHelper($z2, false, $z0, false); + $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xy = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, false); + + return $xy[self::VALUE]; + } + + /** + * Performs long multiplication on two BigIntegers + * + * Modeled after 'multiply' in MutableBigInteger.java. + * + * @param array $x_value + * @param array $y_value + * @return array + */ + protected static function regularMultiply(array $x_value, array $y_value) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return []; + } + + $product_value = self::array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int)($temp - static::BASE_FULL * $carry); + } + + $product_value[$j] = $carry; + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int)($temp - static::BASE_FULL * $carry); + } + + $product_value[$k] = $carry; + } + + return $product_value; + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @return array{static, static} + * @internal This function is based off of + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. + */ + protected function divideHelper(PHP $y) + { + if (count($y->value) == 1) { + list($q, $r) = $this->divide_digit($this->value, $y->value[0]); + $quotient = new static(); + $remainder = new static(); + $quotient->value = $q; + $remainder->value = [$r]; + $quotient->is_negative = $this->is_negative != $y->is_negative; + return [$this->normalize($quotient), $this->normalize($remainder)]; + } + + $x = clone $this; + $y = clone $y; + + $x_sign = $x->is_negative; + $y_sign = $y->is_negative; + + $x->is_negative = $y->is_negative = false; + + $diff = $x->compare($y); + + if (!$diff) { + $temp = new static(); + $temp->value = [1]; + $temp->is_negative = $x_sign != $y_sign; + return [$this->normalize($temp), $this->normalize(static::$zero[static::class])]; + } + + if ($diff < 0) { + // if $x is negative, "add" $y. + if ($x_sign) { + $x = $y->subtract($x); + } + return [$this->normalize(static::$zero[static::class]), $this->normalize($x)]; + } + + // normalize $x and $y as described in HAC 14.23 / 14.24 + $msb = $y->value[count($y->value) - 1]; + for ($shift = 0; !($msb & static::MSB); ++$shift) { + $msb <<= 1; + } + $x->lshift($shift); + $y->lshift($shift); + $y_value = &$y->value; + + $x_max = count($x->value) - 1; + $y_max = count($y->value) - 1; + + $quotient = new static(); + $quotient_value = &$quotient->value; + $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); + + static $temp, $lhs, $rhs; + if (!isset($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + if (static::class != get_class($temp)) { + $temp = new static(); + $lhs = new static(); + $rhs = new static(); + } + $temp_value = &$temp->value; + $rhs_value = &$rhs->value; + + // $temp = $y << ($x_max - $y_max-1) in base 2**26 + $temp_value = array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); + + while ($x->compare($temp) >= 0) { + // calculate the "common residue" + ++$quotient_value[$x_max - $y_max]; + $x = $x->subtract($temp); + $x_max = count($x->value) - 1; + } + + for ($i = $x_max; $i >= $y_max + 1; --$i) { + $x_value = &$x->value; + $x_window = [ + isset($x_value[$i]) ? $x_value[$i] : 0, + isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, + isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 + ]; + $y_window = [ + $y_value[$y_max], + ($y_max > 0) ? $y_value[$y_max - 1] : 0 + ]; + + $q_index = $i - $y_max - 1; + if ($x_window[0] == $y_window[0]) { + $quotient_value[$q_index] = static::MAX_DIGIT; + } else { + $quotient_value[$q_index] = self::safe_divide( + $x_window[0] * static::BASE_FULL + $x_window[1], + $y_window[0] + ); + } + + $temp_value = [$y_window[1], $y_window[0]]; + + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + + $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; + + while ($lhs->compare($rhs) > 0) { + --$quotient_value[$q_index]; + + $lhs->value = [$quotient_value[$q_index]]; + $lhs = $lhs->multiply($temp); + } + + $adjust = self::array_repeat(0, $q_index); + $temp_value = [$quotient_value[$q_index]]; + $temp = $temp->multiply($y); + $temp_value = &$temp->value; + if (count($temp_value)) { + $temp_value = array_merge($adjust, $temp_value); + } + + $x = $x->subtract($temp); + + if ($x->compare(static::$zero[static::class]) < 0) { + $temp_value = array_merge($adjust, $y_value); + $x = $x->add($temp); + + --$quotient_value[$q_index]; + } + + $x_max = count($x_value) - 1; + } + + // unnormalize the remainder + $x->rshift($shift); + + $quotient->is_negative = $x_sign != $y_sign; + + // calculate the "common residue", if appropriate + if ($x_sign) { + $y->rshift($shift); + $x = $y->subtract($x); + } + + return [$this->normalize($quotient), $this->normalize($x)]; + } + + /** + * Divides a BigInteger by a regular integer + * + * abc / x = a00 / x + b0 / x + c / x + * + * @param array $dividend + * @param int $divisor + * @return array + */ + private static function divide_digit(array $dividend, $divisor) + { + $carry = 0; + $result = []; + + for ($i = count($dividend) - 1; $i >= 0; --$i) { + $temp = static::BASE_FULL * $carry + $dividend[$i]; + $result[$i] = self::safe_divide($temp, $divisor); + $carry = (int)($temp - $divisor * $result[$i]); + } + + return [$result, $carry]; + } + + /** + * Single digit division + * + * Even if int64 is being used the division operator will return a float64 value + * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't + * have the precision of int64 this is a problem so, when int64 is being used, + * we'll guarantee that the dividend is divisible by first subtracting the remainder. + * + * @param int $x + * @param int $y + * @return int + */ + private static function safe_divide($x, $y) + { + if (static::BASE === 26) { + return (int)($x / $y); + } + + // static::BASE === 31 + /** @var int */ + return ($x - ($x % $y)) / $y; + } + + /** + * Convert an array / boolean to a PHP BigInteger object + * + * @param array $arr + * @return static + */ + protected function convertToObj(array $arr) + { + $result = new static(); + $result->value = $arr[self::VALUE]; + $result->is_negative = $arr[self::SIGN]; + + return $this->normalize($result); + } + + /** + * Normalize + * + * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision + * + * @param PHP $result + * @return static + */ + protected function normalize(PHP $result) + { + $result->precision = $this->precision; + $result->bitmask = $this->bitmask; + + $value = &$result->value; + + if (!count($value)) { + $result->is_negative = false; + return $result; + } + + $value = static::trim($value); + + if (!empty($result->bitmask->value)) { + $length = min(count($value), count($result->bitmask->value)); + $value = array_slice($value, 0, $length); + + for ($i = 0; $i < $length; ++$i) { + $value[$i] = $value[$i] & $result->bitmask->value[$i]; + } + + $value = static::trim($value); + } + + return $result; + } + + /** + * Compares two numbers. + * + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @return int + * @see static::compare() + */ + protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) + { + if ($x_negative != $y_negative) { + return (!$x_negative && $y_negative) ? 1 : -1; + } + + $result = $x_negative ? -1 : 1; + + if (count($x_value) != count($y_value)) { + return (count($x_value) > count($y_value)) ? $result : -$result; + } + $size = max(count($x_value), count($y_value)); + + $x_value = array_pad($x_value, $size, 0); + $y_value = array_pad($y_value, $size, 0); + + for ($i = count($x_value) - 1; $i >= 0; --$i) { + if ($x_value[$i] != $y_value[$i]) { + return ($x_value[$i] > $y_value[$i]) ? $result : -$result; + } + } + + return 0; + } + + /** + * Absolute value. + * + * @return PHP + */ + public function abs() + { + $temp = new static(); + $temp->value = $this->value; + + return $temp; + } + + /** + * Trim + * + * Removes leading zeros + * + * @param list $value + * @return list + */ + protected static function trim(array $value) + { + for ($i = count($value) - 1; $i >= 0; --$i) { + if ($value[$i]) { + break; + } + unset($value[$i]); + } + + return $value; + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. + * + * @param int $shift + * @return PHP + */ + public function bitwise_rightShift($shift) + { + $temp = new static(); + + // could just replace lshift with this, but then all lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->rshift($shift); + + return $this->normalize($temp); + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. + * + * @param int $shift + * @return PHP + */ + public function bitwise_leftShift($shift) + { + $temp = new static(); + // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten + // and I don't want to do that... + $temp->value = $this->value; + $temp->lshift($shift); + + return $this->normalize($temp); + } + + /** + * Converts 32-bit integers to bytes. + * + * @param int $x + * @return string + */ + private static function int2bytes($x) + { + return ltrim(pack('N', $x), chr(0)); + } + + /** + * Array Repeat + * + * @param int $input + * @param int $multiplier + * @return array + */ + protected static function array_repeat($input, $multiplier) + { + return $multiplier ? array_fill(0, $multiplier, $input) : []; + } + + /** + * Logical Left Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function lshift($shift) + { + if ($shift == 0) { + return; + } + + $num_digits = (int)($shift / static::BASE); + $shift %= static::BASE; + $shift = 1 << $shift; + + $carry = 0; + + for ($i = 0; $i < count($this->value); ++$i) { + $temp = $this->value[$i] * $shift + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $this->value[$i] = (int)($temp - $carry * static::BASE_FULL); + } + + if ($carry) { + $this->value[count($this->value)] = $carry; + } + + while ($num_digits--) { + array_unshift($this->value, 0); + } + } + + /** + * Logical Right Shift + * + * Shifts BigInteger's by $shift bits. + * + * @param int $shift + */ + protected function rshift($shift) + { + if ($shift == 0) { + return; + } + + $num_digits = (int)($shift / static::BASE); + $shift %= static::BASE; + $carry_shift = static::BASE - $shift; + $carry_mask = (1 << $shift) - 1; + + if ($num_digits) { + $this->value = array_slice($this->value, $num_digits); + } + + $carry = 0; + + for ($i = count($this->value) - 1; $i >= 0; --$i) { + $temp = $this->value[$i] >> $shift | $carry; + $carry = ($this->value[$i] & $carry_mask) << $carry_shift; + $this->value[$i] = $temp; + } + + $this->value = static::trim($this->value); + } + + /** + * Performs modular exponentiation. + * + * @param PHP $e + * @param PHP $n + * @return PHP + */ + protected function powModInner(PHP $e, PHP $n) + { + try { + $class = static::$modexpEngine[static::class]; + return $class::powModHelper($this, $e, $n, static::class); + } catch (\Exception $err) { + return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); + } + } + + /** + * Performs squaring + * + * @param list $x + * @return list + */ + protected static function square(array $x) + { + return count($x) < 2 * self::KARATSUBA_CUTOFF ? + self::trim(self::baseSquare($x)) : + self::trim(self::karatsubaSquare($x)); + } + + /** + * Performs traditional squaring on two BigIntegers + * + * Squaring can be done faster than multiplying a number by itself can be. See + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. + * + * @param array $value + * @return array + */ + protected static function baseSquare(array $value) + { + if (empty($value)) { + return []; + } + $square_value = self::array_repeat(0, 2 * count($value)); + + for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { + $i2 = $i << 1; + + $temp = $square_value[$i2] + $value[$i] * $value[$i]; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$i2] = (int)($temp - static::BASE_FULL * $carry); + + // note how we start from $i+1 instead of 0 as we do in multiplication. + for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { + $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; + $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $square_value[$k] = (int)($temp - static::BASE_FULL * $carry); + } + + // the following line can yield values larger 2**15. at this point, PHP should switch + // over to floats. + $square_value[$i + $max_index + 1] = $carry; + } + + return $square_value; + } + + /** + * Performs Karatsuba "squaring" on two BigIntegers + * + * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. + * + * @param array $value + * @return array + */ + protected static function karatsubaSquare(array $value) + { + $m = count($value) >> 1; + + if ($m < self::KARATSUBA_CUTOFF) { + return self::baseSquare($value); + } + + $x1 = array_slice($value, $m); + $x0 = array_slice($value, 0, $m); + + $z2 = self::karatsubaSquare($x1); + $z0 = self::karatsubaSquare($x0); + + $z1 = self::addHelper($x1, false, $x0, false); + $z1 = self::karatsubaSquare($z1[self::VALUE]); + $temp = self::addHelper($z2, false, $z0, false); + $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); + + $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); + $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); + + $xx = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); + $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, false); + + return $xx[self::VALUE]; + } + + /** + * Make the current number odd + * + * If the current number is odd it'll be unchanged. If it's even, one will be added to it. + * + * @see self::randomPrime() + */ + protected function make_odd() + { + $this->value[0] |= 1; + } + + /** + * Test the number against small primes. + * + * @see self::isPrime() + */ + protected function testSmallPrimes() + { + if ($this->value == [1]) { + return false; + } + if ($this->value == [2]) { + return true; + } + if (~$this->value[0] & 1) { + return false; + } + + $value = $this->value; + foreach (static::PRIMES as $prime) { + list(, $r) = self::divide_digit($value, $prime); + if (!$r) { + return count($value) == 1 && $value[0] == $prime; + } + } + + return true; + } + + /** + * Scan for 1 and right shift by that amount + * + * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); + * + * @param PHP $r + * @return int + * @see self::isPrime() + */ + public static function scan1divide(PHP $r) + { + $r_value = &$r->value; + for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { + $temp = ~$r_value[$i] & static::MAX_DIGIT; + for ($j = 1; ($temp >> $j) & 1; ++$j) { + } + if ($j <= static::BASE) { + break; + } + } + $s = static::BASE * $i + $j; + $r->rshift($s); + return $s; + } + + /** + * Performs exponentiation. + * + * @param PHP $n + * @return PHP + */ + protected function powHelper(PHP $n) + { + if ($n->compare(static::$zero[static::class]) == 0) { + return new static(1); + } // n^0 = 1 + + $temp = clone $this; + while (!$n->equals(static::$one[static::class])) { + $temp = $temp->multiply($this); + $n = $n->subtract(static::$one[static::class]); + } + + return $temp; + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return (bool)($this->value[0] & 1); + } + + /** + * Tests if a bit is set + * + * @return bool + */ + public function testBit($x) + { + $digit = (int) floor($x / static::BASE); + $bit = $x % static::BASE; + + if (!isset($this->value[$digit])) { + return false; + } + + return (bool)($this->value[$digit] & (1 << $bit)); + } + + /** + * Is Negative? + * + * @return bool + */ + public function isNegative() + { + return $this->is_negative; + } + + /** + * Negate + * + * Given $k, returns -$k + * + * @return static + */ + public function negate() + { + $temp = clone $this; + $temp->is_negative = !$temp->is_negative; + + return $temp; + } + + /** + * Bitwise Split + * + * Splits BigInteger's into chunks of $split bits + * + * @param int $split + * @return list + */ + public function bitwise_split($split) + { + if ($split < 1) { + throw new \RuntimeException('Offset must be greater than 1'); + } + + $width = (int)($split / static::BASE); + if (!$width) { + $arr = $this->bitwise_small_split($split); + return array_map(function ($digit) { + $temp = new static(); + $temp->value = $digit != 0 ? [$digit] : []; + return $temp; + }, $arr); + } + + $vals = []; + $val = $this->value; + + $i = $overflow = 0; + $len = count($val); + while ($i < $len) { + $digit = []; + if (!$overflow) { + $digit = array_slice($val, $i, $width); + $i += $width; + $overflow = $split % static::BASE; + if ($overflow) { + $mask = (1 << $overflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $mask; + } + } else { + $remaining = static::BASE - $overflow; + $tempsplit = $split - $remaining; + $tempwidth = (int)($tempsplit / static::BASE + 1); + $digit = array_slice($val, $i, $tempwidth); + $i += $tempwidth; + $tempoverflow = $tempsplit % static::BASE; + if ($tempoverflow) { + $tempmask = (1 << $tempoverflow) - 1; + $temp = isset($val[$i]) ? $val[$i] : 0; + $digit[] = $temp & $tempmask; + } + $newbits = 0; + for ($j = count($digit) - 1; $j >= 0; $j--) { + $temp = $digit[$j] & $mask; + $digit[$j] = ($digit[$j] >> $overflow) | ($newbits << $remaining); + $newbits = $temp; + } + $overflow = $tempoverflow; + $mask = $tempmask; + } + $temp = new static(); + $temp->value = static::trim($digit); + $vals[] = $temp; + } + + return array_reverse($vals); + } + + /** + * Bitwise Split where $split < static::BASE + * + * @param int $split + * @return list + */ + private function bitwise_small_split($split) + { + $vals = []; + $val = $this->value; + + $mask = (1 << $split) - 1; + + $i = $overflow = 0; + $len = count($val); + $val[] = 0; + $remaining = static::BASE; + while ($i != $len) { + $digit = $val[$i] & $mask; + $val[$i] >>= $split; + if (!$overflow) { + $remaining -= $split; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + + if (!$remaining) { + $i++; + $remaining = static::BASE; + $overflow = 0; + } + } elseif (++$i != $len) { + $tempmask = (1 << $overflow) - 1; + $digit |= ($val[$i] & $tempmask) << $remaining; + $val[$i] >>= $overflow; + $remaining = static::BASE - $overflow; + $overflow = $split <= $remaining ? 0 : $split - $remaining; + } + + $vals[] = $digit; + } + + while ($vals[count($vals) - 1] == 0) { + unset($vals[count($vals) - 1]); + } + + return array_reverse($vals); + } + + /** + * @return bool + */ + protected static function testJITOnWindows() + { + // see https://github.com/php/php-src/issues/11917 + if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && PHP_VERSION_ID < 80213 && !defined('PHPSECLIB_ALLOW_JIT')) { + $status = opcache_get_status(); + if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { + return true; + } + } + return false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php new file mode 100644 index 0000000..40f64bd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php @@ -0,0 +1,143 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP; + +/** + * PHP Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Base extends PHP +{ + /** + * Cache constants + * + * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. + * + */ + const VARIABLE = 0; + /** + * $cache[self::DATA] contains the cached data. + * + */ + const DATA = 1; + + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * The most naive approach to modular exponentiation has very unreasonable requirements, and + * and although the approach involving repeated squaring does vastly better, it, too, is impractical + * for our purposes. The reason being that division - by far the most complicated and time-consuming + * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. + * + * Modular reductions resolve this issue. Although an individual modular reduction takes more time + * then an individual division, when performed in succession (with the same modulo), they're a lot faster. + * + * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, + * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the + * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because + * the product of two odd numbers is odd), but what about when RSA isn't used? + * + * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a + * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the + * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, + * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and + * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. + * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. + * + * @param PHP $x + * @param PHP $e + * @param PHP $n + * @param string $class + * @return PHP + */ + protected static function powModHelper(PHP $x, PHP $e, PHP $n, $class) + { + if (empty($e->value)) { + $temp = new $class(); + $temp->value = [1]; + return $x->normalize($temp); + } + + if ($e->value == [1]) { + list(, $temp) = $x->divide($n); + return $x->normalize($temp); + } + + if ($e->value == [2]) { + $temp = new $class(); + $temp->value = $class::square($x->value); + list(, $temp) = $temp->divide($n); + return $x->normalize($temp); + } + + return $x->normalize(static::slidingWindow($x, $e, $n, $class)); + } + + /** + * Modular reduction preparation + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return static::reduce($x, $n, $class); + } + + /** + * Modular multiply + * + * @param array $x + * @param array $y + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function multiplyReduce(array $x, array $y, array $n, $class) + { + $temp = $class::multiplyHelper($x, false, $y, false); + return static::reduce($temp[self::VALUE], $n, $class); + } + + /** + * Modular square + * + * @param array $x + * @param array $n + * @param string $class + * @see self::slidingWindow() + * @return array + */ + protected static function squareReduce(array $x, array $n, $class) + { + return static::reduce($class::square($x), $n, $class); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php new file mode 100644 index 0000000..6d33532 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; + +/** + * PHP Default Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class DefaultEngine extends EvalBarrett +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php new file mode 100644 index 0000000..09f825f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php @@ -0,0 +1,89 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\Engine; +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; + +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Montgomery extends Base +{ + /** + * Test for engine validity + * + * @return bool + */ + public static function isValidEngine() + { + return static::class != __CLASS__; + } + + /** + * Performs modular exponentiation. + * + * @template T of Engine + * @param Engine $x + * @param Engine $e + * @param Engine $n + * @param class-string $class + * @return T + */ + protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) + { + // is the modulo odd? + if ($n->value[0] & 1) { + return parent::slidingWindow($x, $e, $n, $class); + } + // if it's not, it's even + + // find the lowest set bit (eg. the max pow of 2 that divides $n) + for ($i = 0; $i < count($n->value); ++$i) { + if ($n->value[$i]) { + $temp = decbin($n->value[$i]); + $j = strlen($temp) - strrpos($temp, '1') - 1; + $j += $class::BASE * $i; + break; + } + } + // at this point, 2^$j * $n/(2^$j) == $n + + $mod1 = clone $n; + $mod1->rshift($j); + $mod2 = new $class(); + $mod2->value = [1]; + $mod2->lshift($j); + + $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); + $part2 = PowerOfTwo::slidingWindow($x, $e, $mod2, $class); + + $y1 = $mod2->modInverse($mod1); + $y2 = $mod1->modInverse($mod2); + + $result = $part1->multiply($mod2); + $result = $result->multiply($y1); + + $temp = $part2->multiply($mod1); + $temp = $temp->multiply($y2); + + $result = $result->add($temp); + list(, $result) = $result->divide($n); + + return $result; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php new file mode 100644 index 0000000..eddd25e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php @@ -0,0 +1,25 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP; + +use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; + +/** + * OpenSSL Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class OpenSSL extends Progenitor +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php new file mode 100644 index 0000000..3518d76 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php @@ -0,0 +1,281 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Barrett extends Base +{ + /** + * Barrett Modular Reduction + * + * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, + * so as not to require negative numbers (initially, this script didn't support negative numbers). + * + * Employs "folding", as described at + * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from + * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." + * + * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that + * usable on account of (1) its not using reasonable radix points as discussed in + * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable + * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that + * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line + * comments for details. + * + * @param array $n + * @param array $m + * @param class-string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $m_length = count($m); + + // if (self::compareHelper($n, $static::square($m)) >= 0) { + if (count($n) > 2 * $m_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $n; + $rhs->value = $m; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced + if ($m_length < 5) { + return self::regularBarrett($n, $m, $class); + } + // n = 2 * m.length + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + + $lhs = new $class(); + $lhs_value = &$lhs->value; + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $m; + + list($u, $m1) = $lhs->divide($rhs); + $u = $u->value; + $m1 = $m1->value; + + $cache[self::DATA][] = [ + 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) + 'm1' => $m1 // m.length + ]; + } else { + extract($cache[self::DATA][$key]); + } + + $cutoff = $m_length + ($m_length >> 1); + $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) + $msd = array_slice($n, $cutoff); // m.length >> 1 + + $lsd = self::trim($lsd); + $temp = $class::multiplyHelper($msd, false, $m1, false); // m.length + (m.length >> 1) + $n = $class::addHelper($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) + //if ($m_length & 1) { + // return self::regularBarrett($n[self::VALUE], $m, $class); + //} + + // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 + $temp = array_slice($n[self::VALUE], $m_length - 1); + // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 + // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 + $temp = $class::multiplyHelper($temp, false, $u, false); + // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 + // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); + // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 + // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) + $temp = $class::multiplyHelper($temp, false, $m, false); + + // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit + // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop + // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). + + $result = $class::subtractHelper($n[self::VALUE], false, $temp[self::VALUE], false); + + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, false); + } + + return $result[self::VALUE]; + } + + /** + * (Regular) Barrett Modular Reduction + * + * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this + * is that this function does not fold the denominator into a smaller form. + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + private static function regularBarrett(array $x, array $n, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + $n_length = count($n); + + if (count($x) > 2 * $n_length) { + $lhs = new $class(); + $rhs = new $class(); + $lhs->value = $x; + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $n; + $lhs = new $class(); + $lhs_value = &$lhs->value; + $lhs_value = self::array_repeat(0, 2 * $n_length); + $lhs_value[] = 1; + $rhs = new $class(); + $rhs->value = $n; + list($temp, ) = $lhs->divide($rhs); // m.length + $cache[self::DATA][] = $temp->value; + } + + // 2 * m.length - (m.length - 1) = m.length + 1 + $temp = array_slice($x, $n_length - 1); + // (m.length + 1) + m.length = 2 * m.length + 1 + $temp = $class::multiplyHelper($temp, false, $cache[self::DATA][$key], false); + // (2 * m.length + 1) - (m.length - 1) = m.length + 2 + $temp = array_slice($temp[self::VALUE], $n_length + 1); + + // m.length + 1 + $result = array_slice($x, 0, $n_length + 1); + // m.length + 1 + $temp = self::multiplyLower($temp, false, $n, false, $n_length + 1, $class); + // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) + + if (self::compareHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { + $corrector_value = self::array_repeat(0, $n_length + 1); + $corrector_value[count($corrector_value)] = 1; + $result = $class::addHelper($result, false, $corrector_value, false); + $result = $result[self::VALUE]; + } + + // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits + $result = $class::subtractHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]); + while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { + $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Performs long multiplication up to $stop digits + * + * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. + * + * @see self::regularBarrett() + * @param array $x_value + * @param bool $x_negative + * @param array $y_value + * @param bool $y_negative + * @param int $stop + * @param string $class + * @return array + */ + private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) + { + $x_length = count($x_value); + $y_length = count($y_value); + + if (!$x_length || !$y_length) { // a 0 is being multiplied + return [ + self::VALUE => [], + self::SIGN => false + ]; + } + + if ($x_length < $y_length) { + $temp = $x_value; + $x_value = $y_value; + $y_value = $temp; + + $x_length = count($x_value); + $y_length = count($y_value); + } + + $product_value = self::array_repeat(0, $x_length + $y_length); + + // the following for loop could be removed if the for loop following it + // (the one with nested for loops) initially set $i to 0, but + // doing so would also make the result in one set of unnecessary adds, + // since on the outermost loops first pass, $product->value[$k] is going + // to always be 0 + + $carry = 0; + + for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i + $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 + $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); + } + + if ($j < $stop) { + $product_value[$j] = $carry; + } + + // the above for loop is what the previous comment was talking about. the + // following for loop is the "one with nested for loops" + + for ($i = 1; $i < $y_length; ++$i) { + $carry = 0; + + for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { + $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; + $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); + $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); + } + + if ($k < $stop) { + $product_value[$k] = $carry; + } + } + + return [ + self::VALUE => self::trim($product_value), + self::SIGN => $x_negative != $y_negative + ]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php new file mode 100644 index 0000000..54f3b86 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php @@ -0,0 +1,42 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Classic Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Classic extends Base +{ + /** + * Regular Division + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php new file mode 100644 index 0000000..2f94331 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php @@ -0,0 +1,484 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP; +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Dynamic Barrett Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class EvalBarrett extends Base +{ + /** + * Custom Reduction Function + * + * @see self::generateCustomReduction + */ + private static $custom_reduction; + + /** + * Barrett Modular Reduction + * + * This calls a dynamically generated loop unrolled function that's specific to a given modulo. + * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. + * + * @param array $n + * @param array $m + * @param string $class + * @return array + */ + protected static function reduce(array $n, array $m, $class) + { + $inline = self::$custom_reduction; + return $inline($n); + } + + /** + * Generate Custom Reduction + * + * @param PHP $m + * @param string $class + * @return callable + */ + protected static function generateCustomReduction(PHP $m, $class) + { + $m_length = count($m->value); + + if ($m_length < 5) { + $code = ' + $lhs = new ' . $class . '(); + $lhs->value = $x; + $rhs = new ' . $class . '(); + $rhs->value = [' . + implode(',', array_map(self::class . '::float2string', $m->value)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + '; + eval('$func = function ($x) { ' . $code . '};'); + self::$custom_reduction = $func; + //self::$custom_reduction = \Closure::bind($func, $m, $class); + return $func; + } + + $lhs = new $class(); + $lhs_value = &$lhs->value; + + $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); + $lhs_value[] = 1; + $rhs = new $class(); + + list($u, $m1) = $lhs->divide($m); + + if ($class::BASE != 26) { + $u = $u->value; + } else { + $lhs_value = self::array_repeat(0, 2 * $m_length); + $lhs_value[] = 1; + $rhs = new $class(); + + list($u) = $lhs->divide($m); + $u = $u->value; + } + + $m = $m->value; + $m1 = $m1->value; + + $cutoff = count($m) + (count($m) >> 1); + + $code = ' + if (count($n) > ' . (2 * count($m)) . ') { + $lhs = new ' . $class . '(); + $rhs = new ' . $class . '(); + $lhs->value = $n; + $rhs->value = [' . + implode(',', array_map(self::class . '::float2string', $m)) . ']; + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + $lsd = array_slice($n, 0, ' . $cutoff . '); + $msd = array_slice($n, ' . $cutoff . ');'; + + $code .= self::generateInlineTrim('msd'); + $code .= self::generateInlineMultiply('msd', $m1, 'temp', $class); + $code .= self::generateInlineAdd('lsd', 'temp', 'n', $class); + + $code .= '$temp = array_slice($n, ' . (count($m) - 1) . ');'; + $code .= self::generateInlineMultiply('temp', $u, 'temp2', $class); + $code .= self::generateInlineTrim('temp2'); + + $code .= $class::BASE == 26 ? + '$temp = array_slice($temp2, ' . (count($m) + 1) . ');' : + '$temp = array_slice($temp2, ' . ((count($m) >> 1) + 1) . ');'; + $code .= self::generateInlineMultiply('temp', $m, 'temp2', $class); + $code .= self::generateInlineTrim('temp2'); + + /* + if ($class::BASE == 26) { + $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); + $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; + } + */ + + $code .= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); + + $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); + $subcode .= '$temp = $temp2;'; + + $code .= self::generateInlineCompare($m, 'temp', $subcode); + + $code .= 'return $temp;'; + + eval('$func = function ($n) { ' . $code . '};'); + + self::$custom_reduction = $func; + + return $func; + + //self::$custom_reduction = \Closure::bind($func, $m, $class); + } + + /** + * Inline Trim + * + * Removes leading zeros + * + * @param string $name + * @return string + */ + private static function generateInlineTrim($name) + { + return ' + for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { + if ($' . $name . '[$i]) { + break; + } + unset($' . $name . '[$i]); + }'; + } + + /** + * Inline Multiply (unknown, known) + * + * @param string $input + * @param array $arr + * @param string $output + * @param string $class + * @return string + */ + private static function generateInlineMultiply($input, array $arr, $output, $class) + { + if (!count($arr)) { + return 'return [];'; + } + + $regular = ' + $length = count($' . $input . '); + if (!$length) { + $' . $output . ' = []; + }else{ + $' . $output . ' = array_fill(0, $length + ' . count($arr) . ', 0); + $carry = 0;'; + + for ($i = 0; $i < count($arr); $i++) { + $regular .= ' + $subtemp = $' . $input . '[0] * ' . $arr[$i]; + $regular .= $i ? ' + $carry;' : ';'; + + $regular .= '$carry = '; + $regular .= $class::BASE === 26 ? + 'intval($subtemp / 0x4000000);' : + '$subtemp >> 31;'; + $regular .= + '$' . $output . '[' . $i . '] = '; + if ($class::BASE === 26) { + $regular .= '(int) ('; + } + $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular .= $class::BASE === 26 ? ');' : ';'; + } + + $regular .= '$' . $output . '[' . count($arr) . '] = $carry;'; + + $regular .= ' + for ($i = 1; $i < $length; ++$i) {'; + + for ($j = 0; $j < count($arr); $j++) { + $regular .= $j ? '$k++;' : '$k = $i;'; + $regular .= ' + $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; + $regular .= $j ? ' + $carry;' : ';'; + + $regular .= '$carry = '; + $regular .= $class::BASE === 26 ? + 'intval($subtemp / 0x4000000);' : + '$subtemp >> 31;'; + $regular .= + '$' . $output . '[$k] = '; + if ($class::BASE === 26) { + $regular .= '(int) ('; + } + $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; + $regular .= $class::BASE === 26 ? ');' : ';'; + } + + $regular .= '$' . $output . '[++$k] = $carry; $carry = 0;'; + + $regular .= '}}'; + + //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { + //} + + return $regular; + } + + /** + * Inline Addition + * + * @param string $x + * @param string $y + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineAdd($x, $y, $result, $class) + { + $code = ' + $length = max(count($' . $x . '), count($' . $y . ')); + $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); + $_' . $y . ' = array_pad($' . $y . ', $length, 0); + $carry = 0; + for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { + $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' + + $' . $result . '[$i] + $_' . $y . '[$i] + + $carry; + $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; + $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; + + $code .= $class::BASE === 26 ? + '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : + '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; + $code .= ' + $' . $result . '[$j] = $upper; + } + if ($j == $length) { + $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; + $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; + $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; + ++$i; + } + if ($carry) { + for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { + $' . $result . '[$i] = 0; + } + ++$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Subtraction 2 + * + * For when $known is more digits than $unknown. This is the harder use case to optimize for. + * + * @param string $known + * @param string $unknown + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract2($known, $unknown, $result, $class) + { + $code = ' + $' . $result . ' = $' . $known . '; + $carry = 0; + $size = count($' . $unknown . '); + for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { + $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] + - $' . $unknown . '[$i] + - $carry; + $carry = $sum < 0; + if ($carry) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code .= $class::BASE === 26 ? + 'intval($sum / 0x4000000);' : + '$sum >> 31;'; + $code .= '$' . $result . '[$i] = '; + if ($class::BASE === 26) { + $code .= '(int) ('; + } + $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code .= ')'; + } + $code .= '; + $' . $result . '[$j] = $subtemp; + } + if ($j == $size) { + $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; + $carry = $sum < 0; + $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i; + } + + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + + $code .= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Subtraction 1 + * + * For when $unknown is more digits than $known. This is the easier use case to optimize for. + * + * @param string $unknown + * @param array $known + * @param string $result + * @param string $class + * @return string + */ + private static function generateInlineSubtract1($unknown, array $known, $result, $class) + { + $code = '$' . $result . ' = $' . $unknown . ';'; + for ($i = 0, $j = 1; $j < count($known); $i += 2, $j += 2) { + $code .= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; + $code .= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); + if ($i != 0) { + $code .= ' - $carry'; + } + + $code .= '; + if ($carry = $sum < 0) { + $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; + } + $subtemp = '; + $code .= $class::BASE === 26 ? + 'intval($sum / 0x4000000);' : + '$sum >> 31;'; + $code .= ' + $' . $result . '[' . $i . '] = '; + if ($class::BASE === 26) { + $code .= ' (int) ('; + } + $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; + if ($class::BASE === 26) { + $code .= ')'; + } + $code .= '; + $' . $result . '[' . $j . '] = $subtemp;'; + } + + $code .= '$i = ' . $i . ';'; + + if ($j == count($known)) { + $code .= ' + $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; + $carry = $sum < 0; + $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; + ++$i;'; + } + + $code .= ' + if ($carry) { + for (; !$' . $result . '[$i]; ++$i) { + $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; + } + --$' . $result . '[$i]; + }'; + $code .= self::generateInlineTrim($result); + + return $code; + } + + /** + * Inline Comparison + * + * If $unknown >= $known then loop + * + * @param array $known + * @param string $unknown + * @param string $subcode + * @return string + */ + private static function generateInlineCompare(array $known, $unknown, $subcode) + { + $uniqid = uniqid(); + $code = 'loop_' . $uniqid . ': + $clength = count($' . $unknown . '); + switch (true) { + case $clength < ' . count($known) . ': + goto end_' . $uniqid . '; + case $clength > ' . count($known) . ':'; + for ($i = count($known) - 1; $i >= 0; $i--) { + $code .= ' + case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': + goto subcode_' . $uniqid . '; + case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': + goto end_' . $uniqid . ';'; + } + $code .= ' + default: + // do subcode + } + + subcode_' . $uniqid . ':' . $subcode . ' + goto loop_' . $uniqid . '; + + end_' . $uniqid . ':'; + + return $code; + } + + /** + * Convert a float to a string + * + * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of + * precision but displayed in this way there will be precision loss, hence the need for this method. + * + * @param int|float $num + * @return string + */ + private static function float2string($num) + { + if (!is_float($num)) { + return (string) $num; + } + + if ($num < 0) { + return '-' . self::float2string(abs($num)); + } + + $temp = ''; + while ($num) { + $temp = fmod($num, 10) . $temp; + $num = floor($num / 10); + } + + return $temp; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php new file mode 100644 index 0000000..a34035e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php @@ -0,0 +1,126 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; + +/** + * PHP Montgomery Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class Montgomery extends Progenitor +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = array_merge(self::array_repeat(0, count($n)), $x); + $rhs = new $class(); + $rhs->value = $n; + + list(, $temp) = $lhs->divide($rhs); + return $temp->value; + } + + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + if (($key = array_search($n, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $x; + $cache[self::DATA][] = self::modInverse67108864($n, $class); + } + + $k = count($n); + + $result = [self::VALUE => $x]; + + for ($i = 0; $i < $k; ++$i) { + $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $class::regularMultiply([$temp], $n); + $temp = array_merge(self::array_repeat(0, $i), $temp); + $result = $class::addHelper($result[self::VALUE], false, $temp, false); + } + + $result[self::VALUE] = array_slice($result[self::VALUE], $k); + + if (self::compareHelper($result, false, $n, false) >= 0) { + $result = $class::subtractHelper($result[self::VALUE], false, $n, false); + } + + return $result[self::VALUE]; + } + + /** + * Modular Inverse of a number mod 2**26 (eg. 67108864) + * + * Based off of the bnpInvDigit function implemented and justified in the following URL: + * + * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} + * + * The following URL provides more info: + * + * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} + * + * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For + * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields + * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't + * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that + * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the + * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to + * 40 bits, which only 64-bit floating points will support. + * + * Thanks to Pedro Gimeno Fortea for input! + * + * @param array $x + * @param string $class + * @return int + */ + protected static function modInverse67108864(array $x, $class) // 2**26 == 67,108,864 + { + $x = -$x[0]; + $result = $x & 0x3; // x**-1 mod 2**2 + $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 + $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 + $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 + $result = $class::BASE == 26 ? + fmod($result * (2 - fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : // x**-1 mod 2**26 + ($result * (2 - ($x * $result) % $class::BASE_FULL)) % $class::BASE_FULL; + return $result & $class::MAX_DIGIT; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php new file mode 100644 index 0000000..4fed3c3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php @@ -0,0 +1,76 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP; + +/** + * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication + * + * @author Jim Wigginton + */ +abstract class MontgomeryMult extends Montgomery +{ + /** + * Montgomery Multiply + * + * Interleaves the montgomery reduction and long multiplication algorithms together as described in + * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} + * + * @see self::_prepMontgomery() + * @see self::_montgomery() + * @param array $x + * @param array $y + * @param array $m + * @param class-string $class + * @return array + */ + public static function multiplyReduce(array $x, array $y, array $m, $class) + { + // the following code, although not callable, can be run independently of the above code + // although the above code performed better in my benchmarks the following could might + // perform better under different circumstances. in lieu of deleting it it's just been + // made uncallable + + static $cache = [ + self::VARIABLE => [], + self::DATA => [] + ]; + + if (($key = array_search($m, $cache[self::VARIABLE])) === false) { + $key = count($cache[self::VARIABLE]); + $cache[self::VARIABLE][] = $m; + $cache[self::DATA][] = self::modInverse67108864($m, $class); + } + + $n = max(count($x), count($y), count($m)); + $x = array_pad($x, $n, 0); + $y = array_pad($y, $n, 0); + $m = array_pad($m, $n, 0); + $a = [self::VALUE => self::array_repeat(0, $n + 1)]; + for ($i = 0; $i < $n; ++$i) { + $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $temp * $cache[self::DATA][$key]; + $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); + $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), false, $class::regularMultiply([$temp], $m), false); + $a = $class::addHelper($a[self::VALUE], false, $temp[self::VALUE], false); + $a[self::VALUE] = array_slice($a[self::VALUE], 1); + } + if (self::compareHelper($a[self::VALUE], false, $m, false) >= 0) { + $a = $class::subtractHelper($a[self::VALUE], false, $m, false); + } + return $a[self::VALUE]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php new file mode 100644 index 0000000..9da133a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php @@ -0,0 +1,59 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; + +use phpseclib3\Math\BigInteger\Engines\PHP\Base; + +/** + * PHP Power Of Two Modular Exponentiation Engine + * + * @author Jim Wigginton + */ +abstract class PowerOfTwo extends Base +{ + /** + * Prepare a number for use in Montgomery Modular Reductions + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function prepareReduce(array $x, array $n, $class) + { + return self::reduce($x, $n, $class); + } + + /** + * Power Of Two Reduction + * + * @param array $x + * @param array $n + * @param string $class + * @return array + */ + protected static function reduce(array $x, array $n, $class) + { + $lhs = new $class(); + $lhs->value = $x; + $rhs = new $class(); + $rhs->value = $n; + + $temp = new $class(); + $temp->value = [1]; + + $result = $lhs->bitwise_and($rhs->subtract($temp)); + return $result->value; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php new file mode 100644 index 0000000..3a775e7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php @@ -0,0 +1,371 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +/** + * Pure-PHP 32-bit Engine. + * + * Uses 64-bit floats if int size is 4 bits + * + * @author Jim Wigginton + */ +class PHP32 extends PHP +{ + // Constants used by PHP.php + const BASE = 26; + const BASE_FULL = 0x4000000; + const MAX_DIGIT = 0x3FFFFFF; + const MSB = 0x2000000; + + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 10000000; + + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 7; + const MAX_DIGIT2 = 4503599627370496; + + /** + * Initialize a PHP32 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + + $val = $this->value; + $this->value = []; + $vals = &$this->value; + $i = strlen($val); + if (!$i) { + return; + } + + while (true) { + $i -= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = substr($val, 0, 4 + $i); + $val = str_pad($val, 4, "\0", STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = unpack('N', substr($val, $i, 4)); + if ($digit < 0) { + $digit += 0xFFFFFFFF + 1; + } + $step = count($vals) & 3; + if ($step) { + $digit = (int) floor($digit / pow(2, 2 * $step)); + } + if ($step != 3) { + $digit = (int) fmod($digit, static::BASE_FULL); + $i++; + } + $vals[] = $digit; + } + while (end($vals) === 0) { + array_pop($vals); + } + reset($vals); + } + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return PHP_INT_SIZE >= 4 && !self::testJITOnWindows(); + } + + /** + * Adds two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function add(PHP32 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function subtract(PHP32 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param PHP32 $y + * @return PHP32 + */ + public function multiply(PHP32 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP32 $y + * @return array{PHP32, PHP32} + */ + public function divide(PHP32 $y) + { + return $this->divideHelper($y); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return false|PHP32 + */ + public function modInverse(PHP32 $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP32 $n + * @return PHP32[] + */ + public function extendedGCD(PHP32 $n) + { + return $this->extendedGCDHelper($n); + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP32 $n + * @return PHP32 + */ + public function gcd(PHP32 $n) + { + return $this->extendedGCD($n)['gcd']; + } + + /** + * Logical And + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_and(PHP32 $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_or(PHP32 $x) + { + return $this->bitwiseOrHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param PHP32 $x + * @return PHP32 + */ + public function bitwise_xor(PHP32 $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP32 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(PHP32 $y) + { + return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP32 $x + * @return bool + */ + public function equals(PHP32 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + + /** + * Performs modular exponentiation. + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function modPow(PHP32 $e, PHP32 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP32 $e + * @param PHP32 $n + * @return PHP32 + */ + public function powMod(PHP32 $e, PHP32 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP32 $min + * @param PHP32 $max + * @return false|PHP32 + */ + public static function randomRangePrime(PHP32 $min, PHP32 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP32 $min + * @param PHP32 $max + * @return PHP32 + */ + public static function randomRange(PHP32 $min, PHP32 $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Performs exponentiation. + * + * @param PHP32 $n + * @return PHP32 + */ + public function pow(PHP32 $n) + { + return $this->powHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function min(PHP32 ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP32 ...$nums + * @return PHP32 + */ + public static function max(PHP32 ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP32 $min + * @param PHP32 $max + * @return bool + */ + public function between(PHP32 $min, PHP32 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php new file mode 100644 index 0000000..70a2e17 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php @@ -0,0 +1,372 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math\BigInteger\Engines; + +/** + * Pure-PHP 64-bit Engine. + * + * Uses 64-bit integers if int size is 8 bits + * + * @author Jim Wigginton + */ +class PHP64 extends PHP +{ + // Constants used by PHP.php + const BASE = 31; + const BASE_FULL = 0x80000000; + const MAX_DIGIT = 0x7FFFFFFF; + const MSB = 0x40000000; + + /** + * MAX10 in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10 = 1000000000; + + /** + * MAX10LEN in greatest MAX10LEN satisfying + * MAX10 = 10**MAX10LEN <= 2**BASE. + */ + const MAX10LEN = 9; + const MAX_DIGIT2 = 4611686018427387904; + + /** + * Initialize a PHP64 BigInteger Engine instance + * + * @param int $base + * @see parent::initialize() + */ + protected function initialize($base) + { + if ($base != 256 && $base != -256) { + return parent::initialize($base); + } + + $val = $this->value; + $this->value = []; + $vals = &$this->value; + $i = strlen($val); + if (!$i) { + return; + } + + while (true) { + $i -= 4; + if ($i < 0) { + if ($i == -4) { + break; + } + $val = substr($val, 0, 4 + $i); + $val = str_pad($val, 4, "\0", STR_PAD_LEFT); + if ($val == "\0\0\0\0") { + break; + } + $i = 0; + } + list(, $digit) = unpack('N', substr($val, $i, 4)); + $step = count($vals) & 7; + if (!$step) { + $digit &= static::MAX_DIGIT; + $i++; + } else { + $shift = 8 - $step; + $digit >>= $shift; + $shift = 32 - $shift; + $digit &= (1 << $shift) - 1; + $temp = $i > 0 ? ord($val[$i - 1]) : 0; + $digit |= ($temp << $shift) & 0x7F000000; + } + $vals[] = $digit; + } + while (end($vals) === 0) { + array_pop($vals); + } + reset($vals); + } + + /** + * Test for engine validity + * + * @see parent::__construct() + * @return bool + */ + public static function isValidEngine() + { + return PHP_INT_SIZE >= 8 && !self::testJITOnWindows(); + } + + /** + * Adds two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function add(PHP64 $y) + { + $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Subtracts two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function subtract(PHP64 $y) + { + $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Multiplies two BigIntegers. + * + * @param PHP64 $y + * @return PHP64 + */ + public function multiply(PHP64 $y) + { + $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + + return $this->convertToObj($temp); + } + + /** + * Divides two BigIntegers. + * + * Returns an array whose first element contains the quotient and whose second element contains the + * "common residue". If the remainder would be positive, the "common residue" and the remainder are the + * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder + * and the divisor (basically, the "common residue" is the first positive modulo). + * + * @param PHP64 $y + * @return array{PHP64, PHP64} + */ + public function divide(PHP64 $y) + { + return $this->divideHelper($y); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return false|PHP64 + */ + public function modInverse(PHP64 $n) + { + return $this->modInverseHelper($n); + } + + /** + * Calculates modular inverses. + * + * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. + * @param PHP64 $n + * @return PHP64[] + */ + public function extendedGCD(PHP64 $n) + { + return $this->extendedGCDHelper($n); + } + + /** + * Calculates the greatest common divisor + * + * Say you have 693 and 609. The GCD is 21. + * + * @param PHP64 $n + * @return PHP64 + */ + public function gcd(PHP64 $n) + { + return $this->extendedGCD($n)['gcd']; + } + + /** + * Logical And + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_and(PHP64 $x) + { + return $this->bitwiseAndHelper($x); + } + + /** + * Logical Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_or(PHP64 $x) + { + return $this->bitwiseOrHelper($x); + } + + /** + * Logical Exclusive Or + * + * @param PHP64 $x + * @return PHP64 + */ + public function bitwise_xor(PHP64 $x) + { + return $this->bitwiseXorHelper($x); + } + + /** + * Compares two numbers. + * + * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is + * demonstrated thusly: + * + * $x > $y: $x->compare($y) > 0 + * $x < $y: $x->compare($y) < 0 + * $x == $y: $x->compare($y) == 0 + * + * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). + * + * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} + * + * @param PHP64 $y + * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. + * @see self::equals() + */ + public function compare(PHP64 $y) + { + return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); + } + + /** + * Tests the equality of two numbers. + * + * If you need to see if one number is greater than or less than another number, use BigInteger::compare() + * + * @param PHP64 $x + * @return bool + */ + public function equals(PHP64 $x) + { + return $this->value === $x->value && $this->is_negative == $x->is_negative; + } + + /** + * Performs modular exponentiation. + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64 + */ + public function modPow(PHP64 $e, PHP64 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Performs modular exponentiation. + * + * Alias for modPow(). + * + * @param PHP64 $e + * @param PHP64 $n + * @return PHP64|false + */ + public function powMod(PHP64 $e, PHP64 $n) + { + return $this->powModOuter($e, $n); + } + + /** + * Generate a random prime number between a range + * + * If there's not a prime within the given range, false will be returned. + * + * @param PHP64 $min + * @param PHP64 $max + * @return false|PHP64 + */ + public static function randomRangePrime(PHP64 $min, PHP64 $max) + { + return self::randomRangePrimeOuter($min, $max); + } + + /** + * Generate a random number between a range + * + * Returns a random number between $min and $max where $min and $max + * can be defined using one of the two methods: + * + * BigInteger::randomRange($min, $max) + * BigInteger::randomRange($max, $min) + * + * @param PHP64 $min + * @param PHP64 $max + * @return PHP64 + */ + public static function randomRange(PHP64 $min, PHP64 $max) + { + return self::randomRangeHelper($min, $max); + } + + /** + * Performs exponentiation. + * + * @param PHP64 $n + * @return PHP64 + */ + public function pow(PHP64 $n) + { + return $this->powHelper($n); + } + + /** + * Return the minimum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function min(PHP64 ...$nums) + { + return self::minHelper($nums); + } + + /** + * Return the maximum BigInteger between an arbitrary number of BigIntegers. + * + * @param PHP64 ...$nums + * @return PHP64 + */ + public static function max(PHP64 ...$nums) + { + return self::maxHelper($nums); + } + + /** + * Tests BigInteger to see if it is between two integers, inclusive + * + * @param PHP64 $min + * @param PHP64 $max + * @return bool + */ + public function between(PHP64 $min, PHP64 $max) + { + return $this->compare($min) >= 0 && $this->compare($max) <= 0; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php new file mode 100644 index 0000000..5da8c93 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php @@ -0,0 +1,203 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BinaryField\Integer; +use phpseclib3\Math\Common\FiniteField; + +/** + * Binary Finite Fields + * + * @author Jim Wigginton + */ +class BinaryField extends FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** @var BigInteger */ + private $randomMax; + + /** + * Default constructor + */ + public function __construct(...$indices) + { + $m = array_shift($indices); + if ($m > 571) { + /* sect571r1 and sect571k1 are the largest binary curves that https://www.secg.org/sec2-v2.pdf defines + altho theoretically there may be legit reasons to use binary finite fields with larger degrees + imposing a limit on the maximum size is both reasonable and precedented. in particular, + http://tools.ietf.org/html/rfc4253#section-6.1 (The Secure Shell (SSH) Transport Layer Protocol) says + "implementations SHOULD check that the packet length is reasonable in order for the implementation to + avoid denial of service and/or buffer overflow attacks" */ + throw new \OutOfBoundsException('Degrees larger than 571 are not supported'); + } + $val = str_repeat('0', $m) . '1'; + foreach ($indices as $index) { + $val[$index] = '1'; + } + $modulo = static::base2ToBase256(strrev($val)); + + $mStart = 2 * $m - 2; + $t = ceil($m / 8); + $finalMask = chr((1 << ($m % 8)) - 1); + if ($finalMask == "\0") { + $finalMask = "\xFF"; + } + $bitLen = $mStart + 1; + $pad = ceil($bitLen / 8); + $h = $bitLen & 7; + $h = $h ? 8 - $h : 0; + + $r = rtrim(substr($val, 0, -1), '0'); + $u = [static::base2ToBase256(strrev($r))]; + for ($i = 1; $i < 8; $i++) { + $u[] = static::base2ToBase256(strrev(str_repeat('0', $i) . $r)); + } + + // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" + // with W = 8 + $reduce = function ($c) use ($u, $mStart, $m, $t, $finalMask, $pad, $h) { + $c = str_pad($c, $pad, "\0", STR_PAD_LEFT); + for ($i = $mStart; $i >= $m;) { + $g = $h >> 3; + $mask = $h & 7; + $mask = $mask ? 1 << (7 - $mask) : 0x80; + for (; $mask > 0; $mask >>= 1, $i--, $h++) { + if (ord($c[$g]) & $mask) { + $temp = $i - $m; + $j = $temp >> 3; + $k = $temp & 7; + $t1 = $j ? substr($c, 0, -$j) : $c; + $length = strlen($t1); + if ($length) { + $t2 = str_pad($u[$k], $length, "\0", STR_PAD_LEFT); + $temp = $t1 ^ $t2; + $c = $j ? substr_replace($c, $temp, 0, $length) : $temp; + } + } + } + } + $c = substr($c, -$t); + if (strlen($c) == $t) { + $c[0] = $c[0] & $finalMask; + } + return ltrim($c, "\0"); + }; + + $this->instanceID = self::$instanceCounter++; + Integer::setModulo($this->instanceID, $modulo); + Integer::setRecurringModuloFunction($this->instanceID, $reduce); + + $this->randomMax = new BigInteger($modulo, 2); + } + + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @param string $num + * @return Integer + */ + public function newInteger($num) + { + return new Integer($this->instanceID, $num instanceof BigInteger ? $num->toBytes() : $num); + } + + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return Integer + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return new Integer($this->instanceID, BigInteger::randomRange($one, $this->randomMax)->toBytes()); + } + + /** + * Returns the length of the modulo in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return strlen(Integer::getModulo($this->instanceID)); + } + + /** + * Returns the length of the modulo in bits + * + * @return int + */ + public function getLength() + { + return strlen(Integer::getModulo($this->instanceID)) << 3; + } + + /** + * Converts a base-2 string to a base-256 string + * + * @param string $x + * @param int|null $size + * @return string + */ + public static function base2ToBase256($x, $size = null) + { + $str = Strings::bits2bin($x); + + $pad = strlen($x) >> 3; + if (strlen($x) & 3) { + $pad++; + } + $str = str_pad($str, $pad, "\0", STR_PAD_LEFT); + if (isset($size)) { + $str = str_pad($str, $size, "\0", STR_PAD_LEFT); + } + + return $str; + } + + /** + * Converts a base-256 string to a base-2 string + * + * @param string $x + * @return string + */ + public static function base256ToBase2($x) + { + if (function_exists('gmp_import')) { + return gmp_strval(gmp_import($x), 2); + } + + return Strings::bin2bits($x); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php new file mode 100644 index 0000000..8e88058 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php @@ -0,0 +1,516 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\BinaryField; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\BinaryField; +use phpseclib3\Math\Common\FiniteField\Integer as Base; + +/** + * Binary Finite Fields + * + * @author Jim Wigginton + */ +class Integer extends Base +{ + /** + * Holds the BinaryField's value + * + * @var string + */ + protected $value; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Holds the PrimeField's modulo + * + * @var array + */ + protected static $modulo; + + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var callable[] + */ + protected static $reduce; + + /** + * Default constructor + */ + public function __construct($instanceID, $num = '') + { + $this->instanceID = $instanceID; + if (!strlen($num)) { + $this->value = ''; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + + /** + * Set the modulo for a given instance + * @param int $instanceID + * @param string $modulo + */ + public static function setModulo($instanceID, $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + + /** + * Set the modulo for a given instance + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + } + + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + */ + private static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); + } + } + + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + + return $this->value == $x->value; + } + + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + + $a = $this->value; + $b = $x->value; + + $length = max(strlen($a), strlen($b)); + + $a = str_pad($a, $length, "\0", STR_PAD_LEFT); + $b = str_pad($b, $length, "\0", STR_PAD_LEFT); + + return strcmp($a, $b); + } + + /** + * Returns the degree of the polynomial + * + * @param string $x + * @return int + */ + private static function deg($x) + { + $x = ltrim($x, "\0"); + $xbit = decbin(ord($x[0])); + $xlen = $xbit == '0' ? 0 : strlen($xbit); + $len = strlen($x); + if (!$len) { + return -1; + } + return 8 * strlen($x) - 9 + $xlen; + } + + /** + * Perform polynomial division + * + * @return string[] + * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division + */ + private static function polynomialDivide($x, $y) + { + // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's + // always going to be 1. + + $q = chr(0); + $d = static::deg($y); + $r = $x; + while (($degr = static::deg($r)) >= $d) { + $s = '1' . str_repeat('0', $degr - $d); + $s = BinaryField::base2ToBase256($s); + $length = max(strlen($s), strlen($q)); + $q = !isset($q) ? $s : + str_pad($q, $length, "\0", STR_PAD_LEFT) ^ + str_pad($s, $length, "\0", STR_PAD_LEFT); + $s = static::polynomialMultiply($s, $y); + $length = max(strlen($r), strlen($s)); + $r = str_pad($r, $length, "\0", STR_PAD_LEFT) ^ + str_pad($s, $length, "\0", STR_PAD_LEFT); + } + + return [ltrim($q, "\0"), ltrim($r, "\0")]; + } + + /** + * Perform polynomial multiplation in the traditional way + * + * @return string + * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication + */ + private static function regularPolynomialMultiply($x, $y) + { + $precomputed = [ltrim($x, "\0")]; + $x = strrev(BinaryField::base256ToBase2($x)); + $y = strrev(BinaryField::base256ToBase2($y)); + if (strlen($x) == strlen($y)) { + $length = strlen($x); + } else { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, '0'); + $y = str_pad($y, $length, '0'); + } + $result = str_repeat('0', 2 * $length - 1); + $result = BinaryField::base2ToBase256($result); + $size = strlen($result); + $x = strrev($x); + + // precompute left shift 1 through 7 + for ($i = 1; $i < 8; $i++) { + $precomputed[$i] = BinaryField::base2ToBase256($x . str_repeat('0', $i)); + } + for ($i = 0; $i < strlen($y); $i++) { + if ($y[$i] == '1') { + $temp = $precomputed[$i & 7] . str_repeat("\0", $i >> 3); + $result ^= str_pad($temp, $size, "\0", STR_PAD_LEFT); + } + } + + return $result; + } + + /** + * Perform polynomial multiplation + * + * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications + * + * @return string + * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm + */ + private static function polynomialMultiply($x, $y) + { + if (strlen($x) == strlen($y)) { + $length = strlen($x); + } else { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + } + + switch (true) { + case PHP_INT_SIZE == 8 && $length <= 4: + return $length != 4 ? + self::subMultiply(str_pad($x, 4, "\0", STR_PAD_LEFT), str_pad($y, 4, "\0", STR_PAD_LEFT)) : + self::subMultiply($x, $y); + case PHP_INT_SIZE == 4 || $length > 32: + return self::regularPolynomialMultiply($x, $y); + } + + $m = $length >> 1; + + $x1 = substr($x, 0, -$m); + $x0 = substr($x, -$m); + $y1 = substr($y, 0, -$m); + $y0 = substr($y, -$m); + + $z2 = self::polynomialMultiply($x1, $y1); + $z0 = self::polynomialMultiply($x0, $y0); + $z1 = self::polynomialMultiply( + self::subAdd2($x1, $x0), + self::subAdd2($y1, $y0) + ); + + $z1 = self::subAdd3($z1, $z2, $z0); + + $xy = self::subAdd3( + $z2 . str_repeat("\0", 2 * $m), + $z1 . str_repeat("\0", $m), + $z0 + ); + + return ltrim($xy, "\0"); + } + + /** + * Perform polynomial multiplication on 2x 32-bit numbers, returning + * a 64-bit number + * + * @param string $x + * @param string $y + * @return string + * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm + */ + private static function subMultiply($x, $y) + { + $x = unpack('N', $x)[1]; + $y = unpack('N', $y)[1]; + + $x0 = $x & 0x11111111; + $x1 = $x & 0x22222222; + $x2 = $x & 0x44444444; + $x3 = $x & 0x88888888; + + $y0 = $y & 0x11111111; + $y1 = $y & 0x22222222; + $y2 = $y & 0x44444444; + $y3 = $y & 0x88888888; + + $z0 = ($x0 * $y0) ^ ($x1 * $y3) ^ ($x2 * $y2) ^ ($x3 * $y1); + $z1 = ($x0 * $y1) ^ ($x1 * $y0) ^ ($x2 * $y3) ^ ($x3 * $y2); + $z2 = ($x0 * $y2) ^ ($x1 * $y1) ^ ($x2 * $y0) ^ ($x3 * $y3); + $z3 = ($x0 * $y3) ^ ($x1 * $y2) ^ ($x2 * $y1) ^ ($x3 * $y0); + + $z0 &= 0x1111111111111111; + $z1 &= 0x2222222222222222; + $z2 &= 0x4444444444444444; + $z3 &= -8608480567731124088; // 0x8888888888888888 gets interpreted as a float + + $z = $z0 | $z1 | $z2 | $z3; + + return pack('J', $z); + } + + /** + * Adds two numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd2($x, $y) + { + $length = max(strlen($x), strlen($y)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + return $x ^ $y; + } + + /** + * Adds three numbers + * + * @param string $x + * @param string $y + * @return string + */ + private static function subAdd3($x, $y, $z) + { + $length = max(strlen($x), strlen($y), strlen($z)); + $x = str_pad($x, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y, $length, "\0", STR_PAD_LEFT); + $z = str_pad($z, $length, "\0", STR_PAD_LEFT); + return $x ^ $y ^ $z; + } + + /** + * Adds two BinaryFieldIntegers. + * + * @return static + */ + public function add(self $y) + { + static::checkInstance($this, $y); + + $length = strlen(static::$modulo[$this->instanceID]); + + $x = str_pad($this->value, $length, "\0", STR_PAD_LEFT); + $y = str_pad($y->value, $length, "\0", STR_PAD_LEFT); + + return new static($this->instanceID, $x ^ $y); + } + + /** + * Subtracts two BinaryFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + return $this->add($x); + } + + /** + * Multiplies two BinaryFieldIntegers. + * + * @return static + */ + public function multiply(self $y) + { + static::checkInstance($this, $y); + + return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); + } + + /** + * Returns the modular inverse of a BinaryFieldInteger + * + * @return static + */ + public function modInverse() + { + $remainder0 = static::$modulo[$this->instanceID]; + $remainder1 = $this->value; + + if ($remainder1 == '') { + return new static($this->instanceID); + } + + $aux0 = "\0"; + $aux1 = "\1"; + while ($remainder1 != "\1") { + list($q, $r) = static::polynomialDivide($remainder0, $remainder1); + $remainder0 = $remainder1; + $remainder1 = $r; + // the auxiliary in row n is given by the sum of the auxiliary in + // row n-2 and the product of the quotient and the auxiliary in row + // n-1 + $temp = static::polynomialMultiply($aux1, $q); + $aux = str_pad($aux0, strlen($temp), "\0", STR_PAD_LEFT) ^ + str_pad($temp, strlen($aux0), "\0", STR_PAD_LEFT); + $aux0 = $aux1; + $aux1 = $aux; + } + + $temp = new static($this->instanceID); + $temp->value = ltrim($aux1, "\0"); + return $temp; + } + + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + + $x = $x->modInverse(); + return $this->multiply($x); + } + + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return object + */ + public function negate() + { + $x = str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); + + return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); + } + + /** + * Returns the modulo + * + * @return string + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + return str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return Strings::bin2hex($this->toBytes()); + } + + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); + return BinaryField::base256ToBase2($this->value); + } + + /** + * Converts an Integer to a BigInteger + * + * @return string + */ + public function toBigInteger() + { + return new BigInteger($this->value, 256); + } + + /** + * __toString() magic method + * + */ + public function __toString() + { + return (string) $this->toBigInteger(); + } + + /** + * __debugInfo() magic method + * + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php new file mode 100644 index 0000000..2ea5f48 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php @@ -0,0 +1,22 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\Common; + +/** + * Finite Fields + * + * @author Jim Wigginton + */ +abstract class FiniteField +{ +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php new file mode 100644 index 0000000..3c959e9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php @@ -0,0 +1,44 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\Common\FiniteField; + +/** + * Finite Field Integer + * + * @author Jim Wigginton + */ +abstract class Integer implements \JsonSerializable +{ + /** + * JSON Serialize + * + * Will be called, automatically, when json_encode() is called on a BigInteger object. + * + * PHP Serialize isn't supported because unserializing would require the factory be + * serialized as well and that just sounds like too much + * + * @return array{hex: string} + */ + #[\ReturnTypeWillChange] + public function jsonSerialize() + { + return ['hex' => $this->toHex(true)]; + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + abstract public function toHex(); +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php new file mode 100644 index 0000000..1a0667f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php @@ -0,0 +1,118 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://pear.php.net/package/Math_BigInteger + */ + +namespace phpseclib3\Math; + +use phpseclib3\Math\Common\FiniteField; +use phpseclib3\Math\PrimeField\Integer; + +/** + * Prime Finite Fields + * + * @author Jim Wigginton + */ +class PrimeField extends FiniteField +{ + /** + * Instance Counter + * + * @var int + */ + private static $instanceCounter = 0; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Default constructor + */ + public function __construct(BigInteger $modulo) + { + if (!$modulo->isPrime()) { + throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); + } + + $this->instanceID = self::$instanceCounter++; + Integer::setModulo($this->instanceID, $modulo); + Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); + } + + /** + * Use a custom defined modular reduction function + * + * @return void + */ + public function setReduction(\Closure $func) + { + $this->reduce = $func->bindTo($this, $this); + } + + /** + * Returns an instance of a dynamically generated PrimeFieldInteger class + * + * @return Integer + */ + public function newInteger(BigInteger $num) + { + return new Integer($this->instanceID, $num); + } + + /** + * Returns an integer on the finite field between one and the prime modulo + * + * @return Integer + */ + public function randomInteger() + { + static $one; + if (!isset($one)) { + $one = new BigInteger(1); + } + + return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); + } + + /** + * Returns the length of the modulo in bytes + * + * @return int + */ + public function getLengthInBytes() + { + return Integer::getModulo($this->instanceID)->getLengthInBytes(); + } + + /** + * Returns the length of the modulo in bits + * + * @return int + */ + public function getLength() + { + return Integer::getModulo($this->instanceID)->getLength(); + } + + /** + * Destructor + */ + public function __destruct() + { + Integer::cleanupCache($this->instanceID); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php new file mode 100644 index 0000000..1bd7aaf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php @@ -0,0 +1,419 @@ + + * @copyright 2017 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + */ + +namespace phpseclib3\Math\PrimeField; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Math\BigInteger; +use phpseclib3\Math\Common\FiniteField\Integer as Base; + +/** + * Prime Finite Fields + * + * @author Jim Wigginton + */ +class Integer extends Base +{ + /** + * Holds the PrimeField's value + * + * @var BigInteger + */ + protected $value; + + /** + * Keeps track of current instance + * + * @var int + */ + protected $instanceID; + + /** + * Holds the PrimeField's modulo + * + * @var array + */ + protected static $modulo; + + /** + * Holds a pre-generated function to perform modulo reductions + * + * @var array + */ + protected static $reduce; + + /** + * Zero + * + * @var BigInteger + */ + protected static $zero; + + /** + * Default constructor + * + * @param int $instanceID + */ + public function __construct($instanceID, BigInteger $num = null) + { + $this->instanceID = $instanceID; + if (!isset($num)) { + $this->value = clone static::$zero[static::class]; + } else { + $reduce = static::$reduce[$instanceID]; + $this->value = $reduce($num); + } + } + + /** + * Set the modulo for a given instance + * + * @param int $instanceID + * @return void + */ + public static function setModulo($instanceID, BigInteger $modulo) + { + static::$modulo[$instanceID] = $modulo; + } + + /** + * Set the modulo for a given instance + * + * @param int $instanceID + * @return void + */ + public static function setRecurringModuloFunction($instanceID, callable $function) + { + static::$reduce[$instanceID] = $function; + if (!isset(static::$zero[static::class])) { + static::$zero[static::class] = new BigInteger(); + } + } + + /** + * Delete the modulo for a given instance + */ + public static function cleanupCache($instanceID) + { + unset(static::$modulo[$instanceID]); + unset(static::$reduce[$instanceID]); + } + + /** + * Returns the modulo + * + * @param int $instanceID + * @return BigInteger + */ + public static function getModulo($instanceID) + { + return static::$modulo[$instanceID]; + } + + /** + * Tests a parameter to see if it's of the right instance + * + * Throws an exception if the incorrect class is being utilized + * + * @return void + */ + public static function checkInstance(self $x, self $y) + { + if ($x->instanceID != $y->instanceID) { + throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); + } + } + + /** + * Tests the equality of two numbers. + * + * @return bool + */ + public function equals(self $x) + { + static::checkInstance($this, $x); + + return $this->value->equals($x->value); + } + + /** + * Compares two numbers. + * + * @return int + */ + public function compare(self $x) + { + static::checkInstance($this, $x); + + return $this->value->compare($x->value); + } + + /** + * Adds two PrimeFieldIntegers. + * + * @return static + */ + public function add(self $x) + { + static::checkInstance($this, $x); + + $temp = new static($this->instanceID); + $temp->value = $this->value->add($x->value); + if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { + $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); + } + + return $temp; + } + + /** + * Subtracts two PrimeFieldIntegers. + * + * @return static + */ + public function subtract(self $x) + { + static::checkInstance($this, $x); + + $temp = new static($this->instanceID); + $temp->value = $this->value->subtract($x->value); + if ($temp->value->isNegative()) { + $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); + } + + return $temp; + } + + /** + * Multiplies two PrimeFieldIntegers. + * + * @return static + */ + public function multiply(self $x) + { + static::checkInstance($this, $x); + + return new static($this->instanceID, $this->value->multiply($x->value)); + } + + /** + * Divides two PrimeFieldIntegers. + * + * @return static + */ + public function divide(self $x) + { + static::checkInstance($this, $x); + + $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); + return new static($this->instanceID, $this->value->multiply($denominator)); + } + + /** + * Performs power operation on a PrimeFieldInteger. + * + * @return static + */ + public function pow(BigInteger $x) + { + $temp = new static($this->instanceID); + $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); + + return $temp; + } + + /** + * Calculates the square root + * + * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm + * @return static|false + */ + public function squareRoot() + { + static $one, $two; + if (!isset($one)) { + $one = new BigInteger(1); + $two = new BigInteger(2); + } + $reduce = static::$reduce[$this->instanceID]; + $p_1 = static::$modulo[$this->instanceID]->subtract($one); + $q = clone $p_1; + $s = BigInteger::scan1divide($q); + list($pow) = $p_1->divide($two); + for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) { + $temp = $z->powMod($pow, static::$modulo[$this->instanceID]); + if ($temp->equals($p_1)) { + break; + } + } + + $m = new BigInteger($s); + $c = $z->powMod($q, static::$modulo[$this->instanceID]); + $t = $this->value->powMod($q, static::$modulo[$this->instanceID]); + list($temp) = $q->add($one)->divide($two); + $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); + + while (!$t->equals($one)) { + for ($i = clone $one; $i->compare($m) < 0; $i = $i->add($one)) { + if ($t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { + break; + } + } + + if ($i->compare($m) == 0) { + return false; + } + $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]); + $m = $i; + $c = $reduce($b->multiply($b)); + $t = $reduce($t->multiply($c)); + $r = $reduce($r->multiply($b)); + } + + return new static($this->instanceID, $r); + } + + /** + * Is Odd? + * + * @return bool + */ + public function isOdd() + { + return $this->value->isOdd(); + } + + /** + * Negate + * + * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo + * so 0-12 is the same thing as modulo-12 + * + * @return static + */ + public function negate() + { + return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); + } + + /** + * Converts an Integer to a byte string (eg. base-256). + * + * @return string + */ + public function toBytes() + { + if (isset(static::$modulo[$this->instanceID])) { + $length = static::$modulo[$this->instanceID]->getLengthInBytes(); + return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); + } + return $this->value->toBytes(); + } + + /** + * Converts an Integer to a hex string (eg. base-16). + * + * @return string + */ + public function toHex() + { + return Strings::bin2hex($this->toBytes()); + } + + /** + * Converts an Integer to a bit string (eg. base-2). + * + * @return string + */ + public function toBits() + { + // return $this->value->toBits(); + static $length; + if (!isset($length)) { + $length = static::$modulo[$this->instanceID]->getLength(); + } + + return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT); + } + + /** + * Returns the w-ary non-adjacent form (wNAF) + * + * @param int $w optional + * @return array + */ + public function getNAF($w = 1) + { + $w++; + + $mask = new BigInteger((1 << $w) - 1); + $sub = new BigInteger(1 << $w); + //$sub = new BigInteger(1 << ($w - 1)); + $d = $this->toBigInteger(); + $d_i = []; + + $i = 0; + while ($d->compare(static::$zero[static::class]) > 0) { + if ($d->isOdd()) { + // start mods + + $bigInteger = $d->testBit($w - 1) ? + $d->bitwise_and($mask)->subtract($sub) : + //$sub->subtract($d->bitwise_and($mask)) : + $d->bitwise_and($mask); + // end mods + $d = $d->subtract($bigInteger); + $d_i[$i] = (int) $bigInteger->toString(); + } else { + $d_i[$i] = 0; + } + $shift = !$d->equals(static::$zero[static::class]) && $d->bitwise_and($mask)->equals(static::$zero[static::class]) ? $w : 1; // $w or $w + 1? + $d = $d->bitwise_rightShift($shift); + while (--$shift > 0) { + $d_i[++$i] = 0; + } + $i++; + } + + return $d_i; + } + + /** + * Converts an Integer to a BigInteger + * + * @return BigInteger + */ + public function toBigInteger() + { + return clone $this->value; + } + + /** + * __toString() magic method + * + * @return string + */ + public function __toString() + { + return (string) $this->value; + } + + /** + * __debugInfo() magic method + * + * @return array + */ + public function __debugInfo() + { + return ['value' => $this->toHex()]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php new file mode 100644 index 0000000..45f748d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php @@ -0,0 +1,3547 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $sftp->pwd() . "\r\n"; + * $sftp->put('filename.ext', 'hello, world!'); + * print_r($sftp->nlist()); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Exception\FileNotFoundException; + +/** + * Pure-PHP implementations of SFTP. + * + * @author Jim Wigginton + */ +class SFTP extends SSH2 +{ + /** + * SFTP channel constant + * + * \phpseclib3\Net\SSH2::exec() uses 0 and \phpseclib3\Net\SSH2::read() / \phpseclib3\Net\SSH2::write() use 1. + * + * @see \phpseclib3\Net\SSH2::send_channel_packet() + * @see \phpseclib3\Net\SSH2::get_channel_packet() + */ + const CHANNEL = 0x100; + + /** + * Reads data from a local file. + * + * @see \phpseclib3\Net\SFTP::put() + */ + const SOURCE_LOCAL_FILE = 1; + /** + * Reads data from a string. + * + * @see \phpseclib3\Net\SFTP::put() + */ + // this value isn't really used anymore but i'm keeping it reserved for historical reasons + const SOURCE_STRING = 2; + /** + * Reads data from callback: + * function callback($length) returns string to proceed, null for EOF + * + * @see \phpseclib3\Net\SFTP::put() + */ + const SOURCE_CALLBACK = 16; + /** + * Resumes an upload + * + * @see \phpseclib3\Net\SFTP::put() + */ + const RESUME = 4; + /** + * Append a local file to an already existing remote file + * + * @see \phpseclib3\Net\SFTP::put() + */ + const RESUME_START = 8; + + /** + * Packet Types + * + * @see self::__construct() + * @var array + * @access private + */ + private static $packet_types = []; + + /** + * Status Codes + * + * @see self::__construct() + * @var array + * @access private + */ + private static $status_codes = []; + + /** @var array */ + private static $attributes; + + /** @var array */ + private static $open_flags; + + /** @var array */ + private static $open_flags5; + + /** @var array */ + private static $file_types; + + /** + * The Request ID + * + * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support + * concurrent actions, so it's somewhat academic, here. + * + * @var boolean + * @see self::_send_sftp_packet() + */ + private $use_request_id = false; + + /** + * The Packet Type + * + * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support + * concurrent actions, so it's somewhat academic, here. + * + * @var int + * @see self::_get_sftp_packet() + */ + private $packet_type = -1; + + /** + * Packet Buffer + * + * @var string + * @see self::_get_sftp_packet() + */ + private $packet_buffer = ''; + + /** + * Extensions supported by the server + * + * @var array + * @see self::_initChannel() + */ + private $extensions = []; + + /** + * Server SFTP version + * + * @var int + * @see self::_initChannel() + */ + private $version; + + /** + * Default Server SFTP version + * + * @var int + * @see self::_initChannel() + */ + private $defaultVersion; + + /** + * Preferred SFTP version + * + * @var int + * @see self::_initChannel() + */ + private $preferredVersion = 3; + + /** + * Current working directory + * + * @var string|bool + * @see self::realpath() + * @see self::chdir() + */ + private $pwd = false; + + /** + * Packet Type Log + * + * @see self::getLog() + * @var array + */ + private $packet_type_log = []; + + /** + * Packet Log + * + * @see self::getLog() + * @var array + */ + private $packet_log = []; + + /** + * Real-time log file pointer + * + * @see self::_append_log() + * @var resource|closed-resource + */ + private $realtime_log_file; + + /** + * Real-time log file size + * + * @see self::_append_log() + * @var int + */ + private $realtime_log_size; + + /** + * Real-time log file wrap boolean + * + * @see self::_append_log() + * @var bool + */ + private $realtime_log_wrap; + + /** + * Current log size + * + * Should never exceed self::LOG_MAX_SIZE + * + * @var int + */ + private $log_size; + + /** + * Error information + * + * @see self::getSFTPErrors() + * @see self::getLastSFTPError() + * @var array + */ + private $sftp_errors = []; + + /** + * Stat Cache + * + * Rather than always having to open a directory and close it immediately there after to see if a file is a directory + * we'll cache the results. + * + * @see self::_update_stat_cache() + * @see self::_remove_from_stat_cache() + * @see self::_query_stat_cache() + * @var array + */ + private $stat_cache = []; + + /** + * Max SFTP Packet Size + * + * @see self::__construct() + * @see self::get() + * @var int + */ + private $max_sftp_packet; + + /** + * Stat Cache Flag + * + * @see self::disableStatCache() + * @see self::enableStatCache() + * @var bool + */ + private $use_stat_cache = true; + + /** + * Sort Options + * + * @see self::_comparator() + * @see self::setListOrder() + * @var array + */ + protected $sortOptions = []; + + /** + * Canonicalization Flag + * + * Determines whether or not paths should be canonicalized before being + * passed on to the remote server. + * + * @see self::enablePathCanonicalization() + * @see self::disablePathCanonicalization() + * @see self::realpath() + * @var bool + */ + private $canonicalize_paths = true; + + /** + * Request Buffers + * + * @see self::_get_sftp_packet() + * @var array + */ + private $requestBuffer = []; + + /** + * Preserve timestamps on file downloads / uploads + * + * @see self::get() + * @see self::put() + * @var bool + */ + private $preserveTime = false; + + /** + * Arbitrary Length Packets Flag + * + * Determines whether or not packets of any length should be allowed, + * in cases where the server chooses the packet length (such as + * directory listings). By default, packets are only allowed to be + * 256 * 1024 bytes (SFTP_MAX_MSG_LENGTH from OpenSSH's sftp-common.h) + * + * @see self::enableArbitraryLengthPackets() + * @see self::_get_sftp_packet() + * @var bool + */ + private $allow_arbitrary_length_packets = false; + + /** + * Was the last packet due to the channels being closed or not? + * + * @see self::get() + * @see self::get_sftp_packet() + * @var bool + */ + private $channel_close = false; + + /** + * Has the SFTP channel been partially negotiated? + * + * @var bool + */ + private $partial_init = false; + + /** + * Default Constructor. + * + * Connects to an SFTP server + * + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host + * @param int $port + * @param int $timeout + */ + public function __construct($host, $port = 22, $timeout = 10) + { + parent::__construct($host, $port, $timeout); + + $this->max_sftp_packet = 1 << 15; + + if (empty(self::$packet_types)) { + self::$packet_types = [ + 1 => 'NET_SFTP_INIT', + 2 => 'NET_SFTP_VERSION', + 3 => 'NET_SFTP_OPEN', + 4 => 'NET_SFTP_CLOSE', + 5 => 'NET_SFTP_READ', + 6 => 'NET_SFTP_WRITE', + 7 => 'NET_SFTP_LSTAT', + 9 => 'NET_SFTP_SETSTAT', + 10 => 'NET_SFTP_FSETSTAT', + 11 => 'NET_SFTP_OPENDIR', + 12 => 'NET_SFTP_READDIR', + 13 => 'NET_SFTP_REMOVE', + 14 => 'NET_SFTP_MKDIR', + 15 => 'NET_SFTP_RMDIR', + 16 => 'NET_SFTP_REALPATH', + 17 => 'NET_SFTP_STAT', + 18 => 'NET_SFTP_RENAME', + 19 => 'NET_SFTP_READLINK', + 20 => 'NET_SFTP_SYMLINK', + 21 => 'NET_SFTP_LINK', + + 101 => 'NET_SFTP_STATUS', + 102 => 'NET_SFTP_HANDLE', + 103 => 'NET_SFTP_DATA', + 104 => 'NET_SFTP_NAME', + 105 => 'NET_SFTP_ATTRS', + + 200 => 'NET_SFTP_EXTENDED' + ]; + self::$status_codes = [ + 0 => 'NET_SFTP_STATUS_OK', + 1 => 'NET_SFTP_STATUS_EOF', + 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', + 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', + 4 => 'NET_SFTP_STATUS_FAILURE', + 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', + 6 => 'NET_SFTP_STATUS_NO_CONNECTION', + 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', + 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', + 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', + 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', + 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', + 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', + 13 => 'NET_SFTP_STATUS_NO_MEDIA', + 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', + 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', + 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', + 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', + 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', + 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', + 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', + 21 => 'NET_SFTP_STATUS_LINK_LOOP', + 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', + 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', + 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', + 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', + 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', + 27 => 'NET_SFTP_STATUS_DELETE_PENDING', + 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', + 29 => 'NET_SFTP_STATUS_OWNER_INVALID', + 30 => 'NET_SFTP_STATUS_GROUP_INVALID', + 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 + // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why + self::$attributes = [ + 0x00000001 => 'NET_SFTP_ATTR_SIZE', + 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ + 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ + 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', + 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', + 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ + 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', + 0x00000040 => 'NET_SFTP_ATTR_ACL', + 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', + 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ + 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ + 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', + 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', + 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', + 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', + 0x00008000 => 'NET_SFTP_ATTR_CTIME', + // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers + // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in + // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. + // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. + (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED' + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 + // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name + // the array for that $this->open5_flags and similarly alter the constant names. + self::$open_flags = [ + 0x00000001 => 'NET_SFTP_OPEN_READ', + 0x00000002 => 'NET_SFTP_OPEN_WRITE', + 0x00000004 => 'NET_SFTP_OPEN_APPEND', + 0x00000008 => 'NET_SFTP_OPEN_CREATE', + 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', + 0x00000020 => 'NET_SFTP_OPEN_EXCL', + 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 + ]; + // SFTPv5+ changed the flags up: + // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 + self::$open_flags5 = [ + // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened + 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', + 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', + 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', + 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', + 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', + // the rest of the flags are not supported + 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" + 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', + 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', + 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', + 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', + 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', + 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', + 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', + 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', + 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', + 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', + 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', + 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', + ]; + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 + // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation + self::$file_types = [ + 1 => 'NET_SFTP_TYPE_REGULAR', + 2 => 'NET_SFTP_TYPE_DIRECTORY', + 3 => 'NET_SFTP_TYPE_SYMLINK', + 4 => 'NET_SFTP_TYPE_SPECIAL', + 5 => 'NET_SFTP_TYPE_UNKNOWN', + // the following types were first defined for use in SFTPv5+ + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 + 6 => 'NET_SFTP_TYPE_SOCKET', + 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', + 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', + 9 => 'NET_SFTP_TYPE_FIFO' + ]; + self::define_array( + self::$packet_types, + self::$status_codes, + self::$attributes, + self::$open_flags, + self::$open_flags5, + self::$file_types + ); + } + + if (!defined('NET_SFTP_QUEUE_SIZE')) { + define('NET_SFTP_QUEUE_SIZE', 32); + } + if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) { + define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024); + } + } + + /** + * Check a few things before SFTP functions are called + * + * @return bool + */ + private function precheck() + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + if ($this->pwd === false) { + return $this->init_sftp_connection(); + } + + return true; + } + + /** + * Partially initialize an SFTP connection + * + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + */ + private function partial_init_sftp_connection() + { + $response = $this->openChannel(self::CHANNEL, true); + if ($response === true && $this->isTimeout()) { + return false; + } + + $packet = Strings::packSSH2( + 'CNsbs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL], + 'subsystem', + true, + 'sftp' + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL, true); + if ($response === false) { + // from PuTTY's psftp.exe + $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . + "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" . + "exec sftp-server"; + // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does + // is redundant + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL], + 'exec', + 1, + $command + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $response = $this->get_channel_packet(self::CHANNEL, true); + if ($response === false) { + return false; + } + } elseif ($response === true && $this->isTimeout()) { + return false; + } + + $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; + $this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3"); + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_VERSION) { + throw new \UnexpectedValueException('Expected NET_SFTP_VERSION. ' + . 'Got packet type: ' . $this->packet_type); + } + + $this->use_request_id = true; + + list($this->defaultVersion) = Strings::unpackSSH2('N', $response); + while (!empty($response)) { + list($key, $value) = Strings::unpackSSH2('ss', $response); + $this->extensions[$key] = $value; + } + + $this->partial_init = true; + + return true; + } + + /** + * (Re)initializes the SFTP channel + * + * @return bool + */ + private function init_sftp_connection() + { + if (!$this->partial_init && !$this->partial_init_sftp_connection()) { + return false; + } + + /* + A Note on SFTPv4/5/6 support: + states the following: + + "If the client wishes to interoperate with servers that support noncontiguous version + numbers it SHOULD send '3'" + + Given that the server only sends its version number after the client has already done so, the above + seems to be suggesting that v3 should be the default version. This makes sense given that v3 is the + most popular. + + states the following; + + "If the server did not send the "versions" extension, or the version-from-list was not included, the + server MAY send a status response describing the failure, but MUST then close the channel without + processing any further requests." + + So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and + a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements + v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed + in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the + channel and reopen it with a new and updated SSH_FXP_INIT packet. + */ + $this->version = $this->defaultVersion; + if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) { + $versions = explode(',', $this->extensions['versions']); + $supported = [6, 5, 4]; + if ($this->preferredVersion) { + $supported = array_diff($supported, [$this->preferredVersion]); + array_unshift($supported, $this->preferredVersion); + } + foreach ($supported as $ver) { + if (in_array($ver, $versions)) { + if ($ver === $this->version) { + break; + } + $this->version = (int) $ver; + $packet = Strings::packSSH2('ss', 'version-select', "$ver"); + $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS_OK. ' + . ' Got ' . $status); + } + break; + } + } + } + + /* + SFTPv4+ defines a 'newline' extension. SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com', + however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's + not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for + one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that + 'newline@vandyke.com' would. + */ + /* + if (isset($this->extensions['newline@vandyke.com'])) { + $this->extensions['newline'] = $this->extensions['newline@vandyke.com']; + unset($this->extensions['newline@vandyke.com']); + } + */ + if ($this->version < 2 || $this->version > 6) { + return false; + } + + $this->pwd = true; + try { + $this->pwd = $this->realpath('.'); + } catch (\UnexpectedValueException $e) { + if (!$this->canonicalize_paths) { + throw $e; + } + $this->canonicalize_paths = false; + $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); + } + + $this->update_stat_cache($this->pwd, []); + + return true; + } + + /** + * Disable the stat cache + * + */ + public function disableStatCache() + { + $this->use_stat_cache = false; + } + + /** + * Enable the stat cache + * + */ + public function enableStatCache() + { + $this->use_stat_cache = true; + } + + /** + * Clear the stat cache + * + */ + public function clearStatCache() + { + $this->stat_cache = []; + } + + /** + * Enable path canonicalization + * + */ + public function enablePathCanonicalization() + { + $this->canonicalize_paths = true; + } + + /** + * Disable path canonicalization + * + * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path + * + */ + public function disablePathCanonicalization() + { + $this->canonicalize_paths = false; + } + + /** + * Enable arbitrary length packets + * + */ + public function enableArbitraryLengthPackets() + { + $this->allow_arbitrary_length_packets = true; + } + + /** + * Disable arbitrary length packets + * + */ + public function disableArbitraryLengthPackets() + { + $this->allow_arbitrary_length_packets = false; + } + + /** + * Returns the current directory name + * + * @return string|bool + */ + public function pwd() + { + if (!$this->precheck()) { + return false; + } + + return $this->pwd; + } + + /** + * Logs errors + * + * @param string $response + * @param int $status + */ + private function logError($response, $status = -1) + { + if ($status == -1) { + list($status) = Strings::unpackSSH2('N', $response); + } + + $error = self::$status_codes[$status]; + + if ($this->version > 2) { + list($message) = Strings::unpackSSH2('s', $response); + $this->sftp_errors[] = "$error: $message"; + } else { + $this->sftp_errors[] = $error; + } + } + + /** + * Canonicalize the Server-Side Path Name + * + * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns + * the absolute (canonicalized) path. + * + * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is. + * + * @see self::chdir() + * @see self::disablePathCanonicalization() + * @param string $path + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + */ + public function realpath($path) + { + if ($this->precheck() === false) { + return false; + } + + if (!$this->canonicalize_paths) { + if ($this->pwd === true) { + return '.'; + } + if (!strlen($path) || $path[0] != '/') { + $path = $this->pwd . '/' . $path; + } + $parts = explode('/', $path); + $afterPWD = $beforePWD = []; + foreach ($parts as $part) { + switch ($part) { + //case '': // some SFTP servers /require/ double /'s. see https://github.com/phpseclib/phpseclib/pull/1137 + case '.': + break; + case '..': + if (!empty($afterPWD)) { + array_pop($afterPWD); + } else { + $beforePWD[] = '..'; + } + break; + default: + $afterPWD[] = $part; + } + } + $beforePWD = count($beforePWD) ? implode('/', $beforePWD) : '.'; + return $beforePWD . '/' . implode('/', $afterPWD); + } + + if ($this->pwd === true) { + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 + $this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path)); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_NAME: + // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following + // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks + // at is the first part and that part is defined the same in SFTP versions 3 through 6. + list(, $filename) = Strings::unpackSSH2('Ns', $response); + return $filename; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + if (!strlen($path) || $path[0] != '/') { + $path = $this->pwd . '/' . $path; + } + + $path = explode('/', $path); + $new = []; + foreach ($path as $dir) { + if (!strlen($dir)) { + continue; + } + switch ($dir) { + case '..': + array_pop($new); + // fall-through + case '.': + break; + default: + $new[] = $dir; + } + } + + return '/' . implode('/', $new); + } + + /** + * Changes the current directory + * + * @param string $dir + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + */ + public function chdir($dir) + { + if (!$this->precheck()) { + return false; + } + + // assume current dir if $dir is empty + if ($dir === '') { + $dir = './'; + // suffix a slash if needed + } elseif ($dir[strlen($dir) - 1] != '/') { + $dir .= '/'; + } + + $dir = $this->realpath($dir); + + // confirm that $dir is, in fact, a valid directory + if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) { + $this->pwd = $dir; + return true; + } + + // we could do a stat on the alleged $dir to see if it's a directory but that doesn't tell us + // the currently logged in user has the appropriate permissions or not. maybe you could see if + // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy + // way to get those with SFTP + + $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); + + // see \phpseclib3\Net\SFTP::nlist() for a more thorough explanation of the following + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS' . + 'Got packet type: ' . $this->packet_type); + } + + if (!$this->close_handle($handle)) { + return false; + } + + $this->update_stat_cache($dir, []); + + $this->pwd = $dir; + return true; + } + + /** + * Returns a list of files in the given directory + * + * @param string $dir + * @param bool $recursive + * @return array|false + */ + public function nlist($dir = '.', $recursive = false) + { + return $this->nlist_helper($dir, $recursive, ''); + } + + /** + * Helper method for nlist + * + * @param string $dir + * @param bool $recursive + * @param string $relativeDir + * @return array|false + */ + private function nlist_helper($dir, $recursive, $relativeDir) + { + $files = $this->readlist($dir, false); + + // If we get an int back, then that is an "unexpected" status. + // We do not have a file list, so return false. + if (is_int($files)) { + return false; + } + + if (!$recursive || $files === false) { + return $files; + } + + $result = []; + foreach ($files as $value) { + if ($value == '.' || $value == '..') { + $result[] = $relativeDir . $value; + continue; + } + if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) { + $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); + $temp = is_array($temp) ? $temp : []; + $result = array_merge($result, $temp); + } else { + $result[] = $relativeDir . $value; + } + } + + return $result; + } + + /** + * Returns a detailed list of files in the given directory + * + * @param string $dir + * @param bool $recursive + * @return array|false + */ + public function rawlist($dir = '.', $recursive = false) + { + $files = $this->readlist($dir, true); + + // If we get an int back, then that is an "unexpected" status. + // We do not have a file list, so return false. + if (is_int($files)) { + return false; + } + + if (!$recursive || $files === false) { + return $files; + } + + static $depth = 0; + + foreach ($files as $key => $value) { + if ($depth != 0 && $key == '..') { + unset($files[$key]); + continue; + } + $is_directory = false; + if ($key != '.' && $key != '..') { + if ($this->use_stat_cache) { + $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key))); + } else { + $stat = $this->lstat($dir . '/' . $key); + $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY; + } + } + + if ($is_directory) { + $depth++; + $files[$key] = $this->rawlist($dir . '/' . $key, true); + $depth--; + } else { + $files[$key] = (object) $value; + } + } + + return $files; + } + + /** + * Reads a list, be it detailed or not, of files in the given directory + * + * @param string $dir + * @param bool $raw + * @return array|false + * @throws \UnexpectedValueException on receipt of unexpected packets + */ + private function readlist($dir, $raw = true) + { + if (!$this->precheck()) { + return false; + } + + $dir = $this->realpath($dir . '/'); + if ($dir === false) { + return false; + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2 + $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2 + // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that + // represent the length of the string and leave it at that + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: + // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + list($status) = Strings::unpackSSH2('N', $response); + $this->logError($response, $status); + return $status; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + $this->update_stat_cache($dir, []); + + $contents = []; + while (true) { + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2 + // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many + // SSH_MSG_CHANNEL_DATA messages is not known to me. + $this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle)); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_NAME: + list($count) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $count; $i++) { + list($shortname) = Strings::unpackSSH2('s', $response); + // SFTPv4 "removed the long filename from the names structure-- it can now be + // built from information available in the attrs structure." + if ($this->version < 4) { + list($longname) = Strings::unpackSSH2('s', $response); + } + $attributes = $this->parseAttributes($response); + if (!isset($attributes['type']) && $this->version < 4) { + $fileType = $this->parseLongname($longname); + if ($fileType) { + $attributes['type'] = $fileType; + } + } + $contents[$shortname] = $attributes + ['filename' => $shortname]; + + if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) { + $this->update_stat_cache($dir . '/' . $shortname, []); + } else { + if ($shortname == '..') { + $temp = $this->realpath($dir . '/..') . '/.'; + } else { + $temp = $dir . '/' . $shortname; + } + $this->update_stat_cache($temp, (object) ['lstat' => $attributes]); + } + // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the + // final SSH_FXP_STATUS packet should tell us that, already. + } + break; + case NET_SFTP_STATUS: + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_EOF) { + $this->logError($response, $status); + return $status; + } + break 2; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + if (!$this->close_handle($handle)) { + return false; + } + + if (count($this->sortOptions)) { + uasort($contents, [&$this, 'comparator']); + } + + return $raw ? $contents : array_map('strval', array_keys($contents)); + } + + /** + * Compares two rawlist entries using parameters set by setListOrder() + * + * Intended for use with uasort() + * + * @param array $a + * @param array $b + * @return int + */ + private function comparator(array $a, array $b) + { + switch (true) { + case $a['filename'] === '.' || $b['filename'] === '.': + if ($a['filename'] === $b['filename']) { + return 0; + } + return $a['filename'] === '.' ? -1 : 1; + case $a['filename'] === '..' || $b['filename'] === '..': + if ($a['filename'] === $b['filename']) { + return 0; + } + return $a['filename'] === '..' ? -1 : 1; + case isset($a['type']) && $a['type'] === NET_SFTP_TYPE_DIRECTORY: + if (!isset($b['type'])) { + return 1; + } + if ($b['type'] !== $a['type']) { + return -1; + } + break; + case isset($b['type']) && $b['type'] === NET_SFTP_TYPE_DIRECTORY: + return 1; + } + foreach ($this->sortOptions as $sort => $order) { + if (!isset($a[$sort]) || !isset($b[$sort])) { + if (isset($a[$sort])) { + return -1; + } + if (isset($b[$sort])) { + return 1; + } + return 0; + } + switch ($sort) { + case 'filename': + $result = strcasecmp($a['filename'], $b['filename']); + if ($result) { + return $order === SORT_DESC ? -$result : $result; + } + break; + case 'mode': + $a[$sort] &= 07777; + $b[$sort] &= 07777; + // fall-through + default: + if ($a[$sort] === $b[$sort]) { + break; + } + return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort]; + } + } + } + + /** + * Defines how nlist() and rawlist() will be sorted - if at all. + * + * If sorting is enabled directories and files will be sorted independently with + * directories appearing before files in the resultant array that is returned. + * + * Any parameter returned by stat is a valid sort parameter for this function. + * Filename comparisons are case insensitive. + * + * Examples: + * + * $sftp->setListOrder('filename', SORT_ASC); + * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC); + * $sftp->setListOrder(true); + * Separates directories from files but doesn't do any sorting beyond that + * $sftp->setListOrder(); + * Don't do any sort of sorting + * + * @param string ...$args + */ + public function setListOrder(...$args) + { + $this->sortOptions = []; + if (empty($args)) { + return; + } + $len = count($args) & 0x7FFFFFFE; + for ($i = 0; $i < $len; $i += 2) { + $this->sortOptions[$args[$i]] = $args[$i + 1]; + } + if (!count($this->sortOptions)) { + $this->sortOptions = ['bogus' => true]; + } + } + + /** + * Save files / directories to cache + * + * @param string $path + * @param mixed $value + */ + private function update_stat_cache($path, $value) + { + if ($this->use_stat_cache === false) { + return; + } + + // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/')) + $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); + + $temp = &$this->stat_cache; + $max = count($dirs) - 1; + foreach ($dirs as $i => $dir) { + // if $temp is an object that means one of two things. + // 1. a file was deleted and changed to a directory behind phpseclib's back + // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to + if (is_object($temp)) { + $temp = []; + } + if (!isset($temp[$dir])) { + $temp[$dir] = []; + } + if ($i === $max) { + if (is_object($temp[$dir]) && is_object($value)) { + if (!isset($value->stat) && isset($temp[$dir]->stat)) { + $value->stat = $temp[$dir]->stat; + } + if (!isset($value->lstat) && isset($temp[$dir]->lstat)) { + $value->lstat = $temp[$dir]->lstat; + } + } + $temp[$dir] = $value; + break; + } + $temp = &$temp[$dir]; + } + } + + /** + * Remove files / directories from cache + * + * @param string $path + * @return bool + */ + private function remove_from_stat_cache($path) + { + $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); + + $temp = &$this->stat_cache; + $max = count($dirs) - 1; + foreach ($dirs as $i => $dir) { + if (!is_array($temp)) { + return false; + } + if ($i === $max) { + unset($temp[$dir]); + return true; + } + if (!isset($temp[$dir])) { + return false; + } + $temp = &$temp[$dir]; + } + } + + /** + * Checks cache for path + * + * Mainly used by file_exists + * + * @param string $path + * @return mixed + */ + private function query_stat_cache($path) + { + $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); + + $temp = &$this->stat_cache; + foreach ($dirs as $dir) { + if (!is_array($temp)) { + return null; + } + if (!isset($temp[$dir])) { + return null; + } + $temp = &$temp[$dir]; + } + return $temp; + } + + /** + * Returns general information about a file. + * + * Returns an array on success and false otherwise. + * + * @param string $filename + * @return array|false + */ + public function stat($filename) + { + if (!$this->precheck()) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + if ($this->use_stat_cache) { + $result = $this->query_stat_cache($filename); + if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) { + return $result['.']->stat; + } + if (is_object($result) && isset($result->stat)) { + return $result->stat; + } + } + + $stat = $this->stat_helper($filename, NET_SFTP_STAT); + if ($stat === false) { + $this->remove_from_stat_cache($filename); + return false; + } + if (isset($stat['type'])) { + if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename .= '/.'; + } + $this->update_stat_cache($filename, (object) ['stat' => $stat]); + return $stat; + } + + $pwd = $this->pwd; + $stat['type'] = $this->chdir($filename) ? + NET_SFTP_TYPE_DIRECTORY : + NET_SFTP_TYPE_REGULAR; + $this->pwd = $pwd; + + if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename .= '/.'; + } + $this->update_stat_cache($filename, (object) ['stat' => $stat]); + + return $stat; + } + + /** + * Returns general information about a file or symbolic link. + * + * Returns an array on success and false otherwise. + * + * @param string $filename + * @return array|false + */ + public function lstat($filename) + { + if (!$this->precheck()) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + if ($this->use_stat_cache) { + $result = $this->query_stat_cache($filename); + if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) { + return $result['.']->lstat; + } + if (is_object($result) && isset($result->lstat)) { + return $result->lstat; + } + } + + $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT); + if ($lstat === false) { + $this->remove_from_stat_cache($filename); + return false; + } + if (isset($lstat['type'])) { + if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename .= '/.'; + } + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + return $lstat; + } + + $stat = $this->stat_helper($filename, NET_SFTP_STAT); + + if ($lstat != $stat) { + $lstat = array_merge($lstat, ['type' => NET_SFTP_TYPE_SYMLINK]); + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + return $stat; + } + + $pwd = $this->pwd; + $lstat['type'] = $this->chdir($filename) ? + NET_SFTP_TYPE_DIRECTORY : + NET_SFTP_TYPE_REGULAR; + $this->pwd = $pwd; + + if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { + $filename .= '/.'; + } + $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); + + return $lstat; + } + + /** + * Returns general information about a file or symbolic link + * + * Determines information without calling \phpseclib3\Net\SFTP::realpath(). + * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. + * + * @param string $filename + * @param int $type + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return array|false + */ + private function stat_helper($filename, $type) + { + // SFTPv4+ adds an additional 32-bit integer field - flags - to the following: + $packet = Strings::packSSH2('s', $filename); + $this->send_sftp_packet($type, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_ATTRS: + return $this->parseAttributes($response); + case NET_SFTP_STATUS: + $this->logError($response); + return false; + } + + throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + /** + * Truncates a file to a given length + * + * @param string $filename + * @param int $new_size + * @return bool + */ + public function truncate($filename, $new_size) + { + $attr = Strings::packSSH2('NQ', NET_SFTP_ATTR_SIZE, $new_size); + + return $this->setstat($filename, $attr, false); + } + + /** + * Sets access and modification time of file. + * + * If the file does not exist, it will be created. + * + * @param string $filename + * @param int $time + * @param int $atime + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + */ + public function touch($filename, $time = null, $atime = null) + { + if (!$this->precheck()) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + if (!isset($time)) { + $time = time(); + } + if (!isset($atime)) { + $atime = $time; + } + + $attr = $this->version < 4 ? + pack('N3', NET_SFTP_ATTR_ACCESSTIME, $atime, $time) : + Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $atime, $time); + + $packet = Strings::packSSH2('s', $filename); + $packet .= $this->version >= 5 ? + pack('N2', 0, NET_SFTP_OPEN_OPEN_EXISTING) : + pack('N', NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL); + $packet .= $attr; + + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + return $this->close_handle(substr($response, 4)); + case NET_SFTP_STATUS: + $this->logError($response); + break; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + return $this->setstat($filename, $attr, false); + } + + /** + * Changes file or directory owner + * + * $uid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string + * would be of the form "user@dns_domain" but it does not need to be. + * `$sftp->getSupportedVersions()['version']` will return the specific version + * that's being used. + * + * Returns true on success or false on error. + * + * @param string $filename + * @param int|string $uid + * @param bool $recursive + * @return bool + */ + public function chown($filename, $uid, $recursive = false) + { + /* + quoting , + + "To avoid a representation that is tied to a particular underlying + implementation at the client or server, the use of UTF-8 strings has + been chosen. The string should be of the form "user@dns_domain". + This will allow for a client and server that do not use the same + local representation the ability to translate to a common syntax that + can be interpreted by both. In the case where there is no + translation available to the client or server, the attribute value + must be constructed without the "@"." + + phpseclib _could_ auto append the dns_domain to $uid BUT what if it shouldn't + have one? phpseclib would have no way of knowing so rather than guess phpseclib + will just use whatever value the user provided + */ + + $attr = $this->version < 4 ? + // quoting , + // "if the owner or group is specified as -1, then that ID is not changed" + pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1) : + // quoting , + // "If either the owner or group field is zero length, the field should be + // considered absent, and no change should be made to that specific field + // during a modification operation" + Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, $uid, ''); + + return $this->setstat($filename, $attr, $recursive); + } + + /** + * Changes file or directory group + * + * $gid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string + * would be of the form "user@dns_domain" but it does not need to be. + * `$sftp->getSupportedVersions()['version']` will return the specific version + * that's being used. + * + * Returns true on success or false on error. + * + * @param string $filename + * @param int|string $gid + * @param bool $recursive + * @return bool + */ + public function chgrp($filename, $gid, $recursive = false) + { + $attr = $this->version < 4 ? + pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) : + Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, '', $gid); + + return $this->setstat($filename, $attr, $recursive); + } + + /** + * Set permissions on a file. + * + * Returns the new file permissions on success or false on error. + * If $recursive is true than this just returns true or false. + * + * @param int $mode + * @param string $filename + * @param bool $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + */ + public function chmod($mode, $filename, $recursive = false) + { + if (is_string($mode) && is_int($filename)) { + $temp = $mode; + $mode = $filename; + $filename = $temp; + } + + $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777); + if (!$this->setstat($filename, $attr, $recursive)) { + return false; + } + if ($recursive) { + return true; + } + + $filename = $this->realpath($filename); + // rather than return what the permissions *should* be, we'll return what they actually are. this will also + // tell us if the file actually exists. + // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following: + $packet = pack('Na*', strlen($filename), $filename); + $this->send_sftp_packet(NET_SFTP_STAT, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_ATTRS: + $attrs = $this->parseAttributes($response); + return $attrs['mode']; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + } + + throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + /** + * Sets information about a file + * + * @param string $filename + * @param string $attr + * @param bool $recursive + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + */ + private function setstat($filename, $attr, $recursive) + { + if (!$this->precheck()) { + return false; + } + + $filename = $this->realpath($filename); + if ($filename === false) { + return false; + } + + $this->remove_from_stat_cache($filename); + + if ($recursive) { + $i = 0; + $result = $this->setstat_recursive($filename, $attr, $i); + $this->read_put_responses($i); + return $result; + } + + $packet = Strings::packSSH2('s', $filename); + $packet .= $this->version >= 4 ? + pack('a*Ca*', substr($attr, 0, 4), NET_SFTP_TYPE_UNKNOWN, substr($attr, 4)) : + $attr; + $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); + + /* + "Because some systems must use separate system calls to set various attributes, it is possible that a failure + response will be returned, but yet some of the attributes may be have been successfully modified. If possible, + servers SHOULD avoid this situation; however, clients MUST be aware that this is possible." + + -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6 + */ + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + return true; + } + + /** + * Recursively sets information on directories on the SFTP server + * + * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. + * + * @param string $path + * @param string $attr + * @param int $i + * @return bool + */ + private function setstat_recursive($path, $attr, &$i) + { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + $entries = $this->readlist($path, true); + + if ($entries === false || is_int($entries)) { + return $this->setstat($path, $attr, false); + } + + // normally $entries would have at least . and .. but it might not if the directories + // permissions didn't allow reading + if (empty($entries)) { + return false; + } + + unset($entries['.'], $entries['..']); + foreach ($entries as $filename => $props) { + if (!isset($props['type'])) { + return false; + } + + $temp = $path . '/' . $filename; + if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { + if (!$this->setstat_recursive($temp, $attr, $i)) { + return false; + } + } else { + $packet = Strings::packSSH2('s', $temp); + $packet .= $this->version >= 4 ? + pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : + $attr; + $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + } + } + + $packet = Strings::packSSH2('s', $path); + $packet .= $this->version >= 4 ? + pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : + $attr; + $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + + return true; + } + + /** + * Return the target of a symbolic link + * + * @param string $link + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return mixed + */ + public function readlink($link) + { + if (!$this->precheck()) { + return false; + } + + $link = $this->realpath($link); + + $this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link)); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_NAME: + break; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($count) = Strings::unpackSSH2('N', $response); + // the file isn't a symlink + if (!$count) { + return false; + } + + list($filename) = Strings::unpackSSH2('s', $response); + + return $filename; + } + + /** + * Create a symlink + * + * symlink() creates a symbolic link to the existing target with the specified name link. + * + * @param string $target + * @param string $link + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + */ + public function symlink($target, $link) + { + if (!$this->precheck()) { + return false; + } + + //$target = $this->realpath($target); + $link = $this->realpath($link); + + /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-12.1 : + + Changed the SYMLINK packet to be LINK and give it the ability to + create hard links. Also change it's packet number because many + implementation implemented SYMLINK with the arguments reversed. + Hopefully the new argument names make it clear which way is which. + */ + if ($this->version == 6) { + $type = NET_SFTP_LINK; + $packet = Strings::packSSH2('ssC', $link, $target, 1); + } else { + $type = NET_SFTP_SYMLINK; + /* quoting http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL#347 : + + 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK + + When OpenSSH's sftp-server was implemented, the order of the arguments + to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, + the reversal was not noticed until the server was widely deployed. Since + fixing this to follow the specification would cause incompatibility, the + current order was retained. For correct operation, clients should send + SSH_FXP_SYMLINK as follows: + + uint32 id + string targetpath + string linkpath */ + $packet = substr($this->server_identifier, 0, 15) == 'SSH-2.0-OpenSSH' ? + Strings::packSSH2('ss', $target, $link) : + Strings::packSSH2('ss', $link, $target); + } + $this->send_sftp_packet($type, $packet); + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + return true; + } + + /** + * Creates a directory. + * + * @param string $dir + * @param int $mode + * @param bool $recursive + * @return bool + */ + public function mkdir($dir, $mode = -1, $recursive = false) + { + if (!$this->precheck()) { + return false; + } + + $dir = $this->realpath($dir); + + if ($recursive) { + $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir)); + if (empty($dirs[0])) { + array_shift($dirs); + $dirs[0] = '/' . $dirs[0]; + } + for ($i = 0; $i < count($dirs); $i++) { + $temp = array_slice($dirs, 0, $i + 1); + $temp = implode('/', $temp); + $result = $this->mkdir_helper($temp, $mode); + } + return $result; + } + + return $this->mkdir_helper($dir, $mode); + } + + /** + * Helper function for directory creation + * + * @param string $dir + * @param int $mode + * @return bool + */ + private function mkdir_helper($dir, $mode) + { + // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing) + $this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0"); + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + if ($mode !== -1) { + $this->chmod($mode, $dir); + } + + return true; + } + + /** + * Removes a directory. + * + * @param string $dir + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return bool + */ + public function rmdir($dir) + { + if (!$this->precheck()) { + return false; + } + + $dir = $this->realpath($dir); + if ($dir === false) { + return false; + } + + $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir)); + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? + $this->logError($response, $status); + return false; + } + + $this->remove_from_stat_cache($dir); + // the following will do a soft delete, which would be useful if you deleted a file + // and then tried to do a stat on the deleted file. the above, in contrast, does + // a hard delete + //$this->update_stat_cache($dir, false); + + return true; + } + + /** + * Uploads a file to the SFTP server. + * + * By default, \phpseclib3\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. + * So, for example, if you set $data to 'filename.ext' and then do \phpseclib3\Net\SFTP::get(), you will get a file, twelve bytes + * long, containing 'filename.ext' as its contents. + * + * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will + * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how + * large $remote_file will be, as well. + * + * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number + * of bytes to return, and returns a string if there is some data or null if there is no more data + * + * If $data is a resource then it'll be used as a resource instead. + * + * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take + * care of that, yourself. + * + * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with + * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following: + * + * self::SOURCE_LOCAL_FILE | self::RESUME + * + * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace + * self::RESUME with self::RESUME_START. + * + * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed. + * + * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME + * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle + * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the + * middle of one. + * + * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE. + * + * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} + * + * @param string $remote_file + * @param string|resource $data + * @param int $mode + * @param int $start + * @param int $local_start + * @param callable|null $progressCallback + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid + * @throws \phpseclib3\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist + * @return bool + */ + public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) + { + if (!$this->precheck()) { + return false; + } + + $remote_file = $this->realpath($remote_file); + if ($remote_file === false) { + return false; + } + + $this->remove_from_stat_cache($remote_file); + + if ($this->version >= 5) { + $flags = NET_SFTP_OPEN_OPEN_OR_CREATE; + } else { + $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; + // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." + // in practice, it doesn't seem to do that. + //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; + } + + if ($start >= 0) { + $offset = $start; + } elseif ($mode & (self::RESUME | self::RESUME_START)) { + // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called + $size = $this->stat($remote_file)['size']; + $offset = $size !== false ? $size : 0; + } else { + $offset = 0; + if ($this->version >= 5) { + $flags = NET_SFTP_OPEN_CREATE_TRUNCATE; + } else { + $flags |= NET_SFTP_OPEN_TRUNCATE; + } + } + + $this->remove_from_stat_cache($remote_file); + + $packet = Strings::packSSH2('s', $remote_file); + $packet .= $this->version >= 5 ? + pack('N3', 0, $flags, 0) : + pack('N2', $flags, 0); + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 + $dataCallback = false; + switch (true) { + case $mode & self::SOURCE_CALLBACK: + if (!is_callable($data)) { + throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); + } + $dataCallback = $data; + // do nothing + break; + case is_resource($data): + $mode = $mode & ~self::SOURCE_LOCAL_FILE; + $info = stream_get_meta_data($data); + if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { + $fp = fopen('php://memory', 'w+'); + stream_copy_to_stream($data, $fp); + rewind($fp); + } else { + $fp = $data; + } + break; + case $mode & self::SOURCE_LOCAL_FILE: + if (!is_file($data)) { + throw new FileNotFoundException("$data is not a valid file"); + } + $fp = @fopen($data, 'rb'); + if (!$fp) { + return false; + } + } + + if (isset($fp)) { + $stat = fstat($fp); + $size = !empty($stat) ? $stat['size'] : 0; + + if ($local_start >= 0) { + fseek($fp, $local_start); + $size -= $local_start; + } elseif ($mode & self::RESUME) { + fseek($fp, $offset); + $size -= $offset; + } + } elseif ($dataCallback) { + $size = 0; + } else { + $size = strlen($data); + } + + $sent = 0; + $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; + + $sftp_packet_size = $this->max_sftp_packet; + // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header" + $sftp_packet_size -= strlen($handle) + 25; + $i = $j = 0; + while ($dataCallback || ($size === 0 || $sent < $size)) { + if ($dataCallback) { + $temp = $dataCallback($sftp_packet_size); + if (is_null($temp)) { + break; + } + } else { + $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size); + if ($temp === false || $temp === '') { + break; + } + } + + $subtemp = $offset + $sent; + $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); + try { + $this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j); + } catch (\Exception $e) { + if ($mode & self::SOURCE_LOCAL_FILE) { + fclose($fp); + } + throw $e; + } + $sent += strlen($temp); + if (is_callable($progressCallback)) { + $progressCallback($sent); + } + + $i++; + $j++; + if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + $i = 0; + break; + } + $i = 0; + } + } + + $result = $this->close_handle($handle); + + if (!$this->read_put_responses($i)) { + if ($mode & self::SOURCE_LOCAL_FILE) { + fclose($fp); + } + $this->close_handle($handle); + return false; + } + + if ($mode & SFTP::SOURCE_LOCAL_FILE) { + if (isset($fp) && is_resource($fp)) { + fclose($fp); + } + + if ($this->preserveTime) { + $stat = stat($data); + $attr = $this->version < 4 ? + pack('N3', NET_SFTP_ATTR_ACCESSTIME, $stat['atime'], $stat['mtime']) : + Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $stat['atime'], $stat['mtime']); + if (!$this->setstat($remote_file, $attr, false)) { + throw new \RuntimeException('Error setting file time'); + } + } + } + + return $result; + } + + /** + * Reads multiple successive SSH_FXP_WRITE responses + * + * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i + * SSH_FXP_WRITEs, in succession, and then reading $i responses. + * + * @param int $i + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + */ + private function read_put_responses($i) + { + while ($i--) { + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + break; + } + } + + return $i < 0; + } + + /** + * Close handle + * + * @param string $handle + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + */ + private function close_handle($handle) + { + $this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle)); + + // "The client MUST release all resources associated with the handle regardless of the status." + // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + return true; + } + + /** + * Downloads a file from the SFTP server. + * + * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if + * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the + * operation. + * + * $offset and $length can be used to download files in chunks. + * + * @param string $remote_file + * @param string|bool|resource|callable $local_file + * @param int $offset + * @param int $length + * @param callable|null $progressCallback + * @throws \UnexpectedValueException on receipt of unexpected packets + * @return string|bool + */ + public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) + { + if (!$this->precheck()) { + return false; + } + + $remote_file = $this->realpath($remote_file); + if ($remote_file === false) { + return false; + } + + $packet = Strings::packSSH2('s', $remote_file); + $packet .= $this->version >= 5 ? + pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) : + pack('N2', NET_SFTP_OPEN_READ, 0); + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + $handle = substr($response, 4); + break; + case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + $this->logError($response); + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + if (is_resource($local_file)) { + $fp = $local_file; + $stat = fstat($fp); + $res_offset = $stat['size']; + } else { + $res_offset = 0; + if ($local_file !== false && !is_callable($local_file)) { + $fp = fopen($local_file, 'wb'); + if (!$fp) { + return false; + } + } else { + $content = ''; + } + } + + $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file); + + $start = $offset; + $read = 0; + while (true) { + $i = 0; + + while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) { + $tempoffset = $start + $read; + + $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet; + + $packet = Strings::packSSH2('sN3', $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); + try { + $this->send_sftp_packet(NET_SFTP_READ, $packet, $i); + } catch (\Exception $e) { + if ($fclose_check) { + fclose($fp); + } + throw $e; + } + $packet = null; + $read += $packet_size; + $i++; + } + + if (!$i) { + break; + } + + $packets_sent = $i - 1; + + $clear_responses = false; + while ($i > 0) { + $i--; + + if ($clear_responses) { + $this->get_sftp_packet($packets_sent - $i); + continue; + } else { + $response = $this->get_sftp_packet($packets_sent - $i); + } + + switch ($this->packet_type) { + case NET_SFTP_DATA: + $temp = substr($response, 4); + $offset += strlen($temp); + if ($local_file === false) { + $content .= $temp; + } elseif (is_callable($local_file)) { + $local_file($temp); + } else { + fputs($fp, $temp); + } + if (is_callable($progressCallback)) { + call_user_func($progressCallback, $offset); + } + $temp = null; + break; + case NET_SFTP_STATUS: + // could, in theory, return false if !strlen($content) but we'll hold off for the time being + $this->logError($response); + $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses + break; + default: + if ($fclose_check) { + fclose($fp); + } + if ($this->channel_close) { + $this->partial_init = false; + $this->init_sftp_connection(); + return false; + } else { + throw new \UnexpectedValueException('Expected NET_SFTP_DATA or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + $response = null; + } + + if ($clear_responses) { + break; + } + } + + if ($fclose_check) { + fclose($fp); + + if ($this->preserveTime) { + $stat = $this->stat($remote_file); + touch($local_file, $stat['mtime'], $stat['atime']); + } + } + + if (!$this->close_handle($handle)) { + return false; + } + + // if $content isn't set that means a file was written to + return isset($content) ? $content : true; + } + + /** + * Deletes a file on the SFTP server. + * + * @param string $path + * @param bool $recursive + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + */ + public function delete($path, $recursive = true) + { + if (!$this->precheck()) { + return false; + } + + if (is_object($path)) { + // It's an object. Cast it as string before we check anything else. + $path = (string) $path; + } + + if (!is_string($path) || $path == '') { + return false; + } + + $path = $this->realpath($path); + if ($path === false) { + return false; + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 + $this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path)); + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + if (!$recursive) { + return false; + } + + $i = 0; + $result = $this->delete_recursive($path, $i); + $this->read_put_responses($i); + return $result; + } + + $this->remove_from_stat_cache($path); + + return true; + } + + /** + * Recursively deletes directories on the SFTP server + * + * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. + * + * @param string $path + * @param int $i + * @return bool + */ + private function delete_recursive($path, &$i) + { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + $entries = $this->readlist($path, true); + + // The folder does not exist at all, so we cannot delete it. + if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) { + return false; + } + + // Normally $entries would have at least . and .. but it might not if the directories + // permissions didn't allow reading. If this happens then default to an empty list of files. + if ($entries === false || is_int($entries)) { + $entries = []; + } + + unset($entries['.'], $entries['..']); + foreach ($entries as $filename => $props) { + if (!isset($props['type'])) { + return false; + } + + $temp = $path . '/' . $filename; + if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { + if (!$this->delete_recursive($temp, $i)) { + return false; + } + } else { + $this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp)); + $this->remove_from_stat_cache($temp); + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + } + } + + $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path)); + $this->remove_from_stat_cache($path); + + $i++; + + if ($i >= NET_SFTP_QUEUE_SIZE) { + if (!$this->read_put_responses($i)) { + return false; + } + $i = 0; + } + + return true; + } + + /** + * Checks whether a file or directory exists + * + * @param string $path + * @return bool + */ + public function file_exists($path) + { + if ($this->use_stat_cache) { + if (!$this->precheck()) { + return false; + } + + $path = $this->realpath($path); + + $result = $this->query_stat_cache($path); + + if (isset($result)) { + // return true if $result is an array or if it's an stdClass object + return $result !== false; + } + } + + return $this->stat($path) !== false; + } + + /** + * Tells whether the filename is a directory + * + * @param string $path + * @return bool + */ + public function is_dir($path) + { + $result = $this->get_stat_cache_prop($path, 'type'); + if ($result === false) { + return false; + } + return $result === NET_SFTP_TYPE_DIRECTORY; + } + + /** + * Tells whether the filename is a regular file + * + * @param string $path + * @return bool + */ + public function is_file($path) + { + $result = $this->get_stat_cache_prop($path, 'type'); + if ($result === false) { + return false; + } + return $result === NET_SFTP_TYPE_REGULAR; + } + + /** + * Tells whether the filename is a symbolic link + * + * @param string $path + * @return bool + */ + public function is_link($path) + { + $result = $this->get_lstat_cache_prop($path, 'type'); + if ($result === false) { + return false; + } + return $result === NET_SFTP_TYPE_SYMLINK; + } + + /** + * Tells whether a file exists and is readable + * + * @param string $path + * @return bool + */ + public function is_readable($path) + { + if (!$this->precheck()) { + return false; + } + + $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0); + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + return true; + case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + return false; + default: + throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + /** + * Tells whether the filename is writable + * + * @param string $path + * @return bool + */ + public function is_writable($path) + { + if (!$this->precheck()) { + return false; + } + + $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0); + $this->send_sftp_packet(NET_SFTP_OPEN, $packet); + + $response = $this->get_sftp_packet(); + switch ($this->packet_type) { + case NET_SFTP_HANDLE: + return true; + case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + return false; + default: + throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + } + + /** + * Tells whether the filename is writeable + * + * Alias of is_writable + * + * @param string $path + * @return bool + */ + public function is_writeable($path) + { + return $this->is_writable($path); + } + + /** + * Gets last access time of file + * + * @param string $path + * @return mixed + */ + public function fileatime($path) + { + return $this->get_stat_cache_prop($path, 'atime'); + } + + /** + * Gets file modification time + * + * @param string $path + * @return mixed + */ + public function filemtime($path) + { + return $this->get_stat_cache_prop($path, 'mtime'); + } + + /** + * Gets file permissions + * + * @param string $path + * @return mixed + */ + public function fileperms($path) + { + return $this->get_stat_cache_prop($path, 'mode'); + } + + /** + * Gets file owner + * + * @param string $path + * @return mixed + */ + public function fileowner($path) + { + return $this->get_stat_cache_prop($path, 'uid'); + } + + /** + * Gets file group + * + * @param string $path + * @return mixed + */ + public function filegroup($path) + { + return $this->get_stat_cache_prop($path, 'gid'); + } + + /** + * Recursively go through rawlist() output to get the total filesize + * + * @return int + */ + private static function recursiveFilesize(array $files) + { + $size = 0; + foreach ($files as $name => $file) { + if ($name == '.' || $name == '..') { + continue; + } + $size += is_array($file) ? + self::recursiveFilesize($file) : + $file->size; + } + return $size; + } + + /** + * Gets file size + * + * @param string $path + * @param bool $recursive + * @return mixed + */ + public function filesize($path, $recursive = false) + { + return !$recursive || $this->filetype($path) != 'dir' ? + $this->get_stat_cache_prop($path, 'size') : + self::recursiveFilesize($this->rawlist($path, true)); + } + + /** + * Gets file type + * + * @param string $path + * @return string|false + */ + public function filetype($path) + { + $type = $this->get_stat_cache_prop($path, 'type'); + if ($type === false) { + return false; + } + + switch ($type) { + case NET_SFTP_TYPE_BLOCK_DEVICE: + return 'block'; + case NET_SFTP_TYPE_CHAR_DEVICE: + return 'char'; + case NET_SFTP_TYPE_DIRECTORY: + return 'dir'; + case NET_SFTP_TYPE_FIFO: + return 'fifo'; + case NET_SFTP_TYPE_REGULAR: + return 'file'; + case NET_SFTP_TYPE_SYMLINK: + return 'link'; + default: + return false; + } + } + + /** + * Return a stat properity + * + * Uses cache if appropriate. + * + * @param string $path + * @param string $prop + * @return mixed + */ + private function get_stat_cache_prop($path, $prop) + { + return $this->get_xstat_cache_prop($path, $prop, 'stat'); + } + + /** + * Return an lstat properity + * + * Uses cache if appropriate. + * + * @param string $path + * @param string $prop + * @return mixed + */ + private function get_lstat_cache_prop($path, $prop) + { + return $this->get_xstat_cache_prop($path, $prop, 'lstat'); + } + + /** + * Return a stat or lstat properity + * + * Uses cache if appropriate. + * + * @param string $path + * @param string $prop + * @param string $type + * @return mixed + */ + private function get_xstat_cache_prop($path, $prop, $type) + { + if (!$this->precheck()) { + return false; + } + + if ($this->use_stat_cache) { + $path = $this->realpath($path); + + $result = $this->query_stat_cache($path); + + if (is_object($result) && isset($result->$type)) { + return $result->{$type}[$prop]; + } + } + + $result = $this->$type($path); + + if ($result === false || !isset($result[$prop])) { + return false; + } + + return $result[$prop]; + } + + /** + * Renames a file or a directory on the SFTP server. + * + * If the file already exists this will return false + * + * @param string $oldname + * @param string $newname + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + */ + public function rename($oldname, $newname) + { + if (!$this->precheck()) { + return false; + } + + $oldname = $this->realpath($oldname); + $newname = $this->realpath($newname); + if ($oldname === false || $newname === false) { + return false; + } + + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 + $packet = Strings::packSSH2('ss', $oldname, $newname); + if ($this->version >= 5) { + /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-6.5 , + + 'flags' is 0 or a combination of: + + SSH_FXP_RENAME_OVERWRITE 0x00000001 + SSH_FXP_RENAME_ATOMIC 0x00000002 + SSH_FXP_RENAME_NATIVE 0x00000004 + + (none of these are currently supported) */ + $packet .= "\0\0\0\0"; + } + $this->send_sftp_packet(NET_SFTP_RENAME, $packet); + + $response = $this->get_sftp_packet(); + if ($this->packet_type != NET_SFTP_STATUS) { + throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' + . 'Got packet type: ' . $this->packet_type); + } + + // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED + list($status) = Strings::unpackSSH2('N', $response); + if ($status != NET_SFTP_STATUS_OK) { + $this->logError($response, $status); + return false; + } + + // don't move the stat cache entry over since this operation could very well change the + // atime and mtime attributes + //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); + $this->remove_from_stat_cache($oldname); + $this->remove_from_stat_cache($newname); + + return true; + } + + /** + * Parse Time + * + * See '7.7. Times' of draft-ietf-secsh-filexfer-13 for more info. + * + * @param string $key + * @param int $flags + * @param string $response + * @return array + */ + private function parseTime($key, $flags, &$response) + { + $attr = []; + list($attr[$key]) = Strings::unpackSSH2('Q', $response); + if ($flags & NET_SFTP_ATTR_SUBSECOND_TIMES) { + list($attr[$key . '-nseconds']) = Strings::unpackSSH2('N', $response); + } + return $attr; + } + + /** + * Parse Attributes + * + * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info. + * + * @param string $response + * @return array + */ + protected function parseAttributes(&$response) + { + if ($this->version >= 4) { + list($flags, $attr['type']) = Strings::unpackSSH2('NC', $response); + } else { + list($flags) = Strings::unpackSSH2('N', $response); + } + + foreach (self::$attributes as $key => $value) { + switch ($flags & $key) { + case NET_SFTP_ATTR_UIDGID: + if ($this->version > 3) { + continue 2; + } + break; + case NET_SFTP_ATTR_CREATETIME: + case NET_SFTP_ATTR_MODIFYTIME: + case NET_SFTP_ATTR_ACL: + case NET_SFTP_ATTR_OWNERGROUP: + case NET_SFTP_ATTR_SUBSECOND_TIMES: + if ($this->version < 4) { + continue 2; + } + break; + case NET_SFTP_ATTR_BITS: + if ($this->version < 5) { + continue 2; + } + break; + case NET_SFTP_ATTR_ALLOCATION_SIZE: + case NET_SFTP_ATTR_TEXT_HINT: + case NET_SFTP_ATTR_MIME_TYPE: + case NET_SFTP_ATTR_LINK_COUNT: + case NET_SFTP_ATTR_UNTRANSLATED_NAME: + case NET_SFTP_ATTR_CTIME: + if ($this->version < 6) { + continue 2; + } + } + switch ($flags & $key) { + case NET_SFTP_ATTR_SIZE: // 0x00000001 + // The size attribute is defined as an unsigned 64-bit integer. + // The following will use floats on 32-bit platforms, if necessary. + // As can be seen in the BigInteger class, floats are generally + // IEEE 754 binary64 "double precision" on such platforms and + // as such can represent integers of at least 2^50 without loss + // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. + list($attr['size']) = Strings::unpackSSH2('Q', $response); + break; + case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) + list($attr['uid'], $attr['gid']) = Strings::unpackSSH2('NN', $response); + break; + case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 + list($attr['mode']) = Strings::unpackSSH2('N', $response); + $fileType = $this->parseMode($attr['mode']); + if ($this->version < 4 && $fileType !== false) { + $attr += ['type' => $fileType]; + } + break; + case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 + if ($this->version >= 4) { + $attr += $this->parseTime('atime', $flags, $response); + break; + } + list($attr['atime'], $attr['mtime']) = Strings::unpackSSH2('NN', $response); + break; + case NET_SFTP_ATTR_CREATETIME: // 0x00000010 (SFTPv4+) + $attr += $this->parseTime('createtime', $flags, $response); + break; + case NET_SFTP_ATTR_MODIFYTIME: // 0x00000020 + $attr += $this->parseTime('mtime', $flags, $response); + break; + case NET_SFTP_ATTR_ACL: // 0x00000040 + // access control list + // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7 + // currently unsupported + list($count) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $count; $i++) { + list($type, $flag, $mask, $who) = Strings::unpackSSH2('N3s', $result); + } + break; + case NET_SFTP_ATTR_OWNERGROUP: // 0x00000080 + list($attr['owner'], $attr['$group']) = Strings::unpackSSH2('ss', $response); + break; + case NET_SFTP_ATTR_SUBSECOND_TIMES: // 0x00000100 + break; + case NET_SFTP_ATTR_BITS: // 0x00000200 (SFTPv5+) + // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-5.8 + // currently unsupported + // tells if you file is: + // readonly, system, hidden, case inensitive, archive, encrypted, compressed, sparse + // append only, immutable, sync + list($attrib_bits, $attrib_bits_valid) = Strings::unpackSSH2('N2', $response); + // if we were actually gonna implement the above it ought to be + // $attr['attrib-bits'] and $attr['attrib-bits-valid'] + // eg. - instead of _ + break; + case NET_SFTP_ATTR_ALLOCATION_SIZE: // 0x00000400 (SFTPv6+) + // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4 + // represents the number of bytes that the file consumes on the disk. will + // usually be larger than the 'size' field + list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response); + break; + case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800 + // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10 + // currently unsupported + // tells if file is "known text", "guessed text", "known binary", "guessed binary" + list($text_hint) = Strings::unpackSSH2('C', $response); + // the above should be $attr['text-hint'] + break; + case NET_SFTP_ATTR_MIME_TYPE: // 0x00001000 + // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.11 + list($attr['mime-type']) = Strings::unpackSSH2('s', $response); + break; + case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000 + // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12 + list($attr['link-count']) = Strings::unpackSSH2('N', $response); + break; + case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000 + // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13 + list($attr['untranslated-name']) = Strings::unpackSSH2('s', $response); + break; + case NET_SFTP_ATTR_CTIME: // 0x00008000 + // 'ctime' contains the last time the file attributes were changed. The + // exact meaning of this field depends on the server. + $attr += $this->parseTime('ctime', $flags, $response); + break; + case NET_SFTP_ATTR_EXTENDED: // 0x80000000 + list($count) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $count; $i++) { + list($key, $value) = Strings::unpackSSH2('ss', $response); + $attr[$key] = $value; + } + } + } + return $attr; + } + + /** + * Attempt to identify the file type + * + * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway + * + * @param int $mode + * @return int + */ + private function parseMode($mode) + { + // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 + // see, also, http://linux.die.net/man/2/stat + switch ($mode & 0170000) {// ie. 1111 0000 0000 0000 + case 0000000: // no file type specified - figure out the file type using alternative means + return false; + case 0040000: + return NET_SFTP_TYPE_DIRECTORY; + case 0100000: + return NET_SFTP_TYPE_REGULAR; + case 0120000: + return NET_SFTP_TYPE_SYMLINK; + // new types introduced in SFTPv5+ + // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 + case 0010000: // named pipe (fifo) + return NET_SFTP_TYPE_FIFO; + case 0020000: // character special + return NET_SFTP_TYPE_CHAR_DEVICE; + case 0060000: // block special + return NET_SFTP_TYPE_BLOCK_DEVICE; + case 0140000: // socket + return NET_SFTP_TYPE_SOCKET; + case 0160000: // whiteout + // "SPECIAL should be used for files that are of + // a known type which cannot be expressed in the protocol" + return NET_SFTP_TYPE_SPECIAL; + default: + return NET_SFTP_TYPE_UNKNOWN; + } + } + + /** + * Parse Longname + * + * SFTPv3 doesn't provide any easy way of identifying a file type. You could try to open + * a file as a directory and see if an error is returned or you could try to parse the + * SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does. + * The result is returned using the + * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}. + * + * If the longname is in an unrecognized format bool(false) is returned. + * + * @param string $longname + * @return mixed + */ + private function parseLongname($longname) + { + // http://en.wikipedia.org/wiki/Unix_file_types + // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions + if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) { + switch ($longname[0]) { + case '-': + return NET_SFTP_TYPE_REGULAR; + case 'd': + return NET_SFTP_TYPE_DIRECTORY; + case 'l': + return NET_SFTP_TYPE_SYMLINK; + default: + return NET_SFTP_TYPE_SPECIAL; + } + } + + return false; + } + + /** + * Sends SFTP Packets + * + * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. + * + * @param int $type + * @param string $data + * @param int $request_id + * @see self::_get_sftp_packet() + * @see self::send_channel_packet() + * @return void + */ + private function send_sftp_packet($type, $data, $request_id = 1) + { + // in SSH2.php the timeout is cumulative per function call. eg. exec() will + // timeout after 10s. but for SFTP.php it's cumulative per packet + $this->curTimeout = $this->timeout; + + $packet = $this->use_request_id ? + pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : + pack('NCa*', strlen($data) + 1, $type, $data); + + $start = microtime(true); + $this->send_channel_packet(self::CHANNEL, $packet); + $stop = microtime(true); + + if (defined('NET_SFTP_LOGGING')) { + $packet_type = '-> ' . self::$packet_types[$type] . + ' (' . round($stop - $start, 4) . 's)'; + $this->append_log($packet_type, $data); + } + } + + /** + * Resets a connection for re-use + * + * @param int $reason + */ + protected function reset_connection($reason) + { + parent::reset_connection($reason); + $this->use_request_id = false; + $this->pwd = false; + $this->requestBuffer = []; + $this->partial_init = false; + } + + /** + * Receives SFTP Packets + * + * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. + * + * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present. + * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA + * messages containing one SFTP packet. + * + * @see self::_send_sftp_packet() + * @return string + */ + private function get_sftp_packet($request_id = null) + { + $this->channel_close = false; + + if (isset($request_id) && isset($this->requestBuffer[$request_id])) { + $this->packet_type = $this->requestBuffer[$request_id]['packet_type']; + $temp = $this->requestBuffer[$request_id]['packet']; + unset($this->requestBuffer[$request_id]); + return $temp; + } + + // in SSH2.php the timeout is cumulative per function call. eg. exec() will + // timeout after 10s. but for SFTP.php it's cumulative per packet + $this->curTimeout = $this->timeout; + + $start = microtime(true); + + // SFTP packet length + while (strlen($this->packet_buffer) < 4) { + $temp = $this->get_channel_packet(self::CHANNEL, true); + if ($temp === true) { + if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { + $this->channel_close = true; + } + $this->packet_type = false; + $this->packet_buffer = ''; + return false; + } + $this->packet_buffer .= $temp; + } + if (strlen($this->packet_buffer) < 4) { + throw new \RuntimeException('Packet is too small'); + } + extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); + /** @var integer $length */ + + $tempLength = $length; + $tempLength -= strlen($this->packet_buffer); + + // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h + if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) { + throw new \RuntimeException('Invalid Size'); + } + + // SFTP packet type and data payload + while ($tempLength > 0) { + $temp = $this->get_channel_packet(self::CHANNEL, true); + if ($temp === true) { + if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { + $this->channel_close = true; + } + $this->packet_type = false; + $this->packet_buffer = ''; + return false; + } + $this->packet_buffer .= $temp; + $tempLength -= strlen($temp); + } + + $stop = microtime(true); + + $this->packet_type = ord(Strings::shift($this->packet_buffer)); + + if ($this->use_request_id) { + extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id + $length -= 5; // account for the request id and the packet type + } else { + $length -= 1; // account for the packet type + } + + $packet = Strings::shift($this->packet_buffer, $length); + + if (defined('NET_SFTP_LOGGING')) { + $packet_type = '<- ' . self::$packet_types[$this->packet_type] . + ' (' . round($stop - $start, 4) . 's)'; + $this->append_log($packet_type, $packet); + } + + if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) { + $this->requestBuffer[$packet_id] = [ + 'packet_type' => $this->packet_type, + 'packet' => $packet + ]; + return $this->get_sftp_packet($request_id); + } + + return $packet; + } + + /** + * Logs data packets + * + * Makes sure that only the last 1MB worth of packets will be logged + * + * @param string $message_number + * @param string $message + */ + private function append_log($message_number, $message) + { + $this->append_log_helper( + NET_SFTP_LOGGING, + $message_number, + $message, + $this->packet_type_log, + $this->packet_log, + $this->log_size, + $this->realtime_log_file, + $this->realtime_log_wrap, + $this->realtime_log_size + ); + } + + /** + * Returns a log of the packets that have been sent and received. + * + * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') + * + * @return array|string|false + */ + public function getSFTPLog() + { + if (!defined('NET_SFTP_LOGGING')) { + return false; + } + + switch (NET_SFTP_LOGGING) { + case self::LOG_COMPLEX: + return $this->format_log($this->packet_log, $this->packet_type_log); + break; + //case self::LOG_SIMPLE: + default: + return $this->packet_type_log; + } + } + + /** + * Returns all errors + * + * @return array + */ + public function getSFTPErrors() + { + return $this->sftp_errors; + } + + /** + * Returns the last error + * + * @return string + */ + public function getLastSFTPError() + { + return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : ''; + } + + /** + * Get supported SFTP versions + * + * @return array + */ + public function getSupportedVersions() + { + if (!($this->bitmap & SSH2::MASK_LOGIN)) { + return false; + } + + if (!$this->partial_init) { + $this->partial_init_sftp_connection(); + } + + $temp = ['version' => $this->defaultVersion]; + if (isset($this->extensions['versions'])) { + $temp['extensions'] = $this->extensions['versions']; + } + return $temp; + } + + /** + * Get supported SFTP versions + * + * @return int|false + */ + public function getNegotiatedVersion() + { + if (!$this->precheck()) { + return false; + } + + return $this->version; + } + + /** + * Set preferred version + * + * If you're preferred version isn't supported then the highest supported + * version of SFTP will be utilized. Set to null or false or int(0) to + * unset the preferred version + * + * @param int $version + */ + public function setPreferredVersion($version) + { + $this->preferredVersion = $version; + } + + /** + * Disconnect + * + * @param int $reason + * @return false + */ + protected function disconnect_helper($reason) + { + $this->pwd = false; + return parent::disconnect_helper($reason); + } + + /** + * Enable Date Preservation + * + */ + public function enableDatePreservation() + { + $this->preserveTime = true; + } + + /** + * Disable Date Preservation + * + */ + public function disableDatePreservation() + { + $this->preserveTime = false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php new file mode 100644 index 0000000..24047b4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php @@ -0,0 +1,756 @@ + + * @copyright 2013 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net\SFTP; + +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Net\SFTP; +use phpseclib3\Net\SSH2; + +/** + * SFTP Stream Wrapper + * + * @author Jim Wigginton + */ +class Stream +{ + /** + * SFTP instances + * + * Rather than re-create the connection we re-use instances if possible + * + * @var array + */ + public static $instances; + + /** + * SFTP instance + * + * @var object + */ + private $sftp; + + /** + * Path + * + * @var string + */ + private $path; + + /** + * Mode + * + * @var string + */ + private $mode; + + /** + * Position + * + * @var int + */ + private $pos; + + /** + * Size + * + * @var int + */ + private $size; + + /** + * Directory entries + * + * @var array + */ + private $entries; + + /** + * EOF flag + * + * @var bool + */ + private $eof; + + /** + * Context resource + * + * Technically this needs to be publicly accessible so PHP can set it directly + * + * @var resource + */ + public $context; + + /** + * Notification callback function + * + * @var callable + */ + private $notification; + + /** + * Registers this class as a URL wrapper. + * + * @param string $protocol The wrapper name to be registered. + * @return bool True on success, false otherwise. + */ + public static function register($protocol = 'sftp') + { + if (in_array($protocol, stream_get_wrappers(), true)) { + return false; + } + return stream_wrapper_register($protocol, get_called_class()); + } + + /** + * The Constructor + * + */ + public function __construct() + { + if (defined('NET_SFTP_STREAM_LOGGING')) { + echo "__construct()\r\n"; + } + } + + /** + * Path Parser + * + * Extract a path from a URI and actually connect to an SSH server if appropriate + * + * If "notification" is set as a context parameter the message code for successful login is + * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE. + * + * @param string $path + * @return string + */ + protected function parse_path($path) + { + $orig = $path; + extract(parse_url($path) + ['port' => 22]); + if (isset($query)) { + $path .= '?' . $query; + } elseif (preg_match('/(\?|\?#)$/', $orig)) { + $path .= '?'; + } + if (isset($fragment)) { + $path .= '#' . $fragment; + } elseif ($orig[strlen($orig) - 1] == '#') { + $path .= '#'; + } + + if (!isset($host)) { + return false; + } + + if (isset($this->context)) { + $context = stream_context_get_params($this->context); + if (isset($context['notification'])) { + $this->notification = $context['notification']; + } + } + + if (preg_match('/^{[a-z0-9]+}$/i', $host)) { + $host = SSH2::getConnectionByResourceId($host); + if ($host === false) { + return false; + } + $this->sftp = $host; + } else { + if (isset($this->context)) { + $context = stream_context_get_options($this->context); + } + if (isset($context[$scheme]['session'])) { + $sftp = $context[$scheme]['session']; + } + if (isset($context[$scheme]['sftp'])) { + $sftp = $context[$scheme]['sftp']; + } + if (isset($sftp) && $sftp instanceof SFTP) { + $this->sftp = $sftp; + return $path; + } + if (isset($context[$scheme]['username'])) { + $user = $context[$scheme]['username']; + } + if (isset($context[$scheme]['password'])) { + $pass = $context[$scheme]['password']; + } + if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof PrivateKey) { + $pass = $context[$scheme]['privkey']; + } + + if (!isset($user) || !isset($pass)) { + return false; + } + + // casting $pass to a string is necessary in the event that it's a \phpseclib3\Crypt\RSA object + if (isset(self::$instances[$host][$port][$user][(string) $pass])) { + $this->sftp = self::$instances[$host][$port][$user][(string) $pass]; + } else { + $this->sftp = new SFTP($host, $port); + $this->sftp->disableStatCache(); + if (isset($this->notification) && is_callable($this->notification)) { + /* if !is_callable($this->notification) we could do this: + + user_error('fopen(): failed to call user notifier', E_USER_WARNING); + + the ftp wrapper gives errors like that when the notifier isn't callable. + i've opted not to do that, however, since the ftp wrapper gives the line + on which the fopen occurred as the line number - not the line that the + user_error is on. + */ + call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); + call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); + if (!$this->sftp->login($user, $pass)) { + call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0); + return false; + } + call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0); + } else { + if (!$this->sftp->login($user, $pass)) { + return false; + } + } + self::$instances[$host][$port][$user][(string) $pass] = $this->sftp; + } + } + + return $path; + } + + /** + * Opens file or URL + * + * @param string $path + * @param string $mode + * @param int $options + * @param string $opened_path + * @return bool + */ + private function _stream_open($path, $mode, $options, &$opened_path) + { + $path = $this->parse_path($path); + + if ($path === false) { + return false; + } + $this->path = $path; + + $this->size = $this->sftp->filesize($path); + $this->mode = preg_replace('#[bt]$#', '', $mode); + $this->eof = false; + + if ($this->size === false) { + if ($this->mode[0] == 'r') { + return false; + } else { + $this->sftp->touch($path); + $this->size = 0; + } + } else { + switch ($this->mode[0]) { + case 'x': + return false; + case 'w': + $this->sftp->truncate($path, 0); + $this->size = 0; + } + } + + $this->pos = $this->mode[0] != 'a' ? 0 : $this->size; + + return true; + } + + /** + * Read from stream + * + * @param int $count + * @return mixed + */ + private function _stream_read($count) + { + switch ($this->mode) { + case 'w': + case 'a': + case 'x': + case 'c': + return false; + } + + // commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite + //if ($this->pos >= $this->size) { + // $this->eof = true; + // return false; + //} + + $result = $this->sftp->get($this->path, false, $this->pos, $count); + if (isset($this->notification) && is_callable($this->notification)) { + if ($result === false) { + call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); + return 0; + } + // seems that PHP calls stream_read in 8k chunks + call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size); + } + + if (empty($result)) { // ie. false or empty string + $this->eof = true; + return false; + } + $this->pos += strlen($result); + + return $result; + } + + /** + * Write to stream + * + * @param string $data + * @return int|false + */ + private function _stream_write($data) + { + switch ($this->mode) { + case 'r': + return false; + } + + $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos); + if (isset($this->notification) && is_callable($this->notification)) { + if (!$result) { + call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); + return 0; + } + // seems that PHP splits up strings into 8k blocks before calling stream_write + call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data)); + } + + if ($result === false) { + return false; + } + $this->pos += strlen($data); + if ($this->pos > $this->size) { + $this->size = $this->pos; + } + $this->eof = false; + return strlen($data); + } + + /** + * Retrieve the current position of a stream + * + * @return int + */ + private function _stream_tell() + { + return $this->pos; + } + + /** + * Tests for end-of-file on a file pointer + * + * In my testing there are four classes functions that normally effect the pointer: + * fseek, fputs / fwrite, fgets / fread and ftruncate. + * + * Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof() + * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof() + * will return false. do fread($fp, 1) and feof() will then return true. + * + * @return bool + */ + private function _stream_eof() + { + return $this->eof; + } + + /** + * Seeks to specific location in a stream + * + * @param int $offset + * @param int $whence + * @return bool + */ + private function _stream_seek($offset, $whence) + { + switch ($whence) { + case SEEK_SET: + if ($offset < 0) { + return false; + } + break; + case SEEK_CUR: + $offset += $this->pos; + break; + case SEEK_END: + $offset += $this->size; + } + + $this->pos = $offset; + $this->eof = false; + return true; + } + + /** + * Change stream options + * + * @param string $path + * @param int $option + * @param mixed $var + * @return bool + */ + private function _stream_metadata($path, $option, $var) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + // stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined + // see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246 + // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592 + switch ($option) { + case 1: // PHP_STREAM_META_TOUCH + $time = isset($var[0]) ? $var[0] : null; + $atime = isset($var[1]) ? $var[1] : null; + return $this->sftp->touch($path, $time, $atime); + case 2: // PHP_STREAM_OWNER_NAME + case 3: // PHP_STREAM_GROUP_NAME + return false; + case 4: // PHP_STREAM_META_OWNER + return $this->sftp->chown($path, $var); + case 5: // PHP_STREAM_META_GROUP + return $this->sftp->chgrp($path, $var); + case 6: // PHP_STREAM_META_ACCESS + return $this->sftp->chmod($path, $var) !== false; + } + } + + /** + * Retrieve the underlaying resource + * + * @param int $cast_as + * @return resource + */ + private function _stream_cast($cast_as) + { + return $this->sftp->fsock; + } + + /** + * Advisory file locking + * + * @param int $operation + * @return bool + */ + private function _stream_lock($operation) + { + return false; + } + + /** + * Renames a file or directory + * + * Attempts to rename oldname to newname, moving it between directories if necessary. + * If newname exists, it will be overwritten. This is a departure from what \phpseclib3\Net\SFTP + * does. + * + * @param string $path_from + * @param string $path_to + * @return bool + */ + private function _rename($path_from, $path_to) + { + $path1 = parse_url($path_from); + $path2 = parse_url($path_to); + unset($path1['path'], $path2['path']); + if ($path1 != $path2) { + return false; + } + + $path_from = $this->parse_path($path_from); + $path_to = parse_url($path_to); + if ($path_from === false) { + return false; + } + + $path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2 + // "It is an error if there already exists a file with the name specified by newpath." + // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5 + if (!$this->sftp->rename($path_from, $path_to)) { + if ($this->sftp->stat($path_to)) { + return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to); + } + return false; + } + + return true; + } + + /** + * Open directory handle + * + * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and + * removed in 5.4 I'm just going to ignore it. + * + * Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client + * sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting + * the SFTP specs: + * + * The SSH_FXP_NAME response has the following format: + * + * uint32 id + * uint32 count + * repeats count times: + * string filename + * string longname + * ATTRS attrs + * + * @param string $path + * @param int $options + * @return bool + */ + private function _dir_opendir($path, $options) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + $this->pos = 0; + $this->entries = $this->sftp->nlist($path); + return $this->entries !== false; + } + + /** + * Read entry from directory handle + * + * @return mixed + */ + private function _dir_readdir() + { + if (isset($this->entries[$this->pos])) { + return $this->entries[$this->pos++]; + } + return false; + } + + /** + * Rewind directory handle + * + * @return bool + */ + private function _dir_rewinddir() + { + $this->pos = 0; + return true; + } + + /** + * Close directory handle + * + * @return bool + */ + private function _dir_closedir() + { + return true; + } + + /** + * Create a directory + * + * Only valid $options is STREAM_MKDIR_RECURSIVE + * + * @param string $path + * @param int $mode + * @param int $options + * @return bool + */ + private function _mkdir($path, $mode, $options) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE); + } + + /** + * Removes a directory + * + * Only valid $options is STREAM_MKDIR_RECURSIVE per , however, + * does not have a $recursive parameter as mkdir() does so I don't know how + * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as + * $options. What does 8 correspond to? + * + * @param string $path + * @param int $options + * @return bool + */ + private function _rmdir($path, $options) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + return $this->sftp->rmdir($path); + } + + /** + * Flushes the output + * + * See . Always returns true because \phpseclib3\Net\SFTP doesn't cache stuff before writing + * + * @return bool + */ + private function _stream_flush() + { + return true; + } + + /** + * Retrieve information about a file resource + * + * @return mixed + */ + private function _stream_stat() + { + $results = $this->sftp->stat($this->path); + if ($results === false) { + return false; + } + return $results; + } + + /** + * Delete a file + * + * @param string $path + * @return bool + */ + private function _unlink($path) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + return $this->sftp->delete($path, false); + } + + /** + * Retrieve information about a file + * + * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib3\Net\SFTP\Stream is quiet by default + * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll + * cross that bridge when and if it's reached + * + * @param string $path + * @param int $flags + * @return mixed + */ + private function _url_stat($path, $flags) + { + $path = $this->parse_path($path); + if ($path === false) { + return false; + } + + $results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path); + if ($results === false) { + return false; + } + + return $results; + } + + /** + * Truncate stream + * + * @param int $new_size + * @return bool + */ + private function _stream_truncate($new_size) + { + if (!$this->sftp->truncate($this->path, $new_size)) { + return false; + } + + $this->eof = false; + $this->size = $new_size; + + return true; + } + + /** + * Change stream options + * + * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. + * The other two aren't supported because of limitations in \phpseclib3\Net\SFTP. + * + * @param int $option + * @param int $arg1 + * @param int $arg2 + * @return bool + */ + private function _stream_set_option($option, $arg1, $arg2) + { + return false; + } + + /** + * Close an resource + * + */ + private function _stream_close() + { + } + + /** + * __call Magic Method + * + * When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you. + * Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function + * lets you figure that out. + * + * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not + * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method. + * + * @param string $name + * @param array $arguments + * @return mixed + */ + public function __call($name, array $arguments) + { + if (defined('NET_SFTP_STREAM_LOGGING')) { + echo $name . '('; + $last = count($arguments) - 1; + foreach ($arguments as $i => $argument) { + var_export($argument); + if ($i != $last) { + echo ','; + } + } + echo ")\r\n"; + } + $name = '_' . $name; + if (!method_exists($this, $name)) { + return false; + } + return $this->$name(...$arguments); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php new file mode 100644 index 0000000..ac70af9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php @@ -0,0 +1,5397 @@ + + * login('username', 'password')) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * + * login('username', $key)) { + * exit('Login Failed'); + * } + * + * echo $ssh->read('username@username:~$'); + * $ssh->write("ls -la\n"); + * echo $ssh->read('username@username:~$'); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2007 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\Net; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Blowfish; +use phpseclib3\Crypt\ChaCha20; +use phpseclib3\Crypt\Common\AsymmetricKey; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\Common\SymmetricKey; +use phpseclib3\Crypt\DH; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\Hash; +use phpseclib3\Crypt\Random; +use phpseclib3\Crypt\RC4; +use phpseclib3\Crypt\Rijndael; +use phpseclib3\Crypt\RSA; +use phpseclib3\Crypt\TripleDES; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. +use phpseclib3\Crypt\Twofish; +use phpseclib3\Exception\ConnectionClosedException; +use phpseclib3\Exception\InsufficientSetupException; +use phpseclib3\Exception\NoSupportedAlgorithmsException; +use phpseclib3\Exception\UnableToConnectException; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\Exception\UnsupportedCurveException; +use phpseclib3\Math\BigInteger; +use phpseclib3\System\SSH\Agent; + +/** + * Pure-PHP implementation of SSHv2. + * + * @author Jim Wigginton + */ +class SSH2 +{ + /**#@+ + * Compression Types + * + */ + /** + * No compression + */ + const NET_SSH2_COMPRESSION_NONE = 1; + /** + * zlib compression + */ + const NET_SSH2_COMPRESSION_ZLIB = 2; + /** + * zlib@openssh.com + */ + const NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH = 3; + /**#@-*/ + + // Execution Bitmap Masks + const MASK_CONSTRUCTOR = 0x00000001; + const MASK_CONNECTED = 0x00000002; + const MASK_LOGIN_REQ = 0x00000004; + const MASK_LOGIN = 0x00000008; + const MASK_SHELL = 0x00000010; + const MASK_WINDOW_ADJUST = 0x00000020; + + /* + * Channel constants + * + * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer + * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with + * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a + * recipient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel + * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snippet: + * The 'recipient channel' is the channel number given in the original + * open request, and 'sender channel' is the channel number allocated by + * the other side. + * + * @see \phpseclib3\Net\SSH2::send_channel_packet() + * @see \phpseclib3\Net\SSH2::get_channel_packet() + */ + const CHANNEL_EXEC = 1; // PuTTy uses 0x100 + const CHANNEL_SHELL = 2; + const CHANNEL_SUBSYSTEM = 3; + const CHANNEL_AGENT_FORWARD = 4; + const CHANNEL_KEEP_ALIVE = 5; + + /** + * Returns the message numbers + * + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_SIMPLE = 1; + /** + * Returns the message content + * + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_COMPLEX = 2; + /** + * Outputs the content real-time + */ + const LOG_REALTIME = 3; + /** + * Dumps the content real-time to a file + */ + const LOG_REALTIME_FILE = 4; + /** + * Outputs the message numbers real-time + */ + const LOG_SIMPLE_REALTIME = 5; + /** + * Make sure that the log never gets larger than this + * + * @see \phpseclib3\Net\SSH2::getLog() + */ + const LOG_MAX_SIZE = 1048576; // 1024 * 1024 + + /** + * Returns when a string matching $expect exactly is found + * + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_SIMPLE = 1; + /** + * Returns when a string matching the regular expression $expect is found + * + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_REGEX = 2; + /** + * Returns whenever a data packet is received. + * + * Some data packets may only contain a single character so it may be necessary + * to call read() multiple times when using this option + * + * @see \phpseclib3\Net\SSH2::read() + */ + const READ_NEXT = 3; + + /** + * The SSH identifier + * + * @var string + */ + private $identifier; + + /** + * The Socket Object + * + * @var resource|closed-resource|null + */ + public $fsock; + + /** + * Execution Bitmap + * + * The bits that are set represent functions that have been called already. This is used to determine + * if a requisite function has been successfully executed. If not, an error should be thrown. + * + * @var int + */ + protected $bitmap = 0; + + /** + * Error information + * + * @see self::getErrors() + * @see self::getLastError() + * @var array + */ + private $errors = []; + + /** + * Server Identifier + * + * @see self::getServerIdentification() + * @var string|false + */ + protected $server_identifier = false; + + /** + * Key Exchange Algorithms + * + * @see self::getKexAlgorithims() + * @var array|false + */ + private $kex_algorithms = false; + + /** + * Key Exchange Algorithm + * + * @see self::getMethodsNegotiated() + * @var string|false + */ + private $kex_algorithm = false; + + /** + * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + */ + private $kex_dh_group_size_min = 1536; + + /** + * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + */ + private $kex_dh_group_size_preferred = 2048; + + /** + * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods + * + * @see self::_key_exchange() + * @var int + */ + private $kex_dh_group_size_max = 4096; + + /** + * Server Host Key Algorithms + * + * @see self::getServerHostKeyAlgorithms() + * @var array|false + */ + private $server_host_key_algorithms = false; + + /** + * Supported Private Key Algorithms + * + * In theory this should be the same as the Server Host Key Algorithms but, in practice, + * some servers (eg. Azure) will support rsa-sha2-512 as a server host key algorithm but + * not a private key algorithm + * + * @see self::privatekey_login() + * @var array|false + */ + private $supported_private_key_algorithms = false; + + /** + * Encryption Algorithms: Client to Server + * + * @see self::getEncryptionAlgorithmsClient2Server() + * @var array|false + */ + private $encryption_algorithms_client_to_server = false; + + /** + * Encryption Algorithms: Server to Client + * + * @see self::getEncryptionAlgorithmsServer2Client() + * @var array|false + */ + private $encryption_algorithms_server_to_client = false; + + /** + * MAC Algorithms: Client to Server + * + * @see self::getMACAlgorithmsClient2Server() + * @var array|false + */ + private $mac_algorithms_client_to_server = false; + + /** + * MAC Algorithms: Server to Client + * + * @see self::getMACAlgorithmsServer2Client() + * @var array|false + */ + private $mac_algorithms_server_to_client = false; + + /** + * Compression Algorithms: Client to Server + * + * @see self::getCompressionAlgorithmsClient2Server() + * @var array|false + */ + private $compression_algorithms_client_to_server = false; + + /** + * Compression Algorithms: Server to Client + * + * @see self::getCompressionAlgorithmsServer2Client() + * @var array|false + */ + private $compression_algorithms_server_to_client = false; + + /** + * Languages: Server to Client + * + * @see self::getLanguagesServer2Client() + * @var array|false + */ + private $languages_server_to_client = false; + + /** + * Languages: Client to Server + * + * @see self::getLanguagesClient2Server() + * @var array|false + */ + private $languages_client_to_server = false; + + /** + * Preferred Algorithms + * + * @see self::setPreferredAlgorithms() + * @var array + */ + private $preferred = []; + + /** + * Block Size for Server to Client Encryption + * + * "Note that the length of the concatenation of 'packet_length', + * 'padding_length', 'payload', and 'random padding' MUST be a multiple + * of the cipher block size or 8, whichever is larger. This constraint + * MUST be enforced, even when using stream ciphers." + * + * -- http://tools.ietf.org/html/rfc4253#section-6 + * + * @see self::__construct() + * @see self::_send_binary_packet() + * @var int + */ + private $encrypt_block_size = 8; + + /** + * Block Size for Client to Server Encryption + * + * @see self::__construct() + * @see self::_get_binary_packet() + * @var int + */ + private $decrypt_block_size = 8; + + /** + * Server to Client Encryption Object + * + * @see self::_get_binary_packet() + * @var SymmetricKey|false + */ + private $decrypt = false; + + /** + * Decryption Algorithm Name + * + * @var string|null + */ + private $decryptName; + + /** + * Decryption Invocation Counter + * + * Used by GCM + * + * @var string|null + */ + private $decryptInvocationCounter; + + /** + * Fixed Part of Nonce + * + * Used by GCM + * + * @var string|null + */ + private $decryptFixedPart; + + /** + * Server to Client Length Encryption Object + * + * @see self::_get_binary_packet() + * @var object + */ + private $lengthDecrypt = false; + + /** + * Client to Server Encryption Object + * + * @see self::_send_binary_packet() + * @var SymmetricKey|false + */ + private $encrypt = false; + + /** + * Encryption Algorithm Name + * + * @var string|null + */ + private $encryptName; + + /** + * Encryption Invocation Counter + * + * Used by GCM + * + * @var string|null + */ + private $encryptInvocationCounter; + + /** + * Fixed Part of Nonce + * + * Used by GCM + * + * @var string|null + */ + private $encryptFixedPart; + + /** + * Client to Server Length Encryption Object + * + * @see self::_send_binary_packet() + * @var object + */ + private $lengthEncrypt = false; + + /** + * Client to Server HMAC Object + * + * @see self::_send_binary_packet() + * @var object + */ + private $hmac_create = false; + + /** + * Client to Server HMAC Name + * + * @var string|false + */ + private $hmac_create_name; + + /** + * Client to Server ETM + * + * @var int|false + */ + private $hmac_create_etm; + + /** + * Server to Client HMAC Object + * + * @see self::_get_binary_packet() + * @var object + */ + private $hmac_check = false; + + /** + * Server to Client HMAC Name + * + * @var string|false + */ + private $hmac_check_name; + + /** + * Server to Client ETM + * + * @var int|false + */ + private $hmac_check_etm; + + /** + * Size of server to client HMAC + * + * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read. + * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is + * append it. + * + * @see self::_get_binary_packet() + * @var int + */ + private $hmac_size = false; + + /** + * Server Public Host Key + * + * @see self::getServerPublicHostKey() + * @var string + */ + private $server_public_host_key; + + /** + * Session identifier + * + * "The exchange hash H from the first key exchange is additionally + * used as the session identifier, which is a unique identifier for + * this connection." + * + * -- http://tools.ietf.org/html/rfc4253#section-7.2 + * + * @see self::_key_exchange() + * @var string + */ + private $session_id = false; + + /** + * Exchange hash + * + * The current exchange hash + * + * @see self::_key_exchange() + * @var string + */ + private $exchange_hash = false; + + /** + * Message Numbers + * + * @see self::__construct() + * @var array + * @access private + */ + private static $message_numbers = []; + + /** + * Disconnection Message 'reason codes' defined in RFC4253 + * + * @see self::__construct() + * @var array + * @access private + */ + private static $disconnect_reasons = []; + + /** + * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 + * + * @see self::__construct() + * @var array + * @access private + */ + private static $channel_open_failure_reasons = []; + + /** + * Terminal Modes + * + * @link http://tools.ietf.org/html/rfc4254#section-8 + * @see self::__construct() + * @var array + * @access private + */ + private static $terminal_modes = []; + + /** + * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes + * + * @link http://tools.ietf.org/html/rfc4254#section-5.2 + * @see self::__construct() + * @var array + * @access private + */ + private static $channel_extended_data_type_codes = []; + + /** + * Send Sequence Number + * + * See 'Section 6.4. Data Integrity' of rfc4253 for more info. + * + * @see self::_send_binary_packet() + * @var int + */ + private $send_seq_no = 0; + + /** + * Get Sequence Number + * + * See 'Section 6.4. Data Integrity' of rfc4253 for more info. + * + * @see self::_get_binary_packet() + * @var int + */ + private $get_seq_no = 0; + + /** + * Server Channels + * + * Maps client channels to server channels + * + * @see self::get_channel_packet() + * @see self::exec() + * @var array + */ + protected $server_channels = []; + + /** + * Channel Buffers + * + * If a client requests a packet from one channel but receives two packets from another those packets should + * be placed in a buffer + * + * @see self::get_channel_packet() + * @see self::exec() + * @var array + */ + private $channel_buffers = []; + + /** + * Channel Status + * + * Contains the type of the last sent message + * + * @see self::get_channel_packet() + * @var array + */ + protected $channel_status = []; + + /** + * The identifier of the interactive channel which was opened most recently + * + * @see self::getInteractiveChannelId() + * @var int + */ + private $channel_id_last_interactive = 0; + + /** + * Packet Size + * + * Maximum packet size indexed by channel + * + * @see self::send_channel_packet() + * @var array + */ + private $packet_size_client_to_server = []; + + /** + * Message Number Log + * + * @see self::getLog() + * @var array + */ + private $message_number_log = []; + + /** + * Message Log + * + * @see self::getLog() + * @var array + */ + private $message_log = []; + + /** + * The Window Size + * + * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) + * + * @var int + * @see self::send_channel_packet() + * @see self::exec() + */ + protected $window_size = 0x7FFFFFFF; + + /** + * What we resize the window to + * + * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes. + * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so + * we'll just do what PuTTY does + * + * @var int + * @see self::_send_channel_packet() + * @see self::exec() + */ + private $window_resize = 0x40000000; + + /** + * Window size, server to client + * + * Window size indexed by channel + * + * @see self::send_channel_packet() + * @var array + */ + protected $window_size_server_to_client = []; + + /** + * Window size, client to server + * + * Window size indexed by channel + * + * @see self::get_channel_packet() + * @var array + */ + private $window_size_client_to_server = []; + + /** + * Server signature + * + * Verified against $this->session_id + * + * @see self::getServerPublicHostKey() + * @var string + */ + private $signature = ''; + + /** + * Server signature format + * + * ssh-rsa or ssh-dss. + * + * @see self::getServerPublicHostKey() + * @var string + */ + private $signature_format = ''; + + /** + * Interactive Buffer + * + * @see self::read() + * @var string + */ + private $interactiveBuffer = ''; + + /** + * Current log size + * + * Should never exceed self::LOG_MAX_SIZE + * + * @see self::_send_binary_packet() + * @see self::_get_binary_packet() + * @var int + */ + private $log_size; + + /** + * Timeout + * + * @see self::setTimeout() + */ + protected $timeout; + + /** + * Current Timeout + * + * @see self::get_channel_packet() + */ + protected $curTimeout; + + /** + * Keep Alive Interval + * + * @see self::setKeepAlive() + */ + private $keepAlive; + + /** + * Real-time log file pointer + * + * @see self::_append_log() + * @var resource|closed-resource + */ + private $realtime_log_file; + + /** + * Real-time log file size + * + * @see self::_append_log() + * @var int + */ + private $realtime_log_size; + + /** + * Has the signature been validated? + * + * @see self::getServerPublicHostKey() + * @var bool + */ + private $signature_validated = false; + + /** + * Real-time log file wrap boolean + * + * @see self::_append_log() + * @var bool + */ + private $realtime_log_wrap; + + /** + * Flag to suppress stderr from output + * + * @see self::enableQuietMode() + */ + private $quiet_mode = false; + + /** + * Time of first network activity + * + * @var float + */ + private $last_packet; + + /** + * Exit status returned from ssh if any + * + * @var int + */ + private $exit_status; + + /** + * Flag to request a PTY when using exec() + * + * @var bool + * @see self::enablePTY() + */ + private $request_pty = false; + + /** + * Contents of stdError + * + * @var string + */ + private $stdErrorLog; + + /** + * The Last Interactive Response + * + * @see self::_keyboard_interactive_process() + * @var string + */ + private $last_interactive_response = ''; + + /** + * Keyboard Interactive Request / Responses + * + * @see self::_keyboard_interactive_process() + * @var array + */ + private $keyboard_requests_responses = []; + + /** + * Banner Message + * + * Quoting from the RFC, "in some jurisdictions, sending a warning message before + * authentication may be relevant for getting legal protection." + * + * @see self::_filter() + * @see self::getBannerMessage() + * @var string + */ + private $banner_message = ''; + + /** + * Did read() timeout or return normally? + * + * @see self::isTimeout() + * @var bool + */ + private $is_timeout = false; + + /** + * Log Boundary + * + * @see self::_format_log() + * @var string + */ + private $log_boundary = ':'; + + /** + * Log Long Width + * + * @see self::_format_log() + * @var int + */ + private $log_long_width = 65; + + /** + * Log Short Width + * + * @see self::_format_log() + * @var int + */ + private $log_short_width = 16; + + /** + * Hostname + * + * @see self::__construct() + * @see self::_connect() + * @var string + */ + private $host; + + /** + * Port Number + * + * @see self::__construct() + * @see self::_connect() + * @var int + */ + private $port; + + /** + * Number of columns for terminal window size + * + * @see self::getWindowColumns() + * @see self::setWindowColumns() + * @see self::setWindowSize() + * @var int + */ + private $windowColumns = 80; + + /** + * Number of columns for terminal window size + * + * @see self::getWindowRows() + * @see self::setWindowRows() + * @see self::setWindowSize() + * @var int + */ + private $windowRows = 24; + + /** + * Crypto Engine + * + * @see self::setCryptoEngine() + * @see self::_key_exchange() + * @var int + */ + private static $crypto_engine = false; + + /** + * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario + * + * @var Agent + */ + private $agent; + + /** + * Connection storage to replicates ssh2 extension functionality: + * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples} + * + * @var array> + */ + private static $connections; + + /** + * Send the identification string first? + * + * @var bool + */ + private $send_id_string_first = true; + + /** + * Send the key exchange initiation packet first? + * + * @var bool + */ + private $send_kex_first = true; + + /** + * Some versions of OpenSSH incorrectly calculate the key size + * + * @var bool + */ + private $bad_key_size_fix = false; + + /** + * Should we try to re-connect to re-establish keys? + * + * @var bool + */ + private $retry_connect = false; + + /** + * Binary Packet Buffer + * + * @var string|false + */ + private $binary_packet_buffer = false; + + /** + * Preferred Signature Format + * + * @var string|false + */ + protected $preferred_signature_format = false; + + /** + * Authentication Credentials + * + * @var array + */ + protected $auth = []; + + /** + * Terminal + * + * @var string + */ + private $term = 'vt100'; + + /** + * The authentication methods that may productively continue authentication. + * + * @see https://tools.ietf.org/html/rfc4252#section-5.1 + * @var array|null + */ + private $auth_methods_to_continue = null; + + /** + * Compression method + * + * @var int + */ + private $compress = self::NET_SSH2_COMPRESSION_NONE; + + /** + * Decompression method + * + * @var int + */ + private $decompress = self::NET_SSH2_COMPRESSION_NONE; + + /** + * Compression context + * + * @var resource|false|null + */ + private $compress_context; + + /** + * Decompression context + * + * @var resource|object + */ + private $decompress_context; + + /** + * Regenerate Compression Context + * + * @var bool + */ + private $regenerate_compression_context = false; + + /** + * Regenerate Decompression Context + * + * @var bool + */ + private $regenerate_decompression_context = false; + + /** + * Smart multi-factor authentication flag + * + * @var bool + */ + private $smartMFA = true; + + /** + * How many channels are currently opened + * + * @var int + */ + private $channelCount = 0; + + /** + * Does the server support multiple channels? If not then error out + * when multiple channels are attempted to be opened + * + * @var bool + */ + private $errorOnMultipleChannels; + + /** + * Terrapin Countermeasure + * + * "During initial KEX, terminate the connection if any unexpected or out-of-sequence packet is received" + * -- https://github.com/openssh/openssh-portable/commit/1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 + * + * @var int + */ + private $extra_packets; + + /** + * Default Constructor. + * + * $host can either be a string, representing the host, or a stream resource. + * + * @param mixed $host + * @param int $port + * @param int $timeout + * @see self::login() + */ + public function __construct($host, $port = 22, $timeout = 10) + { + if (empty(self::$message_numbers)) { + self::$message_numbers = [ + 1 => 'NET_SSH2_MSG_DISCONNECT', + 2 => 'NET_SSH2_MSG_IGNORE', + 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', + 4 => 'NET_SSH2_MSG_DEBUG', + 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', + 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', + 7 => 'NET_SSH2_MSG_EXT_INFO', // RFC 8308 + 20 => 'NET_SSH2_MSG_KEXINIT', + 21 => 'NET_SSH2_MSG_NEWKEYS', + 30 => 'NET_SSH2_MSG_KEXDH_INIT', + 31 => 'NET_SSH2_MSG_KEXDH_REPLY', + 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', + 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', + 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', + 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', + + 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', + 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', + 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', + 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', + 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', + 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', + 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', + 94 => 'NET_SSH2_MSG_CHANNEL_DATA', + 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', + 96 => 'NET_SSH2_MSG_CHANNEL_EOF', + 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', + 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', + 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', + 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' + ]; + self::$disconnect_reasons = [ + 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', + 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', + 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', + 4 => 'NET_SSH2_DISCONNECT_RESERVED', + 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', + 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', + 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', + 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', + 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', + 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', + 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', + 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', + 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', + 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', + 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' + ]; + self::$channel_open_failure_reasons = [ + 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' + ]; + self::$terminal_modes = [ + 0 => 'NET_SSH2_TTY_OP_END' + ]; + self::$channel_extended_data_type_codes = [ + 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' + ]; + + self::define_array( + self::$message_numbers, + self::$disconnect_reasons, + self::$channel_open_failure_reasons, + self::$terminal_modes, + self::$channel_extended_data_type_codes, + [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], + [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], + [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', + 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], + // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} + [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', + 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', + 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', + 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', + 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], + // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) + [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', + 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] + ); + } + + /** + * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508 + * @var \WeakReference|SSH2 + */ + self::$connections[$this->getResourceId()] = class_exists('WeakReference') + ? \WeakReference::create($this) + : $this; + + if (is_resource($host)) { + $this->fsock = $host; + return; + } + + if (Strings::is_stringable($host)) { + $this->host = $host; + $this->port = $port; + $this->timeout = $timeout; + } + } + + /** + * Set Crypto Engine Mode + * + * Possible $engine values: + * OpenSSL, mcrypt, Eval, PHP + * + * @param int $engine + */ + public static function setCryptoEngine($engine) + { + self::$crypto_engine = $engine; + } + + /** + * Send Identification String First + * + * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, + * both sides MUST send an identification string". It does not say which side sends it first. In + * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendIdentificationStringFirst() + { + $this->send_id_string_first = true; + } + + /** + * Send Identification String Last + * + * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, + * both sides MUST send an identification string". It does not say which side sends it first. In + * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendIdentificationStringLast() + { + $this->send_id_string_first = false; + } + + /** + * Send SSH_MSG_KEXINIT First + * + * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending + * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory + * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendKEXINITFirst() + { + $this->send_kex_first = true; + } + + /** + * Send SSH_MSG_KEXINIT Last + * + * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending + * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory + * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy + * + */ + public function sendKEXINITLast() + { + $this->send_kex_first = false; + } + + /** + * stream_select wrapper + * + * Quoting https://stackoverflow.com/a/14262151/569976, + * "The general approach to `EINTR` is to simply handle the error and retry the operation again" + * + * This wrapper does that loop + */ + private static function stream_select(&$read, &$write, &$except, $seconds, $microseconds = null) + { + $remaining = $seconds + $microseconds / 1000000; + $start = microtime(true); + while (true) { + $result = @stream_select($read, $write, $except, $seconds, $microseconds); + if ($result !== false) { + return $result; + } + $elapsed = microtime(true) - $start; + $seconds = (int) ($remaining - floor($elapsed)); + $microseconds = (int) (1000000 * ($remaining - $seconds)); + if ($elapsed >= $remaining) { + return false; + } + } + } + + /** + * Connect to an SSHv2 server + * + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + private function connect() + { + if ($this->bitmap & self::MASK_CONSTRUCTOR) { + return; + } + + $this->bitmap |= self::MASK_CONSTRUCTOR; + + $this->curTimeout = $this->timeout; + + $this->last_packet = microtime(true); + + if (!is_resource($this->fsock)) { + $start = microtime(true); + // with stream_select a timeout of 0 means that no timeout takes place; + // with fsockopen a timeout of 0 means that you instantly timeout + // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0 + $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); + if (!$this->fsock) { + $host = $this->host . ':' . $this->port; + throw new UnableToConnectException(rtrim("Cannot connect to $host. Error $errno. $errstr")); + } + $elapsed = microtime(true) - $start; + + if ($this->curTimeout) { + $this->curTimeout -= $elapsed; + if ($this->curTimeout < 0) { + throw new \RuntimeException('Connection timed out whilst attempting to open socket connection'); + } + } + } + + $this->identifier = $this->generate_identifier(); + + if ($this->send_id_string_first) { + fputs($this->fsock, $this->identifier . "\r\n"); + } + + /* According to the SSH2 specs, + + "The server MAY send other lines of data before sending the version + string. Each line SHOULD be terminated by a Carriage Return and Line + Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded + in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients + MUST be able to process such lines." */ + $data = ''; + while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) { + $line = ''; + while (true) { + if ($this->curTimeout) { + if ($this->curTimeout < 0) { + throw new \RuntimeException('Connection timed out whilst receiving server identification string'); + } + $read = [$this->fsock]; + $write = $except = null; + $start = microtime(true); + $sec = (int) floor($this->curTimeout); + $usec = (int) (1000000 * ($this->curTimeout - $sec)); + if (static::stream_select($read, $write, $except, $sec, $usec) === false) { + throw new \RuntimeException('Connection timed out whilst receiving server identification string'); + } + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + } + + $temp = stream_get_line($this->fsock, 255, "\n"); + if ($temp === false) { + throw new \RuntimeException('Error reading from socket'); + } + if (strlen($temp) == 255) { + continue; + } + + $line .= "$temp\n"; + + // quoting RFC4253, "Implementers who wish to maintain + // compatibility with older, undocumented versions of this protocol may + // want to process the identification string without expecting the + // presence of the carriage return character for reasons described in + // Section 5 of this document." + + //if (substr($line, -2) == "\r\n") { + // break; + //} + + break; + } + + $data .= $line; + } + + if (feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed by server'); + } + + $extra = $matches[1]; + + if (defined('NET_SSH2_LOGGING')) { + $this->append_log('<-', $matches[0]); + $this->append_log('->', $this->identifier . "\r\n"); + } + + $this->server_identifier = trim($temp, "\r\n"); + if (strlen($extra)) { + $this->errors[] = $data; + } + + if (version_compare($matches[3], '1.99', '<')) { + $this->bitmap = 0; + throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); + } + + // Ubuntu's OpenSSH from 5.8 to 6.9 didn't work with multiple channels. see + // https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1334916 for more info. + // https://lists.ubuntu.com/archives/oneiric-changes/2011-July/005772.html discusses + // when consolekit was incorporated. + // https://marc.info/?l=openssh-unix-dev&m=163409903417589&w=2 discusses some of the + // issues with how Ubuntu incorporated consolekit + $pattern = '#^SSH-2\.0-OpenSSH_([\d.]+)[^ ]* Ubuntu-.*$#'; + $match = preg_match($pattern, $this->server_identifier, $matches); + $match = $match && version_compare('5.8', $matches[1], '<='); + $match = $match && version_compare('6.9', $matches[1], '>='); + $this->errorOnMultipleChannels = $match; + + if (!$this->send_id_string_first) { + fputs($this->fsock, $this->identifier . "\r\n"); + } + + if (!$this->send_kex_first) { + $response = $this->get_binary_packet(); + + if (is_bool($response) || !strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) { + $this->bitmap = 0; + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + } + + $this->key_exchange($response); + } + + if ($this->send_kex_first) { + $this->key_exchange(); + } + + $this->bitmap |= self::MASK_CONNECTED; + + return true; + } + + /** + * Generates the SSH identifier + * + * You should overwrite this method in your own class if you want to use another identifier + * + * @return string + */ + private function generate_identifier() + { + $identifier = 'SSH-2.0-phpseclib_3.0'; + + $ext = []; + if (extension_loaded('sodium')) { + $ext[] = 'libsodium'; + } + + if (extension_loaded('openssl')) { + $ext[] = 'openssl'; + } elseif (extension_loaded('mcrypt')) { + $ext[] = 'mcrypt'; + } + + if (extension_loaded('gmp')) { + $ext[] = 'gmp'; + } elseif (extension_loaded('bcmath')) { + $ext[] = 'bcmath'; + } + + if (!empty($ext)) { + $identifier .= ' (' . implode(', ', $ext) . ')'; + } + + return $identifier; + } + + /** + * Key Exchange + * + * @return bool + * @param string|bool $kexinit_payload_server optional + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible + */ + private function key_exchange($kexinit_payload_server = false) + { + $preferred = $this->preferred; + $send_kex = true; + + $kex_algorithms = isset($preferred['kex']) ? + $preferred['kex'] : + SSH2::getSupportedKEXAlgorithms(); + $server_host_key_algorithms = isset($preferred['hostkey']) ? + $preferred['hostkey'] : + SSH2::getSupportedHostKeyAlgorithms(); + $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? + $preferred['server_to_client']['crypt'] : + SSH2::getSupportedEncryptionAlgorithms(); + $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? + $preferred['client_to_server']['crypt'] : + SSH2::getSupportedEncryptionAlgorithms(); + $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? + $preferred['server_to_client']['mac'] : + SSH2::getSupportedMACAlgorithms(); + $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? + $preferred['client_to_server']['mac'] : + SSH2::getSupportedMACAlgorithms(); + $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? + $preferred['server_to_client']['comp'] : + SSH2::getSupportedCompressionAlgorithms(); + $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? + $preferred['client_to_server']['comp'] : + SSH2::getSupportedCompressionAlgorithms(); + + $kex_algorithms = array_merge($kex_algorithms, ['ext-info-c', 'kex-strict-c-v00@openssh.com']); + + // some SSH servers have buggy implementations of some of the above algorithms + switch (true) { + case $this->server_identifier == 'SSH-2.0-SSHD': + case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK': + if (!isset($preferred['server_to_client']['mac'])) { + $s2c_mac_algorithms = array_values(array_diff( + $s2c_mac_algorithms, + ['hmac-sha1-96', 'hmac-md5-96'] + )); + } + if (!isset($preferred['client_to_server']['mac'])) { + $c2s_mac_algorithms = array_values(array_diff( + $c2s_mac_algorithms, + ['hmac-sha1-96', 'hmac-md5-96'] + )); + } + break; + case substr($this->server_identifier, 0, 24) == 'SSH-2.0-TurboFTP_SERVER_': + if (!isset($preferred['server_to_client']['crypt'])) { + $s2c_encryption_algorithms = array_values(array_diff( + $s2c_encryption_algorithms, + ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] + )); + } + if (!isset($preferred['client_to_server']['crypt'])) { + $c2s_encryption_algorithms = array_values(array_diff( + $c2s_encryption_algorithms, + ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] + )); + } + } + + $client_cookie = Random::string(16); + + $kexinit_payload_client = pack('Ca*', NET_SSH2_MSG_KEXINIT, $client_cookie); + $kexinit_payload_client .= Strings::packSSH2( + 'L10bN', + $kex_algorithms, + $server_host_key_algorithms, + $c2s_encryption_algorithms, + $s2c_encryption_algorithms, + $c2s_mac_algorithms, + $s2c_mac_algorithms, + $c2s_compression_algorithms, + $s2c_compression_algorithms, + [], // language, client to server + [], // language, server to client + false, // first_kex_packet_follows + 0 // reserved for future extension + ); + + if ($kexinit_payload_server === false) { + $this->send_binary_packet($kexinit_payload_client); + + $this->extra_packets = 0; + $kexinit_payload_server = $this->get_binary_packet(); + + if ( + is_bool($kexinit_payload_server) + || !strlen($kexinit_payload_server) + || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT + ) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); + } + + $send_kex = false; + } + + $response = $kexinit_payload_server; + Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) + $server_cookie = Strings::shift($response, 16); + + list( + $this->kex_algorithms, + $this->server_host_key_algorithms, + $this->encryption_algorithms_client_to_server, + $this->encryption_algorithms_server_to_client, + $this->mac_algorithms_client_to_server, + $this->mac_algorithms_server_to_client, + $this->compression_algorithms_client_to_server, + $this->compression_algorithms_server_to_client, + $this->languages_client_to_server, + $this->languages_server_to_client, + $first_kex_packet_follows + ) = Strings::unpackSSH2('L10C', $response); + if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { + if ($this->session_id === false && $this->extra_packets) { + throw new \UnexpectedValueException('Possible Terrapin Attack detected'); + } + } + + $this->supported_private_key_algorithms = $this->server_host_key_algorithms; + + if ($send_kex) { + $this->send_binary_packet($kexinit_payload_client); + } + + // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange + + // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the + // diffie-hellman key exchange as fast as possible + $decrypt = self::array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); + $decryptKeyLength = $this->encryption_algorithm_to_key_size($decrypt); + if ($decryptKeyLength === null) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found'); + } + + $encrypt = self::array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); + $encryptKeyLength = $this->encryption_algorithm_to_key_size($encrypt); + if ($encryptKeyLength === null) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); + } + + // through diffie-hellman key exchange a symmetric key is obtained + $this->kex_algorithm = self::array_intersect_first($kex_algorithms, $this->kex_algorithms); + if ($this->kex_algorithm === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); + } + + $server_host_key_algorithm = self::array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); + if ($server_host_key_algorithm === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); + } + + $mac_algorithm_out = self::array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); + if ($mac_algorithm_out === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); + } + + $mac_algorithm_in = self::array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); + if ($mac_algorithm_in === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); + } + + $compression_map = [ + 'none' => self::NET_SSH2_COMPRESSION_NONE, + 'zlib' => self::NET_SSH2_COMPRESSION_ZLIB, + 'zlib@openssh.com' => self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH + ]; + + $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); + if ($compression_algorithm_in === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); + } + $this->decompress = $compression_map[$compression_algorithm_in]; + + $compression_algorithm_out = self::array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); + if ($compression_algorithm_out === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); + } + $this->compress = $compression_map[$compression_algorithm_out]; + + switch ($this->kex_algorithm) { + case 'diffie-hellman-group15-sha512': + case 'diffie-hellman-group16-sha512': + case 'diffie-hellman-group17-sha512': + case 'diffie-hellman-group18-sha512': + case 'ecdh-sha2-nistp521': + $kexHash = new Hash('sha512'); + break; + case 'ecdh-sha2-nistp384': + $kexHash = new Hash('sha384'); + break; + case 'diffie-hellman-group-exchange-sha256': + case 'diffie-hellman-group14-sha256': + case 'ecdh-sha2-nistp256': + case 'curve25519-sha256@libssh.org': + case 'curve25519-sha256': + $kexHash = new Hash('sha256'); + break; + default: + $kexHash = new Hash('sha1'); + } + + // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. + + $exchange_hash_rfc4419 = ''; + + if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { + $curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? + 'Curve25519' : + substr($this->kex_algorithm, 10); + $ourPrivate = EC::createKey($curve); + $ourPublicBytes = $ourPrivate->getPublicKey()->getEncodedCoordinates(); + $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; + } else { + if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { + $dh_group_sizes_packed = pack( + 'NNN', + $this->kex_dh_group_size_min, + $this->kex_dh_group_size_preferred, + $this->kex_dh_group_size_max + ); + $packet = pack( + 'Ca*', + NET_SSH2_MSG_KEXDH_GEX_REQUEST, + $dh_group_sizes_packed + ); + $this->send_binary_packet($packet); + $this->updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); + + $response = $this->get_binary_packet(); + + list($type, $primeBytes, $gBytes) = Strings::unpackSSH2('Css', $response); + if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); + } + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); + $prime = new BigInteger($primeBytes, -256); + $g = new BigInteger($gBytes, -256); + + $exchange_hash_rfc4419 = $dh_group_sizes_packed . Strings::packSSH2( + 'ss', + $primeBytes, + $gBytes + ); + + $params = DH::createParameters($prime, $g); + $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; + } else { + $params = DH::createParameters($this->kex_algorithm); + $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; + $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; + } + + $keyLength = min($kexHash->getLengthInBytes(), max($encryptKeyLength, $decryptKeyLength)); + + $ourPrivate = DH::createKey($params, 16 * $keyLength); // 2 * 8 * $keyLength + $ourPublic = $ourPrivate->getPublicKey()->toBigInteger(); + $ourPublicBytes = $ourPublic->toBytes(true); + } + + $data = pack('CNa*', constant($clientKexInitMessage), strlen($ourPublicBytes), $ourPublicBytes); + + $this->send_binary_packet($data); + + switch ($clientKexInitMessage) { + case 'NET_SSH2_MSG_KEX_ECDH_INIT': + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); + break; + case 'NET_SSH2_MSG_KEXDH_GEX_INIT': + $this->updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); + } + + $response = $this->get_binary_packet(); + + list( + $type, + $server_public_host_key, + $theirPublicBytes, + $this->signature + ) = Strings::unpackSSH2('Csss', $response); + + if ($type != constant($serverKexReplyMessage)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException("Expected $serverKexReplyMessage"); + } + switch ($serverKexReplyMessage) { + case 'NET_SSH2_MSG_KEX_ECDH_REPLY': + $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); + break; + case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': + $this->updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); + } + + $this->server_public_host_key = $server_public_host_key; + list($public_key_format) = Strings::unpackSSH2('s', $server_public_host_key); + if (strlen($this->signature) < 4) { + throw new \LengthException('The signature needs at least four bytes'); + } + $temp = unpack('Nlength', substr($this->signature, 0, 4)); + $this->signature_format = substr($this->signature, 4, $temp['length']); + + $keyBytes = DH::computeSecret($ourPrivate, $theirPublicBytes); + if (($keyBytes & "\xFF\x80") === "\x00\x00") { + $keyBytes = substr($keyBytes, 1); + } elseif (($keyBytes[0] & "\x80") === "\x80") { + $keyBytes = "\0$keyBytes"; + } + + $this->exchange_hash = Strings::packSSH2( + 's5', + $this->identifier, + $this->server_identifier, + $kexinit_payload_client, + $kexinit_payload_server, + $this->server_public_host_key + ); + $this->exchange_hash .= $exchange_hash_rfc4419; + $this->exchange_hash .= Strings::packSSH2( + 's3', + $ourPublicBytes, + $theirPublicBytes, + $keyBytes + ); + + $this->exchange_hash = $kexHash->hash($this->exchange_hash); + + if ($this->session_id === false) { + $this->session_id = $this->exchange_hash; + } + + switch ($server_host_key_algorithm) { + case 'rsa-sha2-256': + case 'rsa-sha2-512': + //case 'ssh-rsa': + $expected_key_format = 'ssh-rsa'; + break; + default: + $expected_key_format = $server_host_key_algorithm; + } + if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { + switch (true) { + case $this->signature_format == $server_host_key_algorithm: + case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': + case $this->signature_format != 'ssh-rsa': + $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new \RuntimeException('Server Host Key Algorithm Mismatch (' . $this->signature_format . ' vs ' . $server_host_key_algorithm . ')'); + } + } + + $packet = pack('C', NET_SSH2_MSG_NEWKEYS); + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + + list($type) = Strings::unpackSSH2('C', $response); + if ($type != NET_SSH2_MSG_NEWKEYS) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); + } + + if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { + $this->get_seq_no = $this->send_seq_no = 0; + } + + $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); + + $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + if ($this->encrypt) { + if (self::$crypto_engine) { + $this->encrypt->setPreferredEngine(self::$crypto_engine); + } + if ($this->encrypt->getBlockLengthInBytes()) { + $this->encrypt_block_size = $this->encrypt->getBlockLengthInBytes(); + } + $this->encrypt->disablePadding(); + + if ($this->encrypt->usesIV()) { + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + while ($this->encrypt_block_size > strlen($iv)) { + $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); + } + $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); + } + + switch ($encrypt) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); + $this->encryptFixedPart = substr($nonce, 0, 4); + $this->encryptInvocationCounter = substr($nonce, 4, 8); + // fall-through + case 'chacha20-poly1305@openssh.com': + break; + default: + $this->encrypt->enableContinuousBuffer(); + } + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); + while ($encryptKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + switch ($encrypt) { + case 'chacha20-poly1305@openssh.com': + $encryptKeyLength = 32; + $this->lengthEncrypt = self::encryption_algorithm_to_crypt_instance($encrypt); + $this->lengthEncrypt->setKey(substr($key, 32, 32)); + } + $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); + $this->encryptName = $encrypt; + } + + $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + if ($this->decrypt) { + if (self::$crypto_engine) { + $this->decrypt->setPreferredEngine(self::$crypto_engine); + } + if ($this->decrypt->getBlockLengthInBytes()) { + $this->decrypt_block_size = $this->decrypt->getBlockLengthInBytes(); + } + $this->decrypt->disablePadding(); + + if ($this->decrypt->usesIV()) { + $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + while ($this->decrypt_block_size > strlen($iv)) { + $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); + } + $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); + } + + switch ($decrypt) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + // see https://tools.ietf.org/html/rfc5647#section-7.1 + $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); + $this->decryptFixedPart = substr($nonce, 0, 4); + $this->decryptInvocationCounter = substr($nonce, 4, 8); + // fall-through + case 'chacha20-poly1305@openssh.com': + break; + default: + $this->decrypt->enableContinuousBuffer(); + } + + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); + while ($decryptKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + switch ($decrypt) { + case 'chacha20-poly1305@openssh.com': + $decryptKeyLength = 32; + $this->lengthDecrypt = self::encryption_algorithm_to_crypt_instance($decrypt); + $this->lengthDecrypt->setKey(substr($key, 32, 32)); + } + $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); + $this->decryptName = $decrypt; + } + + /* The "arcfour128" algorithm is the RC4 cipher, as described in + [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream + generated by the cipher MUST be discarded, and the first byte of the + first encrypted packet MUST be encrypted using the 1537th byte of + keystream. + + -- http://tools.ietf.org/html/rfc4345#section-4 */ + if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') { + $this->encrypt->encrypt(str_repeat("\0", 1536)); + } + if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') { + $this->decrypt->decrypt(str_repeat("\0", 1536)); + } + + if (!$this->encrypt->usesNonce()) { + list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out); + } else { + $this->hmac_create = new \stdClass(); + $this->hmac_create_name = $mac_algorithm_out; + //$mac_algorithm_out = 'none'; + $createKeyLength = 0; + } + + if ($this->hmac_create instanceof Hash) { + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); + while ($createKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); + $this->hmac_create_name = $mac_algorithm_out; + $this->hmac_create_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out); + } + + if (!$this->decrypt->usesNonce()) { + list($this->hmac_check, $checkKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_in); + $this->hmac_size = $this->hmac_check->getLengthInBytes(); + } else { + $this->hmac_check = new \stdClass(); + $this->hmac_check_name = $mac_algorithm_in; + //$mac_algorithm_in = 'none'; + $checkKeyLength = 0; + $this->hmac_size = 0; + } + + if ($this->hmac_check instanceof Hash) { + $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); + while ($checkKeyLength > strlen($key)) { + $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); + } + $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); + $this->hmac_check_name = $mac_algorithm_in; + $this->hmac_check_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in); + } + + $this->regenerate_compression_context = $this->regenerate_decompression_context = true; + + return true; + } + + /** + * Maps an encryption algorithm name to the number of key bytes. + * + * @param string $algorithm Name of the encryption algorithm + * @return int|null Number of bytes as an integer or null for unknown + */ + private function encryption_algorithm_to_key_size($algorithm) + { + if ($this->bad_key_size_fix && self::bad_algorithm_candidate($algorithm)) { + return 16; + } + + switch ($algorithm) { + case 'none': + return 0; + case 'aes128-gcm@openssh.com': + case 'aes128-cbc': + case 'aes128-ctr': + case 'arcfour': + case 'arcfour128': + case 'blowfish-cbc': + case 'blowfish-ctr': + case 'twofish128-cbc': + case 'twofish128-ctr': + return 16; + case '3des-cbc': + case '3des-ctr': + case 'aes192-cbc': + case 'aes192-ctr': + case 'twofish192-cbc': + case 'twofish192-ctr': + return 24; + case 'aes256-gcm@openssh.com': + case 'aes256-cbc': + case 'aes256-ctr': + case 'arcfour256': + case 'twofish-cbc': + case 'twofish256-cbc': + case 'twofish256-ctr': + return 32; + case 'chacha20-poly1305@openssh.com': + return 64; + } + return null; + } + + /** + * Maps an encryption algorithm name to an instance of a subclass of + * \phpseclib3\Crypt\Common\SymmetricKey. + * + * @param string $algorithm Name of the encryption algorithm + * @return SymmetricKey|null + */ + private static function encryption_algorithm_to_crypt_instance($algorithm) + { + switch ($algorithm) { + case '3des-cbc': + return new TripleDES('cbc'); + case '3des-ctr': + return new TripleDES('ctr'); + case 'aes256-cbc': + case 'aes192-cbc': + case 'aes128-cbc': + return new Rijndael('cbc'); + case 'aes256-ctr': + case 'aes192-ctr': + case 'aes128-ctr': + return new Rijndael('ctr'); + case 'blowfish-cbc': + return new Blowfish('cbc'); + case 'blowfish-ctr': + return new Blowfish('ctr'); + case 'twofish128-cbc': + case 'twofish192-cbc': + case 'twofish256-cbc': + case 'twofish-cbc': + return new Twofish('cbc'); + case 'twofish128-ctr': + case 'twofish192-ctr': + case 'twofish256-ctr': + return new Twofish('ctr'); + case 'arcfour': + case 'arcfour128': + case 'arcfour256': + return new RC4(); + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + return new Rijndael('gcm'); + case 'chacha20-poly1305@openssh.com': + return new ChaCha20(); + } + return null; + } + + /** + * Maps an encryption algorithm name to an instance of a subclass of + * \phpseclib3\Crypt\Hash. + * + * @param string $algorithm Name of the encryption algorithm + * @return array{Hash, int}|null + */ + private static function mac_algorithm_to_hash_instance($algorithm) + { + switch ($algorithm) { + case 'umac-64@openssh.com': + case 'umac-64-etm@openssh.com': + return [new Hash('umac-64'), 16]; + case 'umac-128@openssh.com': + case 'umac-128-etm@openssh.com': + return [new Hash('umac-128'), 16]; + case 'hmac-sha2-512': + case 'hmac-sha2-512-etm@openssh.com': + return [new Hash('sha512'), 64]; + case 'hmac-sha2-256': + case 'hmac-sha2-256-etm@openssh.com': + return [new Hash('sha256'), 32]; + case 'hmac-sha1': + case 'hmac-sha1-etm@openssh.com': + return [new Hash('sha1'), 20]; + case 'hmac-sha1-96': + return [new Hash('sha1-96'), 20]; + case 'hmac-md5': + return [new Hash('md5'), 16]; + case 'hmac-md5-96': + return [new Hash('md5-96'), 16]; + } + } + + /* + * Tests whether or not proposed algorithm has a potential for issues + * + * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html + * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291 + * @param string $algorithm Name of the encryption algorithm + * @return bool + */ + private static function bad_algorithm_candidate($algorithm) + { + switch ($algorithm) { + case 'arcfour256': + case 'aes192-ctr': + case 'aes256-ctr': + return true; + } + + return false; + } + + /** + * Login + * + * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA|EC|DSA object, a \phpseclib3\System\SSH\Agent object or an array + * + * @param string $username + * @param string|PrivateKey|array[]|Agent|null ...$args + * @return bool + * @see self::_login() + */ + public function login($username, ...$args) + { + if (!$this->retry_connect) { + $this->auth[] = func_get_args(); + } + + // try logging with 'none' as an authentication method first since that's what + // PuTTY does + if (substr($this->server_identifier, 0, 15) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) { + if ($this->sublogin($username)) { + return true; + } + if (!count($args)) { + return false; + } + } + return $this->sublogin($username, ...$args); + } + + /** + * Login Helper + * + * @param string $username + * @param string|PrivateKey|array[]|Agent|null ...$args + * @return bool + * @see self::_login_helper() + */ + protected function sublogin($username, ...$args) + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + $this->connect(); + } + + if (empty($args)) { + return $this->login_helper($username); + } + + foreach ($args as $arg) { + switch (true) { + case $arg instanceof PublicKey: + throw new \UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object'); + case $arg instanceof PrivateKey: + case $arg instanceof Agent: + case is_array($arg): + case Strings::is_stringable($arg): + break; + default: + throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); + } + } + + while (count($args)) { + if (!$this->auth_methods_to_continue || !$this->smartMFA) { + $newargs = $args; + $args = []; + } else { + $newargs = []; + foreach ($this->auth_methods_to_continue as $method) { + switch ($method) { + case 'publickey': + foreach ($args as $key => $arg) { + if ($arg instanceof PrivateKey || $arg instanceof Agent) { + $newargs[] = $arg; + unset($args[$key]); + break; + } + } + break; + case 'keyboard-interactive': + $hasArray = $hasString = false; + foreach ($args as $arg) { + if ($hasArray || is_array($arg)) { + $hasArray = true; + break; + } + if ($hasString || Strings::is_stringable($arg)) { + $hasString = true; + break; + } + } + if ($hasArray && $hasString) { + foreach ($args as $key => $arg) { + if (is_array($arg)) { + $newargs[] = $arg; + break 2; + } + } + } + // fall-through + case 'password': + foreach ($args as $key => $arg) { + $newargs[] = $arg; + unset($args[$key]); + break; + } + } + } + } + + if (!count($newargs)) { + return false; + } + + foreach ($newargs as $arg) { + if ($this->login_helper($username, $arg)) { + return true; + } + } + } + return false; + } + + /** + * Login Helper + * + * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages.} + * + * @param string $username + * @param string|AsymmetricKey|array[]|Agent|null ...$args + * @return bool + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + private function login_helper($username, $password = null) + { + if (!($this->bitmap & self::MASK_CONNECTED)) { + return false; + } + + if (!($this->bitmap & self::MASK_LOGIN_REQ)) { + $packet = Strings::packSSH2('Cs', NET_SSH2_MSG_SERVICE_REQUEST, 'ssh-userauth'); + $this->send_binary_packet($packet); + + try { + $response = $this->get_binary_packet(); + } catch (\Exception $e) { + if ($this->retry_connect) { + $this->retry_connect = false; + $this->connect(); + return $this->login_helper($username, $password); + } + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw $e; + } + + list($type) = Strings::unpackSSH2('C', $response); + + if ($type == NET_SSH2_MSG_EXT_INFO) { + list($nr_extensions) = Strings::unpackSSH2('N', $response); + for ($i = 0; $i < $nr_extensions; $i++) { + list($extension_name, $extension_value) = Strings::unpackSSH2('ss', $response); + if ($extension_name == 'server-sig-algs') { + $this->supported_private_key_algorithms = explode(',', $extension_value); + } + } + + $response = $this->get_binary_packet(); + list($type) = Strings::unpackSSH2('C', $response); + } + + list($service) = Strings::unpackSSH2('s', $response); + + if ($type != NET_SSH2_MSG_SERVICE_ACCEPT || $service != 'ssh-userauth') { + $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); + throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); + } + $this->bitmap |= self::MASK_LOGIN_REQ; + } + + if (strlen($this->last_interactive_response)) { + return !Strings::is_stringable($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password); + } + + if ($password instanceof PrivateKey) { + return $this->privatekey_login($username, $password); + } + + if ($password instanceof Agent) { + return $this->ssh_agent_login($username, $password); + } + + if (is_array($password)) { + if ($this->keyboard_interactive_login($username, $password)) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } + return false; + } + + if (!isset($password)) { + $packet = Strings::packSSH2( + 'Cs3', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'none' + ); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($auth_methods) = Strings::unpackSSH2('L', $response); + $this->auth_methods_to_continue = $auth_methods; + // fall-through + default: + return false; + } + } + + $packet = Strings::packSSH2( + 'Cs3bs', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'password', + false, + $password + ); + + // remove the username and password from the logged packet + if (!defined('NET_SSH2_LOGGING')) { + $logged = null; + } else { + $logged = Strings::packSSH2( + 'Cs3bs', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'password', + false, + 'password' + ); + } + + $this->send_binary_packet($packet, $logged); + + $response = $this->get_binary_packet(); + if ($response === false) { + return false; + } + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); + + list($message) = Strings::unpackSSH2('s', $response); + $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $message; + + return $this->disconnect_helper(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); + case NET_SSH2_MSG_USERAUTH_FAILURE: + // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees + // multi-factor authentication + list($auth_methods, $partial_success) = Strings::unpackSSH2('Lb', $response); + $this->auth_methods_to_continue = $auth_methods; + if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { + if ($this->keyboard_interactive_login($username, $password)) { + $this->bitmap |= self::MASK_LOGIN; + return true; + } + return false; + } + return false; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + } + + return false; + } + + /** + * Login via keyboard-interactive authentication + * + * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator. + * + * @param string $username + * @param string|array $password + * @return bool + */ + private function keyboard_interactive_login($username, $password) + { + $packet = Strings::packSSH2( + 'Cs5', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'keyboard-interactive', + '', // language tag + '' // submethods + ); + $this->send_binary_packet($packet); + + return $this->keyboard_interactive_process($password); + } + + /** + * Handle the keyboard-interactive requests / responses. + * + * @param string|array ...$responses + * @return bool + * @throws \RuntimeException on connection error + */ + private function keyboard_interactive_process(...$responses) + { + if (strlen($this->last_interactive_response)) { + $response = $this->last_interactive_response; + } else { + $orig = $response = $this->get_binary_packet(); + } + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: + list( + , // name; may be empty + , // instruction; may be empty + , // language tag; may be empty + $num_prompts + ) = Strings::unpackSSH2('s3N', $response); + + for ($i = 0; $i < count($responses); $i++) { + if (is_array($responses[$i])) { + foreach ($responses[$i] as $key => $value) { + $this->keyboard_requests_responses[$key] = $value; + } + unset($responses[$i]); + } + } + $responses = array_values($responses); + + if (isset($this->keyboard_requests_responses)) { + for ($i = 0; $i < $num_prompts; $i++) { + list( + $prompt, // prompt - ie. "Password: "; must not be empty + // echo + ) = Strings::unpackSSH2('sC', $response); + foreach ($this->keyboard_requests_responses as $key => $value) { + if (substr($prompt, 0, strlen($key)) == $key) { + $responses[] = $value; + break; + } + } + } + } + + // see http://tools.ietf.org/html/rfc4256#section-3.2 + if (strlen($this->last_interactive_response)) { + $this->last_interactive_response = ''; + } else { + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); + } + + if (!count($responses) && $num_prompts) { + $this->last_interactive_response = $orig; + return false; + } + + /* + After obtaining the requested information from the user, the client + MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. + */ + // see http://tools.ietf.org/html/rfc4256#section-3.4 + $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); + for ($i = 0; $i < count($responses); $i++) { + $packet .= Strings::packSSH2('s', $responses[$i]); + $logged .= Strings::packSSH2('s', 'dummy-answer'); + } + + $this->send_binary_packet($packet, $logged); + + $this->updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); + + /* + After receiving the response, the server MUST send either an + SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another + SSH_MSG_USERAUTH_INFO_REQUEST message. + */ + // maybe phpseclib should force close the connection after x request / responses? unless something like that is done + // there could be an infinite loop of request / responses. + return $this->keyboard_interactive_process(); + case NET_SSH2_MSG_USERAUTH_SUCCESS: + return true; + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($auth_methods) = Strings::unpackSSH2('L', $response); + $this->auth_methods_to_continue = $auth_methods; + return false; + } + + return false; + } + + /** + * Login with an ssh-agent provided key + * + * @param string $username + * @param \phpseclib3\System\SSH\Agent $agent + * @return bool + */ + private function ssh_agent_login($username, Agent $agent) + { + $this->agent = $agent; + $keys = $agent->requestIdentities(); + foreach ($keys as $key) { + if ($this->privatekey_login($username, $key)) { + return true; + } + } + + return false; + } + + /** + * Login with an RSA private key + * + * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} + * by sending dummy SSH_MSG_IGNORE messages.} + * + * @param string $username + * @param \phpseclib3\Crypt\Common\PrivateKey $privatekey + * @return bool + * @throws \RuntimeException on connection error + */ + private function privatekey_login($username, PrivateKey $privatekey) + { + $publickey = $privatekey->getPublicKey(); + + if ($publickey instanceof RSA) { + $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); + $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; + if (isset($this->preferred['hostkey'])) { + $algos = array_intersect($algos, $this->preferred['hostkey']); + } + $algo = self::array_intersect_first($algos, $this->supported_private_key_algorithms); + switch ($algo) { + case 'rsa-sha2-512': + $hash = 'sha512'; + $signatureType = 'rsa-sha2-512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + $signatureType = 'rsa-sha2-256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + $signatureType = 'ssh-rsa'; + } + } elseif ($publickey instanceof EC) { + $privatekey = $privatekey->withSignatureFormat('SSH2'); + $curveName = $privatekey->getCurve(); + switch ($curveName) { + case 'Ed25519': + $hash = 'sha512'; + $signatureType = 'ssh-ed25519'; + break; + case 'secp256r1': // nistp256 + $hash = 'sha256'; + $signatureType = 'ecdsa-sha2-nistp256'; + break; + case 'secp384r1': // nistp384 + $hash = 'sha384'; + $signatureType = 'ecdsa-sha2-nistp384'; + break; + case 'secp521r1': // nistp521 + $hash = 'sha512'; + $signatureType = 'ecdsa-sha2-nistp521'; + break; + default: + if (is_array($curveName)) { + throw new UnsupportedCurveException('Specified Curves are not supported by SSH2'); + } + throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported by phpseclib3\'s SSH2 implementation'); + } + } elseif ($publickey instanceof DSA) { + $privatekey = $privatekey->withSignatureFormat('SSH2'); + $hash = 'sha1'; + $signatureType = 'ssh-dss'; + } else { + throw new UnsupportedAlgorithmException('Please use either an RSA key, an EC one or a DSA key'); + } + + $publickeyStr = $publickey->toString('OpenSSH', ['binary' => true]); + + $part1 = Strings::packSSH2( + 'Csss', + NET_SSH2_MSG_USERAUTH_REQUEST, + $username, + 'ssh-connection', + 'publickey' + ); + $part2 = Strings::packSSH2('ss', $signatureType, $publickeyStr); + + $packet = $part1 . chr(0) . $part2; + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_FAILURE: + list($auth_methods) = Strings::unpackSSH2('L', $response); + if (in_array('publickey', $auth_methods) && substr($signatureType, 0, 9) == 'rsa-sha2-') { + $this->supported_private_key_algorithms = array_diff($this->supported_private_key_algorithms, ['rsa-sha2-256', 'rsa-sha2-512']); + return $this->privatekey_login($username, $privatekey); + } + $this->auth_methods_to_continue = $auth_methods; + $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE'; + return false; + case NET_SSH2_MSG_USERAUTH_PK_OK: + // we'll just take it on faith that the public key blob and the public key algorithm name are as + // they should be + $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); + break; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new ConnectionClosedException('Unexpected response to publickey authentication pt 1'); + } + + $packet = $part1 . chr(1) . $part2; + $privatekey = $privatekey->withHash($hash); + $signature = $privatekey->sign(Strings::packSSH2('s', $this->session_id) . $packet); + if ($publickey instanceof RSA) { + $signature = Strings::packSSH2('ss', $signatureType, $signature); + } + $packet .= Strings::packSSH2('s', $signature); + + $this->send_binary_packet($packet); + + $response = $this->get_binary_packet(); + + list($type) = Strings::unpackSSH2('C', $response); + switch ($type) { + case NET_SSH2_MSG_USERAUTH_FAILURE: + // either the login is bad or the server employs multi-factor authentication + list($auth_methods) = Strings::unpackSSH2('L', $response); + $this->auth_methods_to_continue = $auth_methods; + return false; + case NET_SSH2_MSG_USERAUTH_SUCCESS: + $this->bitmap |= self::MASK_LOGIN; + return true; + } + + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new ConnectionClosedException('Unexpected response to publickey authentication pt 2'); + } + + /** + * Return the currently configured timeout + * + * @return int + */ + public function getTimeout() + { + return $this->timeout; + } + + /** + * Set Timeout + * + * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. + * Setting $timeout to false or 0 will mean there is no timeout. + * + * @param mixed $timeout + */ + public function setTimeout($timeout) + { + $this->timeout = $this->curTimeout = $timeout; + } + + /** + * Set Keep Alive + * + * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. + * + * @param int $interval + */ + public function setKeepAlive($interval) + { + $this->keepAlive = $interval; + } + + /** + * Get the output from stdError + * + */ + public function getStdError() + { + return $this->stdErrorLog; + } + + /** + * Execute Command + * + * If $callback is set to false then \phpseclib3\Net\SSH2::get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. + * In all likelihood, this is not a feature you want to be taking advantage of. + * + * @param string $command + * @return string|bool + * @psalm-return ($callback is callable ? bool : string|bool) + * @throws \RuntimeException on connection error + */ + public function exec($command, callable $callback = null) + { + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + $this->stdErrorLog = ''; + + if (!$this->isAuthenticated()) { + return false; + } + + //if ($this->isPTYOpen()) { + // throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); + //} + + $this->openChannel(self::CHANNEL_EXEC); + + if ($this->request_pty === true) { + $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); + $packet = Strings::packSSH2( + 'CNsCsN4s', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_EXEC], + 'pty-req', + 1, + $this->term, + $this->windowColumns, + $this->windowRows, + 0, + 0, + $terminal_modes + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; + if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to request pseudo-terminal'); + } + } + + // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things + // down. the one place where it might be desirable is if you're doing something like \phpseclib3\Net\SSH2::exec('ping localhost &'). + // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then + // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but + // neither will your script. + + // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by + // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the + // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_EXEC], + 'exec', + 1, + $command + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { + return false; + } + + $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; + + if ($this->request_pty === true) { + $this->channel_id_last_interactive = self::CHANNEL_EXEC; + return true; + } + + $output = ''; + while (true) { + $temp = $this->get_channel_packet(self::CHANNEL_EXEC); + switch (true) { + case $temp === true: + return is_callable($callback) ? true : $output; + case $temp === false: + return false; + default: + if (is_callable($callback)) { + if ($callback($temp) === true) { + $this->close_channel(self::CHANNEL_EXEC); + return true; + } + } else { + $output .= $temp; + } + } + } + } + + /** + * How many channels are currently open? + * + * @return int + */ + public function getOpenChannelCount() + { + return $this->channelCount; + } + + /** + * Opens a channel + * + * @param string $channel + * @param bool $skip_extended + * @return bool + */ + protected function openChannel($channel, $skip_extended = false) + { + if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) { + throw new \RuntimeException('Please close the channel (' . $channel . ') before trying to open it again'); + } + + $this->channelCount++; + + if ($this->channelCount > 1 && $this->errorOnMultipleChannels) { + throw new \RuntimeException("Ubuntu's OpenSSH from 5.8 to 6.9 doesn't work with multiple channels"); + } + + // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to + // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, + // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. + // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info + $this->window_size_server_to_client[$channel] = $this->window_size; + // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy + // uses 0x4000, that's what will be used here, as well. + $packet_size = 0x4000; + + $packet = Strings::packSSH2( + 'CsN3', + NET_SSH2_MSG_CHANNEL_OPEN, + 'session', + $channel, + $this->window_size_server_to_client[$channel], + $packet_size + ); + + $this->send_binary_packet($packet); + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_OPEN; + + return $this->get_channel_packet($channel, $skip_extended); + } + + /** + * Creates an interactive shell + * + * Returns bool(true) if the shell was opened. + * Returns bool(false) if the shell was already open. + * + * @see self::isShellOpen() + * @see self::read() + * @see self::write() + * @return bool + * @throws InsufficientSetupException if not authenticated + * @throws \UnexpectedValueException on receipt of unexpected packets + * @throws \RuntimeException on other errors + */ + public function openShell() + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + $this->openChannel(self::CHANNEL_SHELL); + + $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); + $packet = Strings::packSSH2( + 'CNsbsN4s', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SHELL], + 'pty-req', + true, // want reply + $this->term, + $this->windowColumns, + $this->windowRows, + 0, + 0, + $terminal_modes + ); + + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$this->get_channel_packet(self::CHANNEL_SHELL)) { + throw new \RuntimeException('Unable to request pty'); + } + + $packet = Strings::packSSH2( + 'CNsb', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SHELL], + 'shell', + true // want reply + ); + $this->send_binary_packet($packet); + + $response = $this->get_channel_packet(self::CHANNEL_SHELL); + if ($response === false) { + throw new \RuntimeException('Unable to request shell'); + } + + $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; + + $this->channel_id_last_interactive = self::CHANNEL_SHELL; + + $this->bitmap |= self::MASK_SHELL; + + return true; + } + + /** + * Return the channel to be used with read(), write(), and reset(), if none were specified + * @deprecated for lack of transparency in intended channel target, to be potentially replaced + * with method which guarantees open-ness of all yielded channels and throws + * error for multiple open channels + * @see self::read() + * @see self::write() + * @return int + */ + private function get_interactive_channel() + { + switch (true) { + case $this->is_channel_status_data(self::CHANNEL_SUBSYSTEM): + return self::CHANNEL_SUBSYSTEM; + case $this->is_channel_status_data(self::CHANNEL_EXEC): + return self::CHANNEL_EXEC; + default: + return self::CHANNEL_SHELL; + } + } + + /** + * Indicates the DATA status on the given channel + * + * @param int $channel The channel number to evaluate + * @return bool + */ + private function is_channel_status_data($channel) + { + return isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA; + } + + /** + * Return an available open channel + * + * @return int + */ + private function get_open_channel() + { + $channel = self::CHANNEL_EXEC; + do { + if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) { + return $channel; + } + } while ($channel++ < self::CHANNEL_SUBSYSTEM); + + return false; + } + + /** + * Request agent forwarding of remote server + * + * @return bool + */ + public function requestAgentForwarding() + { + $request_channel = $this->get_open_channel(); + if ($request_channel === false) { + return false; + } + + $packet = Strings::packSSH2( + 'CNsC', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[$request_channel], + 'auth-agent-req@openssh.com', + 1 + ); + + $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; + + $this->send_binary_packet($packet); + + if (!$this->get_channel_packet($request_channel)) { + return false; + } + + $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; + + return true; + } + + /** + * Returns the output of an interactive shell + * + * Returns when there's a match for $expect, which can take the form of a string literal or, + * if $mode == self::READ_REGEX, a regular expression. + * + * If not specifying a channel, an open interactive channel will be selected, or, if there are + * no open channels, an interactive shell will be created. If there are multiple open + * interactive channels, a legacy behavior will apply in which channel selection prioritizes + * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive + * channels, callers are discouraged from relying on this legacy behavior and should specify + * the intended channel. + * + * @see self::write() + * @param string $expect + * @param int $mode One of the self::READ_* constants + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return string|bool|null + * @throws \RuntimeException on connection error + * @throws InsufficientSetupException on unexpected channel status, possibly due to closure + */ + public function read($expect = '', $mode = self::READ_SIMPLE, $channel = null) + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + $this->curTimeout = $this->timeout; + $this->is_timeout = false; + + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + + if (!$this->is_channel_status_data($channel) && empty($this->channel_buffers[$channel])) { + if ($channel != self::CHANNEL_SHELL) { + throw new InsufficientSetupException('Data is not available on channel'); + } elseif (!$this->openShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + } + + if ($mode == self::READ_NEXT) { + return $this->get_channel_packet($channel); + } + + $match = $expect; + while (true) { + if ($mode == self::READ_REGEX) { + preg_match($expect, substr($this->interactiveBuffer, -1024), $matches); + $match = isset($matches[0]) ? $matches[0] : ''; + } + $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; + if ($pos !== false) { + return Strings::shift($this->interactiveBuffer, $pos + strlen($match)); + } + $response = $this->get_channel_packet($channel); + if ($response === true) { + return Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); + } + + $this->interactiveBuffer .= $response; + } + } + + /** + * Inputs a command into an interactive shell. + * + * If not specifying a channel, an open interactive channel will be selected, or, if there are + * no open channels, an interactive shell will be created. If there are multiple open + * interactive channels, a legacy behavior will apply in which channel selection prioritizes + * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive + * channels, callers are discouraged from relying on this legacy behavior and should specify + * the intended channel. + * + * @see SSH2::read() + * @param string $cmd + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return void + * @throws \RuntimeException on connection error + * @throws InsufficientSetupException on unexpected channel status, possibly due to closure + */ + public function write($cmd, $channel = null) + { + if (!$this->isAuthenticated()) { + throw new InsufficientSetupException('Operation disallowed prior to login()'); + } + + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + + if (!$this->is_channel_status_data($channel)) { + if ($channel != self::CHANNEL_SHELL) { + throw new InsufficientSetupException('Data is not available on channel'); + } elseif (!$this->openShell()) { + throw new \RuntimeException('Unable to initiate an interactive shell session'); + } + } + + $this->send_channel_packet($channel, $cmd); + } + + /** + * Start a subsystem. + * + * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept + * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened. + * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and + * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented + * if there's sufficient demand for such a feature. + * + * @see self::stopSubsystem() + * @param string $subsystem + * @return bool + */ + public function startSubsystem($subsystem) + { + $this->openChannel(self::CHANNEL_SUBSYSTEM); + + $packet = Strings::packSSH2( + 'CNsCs', + NET_SSH2_MSG_CHANNEL_REQUEST, + $this->server_channels[self::CHANNEL_SUBSYSTEM], + 'subsystem', + 1, + $subsystem + ); + $this->send_binary_packet($packet); + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; + + if (!$this->get_channel_packet(self::CHANNEL_SUBSYSTEM)) { + return false; + } + + $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; + + $this->channel_id_last_interactive = self::CHANNEL_SUBSYSTEM; + + return true; + } + + /** + * Stops a subsystem. + * + * @see self::startSubsystem() + * @return bool + */ + public function stopSubsystem() + { + if ($this->isInteractiveChannelOpen(self::CHANNEL_SUBSYSTEM)) { + $this->close_channel(self::CHANNEL_SUBSYSTEM); + } + return true; + } + + /** + * Closes a channel + * + * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call + * + * If not specifying a channel, an open interactive channel will be selected. If there are + * multiple open interactive channels, a legacy behavior will apply in which channel selection + * prioritizes an active subsystem, the exec pty, and, lastly, the shell. If using multiple + * interactive channels, callers are discouraged from relying on this legacy behavior and + * should specify the intended channel. + * + * @param int|null $channel Channel id returned by self::getInteractiveChannelId() + * @return void + */ + public function reset($channel = null) + { + if ($channel === null) { + $channel = $this->get_interactive_channel(); + } + if ($this->isInteractiveChannelOpen($channel)) { + $this->close_channel($channel); + } + } + + /** + * Is timeout? + * + * Did exec() or read() return because they timed out or because they encountered the end? + * + */ + public function isTimeout() + { + return $this->is_timeout; + } + + /** + * Disconnect + * + */ + public function disconnect() + { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { + fclose($this->realtime_log_file); + } + unset(self::$connections[$this->getResourceId()]); + } + + /** + * Destructor. + * + * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call + * disconnect(). + * + */ + public function __destruct() + { + $this->disconnect(); + } + + /** + * Is the connection still active? + * + * @return bool + */ + public function isConnected() + { + return ($this->bitmap & self::MASK_CONNECTED) && is_resource($this->fsock) && !feof($this->fsock); + } + + /** + * Have you successfully been logged in? + * + * @return bool + */ + public function isAuthenticated() + { + return (bool) ($this->bitmap & self::MASK_LOGIN); + } + + /** + * Is the interactive shell active? + * + * @return bool + */ + public function isShellOpen() + { + return $this->isInteractiveChannelOpen(self::CHANNEL_SHELL); + } + + /** + * Is the exec pty active? + * + * @return bool + */ + public function isPTYOpen() + { + return $this->isInteractiveChannelOpen(self::CHANNEL_EXEC); + } + + /** + * Is the given interactive channel active? + * + * @param int $channel Channel id returned by self::getInteractiveChannelId() + * @return bool + */ + public function isInteractiveChannelOpen($channel) + { + return $this->isAuthenticated() && $this->is_channel_status_data($channel); + } + + /** + * Returns a channel identifier, presently of the last interactive channel opened, regardless of current status. + * Returns 0 if no interactive channel has been opened. + * + * @see self::isInteractiveChannelOpen() + * @return int + */ + public function getInteractiveChannelId() + { + return $this->channel_id_last_interactive; + } + + /** + * Pings a server connection, or tries to reconnect if the connection has gone down + * + * Inspired by http://php.net/manual/en/mysqli.ping.php + * + * @return bool + */ + public function ping() + { + if (!$this->isAuthenticated()) { + if (!empty($this->auth)) { + return $this->reconnect(); + } + return false; + } + + try { + $this->openChannel(self::CHANNEL_KEEP_ALIVE); + } catch (\RuntimeException $e) { + return $this->reconnect(); + } + + $this->close_channel(self::CHANNEL_KEEP_ALIVE); + return true; + } + + /** + * In situ reconnect method + * + * @return boolean + */ + private function reconnect() + { + $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); + $this->retry_connect = true; + $this->connect(); + foreach ($this->auth as $auth) { + $result = $this->login(...$auth); + } + return $result; + } + + /** + * Resets a connection for re-use + * + * @param int $reason + */ + protected function reset_connection($reason) + { + $this->disconnect_helper($reason); + $this->decrypt = $this->encrypt = false; + $this->decrypt_block_size = $this->encrypt_block_size = 8; + $this->hmac_check = $this->hmac_create = false; + $this->hmac_size = false; + $this->session_id = false; + $this->retry_connect = true; + $this->get_seq_no = $this->send_seq_no = 0; + $this->channel_status = []; + $this->channel_id_last_interactive = 0; + } + + /** + * Gets Binary Packets + * + * See '6. Binary Packet Protocol' of rfc4253 for more info. + * + * @see self::_send_binary_packet() + * @param bool $skip_channel_filter + * @return bool|string + */ + private function get_binary_packet($skip_channel_filter = false) + { + if ($skip_channel_filter) { + if (!is_resource($this->fsock)) { + throw new \InvalidArgumentException('fsock is not a resource.'); + } + $read = [$this->fsock]; + $write = $except = null; + + if (!$this->curTimeout) { + if ($this->keepAlive <= 0) { + static::stream_select($read, $write, $except, null); + } else { + if (!static::stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + return $this->get_binary_packet(true); + } + } + } else { + if ($this->curTimeout < 0) { + $this->is_timeout = true; + return true; + } + + $start = microtime(true); + + if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { + if (!static::stream_select($read, $write, $except, $this->keepAlive)) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + return $this->get_binary_packet(true); + } + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + } + + $sec = (int) floor($this->curTimeout); + $usec = (int) (1000000 * ($this->curTimeout - $sec)); + + // this can return a "stream_select(): unable to select [4]: Interrupted system call" error + if (!static::stream_select($read, $write, $except, $sec, $usec)) { + $this->is_timeout = true; + return true; + } + $elapsed = microtime(true) - $start; + $this->curTimeout -= $elapsed; + } + } + + if (!is_resource($this->fsock) || feof($this->fsock)) { + $this->bitmap = 0; + $str = 'Connection closed (by server) prematurely'; + if (isset($elapsed)) { + $str .= ' ' . $elapsed . 's'; + } + throw new ConnectionClosedException($str); + } + + $start = microtime(true); + $raw = stream_get_contents($this->fsock, $this->decrypt_block_size); + + if (!strlen($raw)) { + $this->bitmap = 0; + throw new ConnectionClosedException('No data received from server'); + } + + if ($this->decrypt) { + switch ($this->decryptName) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $this->decrypt->setNonce( + $this->decryptFixedPart . + $this->decryptInvocationCounter + ); + Strings::increment_str($this->decryptInvocationCounter); + $this->decrypt->setAAD($temp = Strings::shift($raw, 4)); + extract(unpack('Npacket_length', $temp)); + /** + * @var integer $packet_length + */ + + $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $tag = stream_get_contents($this->fsock, $this->decrypt_block_size); + $this->decrypt->setTag($tag); + $raw = $this->decrypt->decrypt($raw); + $raw = $temp . $raw; + $remaining_length = 0; + break; + case 'chacha20-poly1305@openssh.com': + // This should be impossible, but we are checking anyway to narrow the type for Psalm. + if (!($this->decrypt instanceof ChaCha20)) { + throw new \LogicException('$this->decrypt is not a ' . ChaCha20::class); + } + + $nonce = pack('N2', 0, $this->get_seq_no); + + $this->lengthDecrypt->setNonce($nonce); + $temp = $this->lengthDecrypt->decrypt($aad = Strings::shift($raw, 4)); + extract(unpack('Npacket_length', $temp)); + /** + * @var integer $packet_length + */ + + $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $tag = stream_get_contents($this->fsock, 16); + + $this->decrypt->setNonce($nonce); + $this->decrypt->setCounter(0); + // this is the same approach that's implemented in Salsa20::createPoly1305Key() + // but we don't want to use the same AEAD construction that RFC8439 describes + // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) + $this->decrypt->setPoly1305Key( + $this->decrypt->encrypt(str_repeat("\0", 32)) + ); + $this->decrypt->setAAD($aad); + $this->decrypt->setCounter(1); + $this->decrypt->setTag($tag); + $raw = $this->decrypt->decrypt($raw); + $raw = $temp . $raw; + $remaining_length = 0; + break; + default: + if (!$this->hmac_check instanceof Hash || !$this->hmac_check_etm) { + $raw = $this->decrypt->decrypt($raw); + break; + } + extract(unpack('Npacket_length', $temp = Strings::shift($raw, 4))); + /** + * @var integer $packet_length + */ + $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); + $stop = microtime(true); + $encrypted = $temp . $raw; + $raw = $temp . $this->decrypt->decrypt($raw); + $remaining_length = 0; + } + } + + if (strlen($raw) < 5) { + $this->bitmap = 0; + throw new \RuntimeException('Plaintext is too short'); + } + extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5))); + /** + * @var integer $packet_length + * @var integer $padding_length + */ + + if (!isset($remaining_length)) { + $remaining_length = $packet_length + 4 - $this->decrypt_block_size; + } + + $buffer = $this->read_remaining_bytes($remaining_length); + + if (!isset($stop)) { + $stop = microtime(true); + } + if (strlen($buffer)) { + $raw .= $this->decrypt ? $this->decrypt->decrypt($buffer) : $buffer; + } + + $payload = Strings::shift($raw, $packet_length - $padding_length - 1); + $padding = Strings::shift($raw, $padding_length); // should leave $raw empty + + if ($this->hmac_check instanceof Hash) { + $hmac = stream_get_contents($this->fsock, $this->hmac_size); + if ($hmac === false || strlen($hmac) != $this->hmac_size) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Error reading socket'); + } + + $reconstructed = !$this->hmac_check_etm ? + pack('NCa*', $packet_length, $padding_length, $payload . $padding) : + $encrypted; + if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); + if ($hmac != $this->hmac_check->hash($reconstructed)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Invalid UMAC'); + } + } else { + if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); + throw new \RuntimeException('Invalid HMAC'); + } + } + } + + switch ($this->decompress) { + case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: + if (!$this->isAuthenticated()) { + break; + } + // fall-through + case self::NET_SSH2_COMPRESSION_ZLIB: + if ($this->regenerate_decompression_context) { + $this->regenerate_decompression_context = false; + + $cmf = ord($payload[0]); + $cm = $cmf & 0x0F; + if ($cm != 8) { // deflate + user_error("Only CM = 8 ('deflate') is supported ($cm)"); + } + $cinfo = ($cmf & 0xF0) >> 4; + if ($cinfo > 7) { + user_error("CINFO above 7 is not allowed ($cinfo)"); + } + $windowSize = 1 << ($cinfo + 8); + + $flg = ord($payload[1]); + //$fcheck = $flg && 0x0F; + if ((($cmf << 8) | $flg) % 31) { + user_error('fcheck failed'); + } + $fdict = boolval($flg & 0x20); + $flevel = ($flg & 0xC0) >> 6; + + $this->decompress_context = inflate_init(ZLIB_ENCODING_RAW, ['window' => $cinfo + 8]); + $payload = substr($payload, 2); + } + if ($this->decompress_context) { + $payload = inflate_add($this->decompress_context, $payload, ZLIB_PARTIAL_FLUSH); + } + } + + $this->get_seq_no++; + + if (defined('NET_SSH2_LOGGING')) { + $current = microtime(true); + $message_number = isset(self::$message_numbers[ord($payload[0])]) ? self::$message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; + $message_number = '<- ' . $message_number . + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; + $this->append_log($message_number, $payload); + $this->last_packet = $current; + } + + return $this->filter($payload, $skip_channel_filter); + } + + /** + * Read Remaining Bytes + * + * @see self::get_binary_packet() + * @param int $remaining_length + * @return string + */ + private function read_remaining_bytes($remaining_length) + { + if (!$remaining_length) { + return ''; + } + + $adjustLength = false; + if ($this->decrypt) { + switch (true) { + case $this->decryptName == 'aes128-gcm@openssh.com': + case $this->decryptName == 'aes256-gcm@openssh.com': + case $this->decryptName == 'chacha20-poly1305@openssh.com': + case $this->hmac_check instanceof Hash && $this->hmac_check_etm: + $remaining_length += $this->decrypt_block_size - 4; + $adjustLength = true; + } + } + + // quoting , + // "implementations SHOULD check that the packet length is reasonable" + // PuTTY uses 0x9000 as the actual max packet size and so to shall we + // don't do this when GCM mode is used since GCM mode doesn't encrypt the length + if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { + if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decryptName : '') && !($this->bitmap & SSH2::MASK_LOGIN)) { + $this->bad_key_size_fix = true; + $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); + return false; + } + throw new \RuntimeException('Invalid size'); + } + + if ($adjustLength) { + $remaining_length -= $this->decrypt_block_size - 4; + } + + $buffer = ''; + while ($remaining_length > 0) { + $temp = stream_get_contents($this->fsock, $remaining_length); + if ($temp === false || feof($this->fsock)) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new \RuntimeException('Error reading from socket'); + } + $buffer .= $temp; + $remaining_length -= strlen($temp); + } + + return $buffer; + } + + /** + * Filter Binary Packets + * + * Because some binary packets need to be ignored... + * + * @see self::_get_binary_packet() + * @param string $payload + * @param bool $skip_channel_filter + * @return string|bool + */ + private function filter($payload, $skip_channel_filter) + { + switch (ord($payload[0])) { + case NET_SSH2_MSG_DISCONNECT: + Strings::shift($payload, 1); + list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); + $this->errors[] = 'SSH_MSG_DISCONNECT: ' . self::$disconnect_reasons[$reason_code] . "\r\n$message"; + $this->bitmap = 0; + return false; + case NET_SSH2_MSG_IGNORE: + $this->extra_packets++; + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_DEBUG: + $this->extra_packets++; + Strings::shift($payload, 2); // second byte is "always_display" + list($message) = Strings::unpackSSH2('s', $payload); + $this->errors[] = "SSH_MSG_DEBUG: $message"; + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_UNIMPLEMENTED: + return false; + case NET_SSH2_MSG_KEXINIT: + // this is here for key re-exchanges after the initial key exchange + if ($this->session_id !== false) { + if (!$this->key_exchange($payload)) { + $this->bitmap = 0; + return false; + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + + // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in + if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && !is_bool($payload) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { + Strings::shift($payload, 1); + list($this->banner_message) = Strings::unpackSSH2('s', $payload); + $payload = $this->get_binary_packet(); + } + + // only called when we've already logged in + if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { + if (is_bool($payload)) { + return $payload; + } + + switch (ord($payload[0])) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + if (strlen($payload) == 31) { + extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); + if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { + if (ord(substr($payload, 9 + $length))) { // want reply + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); + } + $payload = $this->get_binary_packet($skip_channel_filter); + } + } + break; + case NET_SSH2_MSG_CHANNEL_DATA: + case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: + case NET_SSH2_MSG_CHANNEL_CLOSE: + case NET_SSH2_MSG_CHANNEL_EOF: + if (!$skip_channel_filter && !empty($this->server_channels)) { + $this->binary_packet_buffer = $payload; + $this->get_channel_packet(true); + $payload = $this->get_binary_packet(); + } + break; + case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 + Strings::shift($payload, 1); + list($request_name) = Strings::unpackSSH2('s', $payload); + $this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name"; + + try { + $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE)); + } catch (\RuntimeException $e) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 + Strings::shift($payload, 1); + list($data, $server_channel) = Strings::unpackSSH2('sN', $payload); + switch ($data) { + case 'auth-agent': + case 'auth-agent@openssh.com': + if (isset($this->agent)) { + $new_channel = self::CHANNEL_AGENT_FORWARD; + + list( + $remote_window_size, + $remote_maximum_packet_size + ) = Strings::unpackSSH2('NN', $payload); + + $this->packet_size_client_to_server[$new_channel] = $remote_window_size; + $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; + $this->window_size_client_to_server[$new_channel] = $this->window_size; + + $packet_size = 0x4000; + + $packet = pack( + 'CN4', + NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, + $server_channel, + $new_channel, + $packet_size, + $packet_size + ); + + $this->server_channels[$new_channel] = $server_channel; + $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; + $this->send_binary_packet($packet); + } + break; + default: + $packet = Strings::packSSH2( + 'CN2ss', + NET_SSH2_MSG_CHANNEL_OPEN_FAILURE, + $server_channel, + NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, + '', // description + '' // language tag + ); + + try { + $this->send_binary_packet($packet); + } catch (\RuntimeException $e) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + } + } + + $payload = $this->get_binary_packet($skip_channel_filter); + break; + case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: + Strings::shift($payload, 1); + list($channel, $window_size) = Strings::unpackSSH2('NN', $payload); + + $this->window_size_client_to_server[$channel] += $window_size; + + $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->get_binary_packet($skip_channel_filter); + } + } + + return $payload; + } + + /** + * Enable Quiet Mode + * + * Suppress stderr from output + * + */ + public function enableQuietMode() + { + $this->quiet_mode = true; + } + + /** + * Disable Quiet Mode + * + * Show stderr in output + * + */ + public function disableQuietMode() + { + $this->quiet_mode = false; + } + + /** + * Returns whether Quiet Mode is enabled or not + * + * @see self::enableQuietMode() + * @see self::disableQuietMode() + * @return bool + */ + public function isQuietModeEnabled() + { + return $this->quiet_mode; + } + + /** + * Enable request-pty when using exec() + * + */ + public function enablePTY() + { + $this->request_pty = true; + } + + /** + * Disable request-pty when using exec() + * + */ + public function disablePTY() + { + if ($this->isPTYOpen()) { + $this->close_channel(self::CHANNEL_EXEC); + } + $this->request_pty = false; + } + + /** + * Returns whether request-pty is enabled or not + * + * @see self::enablePTY() + * @see self::disablePTY() + * @return bool + */ + public function isPTYEnabled() + { + return $this->request_pty; + } + + /** + * Gets channel data + * + * Returns the data as a string. bool(true) is returned if: + * + * - the server closes the channel + * - if the connection times out + * - if the channel status is CHANNEL_OPEN and the response was CHANNEL_OPEN_CONFIRMATION + * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_SUCCESS + * - if the channel status is CHANNEL_CLOSE and the response was CHANNEL_CLOSE + * + * bool(false) is returned if: + * + * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_FAILURE + * + * @param int $client_channel + * @param bool $skip_extended + * @return mixed + * @throws \RuntimeException on connection error + */ + protected function get_channel_packet($client_channel, $skip_extended = false) + { + if (!empty($this->channel_buffers[$client_channel])) { + switch ($this->channel_status[$client_channel]) { + case NET_SSH2_MSG_CHANNEL_REQUEST: + foreach ($this->channel_buffers[$client_channel] as $i => $packet) { + switch (ord($packet[0])) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + case NET_SSH2_MSG_CHANNEL_FAILURE: + unset($this->channel_buffers[$client_channel][$i]); + return substr($packet, 1); + } + } + break; + default: + return substr(array_shift($this->channel_buffers[$client_channel]), 1); + } + } + + while (true) { + if ($this->binary_packet_buffer !== false) { + $response = $this->binary_packet_buffer; + $this->binary_packet_buffer = false; + } else { + $response = $this->get_binary_packet(true); + if ($response === true && $this->is_timeout) { + if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { + $this->close_channel($client_channel); + } + return true; + } + if ($response === false) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); + throw new ConnectionClosedException('Connection closed by server'); + } + } + + if ($client_channel == -1 && $response === true) { + return true; + } + list($type, $channel) = Strings::unpackSSH2('CN', $response); + + // will not be setup yet on incoming channel open request + if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { + $this->window_size_server_to_client[$channel] -= strlen($response); + + // resize the window, if appropriate + if ($this->window_size_server_to_client[$channel] < 0) { + // PuTTY does something more analogous to the following: + //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { + $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); + $this->send_binary_packet($packet); + $this->window_size_server_to_client[$channel] += $this->window_resize; + } + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: + /* + if ($client_channel == self::CHANNEL_EXEC) { + $this->send_channel_packet($client_channel, chr(0)); + } + */ + // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR + list($data_type_code, $data) = Strings::unpackSSH2('Ns', $response); + $this->stdErrorLog .= $data; + if ($skip_extended || $this->quiet_mode) { + continue 2; + } + if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) { + return $data; + } + $this->channel_buffers[$channel][] = chr($type) . $data; + + continue 2; + case NET_SSH2_MSG_CHANNEL_REQUEST: + if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) { + continue 2; + } + list($value) = Strings::unpackSSH2('s', $response); + switch ($value) { + case 'exit-signal': + list( + , // FALSE + $signal_name, + , // core dumped + $error_message + ) = Strings::unpackSSH2('bsbs', $response); + + $this->errors[] = "SSH_MSG_CHANNEL_REQUEST (exit-signal): $signal_name"; + if (strlen($error_message)) { + $this->errors[count($this->errors) - 1] .= "\r\n$error_message"; + } + + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF; + + continue 3; + case 'exit-status': + list(, $this->exit_status) = Strings::unpackSSH2('CN', $response); + + // "The client MAY ignore these messages." + // -- http://tools.ietf.org/html/rfc4254#section-6.10 + + continue 3; + default: + // "Some systems may not implement signals, in which case they SHOULD ignore this message." + // -- http://tools.ietf.org/html/rfc4254#section-6.9 + continue 3; + } + } + + switch ($this->channel_status[$channel]) { + case NET_SSH2_MSG_CHANNEL_OPEN: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: + list( + $this->server_channels[$channel], + $window_size, + $this->packet_size_client_to_server[$channel] + ) = Strings::unpackSSH2('NNN', $response); + + if ($window_size < 0) { + $window_size &= 0x7FFFFFFF; + $window_size += 0x80000000; + } + $this->window_size_client_to_server[$channel] = $window_size; + $result = $client_channel == $channel ? true : $this->get_channel_packet($client_channel, $skip_extended); + $this->on_channel_open(); + return $result; + case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to open channel'); + default: + if ($client_channel == $channel) { + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unexpected response to open request'); + } + return $this->get_channel_packet($client_channel, $skip_extended); + } + break; + case NET_SSH2_MSG_CHANNEL_REQUEST: + switch ($type) { + case NET_SSH2_MSG_CHANNEL_SUCCESS: + return true; + case NET_SSH2_MSG_CHANNEL_FAILURE: + return false; + case NET_SSH2_MSG_CHANNEL_DATA: + list($data) = Strings::unpackSSH2('s', $response); + $this->channel_buffers[$channel][] = chr($type) . $data; + return $this->get_channel_packet($client_channel, $skip_extended); + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException('Unable to fulfill channel request'); + } + case NET_SSH2_MSG_CHANNEL_CLOSE: + if ($client_channel == $channel && $type == NET_SSH2_MSG_CHANNEL_CLOSE) { + return true; + } + return $this->get_channel_packet($client_channel, $skip_extended); + } + } + + // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA + + switch ($type) { + case NET_SSH2_MSG_CHANNEL_DATA: + /* + if ($channel == self::CHANNEL_EXEC) { + // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server + // this actually seems to make things twice as fast. more to the point, the message right after + // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. + // in OpenSSH it slows things down but only by a couple thousandths of a second. + $this->send_channel_packet($channel, chr(0)); + } + */ + list($data) = Strings::unpackSSH2('s', $response); + + if ($channel == self::CHANNEL_AGENT_FORWARD) { + $agent_response = $this->agent->forwardData($data); + if (!is_bool($agent_response)) { + $this->send_channel_packet($channel, $agent_response); + } + break; + } + + if ($client_channel == $channel) { + return $data; + } + $this->channel_buffers[$channel][] = chr($type) . $data; + break; + case NET_SSH2_MSG_CHANNEL_CLOSE: + $this->curTimeout = 5; + + $this->close_channel_bitmap($channel); + + if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); + } + + $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + $this->channelCount--; + + if ($client_channel == $channel) { + return true; + } + // fall-through + case NET_SSH2_MSG_CHANNEL_EOF: + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); + throw new \RuntimeException("Error reading channel data ($type)"); + } + } + } + + /** + * Sends Binary Packets + * + * See '6. Binary Packet Protocol' of rfc4253 for more info. + * + * @param string $data + * @param string $logged + * @see self::_get_binary_packet() + * @return void + */ + protected function send_binary_packet($data, $logged = null) + { + if (!is_resource($this->fsock) || feof($this->fsock)) { + $this->bitmap = 0; + throw new ConnectionClosedException('Connection closed prematurely'); + } + + if (!isset($logged)) { + $logged = $data; + } + + switch ($this->compress) { + case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: + if (!$this->isAuthenticated()) { + break; + } + // fall-through + case self::NET_SSH2_COMPRESSION_ZLIB: + if (!$this->regenerate_compression_context) { + $header = ''; + } else { + $this->regenerate_compression_context = false; + $this->compress_context = deflate_init(ZLIB_ENCODING_RAW, ['window' => 15]); + $header = "\x78\x9C"; + } + if ($this->compress_context) { + $data = $header . deflate_add($this->compress_context, $data, ZLIB_PARTIAL_FLUSH); + } + } + + // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 + $packet_length = strlen($data) + 9; + if ($this->encrypt && $this->encrypt->usesNonce()) { + $packet_length -= 4; + } + // round up to the nearest $this->encrypt_block_size + $packet_length += (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; + // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length + $padding_length = $packet_length - strlen($data) - 5; + switch (true) { + case $this->encrypt && $this->encrypt->usesNonce(): + case $this->hmac_create instanceof Hash && $this->hmac_create_etm: + $padding_length += 4; + $packet_length += 4; + } + + $padding = Random::string($padding_length); + + // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself + $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); + + $hmac = ''; + if ($this->hmac_create instanceof Hash && !$this->hmac_create_etm) { + if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); + $hmac = $this->hmac_create->hash($packet); + } else { + $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); + } + } + + if ($this->encrypt) { + switch ($this->encryptName) { + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + $this->encrypt->setNonce( + $this->encryptFixedPart . + $this->encryptInvocationCounter + ); + Strings::increment_str($this->encryptInvocationCounter); + $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF")); + $packet = $temp . $this->encrypt->encrypt(substr($packet, 4)); + break; + case 'chacha20-poly1305@openssh.com': + // This should be impossible, but we are checking anyway to narrow the type for Psalm. + if (!($this->encrypt instanceof ChaCha20)) { + throw new \LogicException('$this->encrypt is not a ' . ChaCha20::class); + } + + $nonce = pack('N2', 0, $this->send_seq_no); + + $this->encrypt->setNonce($nonce); + $this->lengthEncrypt->setNonce($nonce); + + $length = $this->lengthEncrypt->encrypt($packet & "\xFF\xFF\xFF\xFF"); + + $this->encrypt->setCounter(0); + // this is the same approach that's implemented in Salsa20::createPoly1305Key() + // but we don't want to use the same AEAD construction that RFC8439 describes + // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) + $this->encrypt->setPoly1305Key( + $this->encrypt->encrypt(str_repeat("\0", 32)) + ); + $this->encrypt->setAAD($length); + $this->encrypt->setCounter(1); + $packet = $length . $this->encrypt->encrypt(substr($packet, 4)); + break; + default: + $packet = $this->hmac_create instanceof Hash && $this->hmac_create_etm ? + ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) : + $this->encrypt->encrypt($packet); + } + } + + if ($this->hmac_create instanceof Hash && $this->hmac_create_etm) { + if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { + $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); + $hmac = $this->hmac_create->hash($packet); + } else { + $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); + } + } + + $this->send_seq_no++; + + $packet .= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; + + $start = microtime(true); + $sent = @fputs($this->fsock, $packet); + $stop = microtime(true); + + if (defined('NET_SSH2_LOGGING')) { + $current = microtime(true); + $message_number = isset(self::$message_numbers[ord($logged[0])]) ? self::$message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; + $message_number = '-> ' . $message_number . + ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; + $this->append_log($message_number, $logged); + $this->last_packet = $current; + } + + if (strlen($packet) != $sent) { + $this->bitmap = 0; + $message = $sent === false ? + 'Unable to write ' . strlen($packet) . ' bytes' : + "Only $sent of " . strlen($packet) . " bytes were sent"; + throw new \RuntimeException($message); + } + } + + /** + * Logs data packets + * + * Makes sure that only the last 1MB worth of packets will be logged + * + * @param string $message_number + * @param string $message + */ + private function append_log($message_number, $message) + { + $this->append_log_helper( + NET_SSH2_LOGGING, + $message_number, + $message, + $this->message_number_log, + $this->message_log, + $this->log_size, + $this->realtime_log_file, + $this->realtime_log_wrap, + $this->realtime_log_size + ); + } + + /** + * Logs data packet helper + * + * @param int $constant + * @param string $message_number + * @param string $message + * @param array &$message_number_log + * @param array &$message_log + * @param int &$log_size + * @param resource &$realtime_log_file + * @param bool &$realtime_log_wrap + * @param int &$realtime_log_size + */ + protected function append_log_helper($constant, $message_number, $message, array &$message_number_log, array &$message_log, &$log_size, &$realtime_log_file, &$realtime_log_wrap, &$realtime_log_size) + { + // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) + if (strlen($message_number) > 2) { + Strings::shift($message); + } + + switch ($constant) { + // useful for benchmarks + case self::LOG_SIMPLE: + $message_number_log[] = $message_number; + break; + case self::LOG_SIMPLE_REALTIME: + echo $message_number; + echo PHP_SAPI == 'cli' ? "\r\n" : '
          '; + @flush(); + @ob_flush(); + break; + // the most useful log for SSH2 + case self::LOG_COMPLEX: + $message_number_log[] = $message_number; + $log_size += strlen($message); + $message_log[] = $message; + while ($log_size > self::LOG_MAX_SIZE) { + $log_size -= strlen(array_shift($message_log)); + array_shift($message_number_log); + } + break; + // dump the output out realtime; packets may be interspersed with non packets, + // passwords won't be filtered out and select other packets may not be correctly + // identified + case self::LOG_REALTIME: + switch (PHP_SAPI) { + case 'cli': + $start = $stop = "\r\n"; + break; + default: + $start = '
          ';
          +                        $stop = '
          '; + } + echo $start . $this->format_log([$message], [$message_number]) . $stop; + @flush(); + @ob_flush(); + break; + // basically the same thing as self::LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILENAME + // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. + // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily + // at the beginning of the file + case self::LOG_REALTIME_FILE: + if (!isset($realtime_log_file)) { + // PHP doesn't seem to like using constants in fopen() + $filename = NET_SSH2_LOG_REALTIME_FILENAME; + $fp = fopen($filename, 'w'); + $realtime_log_file = $fp; + } + if (!is_resource($realtime_log_file)) { + break; + } + $entry = $this->format_log([$message], [$message_number]); + if ($realtime_log_wrap) { + $temp = "<<< START >>>\r\n"; + $entry .= $temp; + fseek($realtime_log_file, ftell($realtime_log_file) - strlen($temp)); + } + $realtime_log_size += strlen($entry); + if ($realtime_log_size > self::LOG_MAX_SIZE) { + fseek($realtime_log_file, 0); + $realtime_log_size = strlen($entry); + $realtime_log_wrap = true; + } + fputs($realtime_log_file, $entry); + } + } + + /** + * Sends channel data + * + * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate + * + * @param int $client_channel + * @param string $data + * @return void + */ + protected function send_channel_packet($client_channel, $data) + { + while (strlen($data)) { + if (!$this->window_size_client_to_server[$client_channel]) { + $this->bitmap ^= self::MASK_WINDOW_ADJUST; + // using an invalid channel will let the buffers be built up for the valid channels + $this->get_channel_packet(-1); + $this->bitmap ^= self::MASK_WINDOW_ADJUST; + } + + /* The maximum amount of data allowed is determined by the maximum + packet size for the channel, and the current window size, whichever + is smaller. + -- http://tools.ietf.org/html/rfc4254#section-5.2 */ + $max_size = min( + $this->packet_size_client_to_server[$client_channel], + $this->window_size_client_to_server[$client_channel] + ); + + $temp = Strings::shift($data, $max_size); + $packet = Strings::packSSH2( + 'CNs', + NET_SSH2_MSG_CHANNEL_DATA, + $this->server_channels[$client_channel], + $temp + ); + $this->window_size_client_to_server[$client_channel] -= strlen($temp); + $this->send_binary_packet($packet); + } + } + + /** + * Closes and flushes a channel + * + * \phpseclib3\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server + * and for SFTP channels are presumably closed when the client disconnects. This functions is intended + * for SCP more than anything. + * + * @param int $client_channel + * @param bool $want_reply + * @return void + */ + private function close_channel($client_channel, $want_reply = false) + { + // see http://tools.ietf.org/html/rfc4254#section-5.3 + + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); + + if (!$want_reply) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + } + + $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; + $this->channelCount--; + + $this->curTimeout = 5; + + while (!is_bool($this->get_channel_packet($client_channel))) { + } + + if ($want_reply) { + $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); + } + + $this->close_channel_bitmap($client_channel); + } + + /** + * Maintains execution state bitmap in response to channel closure + * + * @param int $client_channel The channel number to maintain closure status of + * @return void + */ + private function close_channel_bitmap($client_channel) + { + switch ($client_channel) { + case self::CHANNEL_SHELL: + // Shell status has been maintained in the bitmap for backwards + // compatibility sake, but can be removed going forward + if ($this->bitmap & self::MASK_SHELL) { + $this->bitmap &= ~self::MASK_SHELL; + } + break; + } + } + + /** + * Disconnect + * + * @param int $reason + * @return false + */ + protected function disconnect_helper($reason) + { + if ($this->bitmap & self::MASK_CONNECTED) { + $data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', ''); + try { + $this->send_binary_packet($data); + } catch (\Exception $e) { + } + } + + $this->bitmap = 0; + if (is_resource($this->fsock) && get_resource_type($this->fsock) === 'stream') { + fclose($this->fsock); + } + + return false; + } + + /** + * Define Array + * + * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of + * named constants from it, using the value as the name of the constant and the index as the value of the constant. + * If any of the constants that would be defined already exists, none of the constants will be defined. + * + * @param mixed[] ...$args + * @access protected + */ + protected static function define_array(...$args) + { + foreach ($args as $arg) { + foreach ($arg as $key => $value) { + if (!defined($value)) { + define($value, $key); + } else { + break 2; + } + } + } + } + + /** + * Returns a log of the packets that have been sent and received. + * + * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') + * + * @return array|false|string + */ + public function getLog() + { + if (!defined('NET_SSH2_LOGGING')) { + return false; + } + + switch (NET_SSH2_LOGGING) { + case self::LOG_SIMPLE: + return $this->message_number_log; + case self::LOG_COMPLEX: + $log = $this->format_log($this->message_log, $this->message_number_log); + return PHP_SAPI == 'cli' ? $log : '
          ' . $log . '
          '; + default: + return false; + } + } + + /** + * Formats a log for printing + * + * @param array $message_log + * @param array $message_number_log + * @return string + */ + protected function format_log(array $message_log, array $message_number_log) + { + $output = ''; + for ($i = 0; $i < count($message_log); $i++) { + $output .= $message_number_log[$i] . "\r\n"; + $current_log = $message_log[$i]; + $j = 0; + do { + if (strlen($current_log)) { + $output .= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; + } + $fragment = Strings::shift($current_log, $this->log_short_width); + $hex = substr(preg_replace_callback('#.#s', function ($matches) { + return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); + }, $fragment), strlen($this->log_boundary)); + // replace non ASCII printable characters with dots + // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters + // also replace < with a . since < messes up the output on web browsers + $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); + $output .= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; + $j++; + } while (strlen($current_log)); + $output .= "\r\n"; + } + + return $output; + } + + /** + * Helper function for agent->on_channel_open() + * + * Used when channels are created to inform agent + * of said channel opening. Must be called after + * channel open confirmation received + * + */ + private function on_channel_open() + { + if (isset($this->agent)) { + $this->agent->registerChannelOpen($this); + } + } + + /** + * Returns the first value of the intersection of two arrays or false if + * the intersection is empty. The order is defined by the first parameter. + * + * @param array $array1 + * @param array $array2 + * @return mixed False if intersection is empty, else intersected value. + */ + private static function array_intersect_first(array $array1, array $array2) + { + foreach ($array1 as $value) { + if (in_array($value, $array2)) { + return $value; + } + } + return false; + } + + /** + * Returns all errors + * + * @return string[] + */ + public function getErrors() + { + return $this->errors; + } + + /** + * Returns the last error + * + * @return string + */ + public function getLastError() + { + $count = count($this->errors); + + if ($count > 0) { + return $this->errors[$count - 1]; + } + } + + /** + * Return the server identification. + * + * @return string|false + */ + public function getServerIdentification() + { + $this->connect(); + + return $this->server_identifier; + } + + /** + * Returns a list of algorithms the server supports + * + * @return array + */ + public function getServerAlgorithms() + { + $this->connect(); + + return [ + 'kex' => $this->kex_algorithms, + 'hostkey' => $this->server_host_key_algorithms, + 'client_to_server' => [ + 'crypt' => $this->encryption_algorithms_client_to_server, + 'mac' => $this->mac_algorithms_client_to_server, + 'comp' => $this->compression_algorithms_client_to_server, + 'lang' => $this->languages_client_to_server + ], + 'server_to_client' => [ + 'crypt' => $this->encryption_algorithms_server_to_client, + 'mac' => $this->mac_algorithms_server_to_client, + 'comp' => $this->compression_algorithms_server_to_client, + 'lang' => $this->languages_server_to_client + ] + ]; + } + + /** + * Returns a list of KEX algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedKEXAlgorithms() + { + $kex_algorithms = [ + // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using + // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the + // libssh repository for more information. + 'curve25519-sha256', + 'curve25519-sha256@libssh.org', + + 'ecdh-sha2-nistp256', // RFC 5656 + 'ecdh-sha2-nistp384', // RFC 5656 + 'ecdh-sha2-nistp521', // RFC 5656 + + 'diffie-hellman-group-exchange-sha256',// RFC 4419 + 'diffie-hellman-group-exchange-sha1', // RFC 4419 + + // Diffie-Hellman Key Agreement (DH) using integer modulo prime + // groups. + 'diffie-hellman-group14-sha256', + 'diffie-hellman-group14-sha1', // REQUIRED + 'diffie-hellman-group15-sha512', + 'diffie-hellman-group16-sha512', + 'diffie-hellman-group17-sha512', + 'diffie-hellman-group18-sha512', + + 'diffie-hellman-group1-sha1', // REQUIRED + ]; + + return $kex_algorithms; + } + + /** + * Returns a list of host key algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedHostKeyAlgorithms() + { + return [ + 'ssh-ed25519', // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-02 + 'ecdsa-sha2-nistp256', // RFC 5656 + 'ecdsa-sha2-nistp384', // RFC 5656 + 'ecdsa-sha2-nistp521', // RFC 5656 + 'rsa-sha2-256', // RFC 8332 + 'rsa-sha2-512', // RFC 8332 + 'ssh-rsa', // RECOMMENDED sign Raw RSA Key + 'ssh-dss' // REQUIRED sign Raw DSS Key + ]; + } + + /** + * Returns a list of symmetric key algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedEncryptionAlgorithms() + { + $algos = [ + // from : + 'aes128-gcm@openssh.com', + 'aes256-gcm@openssh.com', + + // from : + 'arcfour256', + 'arcfour128', + + //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key + + // CTR modes from : + 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key + 'aes192-ctr', // RECOMMENDED AES with 192-bit key + 'aes256-ctr', // RECOMMENDED AES with 256-bit key + + // from : + // one of the big benefits of chacha20-poly1305 is speed. the problem is... + // libsodium doesn't generate the poly1305 keys in the way ssh does and openssl's PHP bindings don't even + // seem to support poly1305 currently. so even if libsodium or openssl are being used for the chacha20 + // part, pure-PHP has to be used for the poly1305 part and that's gonna cause a big slow down. + // speed-wise it winds up being faster to use AES (when openssl or mcrypt are available) and some HMAC + // (which is always gonna be super fast to compute thanks to the hash extension, which + // "is bundled and compiled into PHP by default") + 'chacha20-poly1305@openssh.com', + + 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key + 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key + 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key + + 'aes128-cbc', // RECOMMENDED AES with a 128-bit key + 'aes192-cbc', // OPTIONAL AES with a 192-bit key + 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key + + 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key + 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key + 'twofish256-cbc', + 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc" + // (this is being retained for historical reasons) + + 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode + + 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode + + '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode + + '3des-cbc', // REQUIRED three-key 3DES in CBC mode + + //'none' // OPTIONAL no encryption; NOT RECOMMENDED + ]; + + if (self::$crypto_engine) { + $engines = [self::$crypto_engine]; + } else { + $engines = [ + 'libsodium', + 'OpenSSL (GCM)', + 'OpenSSL', + 'mcrypt', + 'Eval', + 'PHP' + ]; + } + + $ciphers = []; + + foreach ($engines as $engine) { + foreach ($algos as $algo) { + $obj = self::encryption_algorithm_to_crypt_instance($algo); + if ($obj instanceof Rijndael) { + $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); + } + switch ($algo) { + case 'chacha20-poly1305@openssh.com': + case 'arcfour128': + case 'arcfour256': + if ($engine != 'Eval') { + continue 2; + } + break; + case 'aes128-gcm@openssh.com': + case 'aes256-gcm@openssh.com': + if ($engine == 'OpenSSL') { + continue 2; + } + $obj->setNonce('dummydummydu'); + } + if ($obj->isValidEngine($engine)) { + $algos = array_diff($algos, [$algo]); + $ciphers[] = $algo; + } + } + } + + return $ciphers; + } + + /** + * Returns a list of MAC algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedMACAlgorithms() + { + return [ + 'hmac-sha2-256-etm@openssh.com', + 'hmac-sha2-512-etm@openssh.com', + 'umac-64-etm@openssh.com', + 'umac-128-etm@openssh.com', + 'hmac-sha1-etm@openssh.com', + + // from : + 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) + 'hmac-sha2-512',// OPTIONAL HMAC-SHA512 (digest length = key length = 64) + + // from : + 'umac-64@openssh.com', + 'umac-128@openssh.com', + + 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) + 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) + 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) + 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) + //'none' // OPTIONAL no MAC; NOT RECOMMENDED + ]; + } + + /** + * Returns a list of compression algorithms that phpseclib supports + * + * @return array + */ + public static function getSupportedCompressionAlgorithms() + { + $algos = ['none']; // REQUIRED no compression + if (function_exists('deflate_init')) { + $algos[] = 'zlib@openssh.com'; // https://datatracker.ietf.org/doc/html/draft-miller-secsh-compression-delayed + $algos[] = 'zlib'; + } + return $algos; + } + + /** + * Return list of negotiated algorithms + * + * Uses the same format as https://www.php.net/ssh2-methods-negotiated + * + * @return array + */ + public function getAlgorithmsNegotiated() + { + $this->connect(); + + $compression_map = [ + self::NET_SSH2_COMPRESSION_NONE => 'none', + self::NET_SSH2_COMPRESSION_ZLIB => 'zlib', + self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com' + ]; + + return [ + 'kex' => $this->kex_algorithm, + 'hostkey' => $this->signature_format, + 'client_to_server' => [ + 'crypt' => $this->encryptName, + 'mac' => $this->hmac_create_name, + 'comp' => $compression_map[$this->compress], + ], + 'server_to_client' => [ + 'crypt' => $this->decryptName, + 'mac' => $this->hmac_check_name, + 'comp' => $compression_map[$this->decompress], + ] + ]; + } + + /** + * Force multiple channels (even if phpseclib has decided to disable them) + */ + public function forceMultipleChannels() + { + $this->errorOnMultipleChannels = false; + } + + /** + * Allows you to set the terminal + * + * @param string $term + */ + public function setTerminal($term) + { + $this->term = $term; + } + + /** + * Accepts an associative array with up to four parameters as described at + * + * + * @param array $methods + */ + public function setPreferredAlgorithms(array $methods) + { + $preferred = $methods; + + if (isset($preferred['kex'])) { + $preferred['kex'] = array_intersect( + $preferred['kex'], + static::getSupportedKEXAlgorithms() + ); + } + + if (isset($preferred['hostkey'])) { + $preferred['hostkey'] = array_intersect( + $preferred['hostkey'], + static::getSupportedHostKeyAlgorithms() + ); + } + + $keys = ['client_to_server', 'server_to_client']; + foreach ($keys as $key) { + if (isset($preferred[$key])) { + $a = &$preferred[$key]; + if (isset($a['crypt'])) { + $a['crypt'] = array_intersect( + $a['crypt'], + static::getSupportedEncryptionAlgorithms() + ); + } + if (isset($a['comp'])) { + $a['comp'] = array_intersect( + $a['comp'], + static::getSupportedCompressionAlgorithms() + ); + } + if (isset($a['mac'])) { + $a['mac'] = array_intersect( + $a['mac'], + static::getSupportedMACAlgorithms() + ); + } + } + } + + $keys = [ + 'kex', + 'hostkey', + 'client_to_server/crypt', + 'client_to_server/comp', + 'client_to_server/mac', + 'server_to_client/crypt', + 'server_to_client/comp', + 'server_to_client/mac', + ]; + foreach ($keys as $key) { + $p = $preferred; + $m = $methods; + + $subkeys = explode('/', $key); + foreach ($subkeys as $subkey) { + if (!isset($p[$subkey])) { + continue 2; + } + $p = $p[$subkey]; + $m = $m[$subkey]; + } + + if (count($p) != count($m)) { + $diff = array_diff($m, $p); + $msg = count($diff) == 1 ? + ' is not a supported algorithm' : + ' are not supported algorithms'; + throw new UnsupportedAlgorithmException(implode(', ', $diff) . $msg); + } + } + + $this->preferred = $preferred; + } + + /** + * Returns the banner message. + * + * Quoting from the RFC, "in some jurisdictions, sending a warning message before + * authentication may be relevant for getting legal protection." + * + * @return string + */ + public function getBannerMessage() + { + return $this->banner_message; + } + + /** + * Returns the server public host key. + * + * Caching this the first time you connect to a server and checking the result on subsequent connections + * is recommended. Returns false if the server signature is not signed correctly with the public host key. + * + * @return string|false + * @throws \RuntimeException on badly formatted keys + * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format + */ + public function getServerPublicHostKey() + { + if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { + $this->connect(); + } + + $signature = $this->signature; + $server_public_host_key = base64_encode($this->server_public_host_key); + + if ($this->signature_validated) { + return $this->bitmap ? + $this->signature_format . ' ' . $server_public_host_key : + false; + } + + $this->signature_validated = true; + + switch ($this->signature_format) { + case 'ssh-ed25519': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + $key = EC::loadFormat('OpenSSH', $server_public_host_key) + ->withSignatureFormat('SSH2'); + switch ($this->signature_format) { + case 'ssh-ed25519': + $hash = 'sha512'; + break; + case 'ecdsa-sha2-nistp256': + $hash = 'sha256'; + break; + case 'ecdsa-sha2-nistp384': + $hash = 'sha384'; + break; + case 'ecdsa-sha2-nistp521': + $hash = 'sha512'; + } + $key = $key->withHash($hash); + break; + case 'ssh-dss': + $key = DSA::loadFormat('OpenSSH', $server_public_host_key) + ->withSignatureFormat('SSH2') + ->withHash('sha1'); + break; + case 'ssh-rsa': + case 'rsa-sha2-256': + case 'rsa-sha2-512': + // could be ssh-rsa, rsa-sha2-256, rsa-sha2-512 + // we don't check here because we already checked in key_exchange + // some signatures have the type embedded within the message and some don't + list(, $signature) = Strings::unpackSSH2('ss', $signature); + + $key = RSA::loadFormat('OpenSSH', $server_public_host_key) + ->withPadding(RSA::SIGNATURE_PKCS1); + switch ($this->signature_format) { + case 'rsa-sha2-512': + $hash = 'sha512'; + break; + case 'rsa-sha2-256': + $hash = 'sha256'; + break; + //case 'ssh-rsa': + default: + $hash = 'sha1'; + } + $key = $key->withHash($hash); + break; + default: + $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + throw new NoSupportedAlgorithmsException('Unsupported signature format'); + } + + if (!$key->verify($this->exchange_hash, $signature)) { + return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); + }; + + return $this->signature_format . ' ' . $server_public_host_key; + } + + /** + * Returns the exit status of an SSH command or false. + * + * @return false|int + */ + public function getExitStatus() + { + if (is_null($this->exit_status)) { + return false; + } + return $this->exit_status; + } + + /** + * Returns the number of columns for the terminal window size. + * + * @return int + */ + public function getWindowColumns() + { + return $this->windowColumns; + } + + /** + * Returns the number of rows for the terminal window size. + * + * @return int + */ + public function getWindowRows() + { + return $this->windowRows; + } + + /** + * Sets the number of columns for the terminal window size. + * + * @param int $value + */ + public function setWindowColumns($value) + { + $this->windowColumns = $value; + } + + /** + * Sets the number of rows for the terminal window size. + * + * @param int $value + */ + public function setWindowRows($value) + { + $this->windowRows = $value; + } + + /** + * Sets the number of columns and rows for the terminal window size. + * + * @param int $columns + * @param int $rows + */ + public function setWindowSize($columns = 80, $rows = 24) + { + $this->windowColumns = $columns; + $this->windowRows = $rows; + } + + /** + * To String Magic Method + * + * @return string + */ + #[\ReturnTypeWillChange] + public function __toString() + { + return $this->getResourceId(); + } + + /** + * Get Resource ID + * + * We use {} because that symbols should not be in URL according to + * {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}. + * It will safe us from any conflicts, because otherwise regexp will + * match all alphanumeric domains. + * + * @return string + */ + public function getResourceId() + { + return '{' . spl_object_hash($this) . '}'; + } + + /** + * Return existing connection + * + * @param string $id + * + * @return bool|SSH2 will return false if no such connection + */ + public static function getConnectionByResourceId($id) + { + if (isset(self::$connections[$id])) { + return self::$connections[$id] instanceof \WeakReference ? self::$connections[$id]->get() : self::$connections[$id]; + } + return false; + } + + /** + * Return all excising connections + * + * @return array + */ + public static function getConnections() + { + if (!class_exists('WeakReference')) { + /** @var array */ + return self::$connections; + } + $temp = []; + foreach (self::$connections as $key => $ref) { + $temp[$key] = $ref->get(); + } + return $temp; + } + + /* + * Update packet types in log history + * + * @param string $old + * @param string $new + */ + private function updateLogHistory($old, $new) + { + if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { + $this->message_number_log[count($this->message_number_log) - 1] = str_replace( + $old, + $new, + $this->message_number_log[count($this->message_number_log) - 1] + ); + } + } + + /** + * Return the list of authentication methods that may productively continue authentication. + * + * @see https://tools.ietf.org/html/rfc4252#section-5.1 + * @return array|null + */ + public function getAuthMethodsToContinue() + { + return $this->auth_methods_to_continue; + } + + /** + * Enables "smart" multi-factor authentication (MFA) + */ + public function enableSmartMFA() + { + $this->smartMFA = true; + } + + /** + * Disables "smart" multi-factor authentication (MFA) + */ + public function disableSmartMFA() + { + $this->smartMFA = false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php new file mode 100644 index 0000000..26ca322 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php @@ -0,0 +1,286 @@ + + * login('username', $agent)) { + * exit('Login Failed'); + * } + * + * echo $ssh->exec('pwd'); + * echo $ssh->exec('ls -la'); + * ?> + * + * + * @author Jim Wigginton + * @copyright 2014 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\PublicKeyLoader; +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\BadConfigurationException; +use phpseclib3\Net\SSH2; +use phpseclib3\System\SSH\Agent\Identity; + +/** + * Pure-PHP ssh-agent client identity factory + * + * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects + * + * @author Jim Wigginton + */ +class Agent +{ + use Common\Traits\ReadBytes; + + // Message numbers + + // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) + const SSH_AGENTC_REQUEST_IDENTITIES = 11; + // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). + const SSH_AGENT_IDENTITIES_ANSWER = 12; + // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) + const SSH_AGENTC_SIGN_REQUEST = 13; + // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) + const SSH_AGENT_SIGN_RESPONSE = 14; + + // Agent forwarding status + + // no forwarding requested and not active + const FORWARD_NONE = 0; + // request agent forwarding when opportune + const FORWARD_REQUEST = 1; + // forwarding has been request and is active + const FORWARD_ACTIVE = 2; + + /** + * Unused + */ + const SSH_AGENT_FAILURE = 5; + + /** + * Socket Resource + * + * @var resource + */ + private $fsock; + + /** + * Agent forwarding status + * + * @var int + */ + private $forward_status = self::FORWARD_NONE; + + /** + * Buffer for accumulating forwarded authentication + * agent data arriving on SSH data channel destined + * for agent unix socket + * + * @var string + */ + private $socket_buffer = ''; + + /** + * Tracking the number of bytes we are expecting + * to arrive for the agent socket on the SSH data + * channel + * + * @var int + */ + private $expected_bytes = 0; + + /** + * Default Constructor + * + * @return \phpseclib3\System\SSH\Agent + * @throws \phpseclib3\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found + * @throws \RuntimeException on connection errors + */ + public function __construct($address = null) + { + if (!$address) { + switch (true) { + case isset($_SERVER['SSH_AUTH_SOCK']): + $address = $_SERVER['SSH_AUTH_SOCK']; + break; + case isset($_ENV['SSH_AUTH_SOCK']): + $address = $_ENV['SSH_AUTH_SOCK']; + break; + default: + throw new BadConfigurationException('SSH_AUTH_SOCK not found'); + } + } + + if (in_array('unix', stream_get_transports())) { + $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); + if (!$this->fsock) { + throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); + } + } else { + if (substr($address, 0, 9) != '\\\\.\\pipe\\' || strpos(substr($address, 9), '\\') !== false) { + throw new \RuntimeException('Address is not formatted as a named pipe should be'); + } + + $this->fsock = fopen($address, 'r+b'); + if (!$this->fsock) { + throw new \RuntimeException('Unable to open address'); + } + } + } + + /** + * Request Identities + * + * See "2.5.2 Requesting a list of protocol 2 keys" + * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects + * + * @return array + * @throws \RuntimeException on receipt of unexpected packets + */ + public function requestIdentities() + { + if (!$this->fsock) { + return []; + } + + $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); + if (strlen($packet) != fputs($this->fsock, $packet)) { + throw new \RuntimeException('Connection closed while requesting identities'); + } + + $length = current(unpack('N', $this->readBytes(4))); + $packet = $this->readBytes($length); + + list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); + if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { + throw new \RuntimeException('Unable to request identities'); + } + + $identities = []; + for ($i = 0; $i < $keyCount; $i++) { + list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); + $temp = $key_blob; + list($key_type) = Strings::unpackSSH2('s', $temp); + switch ($key_type) { + case 'ssh-rsa': + case 'ssh-dss': + case 'ssh-ed25519': + case 'ecdsa-sha2-nistp256': + case 'ecdsa-sha2-nistp384': + case 'ecdsa-sha2-nistp521': + $key = PublicKeyLoader::load($key_type . ' ' . base64_encode($key_blob)); + } + // resources are passed by reference by default + if (isset($key)) { + $identity = (new Identity($this->fsock)) + ->withPublicKey($key) + ->withPublicKeyBlob($key_blob); + $identities[] = $identity; + unset($key); + } + } + + return $identities; + } + + /** + * Signal that agent forwarding should + * be requested when a channel is opened + * + * @return void + */ + public function startSSHForwarding() + { + if ($this->forward_status == self::FORWARD_NONE) { + $this->forward_status = self::FORWARD_REQUEST; + } + } + + /** + * Request agent forwarding of remote server + * + * @param \phpseclib3\Net\SSH2 $ssh + * @return bool + */ + private function request_forwarding(SSH2 $ssh) + { + if (!$ssh->requestAgentForwarding()) { + return false; + } + + $this->forward_status = self::FORWARD_ACTIVE; + + return true; + } + + /** + * On successful channel open + * + * This method is called upon successful channel + * open to give the SSH Agent an opportunity + * to take further action. i.e. request agent forwarding + * + * @param \phpseclib3\Net\SSH2 $ssh + */ + public function registerChannelOpen(SSH2 $ssh) + { + if ($this->forward_status == self::FORWARD_REQUEST) { + $this->request_forwarding($ssh); + } + } + + /** + * Forward data to SSH Agent and return data reply + * + * @param string $data + * @return string Data from SSH Agent + * @throws \RuntimeException on connection errors + */ + public function forwardData($data) + { + if ($this->expected_bytes > 0) { + $this->socket_buffer .= $data; + $this->expected_bytes -= strlen($data); + } else { + $agent_data_bytes = current(unpack('N', $data)); + $current_data_bytes = strlen($data); + $this->socket_buffer = $data; + if ($current_data_bytes != $agent_data_bytes + 4) { + $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes; + return false; + } + } + + if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { + throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); + } + + $this->socket_buffer = ''; + $this->expected_bytes = 0; + + $agent_reply_bytes = current(unpack('N', $this->readBytes(4))); + + $agent_reply_data = $this->readBytes($agent_reply_bytes); + $agent_reply_data = current(unpack('a*', $agent_reply_data)); + + return pack('Na*', $agent_reply_bytes, $agent_reply_data); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php new file mode 100644 index 0000000..653e8ea --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php @@ -0,0 +1,320 @@ + + * @copyright 2009 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH\Agent; + +use phpseclib3\Common\Functions\Strings; +use phpseclib3\Crypt\Common\PrivateKey; +use phpseclib3\Crypt\Common\PublicKey; +use phpseclib3\Crypt\DSA; +use phpseclib3\Crypt\EC; +use phpseclib3\Crypt\RSA; +use phpseclib3\Exception\UnsupportedAlgorithmException; +use phpseclib3\System\SSH\Agent; +use phpseclib3\System\SSH\Common\Traits\ReadBytes; + +/** + * Pure-PHP ssh-agent client identity object + * + * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class. + * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA + * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. + * The methods in this interface would be getPublicKey and sign since those are the + * methods phpseclib looks for to perform public key authentication. + * + * @author Jim Wigginton + * @internal + */ +class Identity implements PrivateKey +{ + use ReadBytes; + + // Signature Flags + // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 + const SSH_AGENT_RSA2_256 = 2; + const SSH_AGENT_RSA2_512 = 4; + + /** + * Key Object + * + * @var PublicKey + * @see self::getPublicKey() + */ + private $key; + + /** + * Key Blob + * + * @var string + * @see self::sign() + */ + private $key_blob; + + /** + * Socket Resource + * + * @var resource + * @see self::sign() + */ + private $fsock; + + /** + * Signature flags + * + * @var int + * @see self::sign() + * @see self::setHash() + */ + private $flags = 0; + + /** + * Curve Aliases + * + * @var array + */ + private static $curveAliases = [ + 'secp256r1' => 'nistp256', + 'secp384r1' => 'nistp384', + 'secp521r1' => 'nistp521', + 'Ed25519' => 'Ed25519' + ]; + + /** + * Default Constructor. + * + * @param resource $fsock + */ + public function __construct($fsock) + { + $this->fsock = $fsock; + } + + /** + * Set Public Key + * + * Called by \phpseclib3\System\SSH\Agent::requestIdentities() + * + * @param \phpseclib3\Crypt\Common\PublicKey $key + */ + public function withPublicKey(PublicKey $key) + { + if ($key instanceof EC) { + if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) { + throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519'); + } + } + + $new = clone $this; + $new->key = $key; + return $new; + } + + /** + * Set Public Key + * + * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key + * but this saves a small amount of computation. + * + * @param string $key_blob + */ + public function withPublicKeyBlob($key_blob) + { + $new = clone $this; + $new->key_blob = $key_blob; + return $new; + } + + /** + * Get Public Key + * + * Wrapper for $this->key->getPublicKey() + * + * @param string $type optional + * @return mixed + */ + public function getPublicKey($type = 'PKCS8') + { + return $this->key; + } + + /** + * Sets the hash + * + * @param string $hash + */ + public function withHash($hash) + { + $new = clone $this; + + $hash = strtolower($hash); + + if ($this->key instanceof RSA) { + $new->flags = 0; + switch ($hash) { + case 'sha1': + break; + case 'sha256': + $new->flags = self::SSH_AGENT_RSA2_256; + break; + case 'sha512': + $new->flags = self::SSH_AGENT_RSA2_512; + break; + default: + throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512'); + } + } + if ($this->key instanceof EC) { + switch ($this->key->getCurve()) { + case 'secp256r1': + $expectedHash = 'sha256'; + break; + case 'secp384r1': + $expectedHash = 'sha384'; + break; + //case 'secp521r1': + //case 'Ed25519': + default: + $expectedHash = 'sha512'; + } + if ($hash != $expectedHash) { + throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$this->key->getCurve()] . ' is ' . $expectedHash); + } + } + if ($this->key instanceof DSA) { + if ($hash != 'sha1') { + throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1'); + } + } + return $new; + } + + /** + * Sets the padding + * + * Only PKCS1 padding is supported + * + * @param string $padding + */ + public function withPadding($padding) + { + if (!$this->key instanceof RSA) { + throw new UnsupportedAlgorithmException('Only RSA keys support padding'); + } + if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) { + throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures'); + } + return $this; + } + + /** + * Determines the signature padding mode + * + * Valid values are: ASN1, SSH2, Raw + * + * @param string $format + */ + public function withSignatureFormat($format) + { + if ($this->key instanceof RSA) { + throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting'); + } + if ($format != 'SSH2') { + throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported'); + } + + return $this; + } + + /** + * Returns the curve + * + * Returns a string if it's a named curve, an array if not + * + * @return string|array + */ + public function getCurve() + { + if (!$this->key instanceof EC) { + throw new UnsupportedAlgorithmException('Only EC keys have curves'); + } + + return $this->key->getCurve(); + } + + /** + * Create a signature + * + * See "2.6.2 Protocol 2 private key signature request" + * + * @param string $message + * @return string + * @throws \RuntimeException on connection errors + * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported + */ + public function sign($message) + { + // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE + $packet = Strings::packSSH2( + 'CssN', + Agent::SSH_AGENTC_SIGN_REQUEST, + $this->key_blob, + $message, + $this->flags + ); + $packet = Strings::packSSH2('s', $packet); + if (strlen($packet) != fputs($this->fsock, $packet)) { + throw new \RuntimeException('Connection closed during signing'); + } + + $length = current(unpack('N', $this->readBytes(4))); + $packet = $this->readBytes($length); + + list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); + if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { + throw new \RuntimeException('Unable to retrieve signature'); + } + + if (!$this->key instanceof RSA) { + return $signature_blob; + } + + list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); + + return $signature_blob; + } + + /** + * Returns the private key + * + * @param string $type + * @param array $options optional + * @return string + */ + public function toString($type, array $options = []) + { + throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + } + + /** + * Sets the password + * + * @param string|bool $password + * @return never + */ + public function withPassword($password = false) + { + throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php new file mode 100644 index 0000000..6fd032b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php @@ -0,0 +1,37 @@ + + * @copyright 2015 Jim Wigginton + * @license http://www.opensource.org/licenses/mit-license.html MIT License + * @link http://phpseclib.sourceforge.net + */ + +namespace phpseclib3\System\SSH\Common\Traits; + +/** + * ReadBytes trait + * + * @author Jim Wigginton + */ +trait ReadBytes +{ + /** + * Read data + * + * @param int $length + * @throws \RuntimeException on connection errors + */ + public function readBytes($length) + { + $temp = fread($this->fsock, $length); + if (strlen($temp) != $length) { + throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); + } + return $temp; + } +} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php new file mode 100644 index 0000000..517106c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php @@ -0,0 +1,22 @@ +=7.2 +- gmp +- mbstring + +## Installation + +This library is available on +[Packagist](https://packagist.org/packages/sop/asn1). + +```sh +composer require sop/asn1 +``` + +## Usage + +The general idea is that each ASN.1 type has its corresponding PHP class, +that knows the details of encoding and decoding the specific type. + +To decode DER data, use `fromDER` static method of the expected type. +To encode object to DER, use `toDER` instance method. + +Many methods return an `UnspecifiedType` object, that works as an intermediate +wrapper with accessor methods ensuring type safety. + +All objects are immutable and method chaining is promoted for the fluency +of the API. Exception shall be thrown on errors. + +## [Code Examples](https://github.com/sop/asn1/tree/master/examples) + +Here are some simple usage examples. Namespaces are omitted for brevity. + +### [Encode](https://github.com/sop/asn1/blob/master/examples/encode.php) + +Encode a sequence containing a UTF-8 string, an integer +and an explicitly tagged object identifier, conforming to the following +ASN.1 specification: + +```asn.1 +Example ::= SEQUENCE { + greeting UTF8String, + answer INTEGER, + type [1] EXPLICIT OBJECT IDENTIFIER +} +``` + +```php +$seq = new Sequence( + new UTF8String('Hello'), + new Integer(42), + new ExplicitlyTaggedType( + 1, new ObjectIdentifier('1.3.6.1.3')) +); +$der = $seq->toDER(); +``` + +### [Decode](https://github.com/sop/asn1/blob/master/examples/decode.php) + +Decode DER encoding from above. + +```php +$seq = UnspecifiedType::fromDER($der)->asSequence(); +$greeting = $seq->at(0)->asUTF8String()->string(); +$answer = $seq->at(1)->asInteger()->intNumber(); +$type = $seq->at(2)->asTagged()->asExplicit()->asObjectIdentifier()->oid(); +``` + +### Real-World Examples + +See the following for more practical real-world usage examples. + +- EC Private Key + - [Decode](https://github.com/sop/crypto-types/blob/a27fa76d5f5e8c4596cb65a7be9d02a08421ba1e/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php#L72) + - [Encode](https://github.com/sop/crypto-types/blob/a27fa76d5f5e8c4596cb65a7be9d02a08421ba1e/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php#L206) +- X.501 Attribute + - [Decode](https://github.com/sop/x501/blob/c6bdb04673d5c04b9d49f83020e75b8ba7a20064/lib/X501/ASN1/Attribute.php#L55) + - [Encode](https://github.com/sop/x501/blob/c6bdb04673d5c04b9d49f83020e75b8ba7a20064/lib/X501/ASN1/Attribute.php#L114) +- X.509 Certificate (`TBSCertificate` sequence) + - [Decode](https://github.com/sop/x509/blob/f762c743b6930af4f45ef857ccc9f6199980a92e/lib/X509/Certificate/TBSCertificate.php#L130) + - [Encode](https://github.com/sop/x509/blob/f762c743b6930af4f45ef857ccc9f6199980a92e/lib/X509/Certificate/TBSCertificate.php#L576) + +## ASN.1 References + +- [ITU-T X.690 07/2002](https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf) +- [ITU-T X.690 08/2015](https://www.itu.int/rec/T-REC-X.690-201508-I/en) +- Hosted by [OSS Nokalva](http://www.oss.com/asn1/resources/books-whitepapers-pubs/asn1-books.html) + - [ASN.1 — Communication Between Heterogeneous Systems by Olivier Dubuisson](http://www.oss.com/asn1/resources/books-whitepapers-pubs/dubuisson-asn1-book.PDF) + - [ASN.1 Complete by Professor John Larmouth](http://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf) + +## License + +This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/composer.json b/utilities/signing_and_verification/php/vendor/sop/asn1/composer.json new file mode 100644 index 0000000..630511d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/composer.json @@ -0,0 +1,34 @@ +{ + "name": "sop/asn1", + "description": "A PHP library for X.690 ASN.1 DER encoding and decoding.", + "homepage": "https://github.com/sop/asn1", + "license": "MIT", + "type": "library", + "keywords": [ + "asn1", + "asn.1", + "x690", + "x.690", + "der" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "require": { + "php": ">=7.2", + "ext-gmp": "*", + "ext-mbstring": "*" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "autoload": { + "psr-4": { + "Sop\\ASN1\\": "lib/ASN1/" + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php new file mode 100644 index 0000000..42d512f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php @@ -0,0 +1,290 @@ + 'UNIVERSAL', + self::CLASS_APPLICATION => 'APPLICATION', + self::CLASS_CONTEXT_SPECIFIC => 'CONTEXT SPECIFIC', + self::CLASS_PRIVATE => 'PRIVATE', + ]; + + // P/C enumerations + const PRIMITIVE = 0b0; + const CONSTRUCTED = 0b1; + + /** + * Type class. + * + * @var int + */ + private $_class; + + /** + * Primitive or Constructed. + * + * @var int + */ + private $_pc; + + /** + * Content type tag. + * + * @var BigInt + */ + private $_tag; + + /** + * Constructor. + * + * @param int $class Type class + * @param int $pc Primitive / Constructed + * @param \GMP|int|string $tag Type tag number + */ + public function __construct(int $class, int $pc, $tag) + { + $this->_class = 0b11 & $class; + $this->_pc = 0b1 & $pc; + $this->_tag = new BigInt($tag); + } + + /** + * Decode identifier component from DER data. + * + * @param string $data DER encoded data + * @param null|int $offset Reference to the variable that contains offset + * into the data where to start parsing. + * Variable is updated to the offset next to the + * parsed identifier. If null, start from offset 0. + * + * @throws DecodeException If decoding fails + * + * @return self + */ + public static function fromDER(string $data, int &$offset = null): Identifier + { + $idx = $offset ?? 0; + $datalen = strlen($data); + if ($idx >= $datalen) { + throw new DecodeException('Invalid offset.'); + } + $byte = ord($data[$idx++]); + // bits 8 and 7 (class) + // 0 = universal, 1 = application, 2 = context-specific, 3 = private + $class = (0b11000000 & $byte) >> 6; + // bit 6 (0 = primitive / 1 = constructed) + $pc = (0b00100000 & $byte) >> 5; + // bits 5 to 1 (tag number) + $tag = (0b00011111 & $byte); + // long-form identifier + if (0x1f === $tag) { + $tag = self::_decodeLongFormTag($data, $idx); + } + if (isset($offset)) { + $offset = $idx; + } + return new self($class, $pc, $tag); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + $bytes = []; + $byte = $this->_class << 6 | $this->_pc << 5; + $tag = $this->_tag->gmpObj(); + if ($tag < 0x1f) { + $bytes[] = $byte | $tag; + } + // long-form identifier + else { + $bytes[] = $byte | 0x1f; + $octets = []; + for (; $tag > 0; $tag >>= 7) { + array_push($octets, gmp_intval(0x80 | ($tag & 0x7f))); + } + // last octet has bit 8 set to zero + $octets[0] &= 0x7f; + foreach (array_reverse($octets) as $octet) { + $bytes[] = $octet; + } + } + return pack('C*', ...$bytes); + } + + /** + * Get class of the type. + */ + public function typeClass(): int + { + return $this->_class; + } + + /** + * Get P/C. + */ + public function pc(): int + { + return $this->_pc; + } + + /** + * Get the tag number. + * + * @return string Base 10 integer string + */ + public function tag(): string + { + return $this->_tag->base10(); + } + + /** + * Get the tag as an integer. + */ + public function intTag(): int + { + return $this->_tag->intVal(); + } + + /** + * Check whether type is of an universal class. + */ + public function isUniversal(): bool + { + return self::CLASS_UNIVERSAL === $this->_class; + } + + /** + * Check whether type is of an application class. + */ + public function isApplication(): bool + { + return self::CLASS_APPLICATION === $this->_class; + } + + /** + * Check whether type is of a context specific class. + */ + public function isContextSpecific(): bool + { + return self::CLASS_CONTEXT_SPECIFIC === $this->_class; + } + + /** + * Check whether type is of a private class. + */ + public function isPrivate(): bool + { + return self::CLASS_PRIVATE === $this->_class; + } + + /** + * Check whether content is primitive type. + */ + public function isPrimitive(): bool + { + return self::PRIMITIVE === $this->_pc; + } + + /** + * Check hether content is constructed type. + */ + public function isConstructed(): bool + { + return self::CONSTRUCTED === $this->_pc; + } + + /** + * Get self with given type class. + * + * @param int $class One of `CLASS_*` enumerations + * + * @return self + */ + public function withClass(int $class): Identifier + { + $obj = clone $this; + $obj->_class = 0b11 & $class; + return $obj; + } + + /** + * Get self with given type tag. + * + * @param \GMP|int|string $tag Tag number + * + * @return self + */ + public function withTag($tag): Identifier + { + $obj = clone $this; + $obj->_tag = new BigInt($tag); + return $obj; + } + + /** + * Get human readable name of the type class. + */ + public static function classToName(int $class): string + { + if (!array_key_exists($class, self::MAP_CLASS_TO_NAME)) { + return "CLASS {$class}"; + } + return self::MAP_CLASS_TO_NAME[$class]; + } + + /** + * Parse long form tag. + * + * @param string $data DER data + * @param int $offset Reference to the variable containing offset to data + * + * @throws DecodeException If decoding fails + * + * @return \GMP Tag number + */ + private static function _decodeLongFormTag(string $data, int &$offset): \GMP + { + $datalen = strlen($data); + $tag = gmp_init(0, 10); + while (true) { + if ($offset >= $datalen) { + throw new DecodeException( + 'Unexpected end of data while decoding long form identifier.'); + } + $byte = ord($data[$offset++]); + $tag <<= 7; + $tag |= 0x7f & $byte; + // last byte has bit 8 set to zero + if (!(0x80 & $byte)) { + break; + } + } + return $tag; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php new file mode 100644 index 0000000..27216e8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php @@ -0,0 +1,225 @@ +_length = new BigInt($length); + $this->_indefinite = $indefinite; + } + + /** + * Decode length component from DER data. + * + * @param string $data DER encoded data + * @param null|int $offset Reference to the variable that contains offset + * into the data where to start parsing. + * Variable is updated to the offset next to the + * parsed length component. If null, start from offset 0. + * + * @throws DecodeException If decoding fails + */ + public static function fromDER(string $data, int &$offset = null): self + { + $idx = $offset ?? 0; + $datalen = strlen($data); + if ($idx >= $datalen) { + throw new DecodeException( + 'Unexpected end of data while decoding length.'); + } + $indefinite = false; + $byte = ord($data[$idx++]); + // bits 7 to 1 + $length = (0x7f & $byte); + // long form + if (0x80 & $byte) { + if (!$length) { + $indefinite = true; + } else { + if ($idx + $length > $datalen) { + throw new DecodeException( + 'Unexpected end of data while decoding long form length.'); + } + $length = self::_decodeLongFormLength($length, $data, $idx); + } + } + if (isset($offset)) { + $offset = $idx; + } + return new self($length, $indefinite); + } + + /** + * Decode length from DER. + * + * Throws an exception if length doesn't match with expected or if data + * doesn't contain enough bytes. + * + * Requirement of definite length is relaxed contrary to the specification + * (sect. 10.1). + * + * @see self::fromDER + * + * @param string $data DER data + * @param int $offset Reference to the offset variable + * @param null|int $expected Expected length, null to bypass checking + * + * @throws DecodeException If decoding or expectation fails + */ + public static function expectFromDER(string $data, int &$offset, + int $expected = null): self + { + $idx = $offset; + $length = self::fromDER($data, $idx); + // if certain length was expected + if (isset($expected)) { + if ($length->isIndefinite()) { + throw new DecodeException( + sprintf('Expected length %d, got indefinite.', $expected)); + } + if ($expected !== $length->intLength()) { + throw new DecodeException( + sprintf('Expected length %d, got %d.', $expected, + $length->intLength())); + } + } + // check that enough data is available + if (!$length->isIndefinite() + && strlen($data) < $idx + $length->intLength()) { + throw new DecodeException( + sprintf('Length %d overflows data, %d bytes left.', + $length->intLength(), strlen($data) - $idx)); + } + $offset = $idx; + return $length; + } + + /** + * {@inheritdoc} + * + * @throws \DomainException If length is too large to encode + */ + public function toDER(): string + { + $bytes = []; + if ($this->_indefinite) { + $bytes[] = 0x80; + } else { + $num = $this->_length->gmpObj(); + // long form + if ($num > 127) { + $octets = []; + for (; $num > 0; $num >>= 8) { + $octets[] = gmp_intval(0xff & $num); + } + $count = count($octets); + // first octet must not be 0xff + if ($count >= 127) { + throw new \DomainException('Too many length octets.'); + } + $bytes[] = 0x80 | $count; + foreach (array_reverse($octets) as $octet) { + $bytes[] = $octet; + } + } + // short form + else { + $bytes[] = gmp_intval($num); + } + } + return pack('C*', ...$bytes); + } + + /** + * Get the length. + * + * @throws \LogicException If length is indefinite + * + * @return string Length as an integer string + */ + public function length(): string + { + if ($this->_indefinite) { + throw new \LogicException('Length is indefinite.'); + } + return $this->_length->base10(); + } + + /** + * Get the length as an integer. + * + * @throws \LogicException If length is indefinite + * @throws \RuntimeException If length overflows integer size + */ + public function intLength(): int + { + if ($this->_indefinite) { + throw new \LogicException('Length is indefinite.'); + } + return $this->_length->intVal(); + } + + /** + * Whether length is indefinite. + */ + public function isIndefinite(): bool + { + return $this->_indefinite; + } + + /** + * Decode long form length. + * + * @param int $length Number of octets + * @param string $data Data + * @param int $offset reference to the variable containing offset to the data + * + * @throws DecodeException If decoding fails + */ + private static function _decodeLongFormLength(int $length, string $data, + int &$offset): \GMP + { + // first octet must not be 0xff (spec 8.1.3.5c) + if (127 === $length) { + throw new DecodeException('Invalid number of length octets.'); + } + $num = gmp_init(0, 10); + while (--$length >= 0) { + $byte = ord($data[$offset++]); + $num <<= 8; + $num |= $byte; + } + return $num; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php new file mode 100644 index 0000000..055de94 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php @@ -0,0 +1,89 @@ +_identifier = Identifier::fromDER($data, $this->_contentOffset); + // check that length encoding is valid + Length::expectFromDER($data, $this->_contentOffset); + $this->_der = $data; + $this->_typeTag = $this->_identifier->intTag(); + } + + /** + * {@inheritdoc} + */ + public function typeClass(): int + { + return $this->_identifier->typeClass(); + } + + /** + * {@inheritdoc} + */ + public function isConstructed(): bool + { + return $this->_identifier->isConstructed(); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->_der; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + // if there's no content payload + if (strlen($this->_der) === $this->_contentOffset) { + return ''; + } + return substr($this->_der, $this->_contentOffset); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php new file mode 100644 index 0000000..864fe36 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php @@ -0,0 +1,465 @@ + Primitive\EOC::class, + self::TYPE_BOOLEAN => Primitive\Boolean::class, + self::TYPE_INTEGER => Primitive\Integer::class, + self::TYPE_BIT_STRING => Primitive\BitString::class, + self::TYPE_OCTET_STRING => Primitive\OctetString::class, + self::TYPE_NULL => Primitive\NullType::class, + self::TYPE_OBJECT_IDENTIFIER => Primitive\ObjectIdentifier::class, + self::TYPE_OBJECT_DESCRIPTOR => Primitive\ObjectDescriptor::class, + self::TYPE_REAL => Primitive\Real::class, + self::TYPE_ENUMERATED => Primitive\Enumerated::class, + self::TYPE_UTF8_STRING => Primitive\UTF8String::class, + self::TYPE_RELATIVE_OID => Primitive\RelativeOID::class, + self::TYPE_SEQUENCE => Constructed\Sequence::class, + self::TYPE_SET => Constructed\Set::class, + self::TYPE_NUMERIC_STRING => Primitive\NumericString::class, + self::TYPE_PRINTABLE_STRING => Primitive\PrintableString::class, + self::TYPE_T61_STRING => Primitive\T61String::class, + self::TYPE_VIDEOTEX_STRING => Primitive\VideotexString::class, + self::TYPE_IA5_STRING => Primitive\IA5String::class, + self::TYPE_UTC_TIME => Primitive\UTCTime::class, + self::TYPE_GENERALIZED_TIME => Primitive\GeneralizedTime::class, + self::TYPE_GRAPHIC_STRING => Primitive\GraphicString::class, + self::TYPE_VISIBLE_STRING => Primitive\VisibleString::class, + self::TYPE_GENERAL_STRING => Primitive\GeneralString::class, + self::TYPE_UNIVERSAL_STRING => Primitive\UniversalString::class, + self::TYPE_CHARACTER_STRING => Primitive\CharacterString::class, + self::TYPE_BMP_STRING => Primitive\BMPString::class, + ]; + + /** + * Pseudotype for all string types. + * + * May be used as an expectation parameter. + * + * @var int + */ + const TYPE_STRING = -1; + + /** + * Pseudotype for all time types. + * + * May be used as an expectation parameter. + * + * @var int + */ + const TYPE_TIME = -2; + + /** + * Pseudotype for constructed strings. + * + * May be used as an expectation parameter. + * + * @var int + */ + const TYPE_CONSTRUCTED_STRING = -3; + + /** + * Mapping from universal type tag to human readable name. + * + * @internal + * + * @var array + */ + const MAP_TYPE_TO_NAME = [ + self::TYPE_EOC => 'EOC', + self::TYPE_BOOLEAN => 'BOOLEAN', + self::TYPE_INTEGER => 'INTEGER', + self::TYPE_BIT_STRING => 'BIT STRING', + self::TYPE_OCTET_STRING => 'OCTET STRING', + self::TYPE_NULL => 'NULL', + self::TYPE_OBJECT_IDENTIFIER => 'OBJECT IDENTIFIER', + self::TYPE_OBJECT_DESCRIPTOR => 'ObjectDescriptor', + self::TYPE_EXTERNAL => 'EXTERNAL', + self::TYPE_REAL => 'REAL', + self::TYPE_ENUMERATED => 'ENUMERATED', + self::TYPE_EMBEDDED_PDV => 'EMBEDDED PDV', + self::TYPE_UTF8_STRING => 'UTF8String', + self::TYPE_RELATIVE_OID => 'RELATIVE-OID', + self::TYPE_SEQUENCE => 'SEQUENCE', + self::TYPE_SET => 'SET', + self::TYPE_NUMERIC_STRING => 'NumericString', + self::TYPE_PRINTABLE_STRING => 'PrintableString', + self::TYPE_T61_STRING => 'T61String', + self::TYPE_VIDEOTEX_STRING => 'VideotexString', + self::TYPE_IA5_STRING => 'IA5String', + self::TYPE_UTC_TIME => 'UTCTime', + self::TYPE_GENERALIZED_TIME => 'GeneralizedTime', + self::TYPE_GRAPHIC_STRING => 'GraphicString', + self::TYPE_VISIBLE_STRING => 'VisibleString', + self::TYPE_GENERAL_STRING => 'GeneralString', + self::TYPE_UNIVERSAL_STRING => 'UniversalString', + self::TYPE_CHARACTER_STRING => 'CHARACTER STRING', + self::TYPE_BMP_STRING => 'BMPString', + self::TYPE_STRING => 'Any String', + self::TYPE_TIME => 'Any Time', + self::TYPE_CONSTRUCTED_STRING => 'Constructed String', + ]; + + /** + * Element's type tag. + * + * @var int + */ + protected $_typeTag; + + /** + * Whether type shall be encoded with indefinite length. + * + * @var bool + */ + protected $_indefiniteLength = false; + + /** + * {@inheritdoc} + */ + abstract public function typeClass(): int; + + /** + * {@inheritdoc} + */ + abstract public function isConstructed(): bool; + + /** + * Decode element from DER data. + * + * @param string $data DER encoded data + * @param null|int $offset Reference to the variable that contains offset + * into the data where to start parsing. + * Variable is updated to the offset next to the + * parsed element. If null, start from offset 0. + * + * @throws DecodeException If decoding fails + * @throws \UnexpectedValueException If called in the context of an expected + * type, but decoding yields another type + */ + public static function fromDER(string $data, int &$offset = null): ElementBase + { + $idx = $offset ?? 0; + // decode identifier + $identifier = Identifier::fromDER($data, $idx); + // determine class that implements type specific decoding + $cls = self::_determineImplClass($identifier); + // decode remaining element + $element = $cls::_decodeFromDER($identifier, $data, $idx); + // if called in the context of a concrete class, check + // that decoded type matches the type of a calling class + $called_class = get_called_class(); + if (self::class !== $called_class) { + if (!$element instanceof $called_class) { + throw new \UnexpectedValueException( + sprintf('%s expected, got %s.', $called_class, get_class($element))); + } + } + // update offset for the caller + if (isset($offset)) { + $offset = $idx; + } + return $element; + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + $identifier = new Identifier($this->typeClass(), + $this->isConstructed() ? Identifier::CONSTRUCTED : Identifier::PRIMITIVE, + $this->_typeTag); + $content = $this->_encodedContentDER(); + if ($this->_indefiniteLength) { + $length = new Length(0, true); + $eoc = new Primitive\EOC(); + return $identifier->toDER() . $length->toDER() . $content . $eoc->toDER(); + } + $length = new Length(strlen($content)); + return $identifier->toDER() . $length->toDER() . $content; + } + + /** + * {@inheritdoc} + */ + public function tag(): int + { + return $this->_typeTag; + } + + /** + * {@inheritdoc} + */ + public function isType(int $tag): bool + { + // if element is context specific + if (Identifier::CLASS_CONTEXT_SPECIFIC === $this->typeClass()) { + return false; + } + // negative tags identify an abstract pseudotype + if ($tag < 0) { + return $this->_isPseudoType($tag); + } + return $this->_isConcreteType($tag); + } + + /** + * {@inheritdoc} + */ + public function expectType(int $tag): ElementBase + { + if (!$this->isType($tag)) { + throw new \UnexpectedValueException( + sprintf('%s expected, got %s.', self::tagToName($tag), + $this->_typeDescriptorString())); + } + return $this; + } + + /** + * {@inheritdoc} + */ + public function isTagged(): bool + { + return $this instanceof TaggedType; + } + + /** + * {@inheritdoc} + */ + public function expectTagged(?int $tag = null): TaggedType + { + if (!$this->isTagged()) { + throw new \UnexpectedValueException( + sprintf('Context specific element expected, got %s.', + Identifier::classToName($this->typeClass()))); + } + if (isset($tag) && $this->tag() !== $tag) { + throw new \UnexpectedValueException( + sprintf('Tag %d expected, got %d.', $tag, $this->tag())); + } + return $this; + } + + /** + * Whether element has indefinite length. + */ + public function hasIndefiniteLength(): bool + { + return $this->_indefiniteLength; + } + + /** + * Get self with indefinite length encoding set. + * + * @param bool $indefinite True for indefinite length, false for definite length + */ + public function withIndefiniteLength(bool $indefinite = true): self + { + $obj = clone $this; + $obj->_indefiniteLength = $indefinite; + return $obj; + } + + /** + * {@inheritdoc} + */ + final public function asElement(): Element + { + return $this; + } + + /** + * Get element decorated with `UnspecifiedType` object. + */ + public function asUnspecified(): UnspecifiedType + { + return new UnspecifiedType($this); + } + + /** + * Get human readable name for an universal tag. + */ + public static function tagToName(int $tag): string + { + if (!array_key_exists($tag, self::MAP_TYPE_TO_NAME)) { + return "TAG {$tag}"; + } + return self::MAP_TYPE_TO_NAME[$tag]; + } + + /** + * Get the content encoded in DER. + * + * Returns the DER encoded content without identifier and length header octets. + */ + abstract protected function _encodedContentDER(): string; + + /** + * Decode type-specific element from DER. + * + * @param Identifier $identifier Pre-parsed identifier + * @param string $data DER data + * @param int $offset Offset in data to the next byte after identifier + * + * @throws DecodeException If decoding fails + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + throw new \BadMethodCallException( + __METHOD__ . ' must be implemented in derived class.'); + } + + /** + * Determine the class that implements the type. + * + * @return string Class name + */ + protected static function _determineImplClass(Identifier $identifier): string + { + switch ($identifier->typeClass()) { + case Identifier::CLASS_UNIVERSAL: + $cls = self::_determineUniversalImplClass($identifier->intTag()); + // constructed strings may be present in BER + if ($identifier->isConstructed() + && is_subclass_of($cls, StringType::class)) { + $cls = ConstructedString::class; + } + return $cls; + case Identifier::CLASS_CONTEXT_SPECIFIC: + return ContextSpecificType::class; + case Identifier::CLASS_APPLICATION: + return ApplicationType::class; + case Identifier::CLASS_PRIVATE: + return PrivateType::class; + } + throw new \UnexpectedValueException(sprintf('%s %d not implemented.', + Identifier::classToName($identifier->typeClass()), $identifier->tag())); + } + + /** + * Determine the class that implements an universal type of the given tag. + * + * @throws \UnexpectedValueException + * + * @return string Class name + */ + protected static function _determineUniversalImplClass(int $tag): string + { + if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) { + throw new \UnexpectedValueException( + "Universal tag {$tag} not implemented."); + } + return self::MAP_TAG_TO_CLASS[$tag]; + } + + /** + * Get textual description of the type for debugging purposes. + */ + protected function _typeDescriptorString(): string + { + if (Identifier::CLASS_UNIVERSAL === $this->typeClass()) { + return self::tagToName($this->_typeTag); + } + return sprintf('%s TAG %d', Identifier::classToName($this->typeClass()), + $this->_typeTag); + } + + /** + * Check whether the element is a concrete type of a given tag. + */ + private function _isConcreteType(int $tag): bool + { + // if tag doesn't match + if ($this->tag() !== $tag) { + return false; + } + // if type is universal check that instance is of a correct class + if (Identifier::CLASS_UNIVERSAL === $this->typeClass()) { + $cls = self::_determineUniversalImplClass($tag); + if (!$this instanceof $cls) { + return false; + } + } + return true; + } + + /** + * Check whether the element is a pseudotype. + */ + private function _isPseudoType(int $tag): bool + { + switch ($tag) { + case self::TYPE_STRING: + return $this instanceof StringType; + case self::TYPE_TIME: + return $this instanceof TimeType; + case self::TYPE_CONSTRUCTED_STRING: + return $this instanceof ConstructedString; + } + return false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php new file mode 100644 index 0000000..6d53b44 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php @@ -0,0 +1,12 @@ +_validateString($string)) { + throw new \InvalidArgumentException( + sprintf('Not a valid %s string.', self::tagToName($this->_typeTag))); + } + $this->_string = $string; + } + + /** + * {@inheritdoc} + */ + public function __toString(): string + { + return $this->string(); + } + + /** + * Get the string value. + */ + public function string(): string + { + return $this->_string; + } + + /** + * Check whether string is valid for the concrete type. + */ + protected function _validateString(string $string): bool + { + // Override in derived classes + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php new file mode 100644 index 0000000..3723926 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php @@ -0,0 +1,107 @@ +_dateTime = $dt; + } + + /** + * {@inheritdoc} + */ + public function __toString(): string + { + return $this->string(); + } + + /** + * Initialize from datetime string. + * + * @see http://php.net/manual/en/datetime.formats.php + * + * @param string $time Time string + * @param null|string $tz timezone, if null use default + * + * @throws \RuntimeException + */ + public static function fromString(string $time, ?string $tz = null): self + { + try { + if (!isset($tz)) { + $tz = date_default_timezone_get(); + } + return new static( + new \DateTimeImmutable($time, self::_createTimeZone($tz))); + } catch (\Exception $e) { + throw new \RuntimeException( + 'Failed to create DateTime: ' . + self::_getLastDateTimeImmutableErrorsStr(), 0, $e); + } + } + + /** + * Get the date and time. + */ + public function dateTime(): \DateTimeImmutable + { + return $this->_dateTime; + } + + /** + * Get the date and time as a type specific string. + */ + public function string(): string + { + return $this->_encodedContentDER(); + } + + /** + * Create `DateTimeZone` object from string. + * + * @throws \UnexpectedValueException If timezone is invalid + */ + protected static function _createTimeZone(string $tz): \DateTimeZone + { + try { + return new \DateTimeZone($tz); + } catch (\Exception $e) { + throw new \UnexpectedValueException('Invalid timezone.', 0, $e); + } + } + + /** + * Get last error caused by `DateTimeImmutable`. + */ + protected static function _getLastDateTimeImmutableErrorsStr(): string + { + $errors = \DateTimeImmutable::getLastErrors()['errors']; + return implode(', ', $errors); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php new file mode 100644 index 0000000..d45dc4d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php @@ -0,0 +1,131 @@ +string(); + } + + /** + * Create from a list of string type elements. + * + * All strings must have the same type. + * + * @param StringType ...$elements + * + * @throws \LogicException + */ + public static function create(StringType ...$elements): self + { + if (!count($elements)) { + throw new \LogicException('No elements, unable to determine type tag.'); + } + $tag = $elements[0]->tag(); + foreach ($elements as $el) { + if ($el->tag() !== $tag) { + throw new \LogicException( + 'All elements in constructed string must have the same type.'); + } + } + return self::createWithTag($tag, ...$elements); + } + + /** + * Create from strings with a given type tag. + * + * Does not perform any validation on types. + * + * @param int $tag Type tag for the constructed string element + * @param StringType ...$elements Any number of elements + * + * @return self + */ + public static function createWithTag(int $tag, StringType ...$elements) + { + $el = new self(...$elements); + $el->_typeTag = $tag; + return $el; + } + + /** + * Get a list of strings in this structure. + * + * @return string[] + */ + public function strings(): array + { + return array_map(function (StringType $el) { + return $el->string(); + }, $this->_elements); + } + + /** + * Get the contained strings concatenated together. + * + * NOTE: It's unclear how bit strings with unused bits should be concatenated. + */ + public function string(): string + { + return implode('', $this->strings()); + } + + /** + * {@inheritdoc} + * + * @return self + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + /** @var ConstructedString $type */ + $type = forward_static_call_array([parent::class, __FUNCTION__], + [$identifier, $data, &$offset]); + $type->_typeTag = $identifier->intTag(); + return $type; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php new file mode 100644 index 0000000..52f0b86 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php @@ -0,0 +1,25 @@ +_typeTag = self::TYPE_SEQUENCE; + parent::__construct(...$elements); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php new file mode 100644 index 0000000..ce54442 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php @@ -0,0 +1,63 @@ +_typeTag = self::TYPE_SET; + parent::__construct(...$elements); + } + + /** + * Sort by canonical ascending order. + * + * Used for DER encoding of *SET* type. + */ + public function sortedSet(): self + { + $obj = clone $this; + usort($obj->_elements, + function (Element $a, Element $b) { + if ($a->typeClass() !== $b->typeClass()) { + return $a->typeClass() < $b->typeClass() ? -1 : 1; + } + if ($a->tag() === $b->tag()) { + return 0; + } + return $a->tag() < $b->tag() ? -1 : 1; + }); + return $obj; + } + + /** + * Sort by encoding ascending order. + * + * Used for DER encoding of *SET OF* type. + */ + public function sortedSetOf(): self + { + $obj = clone $this; + usort($obj->_elements, + function (Element $a, Element $b) { + $a_der = $a->toDER(); + $b_der = $b->toDER(); + return strcmp($a_der, $b_der); + }); + return $obj; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php new file mode 100644 index 0000000..eb9e20d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php @@ -0,0 +1,40 @@ +_typeTag = self::TYPE_BMP_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + // UCS-2 has fixed with of 2 octets (16 bits) + if (0 !== strlen($string) % 2) { + return false; + } + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php new file mode 100644 index 0000000..c8be9cc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php @@ -0,0 +1,201 @@ +_typeTag = self::TYPE_BIT_STRING; + parent::__construct($string); + $this->_unusedBits = $unused_bits; + } + + /** + * Get the number of bits in the string. + */ + public function numBits(): int + { + return strlen($this->_string) * 8 - $this->_unusedBits; + } + + /** + * Get the number of unused bits in the last octet of the string. + */ + public function unusedBits(): int + { + return $this->_unusedBits; + } + + /** + * Test whether bit is set. + * + * @param int $idx Bit index. Most significant bit of the first octet is index 0. + */ + public function testBit(int $idx): bool + { + // octet index + $oi = (int) floor($idx / 8); + // if octet is outside range + if ($oi < 0 || $oi >= strlen($this->_string)) { + throw new \OutOfBoundsException('Index is out of bounds.'); + } + // bit index + $bi = $idx % 8; + // if tested bit is last octet's unused bit + if ($oi === strlen($this->_string) - 1) { + if ($bi >= 8 - $this->_unusedBits) { + throw new \OutOfBoundsException('Index refers to an unused bit.'); + } + } + $byte = $this->_string[$oi]; + // index 0 is the most significant bit in byte + $mask = 0x01 << (7 - $bi); + return (ord($byte) & $mask) > 0; + } + + /** + * Get range of bits. + * + * @param int $start Index of first bit + * @param int $length Number of bits in range + * + * @throws \OutOfBoundsException + * + * @return string Integer of $length bits + */ + public function range(int $start, int $length): string + { + if (!$length) { + return '0'; + } + if ($start + $length > $this->numBits()) { + throw new \OutOfBoundsException('Not enough bits.'); + } + $bits = gmp_init(0); + $idx = $start; + $end = $start + $length; + while (true) { + $bit = $this->testBit($idx) ? 1 : 0; + $bits |= $bit; + if (++$idx >= $end) { + break; + } + $bits <<= 1; + } + return gmp_strval($bits, 10); + } + + /** + * Get a copy of the bit string with trailing zeroes removed. + */ + public function withoutTrailingZeroes(): self + { + // if bit string was empty + if (!strlen($this->_string)) { + return new self(''); + } + $bits = $this->_string; + // count number of empty trailing octets + $unused_octets = 0; + for ($idx = strlen($bits) - 1; $idx >= 0; --$idx, ++$unused_octets) { + if ("\x0" !== $bits[$idx]) { + break; + } + } + // strip trailing octets + if ($unused_octets) { + $bits = substr($bits, 0, -$unused_octets); + } + // if bit string was full of zeroes + if (!strlen($bits)) { + return new self(''); + } + // count number of trailing zeroes in the last octet + $unused_bits = 0; + $byte = ord($bits[strlen($bits) - 1]); + while (!($byte & 0x01)) { + ++$unused_bits; + $byte >>= 1; + } + return new self($bits, $unused_bits); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + $der = chr($this->_unusedBits); + $der .= $this->_string; + if ($this->_unusedBits) { + $octet = $der[strlen($der) - 1]; + // set unused bits to zero + $octet &= chr(0xff & ~((1 << $this->_unusedBits) - 1)); + $der[strlen($der) - 1] = $octet; + } + return $der; + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $length = Length::expectFromDER($data, $idx); + if ($length->intLength() < 1) { + throw new DecodeException('Bit string length must be at least 1.'); + } + $unused_bits = ord($data[$idx++]); + if ($unused_bits > 7) { + throw new DecodeException( + 'Unused bits in a bit string must be less than 8.'); + } + $str_len = $length->intLength() - 1; + if ($str_len) { + $str = substr($data, $idx, $str_len); + if ($unused_bits) { + $mask = (1 << $unused_bits) - 1; + if (ord($str[strlen($str) - 1]) & $mask) { + throw new DecodeException( + 'DER encoded bit string must have zero padding.'); + } + } + } else { + $str = ''; + } + $offset = $idx + $str_len; + return new self($str, $unused_bits); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php new file mode 100644 index 0000000..4c2f020 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php @@ -0,0 +1,73 @@ +_typeTag = self::TYPE_BOOLEAN; + $this->_bool = $bool; + } + + /** + * Get the value. + */ + public function value(): bool + { + return $this->_bool; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + return $this->_bool ? chr(0xff) : chr(0); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + Length::expectFromDER($data, $idx, 1); + $byte = ord($data[$idx++]); + if (0 !== $byte) { + if (0xff !== $byte) { + throw new DecodeException( + 'DER encoded boolean true must have all bits set to 1.'); + } + } + $offset = $idx; + return new self(0 !== $byte); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php new file mode 100644 index 0000000..cf9476e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php @@ -0,0 +1,25 @@ +_typeTag = self::TYPE_CHARACTER_STRING; + parent::__construct($string); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php new file mode 100644 index 0000000..394ed7f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php @@ -0,0 +1,54 @@ +_typeTag = self::TYPE_EOC; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + return ''; + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + if (!$identifier->isPrimitive()) { + throw new DecodeException('EOC value must be primitive.'); + } + // EOC type has always zero length + Length::expectFromDER($data, $idx, 0); + $offset = $idx; + return new self(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php new file mode 100644 index 0000000..98f467b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php @@ -0,0 +1,22 @@ +_typeTag = self::TYPE_ENUMERATED; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php new file mode 100644 index 0000000..a781a49 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php @@ -0,0 +1,34 @@ +_typeTag = self::TYPE_GENERAL_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + // allow everything + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php new file mode 100644 index 0000000..9cfba85 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php @@ -0,0 +1,125 @@ +_typeTag = self::TYPE_GENERALIZED_TIME; + parent::__construct($dt); + } + + /** + * Clear cached variables on clone. + */ + public function __clone() + { + $this->_formatted = null; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + if (!isset($this->_formatted)) { + $dt = $this->_dateTime->setTimezone( + self::_createTimeZone(self::TZ_UTC)); + $this->_formatted = $dt->format('YmdHis'); + // if fractions were used + $frac = $dt->format('u'); + if (0 !== intval($frac)) { + $frac = rtrim($frac, '0'); + $this->_formatted .= ".{$frac}"; + } + // timezone + $this->_formatted .= 'Z'; + } + return $this->_formatted; + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $length = Length::expectFromDER($data, $idx)->intLength(); + $str = substr($data, $idx, $length); + $idx += $length; + /** @var string[] $match */ + if (!preg_match(self::REGEX, $str, $match)) { + throw new DecodeException('Invalid GeneralizedTime format.'); + } + [, $year, $month, $day, $hour, $minute, $second] = $match; + // if fractions match, there's at least one digit + if (isset($match[7])) { + $frac = $match[7]; + // DER restricts trailing zeroes in fractional seconds component + if ('0' === $frac[strlen($frac) - 1]) { + throw new DecodeException( + 'Fractional seconds must omit trailing zeroes.'); + } + $frac = $frac; + } else { + $frac = '0'; + } + $time = $year . $month . $day . $hour . $minute . $second . '.' . $frac . + self::TZ_UTC; + $dt = \DateTimeImmutable::createFromFormat('!YmdHis.uT', $time, + self::_createTimeZone(self::TZ_UTC)); + if (!$dt) { + throw new DecodeException( + 'Failed to decode GeneralizedTime: ' . + self::_getLastDateTimeImmutableErrorsStr()); + } + $offset = $idx; + return new self($dt); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php new file mode 100644 index 0000000..0fa2480 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php @@ -0,0 +1,34 @@ +_typeTag = self::TYPE_GRAPHIC_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + // allow everything + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php new file mode 100644 index 0000000..4dd29ed --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php @@ -0,0 +1,33 @@ +_typeTag = self::TYPE_IA5_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + return 0 == preg_match('/[^\x00-\x7f]/', $string); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php new file mode 100644 index 0000000..ed77b22 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php @@ -0,0 +1,105 @@ +_typeTag = self::TYPE_INTEGER; + if (!self::_validateNumber($number)) { + $var = is_scalar($number) ? strval($number) : gettype($number); + throw new \InvalidArgumentException("'{$var}' is not a valid number."); + } + $this->_number = new BigInt($number); + } + + /** + * Get the number as a base 10. + * + * @return string Integer as a string + */ + public function number(): string + { + return $this->_number->base10(); + } + + /** + * Get the number as an integer type. + */ + public function intNumber(): int + { + return $this->_number->intVal(); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + return $this->_number->signedOctets(); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $length = Length::expectFromDER($data, $idx)->intLength(); + $bytes = substr($data, $idx, $length); + $idx += $length; + $num = BigInt::fromSignedOctets($bytes)->gmpObj(); + $offset = $idx; + // late static binding since enumerated extends integer type + return new static($num); + } + + /** + * Test that number is valid for this context. + * + * @param mixed $num + */ + private static function _validateNumber($num): bool + { + if (is_int($num)) { + return true; + } + if (is_string($num) && preg_match('/-?\d+/', $num)) { + return true; + } + if ($num instanceof \GMP) { + return true; + } + return false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php new file mode 100644 index 0000000..fa3e86b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php @@ -0,0 +1,54 @@ +_typeTag = self::TYPE_NULL; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + return ''; + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + if (!$identifier->isPrimitive()) { + throw new DecodeException('Null value must be primitive.'); + } + // null type has always zero length + Length::expectFromDER($data, $idx, 0); + $offset = $idx; + return new self(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php new file mode 100644 index 0000000..5a2454d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php @@ -0,0 +1,33 @@ +_typeTag = self::TYPE_NUMERIC_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + return 0 == preg_match('/[^0-9 ]/', $string); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php new file mode 100644 index 0000000..c40bdc1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php @@ -0,0 +1,33 @@ +_string = $descriptor; + $this->_typeTag = self::TYPE_OBJECT_DESCRIPTOR; + } + + /** + * Get the object descriptor. + */ + public function descriptor(): string + { + return $this->_string; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php new file mode 100644 index 0000000..f8cc9d8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php @@ -0,0 +1,207 @@ +_oid = $oid; + $this->_subids = self::_explodeDottedOID($oid); + // if OID is non-empty + if (count($this->_subids) > 0) { + // check that at least two nodes are set + if (count($this->_subids) < 2) { + throw new \UnexpectedValueException( + 'OID must have at least two nodes.'); + } + // check that root arc is in 0..2 range + if ($this->_subids[0] > 2) { + throw new \UnexpectedValueException( + 'Root arc must be in range of 0..2.'); + } + // if root arc is 0 or 1, second node must be in 0..39 range + if ($this->_subids[0] < 2 && $this->_subids[1] >= 40) { + throw new \UnexpectedValueException( + 'Second node must be in 0..39 range for root arcs 0 and 1.'); + } + } + $this->_typeTag = self::TYPE_OBJECT_IDENTIFIER; + } + + /** + * Get OID in dotted format. + */ + public function oid(): string + { + return $this->_oid; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + $subids = $this->_subids; + // encode first two subids to one according to spec section 8.19.4 + if (count($subids) >= 2) { + $num = ($subids[0] * 40) + $subids[1]; + array_splice($subids, 0, 2, [$num]); + } + return self::_encodeSubIDs(...$subids); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $len = Length::expectFromDER($data, $idx)->intLength(); + $subids = self::_decodeSubIDs(substr($data, $idx, $len)); + $idx += $len; + // decode first subidentifier according to spec section 8.19.4 + if (isset($subids[0])) { + if ($subids[0] < 80) { + [$x, $y] = gmp_div_qr($subids[0], '40'); + } else { + $x = gmp_init(2, 10); + $y = $subids[0] - 80; + } + array_splice($subids, 0, 1, [$x, $y]); + } + $offset = $idx; + return new self(self::_implodeSubIDs(...$subids)); + } + + /** + * Explode dotted OID to an array of sub ID's. + * + * @param string $oid OID in dotted format + * + * @return \GMP[] Array of GMP numbers + */ + protected static function _explodeDottedOID(string $oid): array + { + $subids = []; + if (strlen($oid)) { + foreach (explode('.', $oid) as $subid) { + $n = @gmp_init($subid, 10); + if (false === $n) { + throw new \UnexpectedValueException( + "'{$subid}' is not a number."); + } + $subids[] = $n; + } + } + return $subids; + } + + /** + * Implode an array of sub IDs to dotted OID format. + * + * @param \GMP ...$subids + */ + protected static function _implodeSubIDs(\GMP ...$subids): string + { + return implode('.', + array_map(function ($num) { + return gmp_strval($num, 10); + }, $subids)); + } + + /** + * Encode sub ID's to DER. + * + * @param \GMP ...$subids + */ + protected static function _encodeSubIDs(\GMP ...$subids): string + { + $data = ''; + foreach ($subids as $subid) { + // if number fits to one base 128 byte + if ($subid < 128) { + $data .= chr(intval($subid)); + } else { // encode to multiple bytes + $bytes = []; + do { + array_unshift($bytes, 0x7f & gmp_intval($subid)); + $subid >>= 7; + } while ($subid > 0); + // all bytes except last must have bit 8 set to one + foreach (array_splice($bytes, 0, -1) as $byte) { + $data .= chr(0x80 | $byte); + } + $data .= chr(reset($bytes)); + } + } + return $data; + } + + /** + * Decode sub ID's from DER data. + * + * @throws DecodeException + * + * @return \GMP[] Array of GMP numbers + */ + protected static function _decodeSubIDs(string $data): array + { + $subids = []; + $idx = 0; + $end = strlen($data); + while ($idx < $end) { + $num = gmp_init('0', 10); + while (true) { + if ($idx >= $end) { + throw new DecodeException('Unexpected end of data.'); + } + $byte = ord($data[$idx++]); + $num |= $byte & 0x7f; + // bit 8 of the last octet is zero + if (!($byte & 0x80)) { + break; + } + $num <<= 7; + } + $subids[] = $num; + } + return $subids; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php new file mode 100644 index 0000000..547d040 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php @@ -0,0 +1,25 @@ +_typeTag = self::TYPE_OCTET_STRING; + parent::__construct($string); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php new file mode 100644 index 0000000..0b17d22 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php @@ -0,0 +1,34 @@ +_typeTag = self::TYPE_PRINTABLE_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + $chars = preg_quote(" '()+,-./:=?]", '/'); + return 0 == preg_match('/[^A-Za-z0-9' . $chars . ']/', $string); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php new file mode 100644 index 0000000..3efd67f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php @@ -0,0 +1,698 @@ +[+\-])?' . // sign + '(?\d+)' . // integer + '$/'; + + /** + * Regex pattern to parse NR2 form number. + * + * @var string + */ + const NR2_REGEX = '/^\s*' . + '(?[+\-])?' . // sign + '(?(?:\d+[\.,]\d*)|(?:\d*[\.,]\d+))' . // decimal number + '$/'; + + /** + * Regex pattern to parse NR3 form number. + * + * @var string + */ + const NR3_REGEX = '/^\s*' . + '(?[+\-])?' . // mantissa sign + '(?(?:\d+[\.,]\d*)|(?:\d*[\.,]\d+))' . // mantissa + '[Ee](?[+\-])?' . // exponent sign + '(?\d+)' . // exponent + '$/'; + + /** + * Regex pattern to parse PHP exponent number format. + * + * @see http://php.net/manual/en/language.types.float.php + * + * @var string + */ + const PHP_EXPONENT_DNUM = '/^' . + '(?[+\-])?' . // sign + '(?' . + '\d+' . // LNUM + '|' . + '(?:\d*\.\d+|\d+\.\d*)' . // DNUM + ')[eE]' . + '(?[+\-])?(?\d+)' . // exponent + '$/'; + + /** + * Exponent when value is positive or negative infinite. + * + * @var int + */ + const INF_EXPONENT = 2047; + + /** + * Exponent bias for IEEE 754 double precision float. + * + * @var int + */ + const EXP_BIAS = -1023; + + /** + * Signed integer mantissa. + * + * @var BigInt + */ + private $_mantissa; + + /** + * Signed integer exponent. + * + * @var BigInt + */ + private $_exponent; + + /** + * Abstract value base. + * + * Must be 2 or 10. + * + * @var int + */ + private $_base; + + /** + * Whether to encode strictly in DER. + * + * @var bool + */ + private $_strictDer; + + /** + * Number as a native float. + * + * @internal Lazily initialized + * + * @var null|float + */ + private $_float; + + /** + * Constructor. + * + * @param \GMP|int|string $mantissa Integer mantissa + * @param \GMP|int|string $exponent Integer exponent + * @param int $base Base, 2 or 10 + */ + public function __construct($mantissa, $exponent, int $base = 10) + { + if (10 !== $base && 2 !== $base) { + throw new \UnexpectedValueException('Base must be 2 or 10.'); + } + $this->_typeTag = self::TYPE_REAL; + $this->_strictDer = true; + $this->_mantissa = new BigInt($mantissa); + $this->_exponent = new BigInt($exponent); + $this->_base = $base; + } + + /** + * {@inheritdoc} + */ + public function __toString(): string + { + return sprintf('%g', $this->floatVal()); + } + + /** + * Create base 2 real number from float. + */ + public static function fromFloat(float $number): self + { + if (is_infinite($number)) { + return self::_fromInfinite($number); + } + if (is_nan($number)) { + throw new \UnexpectedValueException('NaN values not supported.'); + } + [$m, $e] = self::_parse754Double(pack('E', $number)); + return new self($m, $e, 2); + } + + /** + * Create base 10 real number from string. + * + * @param string $number Real number in base-10 textual form + */ + public static function fromString(string $number): self + { + [$m, $e] = self::_parseString($number); + return new self($m, $e, 10); + } + + /** + * Get self with strict DER flag set or unset. + * + * @param bool $strict whether to encode strictly in DER + */ + public function withStrictDER(bool $strict): self + { + $obj = clone $this; + $obj->_strictDer = $strict; + return $obj; + } + + /** + * Get the mantissa. + */ + public function mantissa(): BigInt + { + return $this->_mantissa; + } + + /** + * Get the exponent. + */ + public function exponent(): BigInt + { + return $this->_exponent; + } + + /** + * Get the base. + */ + public function base(): int + { + return $this->_base; + } + + /** + * Get number as a float. + */ + public function floatVal(): float + { + if (!isset($this->_float)) { + $m = $this->_mantissa->intVal(); + $e = $this->_exponent->intVal(); + $this->_float = (float) ($m * pow($this->_base, $e)); + } + return $this->_float; + } + + /** + * Get number as a NR3 form string conforming to DER rules. + */ + public function nr3Val(): string + { + // convert to base 10 + if (2 === $this->_base) { + [$m, $e] = self::_parseString(sprintf('%15E', $this->floatVal())); + } else { + $m = $this->_mantissa->gmpObj(); + $e = $this->_exponent->gmpObj(); + } + // shift trailing zeroes from the mantissa to the exponent + // (X.690 07-2002, section 11.3.2.4) + while (0 != $m && 0 == $m % 10) { + $m /= 10; + ++$e; + } + // if exponent is zero, it must be prefixed with a "+" sign + // (X.690 07-2002, section 11.3.2.6) + if (0 == $e) { + $es = '+'; + } else { + $es = $e < 0 ? '-' : ''; + } + return sprintf('%s.E%s%s', gmp_strval($m), $es, gmp_strval(gmp_abs($e))); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + if (self::INF_EXPONENT == $this->_exponent->gmpObj()) { + return $this->_encodeSpecial(); + } + // if the real value is the value zero, there shall be no contents + // octets in the encoding. (X.690 07-2002, section 8.5.2) + if (0 == $this->_mantissa->gmpObj()) { + return ''; + } + if (10 === $this->_base) { + return $this->_encodeDecimal(); + } + return $this->_encodeBinary(); + } + + /** + * Encode in binary format. + */ + protected function _encodeBinary(): string + { + [$base, $sign, $m, $e] = $this->_prepareBinaryEncoding(); + $zero = gmp_init(0, 10); + $byte = 0x80; + if ($sign < 0) { + $byte |= 0x40; + } + // normalization: mantissa must be 0 or odd + if (2 === $base) { + // while last bit is zero + while ($m > 0 && 0 === gmp_cmp($m & 0x01, $zero)) { + $m >>= 1; + ++$e; + } + } elseif (8 === $base) { + $byte |= 0x10; + // while last 3 bits are zero + while ($m > 0 && 0 === gmp_cmp($m & 0x07, $zero)) { + $m >>= 3; + ++$e; + } + } else { // base === 16 + $byte |= 0x20; + // while last 4 bits are zero + while ($m > 0 && 0 === gmp_cmp($m & 0x0f, $zero)) { + $m >>= 4; + ++$e; + } + } + // scale factor + $scale = 0; + while ($m > 0 && 0 === gmp_cmp($m & 0x01, $zero)) { + $m >>= 1; + ++$scale; + } + $byte |= ($scale & 0x03) << 2; + // encode exponent + $exp_bytes = (new BigInt($e))->signedOctets(); + $exp_len = strlen($exp_bytes); + if ($exp_len > 0xff) { + throw new \RangeException('Exponent encoding is too long.'); + } + if ($exp_len <= 3) { + $byte |= ($exp_len - 1) & 0x03; + $bytes = chr($byte); + } else { + $byte |= 0x03; + $bytes = chr($byte) . chr($exp_len); + } + $bytes .= $exp_bytes; + // encode mantissa + $bytes .= (new BigInt($m))->unsignedOctets(); + return $bytes; + } + + /** + * Encode in decimal format. + */ + protected function _encodeDecimal(): string + { + // encode in NR3 decimal encoding + return chr(0x03) . $this->nr3Val(); + } + + /** + * Encode special value. + */ + protected function _encodeSpecial(): string + { + switch ($this->_mantissa->intVal()) { + // positive infitinity + case 1: + return chr(0x40); + // negative infinity + case -1: + return chr(0x41); + } + throw new \LogicException('Invalid special value.'); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $length = Length::expectFromDER($data, $idx)->intLength(); + // if length is zero, value is zero (spec 8.5.2) + if (!$length) { + $obj = new self(0, 0, 10); + } else { + $bytes = substr($data, $idx, $length); + $byte = ord($bytes[0]); + if (0x80 & $byte) { // bit 8 = 1 + $obj = self::_decodeBinaryEncoding($bytes); + } elseif (0x00 === $byte >> 6) { // bit 8 = 0, bit 7 = 0 + $obj = self::_decodeDecimalEncoding($bytes); + } else { // bit 8 = 0, bit 7 = 1 + $obj = self::_decodeSpecialRealValue($bytes); + } + } + $offset = $idx + $length; + return $obj; + } + + /** + * Decode binary encoding. + */ + protected static function _decodeBinaryEncoding(string $data) + { + $byte = ord($data[0]); + // bit 7 is set if mantissa is negative + $neg = (bool) (0x40 & $byte); + // encoding base in bits 6 and 5 + switch (($byte >> 4) & 0x03) { + case 0b00: + $base = 2; + break; + case 0b01: + $base = 8; + break; + case 0b10: + $base = 16; + break; + default: + throw new DecodeException( + 'Reserved REAL binary encoding base not supported.'); + } + // scaling factor in bits 4 and 3 + $scale = ($byte >> 2) & 0x03; + $idx = 1; + // content length in bits 2 and 1 + $len = ($byte & 0x03) + 1; + // if both bits are set, the next octet encodes the length + if ($len > 3) { + if (strlen($data) < 2) { + throw new DecodeException( + 'Unexpected end of data while decoding REAL exponent length.'); + } + $len = ord($data[1]); + $idx = 2; + } + if (strlen($data) < $idx + $len) { + throw new DecodeException( + 'Unexpected end of data while decoding REAL exponent.'); + } + // decode exponent + $octets = substr($data, $idx, $len); + $exp = BigInt::fromSignedOctets($octets)->gmpObj(); + if (8 === $base) { + $exp *= 3; + } elseif (16 === $base) { + $exp *= 4; + } + if (strlen($data) <= $idx + $len) { + throw new DecodeException( + 'Unexpected end of data while decoding REAL mantissa.'); + } + // decode mantissa + $octets = substr($data, $idx + $len); + $n = BigInt::fromUnsignedOctets($octets)->gmpObj(); + $n *= 2 ** $scale; + if ($neg) { + $n = gmp_neg($n); + } + return new self($n, $exp, 2); + } + + /** + * Decode decimal encoding. + * + * @throws \RuntimeException + */ + protected static function _decodeDecimalEncoding(string $data): self + { + $nr = ord($data[0]) & 0x3f; + if (!in_array($nr, [1, 2, 3])) { + throw new DecodeException('Unsupported decimal encoding form.'); + } + $str = substr($data, 1); + return self::fromString($str); + } + + /** + * Decode special encoding. + */ + protected static function _decodeSpecialRealValue(string $data): self + { + if (1 !== strlen($data)) { + throw new DecodeException( + 'SpecialRealValue must have one content octet.'); + } + $byte = ord($data[0]); + if (0x40 === $byte) { // positive infinity + return self::_fromInfinite(INF); + } + if (0x41 === $byte) { // negative infinity + return self::_fromInfinite(-INF); + } + throw new DecodeException('Invalid SpecialRealValue encoding.'); + } + + /** + * Prepare value for binary encoding. + * + * @return array (int) base, (int) sign, (\GMP) mantissa and (\GMP) exponent + */ + protected function _prepareBinaryEncoding(): array + { + $base = 2; + $m = $this->_mantissa->gmpObj(); + $ms = gmp_sign($m); + $m = gmp_abs($m); + $e = $this->_exponent->gmpObj(); + $es = gmp_sign($e); + $e = gmp_abs($e); + // DER uses only base 2 binary encoding + if (!$this->_strictDer) { + if (0 == $e % 4) { + $base = 16; + $e = gmp_div_q($e, 4); + } elseif (0 == $e % 3) { + $base = 8; + $e = gmp_div_q($e, 3); + } + } + return [$base, $ms, $m, $e * $es]; + } + + /** + * Initialize from INF or -INF. + */ + private static function _fromInfinite(float $inf): self + { + return new self($inf === -INF ? -1 : 1, self::INF_EXPONENT, 2); + } + + /** + * Parse IEEE 754 big endian formatted double precision float to base 2 + * mantissa and exponent. + * + * @param string $octets 64 bits + * + * @return \GMP[] Tuple of mantissa and exponent + */ + private static function _parse754Double(string $octets): array + { + $n = gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + // sign bit + $neg = gmp_testbit($n, 63); + // 11 bits of biased exponent + $exp = (gmp_and($n, '0x7ff0000000000000') >> 52) + self::EXP_BIAS; + // 52 bits of mantissa + $man = gmp_and($n, '0xfffffffffffff'); + // zero, ASN.1 doesn't differentiate -0 from +0 + if (self::EXP_BIAS == $exp && 0 == $man) { + return [gmp_init(0, 10), gmp_init(0, 10)]; + } + // denormalized value, shift binary point + if (self::EXP_BIAS == $exp) { + ++$exp; + } + // normalized value, insert implicit leading one before the binary point + else { + gmp_setbit($man, 52); + } + // find the last fraction bit that is set + $last = gmp_scan1($man, 0); + $bits_for_fraction = 52 - $last; + // adjust mantissa and exponent so that we have integer values + $man >>= $last; + $exp -= $bits_for_fraction; + // negate mantissa if number was negative + if ($neg) { + $man = gmp_neg($man); + } + return [$man, $exp]; + } + + /** + * Parse textual REAL number to base 10 mantissa and exponent. + * + * @param string $str Number + * + * @return \GMP[] Tuple of mantissa and exponent + */ + private static function _parseString(string $str): array + { + // PHP exponent format + if (preg_match(self::PHP_EXPONENT_DNUM, $str, $match)) { + [$m, $e] = self::_parsePHPExponentMatch($match); + } + // NR3 format + elseif (preg_match(self::NR3_REGEX, $str, $match)) { + [$m, $e] = self::_parseNR3Match($match); + } + // NR2 format + elseif (preg_match(self::NR2_REGEX, $str, $match)) { + [$m, $e] = self::_parseNR2Match($match); + } + // NR1 format + elseif (preg_match(self::NR1_REGEX, $str, $match)) { + [$m, $e] = self::_parseNR1Match($match); + } + // invalid number + else { + throw new \UnexpectedValueException( + "{$str} could not be parsed to REAL."); + } + // normalize so that mantsissa has no trailing zeroes + while (0 != $m && 0 == $m % 10) { + $m /= 10; + ++$e; + } + return [$m, $e]; + } + + /** + * Parse PHP form float to base 10 mantissa and exponent. + * + * @param array $match Regexp match + * + * @return \GMP[] Tuple of mantissa and exponent + */ + private static function _parsePHPExponentMatch(array $match): array + { + // mantissa sign + $ms = '-' === $match['ms'] ? -1 : 1; + $m_parts = explode('.', $match['m']); + // integer part of the mantissa + $int = ltrim($m_parts[0], '0'); + // exponent sign + $es = '-' === $match['es'] ? -1 : 1; + // signed exponent + $e = gmp_init($match['e'], 10) * $es; + // if mantissa had fractional part + if (2 === count($m_parts)) { + $frac = rtrim($m_parts[1], '0'); + $e -= strlen($frac); + $int .= $frac; + } + $m = gmp_init($int, 10) * $ms; + return [$m, $e]; + } + + /** + * Parse NR3 form number to base 10 mantissa and exponent. + * + * @param array $match Regexp match + * + * @return \GMP[] Tuple of mantissa and exponent + */ + private static function _parseNR3Match(array $match): array + { + // mantissa sign + $ms = '-' === $match['ms'] ? -1 : 1; + // explode mantissa to integer and fraction parts + [$int, $frac] = explode('.', str_replace(',', '.', $match['m'])); + $int = ltrim($int, '0'); + $frac = rtrim($frac, '0'); + // exponent sign + $es = '-' === $match['es'] ? -1 : 1; + // signed exponent + $e = gmp_init($match['e'], 10) * $es; + // shift exponent by the number of base 10 fractions + $e -= strlen($frac); + // insert fractions to integer part and produce signed mantissa + $int .= $frac; + if ('' === $int) { + $int = '0'; + } + $m = gmp_init($int, 10) * $ms; + return [$m, $e]; + } + + /** + * Parse NR2 form number to base 10 mantissa and exponent. + * + * @param array $match Regexp match + * + * @return \GMP[] Tuple of mantissa and exponent + */ + private static function _parseNR2Match(array $match): array + { + $sign = '-' === $match['s'] ? -1 : 1; + // explode decimal number to integer and fraction parts + [$int, $frac] = explode('.', str_replace(',', '.', $match['d'])); + $int = ltrim($int, '0'); + $frac = rtrim($frac, '0'); + // shift exponent by the number of base 10 fractions + $e = gmp_init(0, 10); + $e -= strlen($frac); + // insert fractions to integer part and produce signed mantissa + $int .= $frac; + if ('' === $int) { + $int = '0'; + } + $m = gmp_init($int, 10) * $sign; + return [$m, $e]; + } + + /** + * Parse NR1 form number to base 10 mantissa and exponent. + * + * @param array $match Regexp match + * + * @return \GMP[] Tuple of mantissa and exponent + */ + private static function _parseNR1Match(array $match): array + { + $sign = '-' === $match['s'] ? -1 : 1; + $int = ltrim($match['i'], '0'); + if ('' === $int) { + $int = '0'; + } + $m = gmp_init($int, 10) * $sign; + return [$m, gmp_init(0, 10)]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php new file mode 100644 index 0000000..b497527 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php @@ -0,0 +1,48 @@ +_oid = $oid; + $this->_subids = self::_explodeDottedOID($oid); + $this->_typeTag = self::TYPE_RELATIVE_OID; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + return self::_encodeSubIDs(...$this->_subids); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $len = Length::expectFromDER($data, $idx)->intLength(); + $subids = self::_decodeSubIDs(substr($data, $idx, $len)); + $offset = $idx + $len; + return new self(self::_implodeSubIDs(...$subids)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php new file mode 100644 index 0000000..c2bcfbc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php @@ -0,0 +1,35 @@ +_typeTag = self::TYPE_T61_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + // allow everything since there's literally + // thousands of allowed characters (16 bit composed characters) + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php new file mode 100644 index 0000000..6d07d0d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php @@ -0,0 +1,83 @@ +_typeTag = self::TYPE_UTC_TIME; + parent::__construct($dt); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + $dt = $this->_dateTime->setTimezone(self::_createTimeZone(self::TZ_UTC)); + return $dt->format('ymdHis\\Z'); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $length = Length::expectFromDER($data, $idx)->intLength(); + $str = substr($data, $idx, $length); + $idx += $length; + /** @var string[] $match */ + if (!preg_match(self::REGEX, $str, $match)) { + throw new DecodeException('Invalid UTCTime format.'); + } + [, $year, $month, $day, $hour, $minute, $second] = $match; + $time = $year . $month . $day . $hour . $minute . $second . self::TZ_UTC; + $dt = \DateTimeImmutable::createFromFormat('!ymdHisT', $time, + self::_createTimeZone(self::TZ_UTC)); + if (!$dt) { + throw new DecodeException('Failed to decode UTCTime: ' . + self::_getLastDateTimeImmutableErrorsStr()); + } + $offset = $idx; + return new self($dt); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php new file mode 100644 index 0000000..9cb9aa2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php @@ -0,0 +1,35 @@ +_typeTag = self::TYPE_UTF8_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + return mb_check_encoding($string, 'UTF-8'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php new file mode 100644 index 0000000..f0a6c23 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php @@ -0,0 +1,39 @@ +_typeTag = self::TYPE_UNIVERSAL_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + // UCS-4 has fixed with of 4 octets (32 bits) + if (0 !== strlen($string) % 4) { + return false; + } + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php new file mode 100644 index 0000000..d9a6721 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php @@ -0,0 +1,34 @@ +_typeTag = self::TYPE_VIDEOTEX_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + // allow everything + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php new file mode 100644 index 0000000..659317b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php @@ -0,0 +1,33 @@ +_typeTag = self::TYPE_VISIBLE_STRING; + parent::__construct($string); + } + + /** + * {@inheritdoc} + */ + protected function _validateString(string $string): bool + { + return 0 == preg_match('/[^\x20-\x7e]/', $string); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php new file mode 100644 index 0000000..5fef105 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php @@ -0,0 +1,53 @@ +_string; + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + if (!$identifier->isPrimitive()) { + throw new DecodeException('DER encoded string must be primitive.'); + } + $length = Length::expectFromDER($data, $idx)->intLength(); + $str = $length ? substr($data, $idx, $length) : ''; + // substr should never return false, since length is + // checked by Length::expectFromDER. + assert(is_string($str), new DecodeException('substr')); + $offset = $idx + $length; + try { + return new static($str); + } catch (\InvalidArgumentException $e) { + throw new DecodeException($e->getMessage(), 0, $e); + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php new file mode 100644 index 0000000..c645e3f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php @@ -0,0 +1,19 @@ +_elements = array_map( + function (ElementBase $el) { + return $el->asElement(); + }, $elements); + } + + /** + * Clone magic method. + */ + public function __clone() + { + // clear cache-variables + $this->_taggedMap = null; + $this->_unspecifiedTypes = null; + } + + /** + * {@inheritdoc} + */ + public function isConstructed(): bool + { + return true; + } + + /** + * Explode DER structure to DER encoded components that it contains. + * + * @throws DecodeException + * + * @return string[] + */ + public static function explodeDER(string $data): array + { + $offset = 0; + $identifier = Identifier::fromDER($data, $offset); + if (!$identifier->isConstructed()) { + throw new DecodeException('Element is not constructed.'); + } + $length = Length::expectFromDER($data, $offset); + if ($length->isIndefinite()) { + throw new DecodeException( + 'Explode not implemented for indefinite length encoding.'); + } + $end = $offset + $length->intLength(); + $parts = []; + while ($offset < $end) { + // start of the element + $idx = $offset; + // skip identifier + Identifier::fromDER($data, $offset); + // decode element length + $length = Length::expectFromDER($data, $offset)->intLength(); + // extract der encoding of the element + $parts[] = substr($data, $idx, $offset - $idx + $length); + // update offset over content + $offset += $length; + } + return $parts; + } + + /** + * Get self with an element at the given index replaced by another. + * + * @param int $idx Element index + * @param Element $el New element to insert into the structure + * + * @throws \OutOfBoundsException + */ + public function withReplaced(int $idx, Element $el): self + { + if (!isset($this->_elements[$idx])) { + throw new \OutOfBoundsException( + "Structure doesn't have element at index {$idx}."); + } + $obj = clone $this; + $obj->_elements[$idx] = $el; + return $obj; + } + + /** + * Get self with an element inserted before the given index. + * + * @param int $idx Element index + * @param Element $el New element to insert into the structure + * + * @throws \OutOfBoundsException + */ + public function withInserted(int $idx, Element $el): self + { + if (count($this->_elements) < $idx || $idx < 0) { + throw new \OutOfBoundsException("Index {$idx} is out of bounds."); + } + $obj = clone $this; + array_splice($obj->_elements, $idx, 0, [$el]); + return $obj; + } + + /** + * Get self with an element appended to the end. + * + * @param Element $el Element to insert into the structure + */ + public function withAppended(Element $el): self + { + $obj = clone $this; + array_push($obj->_elements, $el); + return $obj; + } + + /** + * Get self with an element prepended in the beginning. + * + * @param Element $el Element to insert into the structure + */ + public function withPrepended(Element $el): self + { + $obj = clone $this; + array_unshift($obj->_elements, $el); + return $obj; + } + + /** + * Get self with an element at the given index removed. + * + * @param int $idx Element index + * + * @throws \OutOfBoundsException + */ + public function withoutElement(int $idx): self + { + if (!isset($this->_elements[$idx])) { + throw new \OutOfBoundsException( + "Structure doesn't have element at index {$idx}."); + } + $obj = clone $this; + array_splice($obj->_elements, $idx, 1); + return $obj; + } + + /** + * Get elements in the structure. + * + * @return UnspecifiedType[] + */ + public function elements(): array + { + if (!isset($this->_unspecifiedTypes)) { + $this->_unspecifiedTypes = array_map( + function (Element $el) { + return new UnspecifiedType($el); + }, $this->_elements); + } + return $this->_unspecifiedTypes; + } + + /** + * Check whether the structure has an element at the given index, optionally + * satisfying given tag expectation. + * + * @param int $idx Index 0..n + * @param null|int $expectedTag Optional type tag expectation + */ + public function has(int $idx, ?int $expectedTag = null): bool + { + if (!isset($this->_elements[$idx])) { + return false; + } + if (isset($expectedTag)) { + if (!$this->_elements[$idx]->isType($expectedTag)) { + return false; + } + } + return true; + } + + /** + * Get the element at the given index, optionally checking that the element + * has a given tag. + * + * @param int $idx Index 0..n + * + * @throws \OutOfBoundsException If element doesn't exists + * @throws \UnexpectedValueException If expectation fails + */ + public function at(int $idx): UnspecifiedType + { + if (!isset($this->_elements[$idx])) { + throw new \OutOfBoundsException( + "Structure doesn't have an element at index {$idx}."); + } + return new UnspecifiedType($this->_elements[$idx]); + } + + /** + * Check whether the structure contains a context specific element with a + * given tag. + * + * @param int $tag Tag number + */ + public function hasTagged(int $tag): bool + { + // lazily build lookup map + if (!isset($this->_taggedMap)) { + $this->_taggedMap = []; + foreach ($this->_elements as $element) { + if ($element->isTagged()) { + $this->_taggedMap[$element->tag()] = $element; + } + } + } + return isset($this->_taggedMap[$tag]); + } + + /** + * Get a context specific element tagged with a given tag. + * + * @throws \LogicException If tag doesn't exists + */ + public function getTagged(int $tag): TaggedType + { + if (!$this->hasTagged($tag)) { + throw new \LogicException("No tagged element for tag {$tag}."); + } + return $this->_taggedMap[$tag]; + } + + /** + * @see \Countable::count() + */ + public function count(): int + { + return count($this->_elements); + } + + /** + * Get an iterator for the `UnspecifiedElement` objects. + * + * @see \IteratorAggregate::getIterator() + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->elements()); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + $data = ''; + foreach ($this->_elements as $element) { + $data .= $element->toDER(); + } + return $data; + } + + /** + * {@inheritdoc} + * + * @return self + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + if (!$identifier->isConstructed()) { + throw new DecodeException( + 'Structured element must have constructed bit set.'); + } + $idx = $offset; + $length = Length::expectFromDER($data, $idx); + if ($length->isIndefinite()) { + $type = self::_decodeIndefiniteLength($data, $idx); + } else { + $type = self::_decodeDefiniteLength($data, $idx, + $length->intLength()); + } + $offset = $idx; + return $type; + } + + /** + * Decode elements for a definite length. + * + * @param string $data DER data + * @param int $offset Offset to data + * @param int $length Number of bytes to decode + * + * @throws DecodeException + */ + private static function _decodeDefiniteLength(string $data, int &$offset, + int $length): ElementBase + { + $idx = $offset; + $end = $idx + $length; + $elements = []; + while ($idx < $end) { + $elements[] = Element::fromDER($data, $idx); + // check that element didn't overflow length + if ($idx > $end) { + throw new DecodeException("Structure's content overflows length."); + } + } + $offset = $idx; + // return instance by static late binding + return new static(...$elements); + } + + /** + * Decode elements for an indefinite length. + * + * @param string $data DER data + * @param int $offset Offset to data + * + * @throws DecodeException + */ + private static function _decodeIndefiniteLength(string $data, int &$offset): ElementBase + { + $idx = $offset; + $elements = []; + $end = strlen($data); + while (true) { + if ($idx >= $end) { + throw new DecodeException( + 'Unexpected end of data while decoding indefinite length structure.'); + } + $el = Element::fromDER($data, $idx); + if ($el->isType(self::TYPE_EOC)) { + break; + } + $elements[] = $el; + } + $offset = $idx; + $type = new static(...$elements); + $type->_indefiniteLength = true; + return $type; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php new file mode 100644 index 0000000..9821e6e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php @@ -0,0 +1,12 @@ +_identifier = $identifier; + $this->_data = $data; + $this->_offset = $offset; + $this->_valueOffset = $value_offset; + $this->_valueLength = $value_length; + $this->_indefiniteLength = $indefinite_length; + $this->_typeTag = $identifier->intTag(); + } + + /** + * {@inheritdoc} + */ + public function typeClass(): int + { + return $this->_identifier->typeClass(); + } + + /** + * {@inheritdoc} + */ + public function isConstructed(): bool + { + return $this->_identifier->isConstructed(); + } + + /** + * {@inheritdoc} + */ + public function implicit(int $tag, int $class = Identifier::CLASS_UNIVERSAL): UnspecifiedType + { + $identifier = $this->_identifier->withClass($class)->withTag($tag); + $cls = self::_determineImplClass($identifier); + $idx = $this->_offset; + /** @var \Sop\ASN1\Feature\ElementBase $element */ + $element = $cls::_decodeFromDER($identifier, $this->_data, $idx); + return $element->asUnspecified(); + } + + /** + * {@inheritdoc} + */ + public function explicit(): UnspecifiedType + { + $idx = $this->_valueOffset; + return Element::fromDER($this->_data, $idx)->asUnspecified(); + } + + /** + * {@inheritdoc} + */ + protected static function _decodeFromDER(Identifier $identifier, + string $data, int &$offset): ElementBase + { + $idx = $offset; + $length = Length::expectFromDER($data, $idx); + // offset to inner value + $value_offset = $idx; + if ($length->isIndefinite()) { + if ($identifier->isPrimitive()) { + throw new DecodeException( + 'Primitive type with indefinite length is not supported.'); + } + while (!Element::fromDER($data, $idx)->isType(self::TYPE_EOC)); + // EOC consists of two octets. + $value_length = $idx - $value_offset - 2; + } else { + $value_length = $length->intLength(); + $idx += $value_length; + } + // late static binding since ApplicationType and PrivateType extend this class + $type = new static($identifier, $data, $offset, $value_offset, + $value_length, $length->isIndefinite()); + $offset = $idx; + return $type; + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + return substr($this->_data, $this->_valueOffset, $this->_valueLength); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php new file mode 100644 index 0000000..be5a300 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php @@ -0,0 +1,19 @@ +_typeTag = $tag; + $this->_element = $element; + $this->_class = $class; + } + + /** + * {@inheritdoc} + */ + public function isConstructed(): bool + { + return true; + } + + /** + * {@inheritdoc} + */ + public function explicit(): UnspecifiedType + { + return $this->_element->asUnspecified(); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + // get the full encoding of the wrapped element + return $this->_element->toDER(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php new file mode 100644 index 0000000..ca2d5ed --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php @@ -0,0 +1,25 @@ +_typeTag = $tag; + $this->_element = $element; + $this->_class = $class; + } + + /** + * {@inheritdoc} + */ + public function isConstructed(): bool + { + // depends on the underlying type + return $this->_element->isConstructed(); + } + + /** + * {@inheritdoc} + */ + public function implicit( + int $tag, int $class = Identifier::CLASS_UNIVERSAL): UnspecifiedType + { + $this->_element->expectType($tag); + if ($this->_element->typeClass() !== $class) { + throw new \UnexpectedValueException( + sprintf('Type class %s expected, got %s.', + Identifier::classToName($class), + Identifier::classToName($this->_element->typeClass()))); + } + return $this->_element->asUnspecified(); + } + + /** + * {@inheritdoc} + */ + protected function _encodedContentDER(): string + { + // get only the content of the wrapped element. + return $this->_element->_encodedContentDER(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php new file mode 100644 index 0000000..6ab626b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php @@ -0,0 +1,12 @@ +_class; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php new file mode 100644 index 0000000..80ae37c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php @@ -0,0 +1,84 @@ +expectTagged($expectedTag); + } + return $el; + } + + /** + * Get the wrapped inner element employing explicit tagging. + * + * @param null|int $expectedTag Optional outer tag expectation + * + * @throws \UnexpectedValueException If expectation fails + */ + public function asExplicit(?int $expectedTag = null): UnspecifiedType + { + return $this->expectExplicit($expectedTag)->explicit(); + } + + /** + * Check whether element supports implicit tagging. + * + * @param null|int $expectedTag Optional outer tag expectation + * + * @throws \UnexpectedValueException If expectation fails + */ + public function expectImplicit(?int $expectedTag = null): ImplicitTagging + { + $el = $this; + if (!$el instanceof ImplicitTagging) { + throw new \UnexpectedValueException( + "Element doesn't implement implicit tagging."); + } + if (isset($expectedTag)) { + $el->expectTagged($expectedTag); + } + return $el; + } + + /** + * Get the wrapped inner element employing implicit tagging. + * + * @param int $tag Type tag of the inner element + * @param null|int $expectedTag Optional outer tag expectation + * @param int $expectedClass Optional inner type class expectation + * + * @throws \UnexpectedValueException If expectation fails + */ + public function asImplicit(int $tag, ?int $expectedTag = null, + int $expectedClass = Identifier::CLASS_UNIVERSAL): UnspecifiedType + { + return $this->expectImplicit($expectedTag)->implicit($tag, + $expectedClass); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php new file mode 100644 index 0000000..cef1a49 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php @@ -0,0 +1,16 @@ +_element = $el; + } + + /** + * Initialize from DER data. + * + * @param string $data DER encoded data + */ + public static function fromDER(string $data): self + { + return Element::fromDER($data)->asUnspecified(); + } + + /** + * Initialize from `ElementBase` interface. + */ + public static function fromElementBase(ElementBase $el): self + { + // if element is already wrapped + if ($el instanceof self) { + return $el; + } + return new self($el->asElement()); + } + + /** + * Get the wrapped element as a context specific tagged type. + * + * @throws \UnexpectedValueException If the element is not tagged + */ + public function asTagged(): TaggedType + { + if (!$this->_element instanceof TaggedType) { + throw new \UnexpectedValueException( + 'Tagged element expected, got ' . $this->_typeDescriptorString()); + } + return $this->_element; + } + + /** + * Get the wrapped element as an application specific type. + * + * @throws \UnexpectedValueException If element is not application specific + * + * @return \Sop\ASN1\Type\Tagged\ApplicationType + */ + public function asApplication(): Tagged\ApplicationType + { + if (!$this->_element instanceof Tagged\ApplicationType) { + throw new \UnexpectedValueException( + 'Application type expected, got ' . $this->_typeDescriptorString()); + } + return $this->_element; + } + + /** + * Get the wrapped element as a private tagged type. + * + * @throws \UnexpectedValueException If element is not using private tagging + * + * @return \Sop\ASN1\Type\Tagged\PrivateType + */ + public function asPrivate(): Tagged\PrivateType + { + if (!$this->_element instanceof Tagged\PrivateType) { + throw new \UnexpectedValueException( + 'Private type expected, got ' . $this->_typeDescriptorString()); + } + return $this->_element; + } + + /** + * Get the wrapped element as a boolean type. + * + * @throws \UnexpectedValueException If the element is not a boolean + * + * @return \Sop\ASN1\Type\Primitive\Boolean + */ + public function asBoolean(): Primitive\Boolean + { + if (!$this->_element instanceof Primitive\Boolean) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_BOOLEAN)); + } + return $this->_element; + } + + /** + * Get the wrapped element as an integer type. + * + * @throws \UnexpectedValueException If the element is not an integer + * + * @return \Sop\ASN1\Type\Primitive\Integer + */ + public function asInteger(): Primitive\Integer + { + if (!$this->_element instanceof Primitive\Integer) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_INTEGER)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a bit string type. + * + * @throws \UnexpectedValueException If the element is not a bit string + * + * @return \Sop\ASN1\Type\Primitive\BitString + */ + public function asBitString(): Primitive\BitString + { + if (!$this->_element instanceof Primitive\BitString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_BIT_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as an octet string type. + * + * @throws \UnexpectedValueException If the element is not an octet string + * + * @return \Sop\ASN1\Type\Primitive\OctetString + */ + public function asOctetString(): Primitive\OctetString + { + if (!$this->_element instanceof Primitive\OctetString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_OCTET_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a null type. + * + * @throws \UnexpectedValueException If the element is not a null + * + * @return \Sop\ASN1\Type\Primitive\NullType + */ + public function asNull(): Primitive\NullType + { + if (!$this->_element instanceof Primitive\NullType) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_NULL)); + } + return $this->_element; + } + + /** + * Get the wrapped element as an object identifier type. + * + * @throws \UnexpectedValueException If the element is not an object identifier + * + * @return \Sop\ASN1\Type\Primitive\ObjectIdentifier + */ + public function asObjectIdentifier(): Primitive\ObjectIdentifier + { + if (!$this->_element instanceof Primitive\ObjectIdentifier) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_OBJECT_IDENTIFIER)); + } + return $this->_element; + } + + /** + * Get the wrapped element as an object descriptor type. + * + * @throws \UnexpectedValueException If the element is not an object descriptor + * + * @return \Sop\ASN1\Type\Primitive\ObjectDescriptor + */ + public function asObjectDescriptor(): Primitive\ObjectDescriptor + { + if (!$this->_element instanceof Primitive\ObjectDescriptor) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_OBJECT_DESCRIPTOR)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a real type. + * + * @throws \UnexpectedValueException If the element is not a real + * + * @return \Sop\ASN1\Type\Primitive\Real + */ + public function asReal(): Primitive\Real + { + if (!$this->_element instanceof Primitive\Real) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_REAL)); + } + return $this->_element; + } + + /** + * Get the wrapped element as an enumerated type. + * + * @throws \UnexpectedValueException If the element is not an enumerated + * + * @return \Sop\ASN1\Type\Primitive\Enumerated + */ + public function asEnumerated(): Primitive\Enumerated + { + if (!$this->_element instanceof Primitive\Enumerated) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_ENUMERATED)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a UTF8 string type. + * + * @throws \UnexpectedValueException If the element is not a UTF8 string + * + * @return \Sop\ASN1\Type\Primitive\UTF8String + */ + public function asUTF8String(): Primitive\UTF8String + { + if (!$this->_element instanceof Primitive\UTF8String) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_UTF8_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a relative OID type. + * + * @throws \UnexpectedValueException If the element is not a relative OID + * + * @return \Sop\ASN1\Type\Primitive\RelativeOID + */ + public function asRelativeOID(): Primitive\RelativeOID + { + if (!$this->_element instanceof Primitive\RelativeOID) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_RELATIVE_OID)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a sequence type. + * + * @throws \UnexpectedValueException If the element is not a sequence + * + * @return \Sop\ASN1\Type\Constructed\Sequence + */ + public function asSequence(): Constructed\Sequence + { + if (!$this->_element instanceof Constructed\Sequence) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_SEQUENCE)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a set type. + * + * @throws \UnexpectedValueException If the element is not a set + * + * @return \Sop\ASN1\Type\Constructed\Set + */ + public function asSet(): Constructed\Set + { + if (!$this->_element instanceof Constructed\Set) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_SET)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a numeric string type. + * + * @throws \UnexpectedValueException If the element is not a numeric string + * + * @return \Sop\ASN1\Type\Primitive\NumericString + */ + public function asNumericString(): Primitive\NumericString + { + if (!$this->_element instanceof Primitive\NumericString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_NUMERIC_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a printable string type. + * + * @throws \UnexpectedValueException If the element is not a printable string + * + * @return \Sop\ASN1\Type\Primitive\PrintableString + */ + public function asPrintableString(): Primitive\PrintableString + { + if (!$this->_element instanceof Primitive\PrintableString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_PRINTABLE_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a T61 string type. + * + * @throws \UnexpectedValueException If the element is not a T61 string + * + * @return \Sop\ASN1\Type\Primitive\T61String + */ + public function asT61String(): Primitive\T61String + { + if (!$this->_element instanceof Primitive\T61String) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_T61_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a videotex string type. + * + * @throws \UnexpectedValueException If the element is not a videotex string + * + * @return \Sop\ASN1\Type\Primitive\VideotexString + */ + public function asVideotexString(): Primitive\VideotexString + { + if (!$this->_element instanceof Primitive\VideotexString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_VIDEOTEX_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a IA5 string type. + * + * @throws \UnexpectedValueException If the element is not a IA5 string + * + * @return \Sop\ASN1\Type\Primitive\IA5String + */ + public function asIA5String(): Primitive\IA5String + { + if (!$this->_element instanceof Primitive\IA5String) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_IA5_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as an UTC time type. + * + * @throws \UnexpectedValueException If the element is not a UTC time + * + * @return \Sop\ASN1\Type\Primitive\UTCTime + */ + public function asUTCTime(): Primitive\UTCTime + { + if (!$this->_element instanceof Primitive\UTCTime) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_UTC_TIME)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a generalized time type. + * + * @throws \UnexpectedValueException If the element is not a generalized time + * + * @return \Sop\ASN1\Type\Primitive\GeneralizedTime + */ + public function asGeneralizedTime(): Primitive\GeneralizedTime + { + if (!$this->_element instanceof Primitive\GeneralizedTime) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_GENERALIZED_TIME)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a graphic string type. + * + * @throws \UnexpectedValueException If the element is not a graphic string + * + * @return \Sop\ASN1\Type\Primitive\GraphicString + */ + public function asGraphicString(): Primitive\GraphicString + { + if (!$this->_element instanceof Primitive\GraphicString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_GRAPHIC_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a visible string type. + * + * @throws \UnexpectedValueException If the element is not a visible string + * + * @return \Sop\ASN1\Type\Primitive\VisibleString + */ + public function asVisibleString(): Primitive\VisibleString + { + if (!$this->_element instanceof Primitive\VisibleString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_VISIBLE_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a general string type. + * + * @throws \UnexpectedValueException If the element is not general string + * + * @return \Sop\ASN1\Type\Primitive\GeneralString + */ + public function asGeneralString(): Primitive\GeneralString + { + if (!$this->_element instanceof Primitive\GeneralString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_GENERAL_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a universal string type. + * + * @throws \UnexpectedValueException If the element is not a universal string + * + * @return \Sop\ASN1\Type\Primitive\UniversalString + */ + public function asUniversalString(): Primitive\UniversalString + { + if (!$this->_element instanceof Primitive\UniversalString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_UNIVERSAL_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a character string type. + * + * @throws \UnexpectedValueException If the element is not a character string + * + * @return \Sop\ASN1\Type\Primitive\CharacterString + */ + public function asCharacterString(): Primitive\CharacterString + { + if (!$this->_element instanceof Primitive\CharacterString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_CHARACTER_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a BMP string type. + * + * @throws \UnexpectedValueException If the element is not a bmp string + * + * @return \Sop\ASN1\Type\Primitive\BMPString + */ + public function asBMPString(): Primitive\BMPString + { + if (!$this->_element instanceof Primitive\BMPString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_BMP_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as a constructed string type. + * + * @throws \UnexpectedValueException If the element is not a constructed string + * + * @return \Sop\ASN1\Type\Constructed\ConstructedString + */ + public function asConstructedString(): Constructed\ConstructedString + { + if (!$this->_element instanceof Constructed\ConstructedString) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_CONSTRUCTED_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as any string type. + * + * @throws \UnexpectedValueException If the element is not a string type + */ + public function asString(): StringType + { + if (!$this->_element instanceof StringType) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_STRING)); + } + return $this->_element; + } + + /** + * Get the wrapped element as any time type. + * + * @throws \UnexpectedValueException If the element is not a time type + */ + public function asTime(): TimeType + { + if (!$this->_element instanceof TimeType) { + throw new \UnexpectedValueException( + $this->_generateExceptionMessage(Element::TYPE_TIME)); + } + return $this->_element; + } + + /** + * {@inheritdoc} + */ + public function asElement(): Element + { + return $this->_element; + } + + /** + * {@inheritdoc} + */ + public function asUnspecified(): UnspecifiedType + { + return $this; + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->_element->toDER(); + } + + /** + * {@inheritdoc} + */ + public function typeClass(): int + { + return $this->_element->typeClass(); + } + + /** + * {@inheritdoc} + */ + public function tag(): int + { + return $this->_element->tag(); + } + + /** + * {@inheritdoc} + */ + public function isConstructed(): bool + { + return $this->_element->isConstructed(); + } + + /** + * {@inheritdoc} + */ + public function isType(int $tag): bool + { + return $this->_element->isType($tag); + } + + /** + * {@inheritdoc} + */ + public function isTagged(): bool + { + return $this->_element->isTagged(); + } + + /** + * {@inheritdoc} + * + * Consider using any of the `as*` accessor methods instead. + */ + public function expectType(int $tag): ElementBase + { + return $this->_element->expectType($tag); + } + + /** + * {@inheritdoc} + * + * Consider using `asTagged()` method instead and chaining + * with `TaggedType::asExplicit()` or `TaggedType::asImplicit()`. + */ + public function expectTagged(?int $tag = null): TaggedType + { + return $this->_element->expectTagged($tag); + } + + /** + * Generate message for exceptions thrown by `as*` methods. + * + * @param int $tag Type tag of the expected element + */ + private function _generateExceptionMessage(int $tag): string + { + return sprintf('%s expected, got %s.', Element::tagToName($tag), + $this->_typeDescriptorString()); + } + + /** + * Get textual description of the wrapped element for debugging purposes. + */ + private function _typeDescriptorString(): string + { + $type_cls = $this->_element->typeClass(); + $tag = $this->_element->tag(); + $str = $this->_element->isConstructed() ? 'constructed ' : 'primitive '; + if (Identifier::CLASS_UNIVERSAL === $type_cls) { + $str .= Element::tagToName($tag); + } else { + $str .= Identifier::classToName($type_cls) . " TAG {$tag}"; + } + return $str; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php new file mode 100644 index 0000000..28e5ccd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php @@ -0,0 +1,218 @@ +_gmp = $num; + } + + public function __toString(): string + { + return $this->base10(); + } + + /** + * Initialize from an arbitrary length of octets as an unsigned integer. + */ + public static function fromUnsignedOctets(string $octets): self + { + if (!strlen($octets)) { + throw new \InvalidArgumentException('Empty octets.'); + } + return new self(gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN)); + } + + /** + * Initialize from an arbitrary length of octets as an signed integer + * having two's complement encoding. + */ + public static function fromSignedOctets(string $octets): self + { + if (!strlen($octets)) { + throw new \InvalidArgumentException('Empty octets.'); + } + $neg = ord($octets[0]) & 0x80; + // negative, apply inversion of two's complement + if ($neg) { + $octets = ~$octets; + } + $num = gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + // negative, apply addition of two's complement and produce negative result + if ($neg) { + $num = gmp_neg($num + 1); + } + return new self($num); + } + + /** + * Get the number as a base 10 integer string. + */ + public function base10(): string + { + if (!isset($this->_num)) { + $this->_num = gmp_strval($this->_gmp, 10); + } + return $this->_num; + } + + /** + * Get the number as an integer. + * + * @throws \RuntimeException If number overflows integer size + */ + public function intVal(): int + { + if (!isset($this->_intNum)) { + if (gmp_cmp($this->_gmp, $this->_intMaxGmp()) > 0) { + throw new \RuntimeException('Integer overflow.'); + } + if (gmp_cmp($this->_gmp, $this->_intMinGmp()) < 0) { + throw new \RuntimeException('Integer underflow.'); + } + $this->_intNum = gmp_intval($this->_gmp); + } + return $this->_intNum; + } + + /** + * Get the number as a `GMP` object. + * + * @throws \RuntimeException if number is not a valid integer + */ + public function gmpObj(): \GMP + { + return clone $this->_gmp; + } + + /** + * Get the number as an unsigned integer encoded in binary. + */ + public function unsignedOctets(): string + { + return gmp_export($this->_gmp, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + } + + /** + * Get the number as a signed integer encoded in two's complement binary. + */ + public function signedOctets(): string + { + switch (gmp_sign($this->_gmp)) { + case 1: + return $this->_signedPositiveOctets(); + case -1: + return $this->_signedNegativeOctets(); + } + // zero + return chr(0); + } + + /** + * Encode positive integer in two's complement binary. + */ + private function _signedPositiveOctets(): string + { + $bin = gmp_export($this->_gmp, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + // if first bit is 1, prepend full zero byte to represent positive two's complement + if (ord($bin[0]) & 0x80) { + $bin = chr(0x00) . $bin; + } + return $bin; + } + + /** + * Encode negative integer in two's complement binary. + */ + private function _signedNegativeOctets(): string + { + $num = gmp_abs($this->_gmp); + // compute number of bytes required + $width = 1; + if ($num > 128) { + $tmp = $num; + do { + ++$width; + $tmp >>= 8; + } while ($tmp > 128); + } + // compute two's complement 2^n - x + $num = gmp_pow('2', 8 * $width) - $num; + $bin = gmp_export($num, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + // if first bit is 0, prepend full inverted byte to represent negative two's complement + if (!(ord($bin[0]) & 0x80)) { + $bin = chr(0xff) . $bin; + } + return $bin; + } + + /** + * Get the maximum integer value. + */ + private function _intMaxGmp(): \GMP + { + static $gmp; + if (!isset($gmp)) { + $gmp = gmp_init(PHP_INT_MAX, 10); + } + return $gmp; + } + + /** + * Get the minimum integer value. + */ + private function _intMinGmp(): \GMP + { + static $gmp; + if (!isset($gmp)) { + $gmp = gmp_init(PHP_INT_MIN, 10); + } + return $gmp; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php new file mode 100644 index 0000000..60c2b0f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php @@ -0,0 +1,144 @@ +_flags = ''; + } else { + // calculate number of unused bits in last octet + $last_octet_bits = $width % 8; + $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; + $num = gmp_init($flags); + // mask bits outside bitfield width + $mask = gmp_sub(gmp_init(1) << $width, 1); + $num &= $mask; + // shift towards MSB if needed + $data = gmp_export($num << $unused_bits, 1, + GMP_MSW_FIRST | GMP_BIG_ENDIAN); + $octets = unpack('C*', $data); + assert(is_array($octets), new \RuntimeException('unpack() failed')); + $bits = count($octets) * 8; + // pad with zeroes + while ($bits < $width) { + array_unshift($octets, 0); + $bits += 8; + } + $this->_flags = pack('C*', ...$octets); + } + $this->_width = $width; + } + + /** + * Initialize from `BitString`. + */ + public static function fromBitString(BitString $bs, int $width): self + { + $num_bits = $bs->numBits(); + $num = gmp_import($bs->string(), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + $num >>= $bs->unusedBits(); + if ($num_bits < $width) { + $num <<= ($width - $num_bits); + } + return new self(gmp_strval($num, 10), $width); + } + + /** + * Check whether a bit at given index is set. + * + * Index 0 is the leftmost bit. + * + * @throws \OutOfBoundsException + */ + public function test(int $idx): bool + { + if ($idx >= $this->_width) { + throw new \OutOfBoundsException('Index is out of bounds.'); + } + // octet index + $oi = (int) floor($idx / 8); + $byte = $this->_flags[$oi]; + // bit index + $bi = $idx % 8; + // index 0 is the most significant bit in byte + $mask = 0x01 << (7 - $bi); + return (ord($byte) & $mask) > 0; + } + + /** + * Get flags as an octet string. + * + * Zeroes are appended to the last octet if width is not divisible by 8. + */ + public function string(): string + { + return $this->_flags; + } + + /** + * Get flags as a base 10 integer. + * + * @return string Integer as a string + */ + public function number(): string + { + $num = gmp_import($this->_flags, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + $last_octet_bits = $this->_width % 8; + $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; + $num >>= $unused_bits; + return gmp_strval($num, 10); + } + + /** + * Get flags as an integer. + */ + public function intNumber(): int + { + $num = new BigInt($this->number()); + return $num->intVal(); + } + + /** + * Get flags as a `BitString` object. + * + * Unused bits are set accordingly. Trailing zeroes are not stripped. + */ + public function bitString(): BitString + { + $last_octet_bits = $this->_width % 8; + $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; + return new BitString($this->_flags, $unused_bits); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE new file mode 100644 index 0000000..146b5cf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2019 Joni Eskelinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md new file mode 100644 index 0000000..38770b1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md @@ -0,0 +1,24 @@ +# CryptoEncoding + +[![Build Status](https://travis-ci.org/sop/crypto-encoding.svg?branch=master)](https://travis-ci.org/sop/crypto-encoding) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sop/crypto-encoding/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sop/crypto-encoding/?branch=master) +[![Coverage Status](https://coveralls.io/repos/github/sop/crypto-encoding/badge.svg?branch=master)](https://coveralls.io/github/sop/crypto-encoding?branch=master) +[![License](https://poser.pugx.org/sop/crypto-encoding/license)](https://github.com/sop/crypto-encoding/blob/master/LICENSE) + +A PHP implementation of [RFC 7468](https://tools.ietf.org/html/rfc7468) +textual encodings of cryptographic structures _(PEM)_. + +## Requirements + +- PHP >=7.2 + +## Installation + +This library is available on +[Packagist](https://packagist.org/packages/sop/crypto-encoding). + + composer require sop/crypto-encoding + +## License + +This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json new file mode 100644 index 0000000..d1764e1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json @@ -0,0 +1,31 @@ +{ + "name": "sop/crypto-encoding", + "description": "A PHP implementation of textual encodings of cryptographic structures.", + "homepage": "https://github.com/sop/crypto-encoding", + "license": "MIT", + "type": "library", + "keywords": [ + "pem", + "public key", + "private key", + "certificate" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "require": { + "php": ">=7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "autoload": { + "psr-4": { + "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" + } + } +} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php new file mode 100644 index 0000000..d55b858 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php @@ -0,0 +1,145 @@ +_type = $type; + $this->_data = $data; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->string(); + } + + /** + * Initialize from a PEM-formatted string. + * + * @param string $str + * + * @throws \UnexpectedValueException If string is not valid PEM + * + * @return self + */ + public static function fromString(string $str): self + { + if (!preg_match(self::PEM_REGEX, $str, $match)) { + throw new \UnexpectedValueException('Not a PEM formatted string.'); + } + $payload = preg_replace('/\s+/', '', $match[2]); + $data = base64_decode($payload, true); + if (false === $data) { + throw new \UnexpectedValueException('Failed to decode PEM data.'); + } + return new self($match[1], $data); + } + + /** + * Initialize from a file. + * + * @param string $filename Path to file + * + * @throws \RuntimeException If file reading fails + * + * @return self + */ + public static function fromFile(string $filename): self + { + if (!is_readable($filename) || + false === ($str = file_get_contents($filename))) { + throw new \RuntimeException("Failed to read {$filename}."); + } + return self::fromString($str); + } + + /** + * Get content type. + * + * @return string + */ + public function type(): string + { + return $this->_type; + } + + /** + * Get payload. + * + * @return string + */ + public function data(): string + { + return $this->_data; + } + + /** + * Encode to PEM string. + * + * @return string + */ + public function string(): string + { + return "-----BEGIN {$this->_type}-----\n" . + trim(chunk_split(base64_encode($this->_data), 64, "\n")) . "\n" . + "-----END {$this->_type}-----"; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php new file mode 100644 index 0000000..54c528d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php @@ -0,0 +1,173 @@ +_pems = $pems; + } + + /** + * @return string + */ + public function __toString(): string + { + return $this->string(); + } + + /** + * Initialize from a string. + * + * @param string $str + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromString(string $str): self + { + if (!preg_match_all(PEM::PEM_REGEX, $str, $matches, PREG_SET_ORDER)) { + throw new \UnexpectedValueException('No PEM blocks.'); + } + $pems = array_map( + function ($match) { + $payload = preg_replace('/\s+/', '', $match[2]); + $data = base64_decode($payload, true); + if (false === $data) { + throw new \UnexpectedValueException( + 'Failed to decode PEM data.'); + } + return new PEM($match[1], $data); + }, $matches); + return new self(...$pems); + } + + /** + * Initialize from a file. + * + * @param string $filename + * + * @throws \RuntimeException If file reading fails + * + * @return self + */ + public static function fromFile(string $filename): self + { + if (!is_readable($filename) || + false === ($str = file_get_contents($filename))) { + throw new \RuntimeException("Failed to read {$filename}."); + } + return self::fromString($str); + } + + /** + * Get self with PEM objects appended. + * + * @param PEM ...$pems + * + * @return self + */ + public function withPEMs(PEM ...$pems): self + { + $obj = clone $this; + $obj->_pems = array_merge($obj->_pems, $pems); + return $obj; + } + + /** + * Get all PEMs in a bundle. + * + * @return PEM[] + */ + public function all(): array + { + return $this->_pems; + } + + /** + * Get the first PEM in a bundle. + * + * @throws \LogicException If bundle contains no PEM objects + * + * @return PEM + */ + public function first(): PEM + { + if (!count($this->_pems)) { + throw new \LogicException('No PEMs.'); + } + return $this->_pems[0]; + } + + /** + * Get the last PEM in a bundle. + * + * @throws \LogicException If bundle contains no PEM objects + * + * @return PEM + */ + public function last(): PEM + { + if (!count($this->_pems)) { + throw new \LogicException('No PEMs.'); + } + return $this->_pems[count($this->_pems) - 1]; + } + + /** + * @see \Countable::count() + * + * @return int + */ + public function count(): int + { + return count($this->_pems); + } + + /** + * Get iterator for PEMs. + * + * @see \IteratorAggregate::getIterator() + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->_pems); + } + + /** + * Encode bundle to a string of contiguous PEM blocks. + * + * @return string + */ + public function string(): string + { + return implode("\n", + array_map( + function (PEM $pem) { + return $pem->string(); + }, $this->_pems)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE b/utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE new file mode 100644 index 0000000..0453e40 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016-2021 Joni Eskelinen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md b/utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md new file mode 100644 index 0000000..bbdccd4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md @@ -0,0 +1,42 @@ +# CryptoTypes + +[![Build Status](https://travis-ci.com/sop/crypto-types.svg?branch=master)](https://travis-ci.com/sop/crypto-types) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sop/crypto-types/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sop/crypto-types/?branch=master) +[![Coverage Status](https://coveralls.io/repos/github/sop/crypto-types/badge.svg?branch=master)](https://coveralls.io/github/sop/crypto-types?branch=master) +[![License](https://poser.pugx.org/sop/crypto-types/license)](https://github.com/sop/crypto-types/blob/master/LICENSE) + +A PHP library of various ASN.1 types for cryptographic applications. + +## Requirements + +- PHP >=7.2 +- gmp +- [sop/asn1](https://github.com/sop/asn1) +- [sop/crypto-encoding](https://github.com/sop/crypto-encoding) +- [sop/x501](https://github.com/sop/x501) + +## Features + +- Asymmetric keys + - [`RSAPrivateKey`](https://tools.ietf.org/html/rfc2437#section-11.1.2), + [`RSAPublicKey`](https://tools.ietf.org/html/rfc2437#section-11.1.1) + - [`ECPrivateKey`](https://tools.ietf.org/html/rfc5915#section-3), + [`ECPublicKey`](https://tools.ietf.org/html/rfc5480#section-2.2) + - [`PrivateKeyInfo`](https://tools.ietf.org/html/rfc5208#section-5) + ([PKCS #8](https://tools.ietf.org/html/rfc5208)) + - [`SubjectPublicKeyInfo`](https://tools.ietf.org/html/rfc5280#section-4.1) + ([X.509](https://tools.ietf.org/html/rfc5280)) +- [RSA](https://tools.ietf.org/html/rfc2313#section-10) and + [EC](https://tools.ietf.org/html/rfc3278#section-8.2) signature types +- Various `AlgorithmIdentifier` types and their OID's + +## Installation + +This library is available on +[Packagist](https://packagist.org/packages/sop/crypto-types). + + composer require sop/crypto-types + +## License + +This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json b/utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json new file mode 100644 index 0000000..d8ba537 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json @@ -0,0 +1,39 @@ +{ + "name": "sop/crypto-types", + "description": "A PHP library of various ASN.1 types for cryptographic applications.", + "homepage": "https://github.com/sop/crypto-types", + "license": "MIT", + "type": "library", + "keywords": [ + "cryptography", + "asn1", + "algorithm identifier", + "rsa", + "ec", + "public key", + "private key", + "signature" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "require": { + "php": ">=7.2", + "ext-gmp": "*", + "sop/asn1": "^4.0.0", + "sop/crypto-encoding": "^0.3.0", + "sop/x501": "0.6.1" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "autoload": { + "psr-4": { + "Sop\\CryptoTypes\\": "lib/CryptoTypes/" + } + } +} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php new file mode 100644 index 0000000..239940f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php @@ -0,0 +1,116 @@ +parse($seq); + } + + /** + * {@inheritdoc} + */ + public function oid(): string + { + return $this->_oid; + } + + /** + * {@inheritdoc} + */ + public function toASN1(): Sequence + { + $elements = [new ObjectIdentifier($this->_oid)]; + $params = $this->_paramsASN1(); + if (isset($params)) { + $elements[] = $params; + } + return new Sequence(...$elements); + } + + /** + * Get algorithm identifier parameters as ASN.1. + * + * If type allows parameters to be omitted, return null. + */ + abstract protected function _paramsASN1(): ?Element; +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php new file mode 100644 index 0000000..3dc182c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php @@ -0,0 +1,119 @@ + Asymmetric\RSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_EC_PUBLIC_KEY => Asymmetric\ECPublicKeyAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_X25519 => Asymmetric\X25519AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_X448 => Asymmetric\X448AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ED25519 => Asymmetric\Ed25519AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ED448 => Asymmetric\Ed448AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_DES_CBC => Cipher\DESCBCAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_DES_EDE3_CBC => Cipher\DESEDE3CBCAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_RC2_CBC => Cipher\RC2CBCAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_AES_128_CBC => Cipher\AES128CBCAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_AES_192_CBC => Cipher\AES192CBCAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_AES_256_CBC => Cipher\AES256CBCAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_HMAC_WITH_SHA1 => Hash\HMACWithSHA1AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_HMAC_WITH_SHA224 => Hash\HMACWithSHA224AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_HMAC_WITH_SHA256 => Hash\HMACWithSHA256AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_HMAC_WITH_SHA384 => Hash\HMACWithSHA384AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_HMAC_WITH_SHA512 => Hash\HMACWithSHA512AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_MD5 => Hash\MD5AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA1 => Hash\SHA1AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA224 => Hash\SHA224AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA256 => Hash\SHA256AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA384 => Hash\SHA384AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA512 => Hash\SHA512AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_MD2_WITH_RSA_ENCRYPTION => Signature\MD2WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_MD4_WITH_RSA_ENCRYPTION => Signature\MD4WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_MD5_WITH_RSA_ENCRYPTION => Signature\MD5WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA1_WITH_RSA_ENCRYPTION => Signature\SHA1WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA224_WITH_RSA_ENCRYPTION => Signature\SHA224WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA256_WITH_RSA_ENCRYPTION => Signature\SHA256WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA384_WITH_RSA_ENCRYPTION => Signature\SHA384WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_SHA512_WITH_RSA_ENCRYPTION => Signature\SHA512WithRSAEncryptionAlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ECDSA_WITH_SHA1 => Signature\ECDSAWithSHA1AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ECDSA_WITH_SHA224 => Signature\ECDSAWithSHA224AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ECDSA_WITH_SHA256 => Signature\ECDSAWithSHA256AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ECDSA_WITH_SHA384 => Signature\ECDSAWithSHA384AlgorithmIdentifier::class, + AlgorithmIdentifier::OID_ECDSA_WITH_SHA512 => Signature\ECDSAWithSHA512AlgorithmIdentifier::class, + ]; + + /** + * Additional algorithm identifier providers. + * + * @var AlgorithmIdentifierProvider[] + */ + private $_additionalProviders; + + /** + * Constructor. + * + * @param AlgorithmIdentifierProvider ...$providers Additional providers + */ + public function __construct(AlgorithmIdentifierProvider ...$providers) + { + $this->_additionalProviders = $providers; + } + + /** + * Get the name of a class that implements algorithm identifier for given + * OID. + * + * @param string $oid Object identifier in dotted format + * + * @return null|string Fully qualified class name or null if not supported + */ + public function getClass(string $oid): ?string + { + // if OID is provided by this factory + if (array_key_exists($oid, self::MAP_OID_TO_CLASS)) { + return self::MAP_OID_TO_CLASS[$oid]; + } + // try additional providers + foreach ($this->_additionalProviders as $provider) { + if ($provider->supportsOID($oid)) { + return $provider->getClassByOID($oid); + } + } + return null; + } + + /** + * Parse AlgorithmIdentifier from an ASN.1 sequence. + */ + public function parse(Sequence $seq): AlgorithmIdentifier + { + $oid = $seq->at(0)->asObjectIdentifier()->oid(); + $params = $seq->has(1) ? $seq->at(1) : null; + /** @var SpecificAlgorithmIdentifier $cls */ + $cls = $this->getClass($oid); + if ($cls) { + return $cls::fromASN1Params($params); + } + // fallback to generic algorithm identifier + return new GenericAlgorithmIdentifier($oid, $params); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php new file mode 100644 index 0000000..5041677 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php @@ -0,0 +1,35 @@ + 192, + self::CURVE_PRIME192V2 => 192, + self::CURVE_PRIME192V3 => 192, + self::CURVE_PRIME239V1 => 239, + self::CURVE_PRIME239V2 => 239, + self::CURVE_PRIME239V3 => 239, + self::CURVE_PRIME256V1 => 256, + self::CURVE_SECP112R1 => 112, + self::CURVE_SECP112R2 => 112, + self::CURVE_SECP128R1 => 128, + self::CURVE_SECP128R2 => 128, + self::CURVE_SECP160K1 => 160, + self::CURVE_SECP160R1 => 160, + self::CURVE_SECP160R2 => 160, + self::CURVE_SECP192K1 => 192, + self::CURVE_SECP224K1 => 224, + self::CURVE_SECP224R1 => 224, + self::CURVE_SECP256K1 => 256, + self::CURVE_SECP384R1 => 384, + self::CURVE_SECP521R1 => 521, + ]; + + /** + * OID of the named curve. + * + * @var string + */ + protected $_namedCurve; + + /** + * Constructor. + * + * @param string $named_curve Curve identifier + */ + public function __construct(string $named_curve) + { + $this->_oid = self::OID_EC_PUBLIC_KEY; + $this->_namedCurve = $named_curve; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecPublicKey'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $named_curve = $params->asObjectIdentifier()->oid(); + return new self($named_curve); + } + + /** + * Get OID of the named curve. + */ + public function namedCurve(): string + { + return $this->_namedCurve; + } + + /** + * {@inheritdoc} + * + * @return ObjectIdentifier + */ + protected function _paramsASN1(): ?Element + { + return new ObjectIdentifier($this->_namedCurve); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php new file mode 100644 index 0000000..b0fbe31 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php @@ -0,0 +1,44 @@ +_oid = self::OID_ED25519; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-Ed25519'; + } + + /** + * {@inheritdoc} + */ + public function supportsKeyAlgorithm(AlgorithmIdentifier $algo): bool + { + return self::OID_ED25519 === $algo->oid(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php new file mode 100644 index 0000000..3b6b270 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php @@ -0,0 +1,44 @@ +_oid = self::OID_ED448; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-Ed448'; + } + + /** + * {@inheritdoc} + */ + public function supportsKeyAlgorithm(AlgorithmIdentifier $algo): bool + { + return self::OID_ED448 === $algo->oid(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php new file mode 100644 index 0000000..e1a6188 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php @@ -0,0 +1,59 @@ +_oid = self::OID_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'rsaEncryption'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $params->asNull(); + return new self(); + } + + /** + * {@inheritdoc} + * + * @return NullType + */ + protected function _paramsASN1(): ?Element + { + return new NullType(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php new file mode 100644 index 0000000..f20005a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_X25519; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-X25519'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php new file mode 100644 index 0000000..86635b5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_X448; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-X448'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php new file mode 100644 index 0000000..6e043cf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php @@ -0,0 +1,42 @@ +_oid = self::OID_AES_128_CBC; + parent::__construct($iv); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'aes128-CBC'; + } + + /** + * {@inheritdoc} + */ + public function keySize(): int + { + return 16; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php new file mode 100644 index 0000000..e228f13 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php @@ -0,0 +1,42 @@ +_oid = self::OID_AES_192_CBC; + parent::__construct($iv); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'aes192-CBC'; + } + + /** + * {@inheritdoc} + */ + public function keySize(): int + { + return 24; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php new file mode 100644 index 0000000..e076d09 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php @@ -0,0 +1,42 @@ +_oid = self::OID_AES_256_CBC; + parent::__construct($iv); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'aes256-CBC'; + } + + /** + * {@inheritdoc} + */ + public function keySize(): int + { + return 32; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php new file mode 100644 index 0000000..44fcb66 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php @@ -0,0 +1,82 @@ +_checkIVSize($iv); + $this->_initializationVector = $iv; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $iv = $params->asOctetString()->string(); + return new static($iv); + } + + /** + * {@inheritdoc} + */ + public function blockSize(): int + { + return 16; + } + + /** + * {@inheritdoc} + */ + public function ivSize(): int + { + return 16; + } + + /** + * {@inheritdoc} + * + * @return OctetString + */ + protected function _paramsASN1(): ?Element + { + if (!isset($this->_initializationVector)) { + throw new \LogicException('IV not set.'); + } + return new OctetString($this->_initializationVector); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php new file mode 100644 index 0000000..49f0f30 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php @@ -0,0 +1,16 @@ +_initializationVector; + } + + /** + * Get copy of the object with given initialization vector. + * + * @param null|string $iv Initialization vector or null to remove + * + * @throws \UnexpectedValueException If initialization vector size is invalid + */ + public function withInitializationVector(?string $iv): self + { + $this->_checkIVSize($iv); + $obj = clone $this; + $obj->_initializationVector = $iv; + return $obj; + } + + /** + * Check that initialization vector size is valid for the cipher. + * + * @throws \UnexpectedValueException + */ + protected function _checkIVSize(?string $iv): void + { + if (null !== $iv && strlen($iv) !== $this->ivSize()) { + throw new \UnexpectedValueException('Invalid IV size.'); + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php new file mode 100644 index 0000000..e3bd9c2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php @@ -0,0 +1,98 @@ +_checkIVSize($iv); + $this->_oid = self::OID_DES_CBC; + $this->_initializationVector = $iv; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'desCBC'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $iv = $params->asOctetString()->string(); + return new self($iv); + } + + /** + * {@inheritdoc} + */ + public function blockSize(): int + { + return 8; + } + + /** + * {@inheritdoc} + */ + public function keySize(): int + { + return 8; + } + + /** + * {@inheritdoc} + */ + public function ivSize(): int + { + return 8; + } + + /** + * {@inheritdoc} + * + * @return OctetString + */ + protected function _paramsASN1(): ?Element + { + if (!isset($this->_initializationVector)) { + throw new \LogicException('IV not set.'); + } + return new OctetString($this->_initializationVector); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php new file mode 100644 index 0000000..79121d6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php @@ -0,0 +1,99 @@ +_checkIVSize($iv); + $this->_oid = self::OID_DES_EDE3_CBC; + $this->_initializationVector = $iv; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'des-EDE3-CBC'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $iv = $params->asOctetString()->string(); + return new self($iv); + } + + /** + * {@inheritdoc} + */ + public function blockSize(): int + { + return 8; + } + + /** + * {@inheritdoc} + */ + public function keySize(): int + { + return 24; + } + + /** + * {@inheritdoc} + */ + public function ivSize(): int + { + return 8; + } + + /** + * {@inheritdoc} + * + * @return OctetString + */ + protected function _paramsASN1(): ?Element + { + if (!isset($this->_initializationVector)) { + throw new \LogicException('IV not set.'); + } + return new OctetString($this->_initializationVector); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php new file mode 100644 index 0000000..52154a7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php @@ -0,0 +1,215 @@ + version + */ + private const EKB_TABLE = [ + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab + ]; + + /** + * Effective key bits. + * + * @var int + */ + protected $_effectiveKeyBits; + + /** + * Constructor. + * + * @param int $key_bits Number of effective key bits + * @param null|string $iv Initialization vector + */ + public function __construct(int $key_bits = 64, ?string $iv = null) + { + $this->_checkIVSize($iv); + $this->_oid = self::OID_RC2_CBC; + $this->_effectiveKeyBits = $key_bits; + $this->_initializationVector = $iv; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'rc2-cbc'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $key_bits = 32; + // rfc2268 a choice containing only IV + if ($params->isType(Element::TYPE_OCTET_STRING)) { + $iv = $params->asOctetString()->string(); + } else { + $seq = $params->asSequence(); + $idx = 0; + // version is optional in rfc2898 + if ($seq->has($idx, Element::TYPE_INTEGER)) { + $version = $seq->at($idx++)->asInteger()->intNumber(); + $key_bits = self::_versionToEKB($version); + } + // IV is present in all variants + $iv = $seq->at($idx)->asOctetString()->string(); + } + return new self($key_bits, $iv); + } + + /** + * Get number of effective key bits. + */ + public function effectiveKeyBits(): int + { + return $this->_effectiveKeyBits; + } + + /** + * {@inheritdoc} + */ + public function blockSize(): int + { + return 8; + } + + /** + * {@inheritdoc} + */ + public function keySize(): int + { + return (int) round($this->_effectiveKeyBits / 8); + } + + /** + * {@inheritdoc} + */ + public function ivSize(): int + { + return 8; + } + + /** + * {@inheritdoc} + * + * @return Sequence + */ + protected function _paramsASN1(): ?Element + { + if ($this->_effectiveKeyBits >= 256) { + $version = $this->_effectiveKeyBits; + } else { + $version = self::EKB_TABLE[$this->_effectiveKeyBits]; + } + if (!isset($this->_initializationVector)) { + throw new \LogicException('IV not set.'); + } + return new Sequence(new Integer($version), + new OctetString($this->_initializationVector)); + } + + /** + * Translate version number to number of effective key bits. + */ + private static function _versionToEKB(int $version): int + { + static $lut; + if ($version > 255) { + return $version; + } + if (!isset($lut)) { + $lut = array_flip(self::EKB_TABLE); + } + return $lut[$version]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php new file mode 100644 index 0000000..5f03e5b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php @@ -0,0 +1,30 @@ +_oid = $oid; + $this->_params = $params; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return $this->_oid; + } + + /** + * Get parameters. + */ + public function parameters(): ?UnspecifiedType + { + return $this->_params; + } + + /** + * {@inheritdoc} + */ + protected function _paramsASN1(): ?Element + { + return $this->_params ? $this->_params->asElement() : null; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php new file mode 100644 index 0000000..93e59b6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php @@ -0,0 +1,66 @@ +_oid = self::OID_HMAC_WITH_SHA1; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'hmacWithSHA1'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (isset($params)) { + throw new \UnexpectedValueException('Parameters must be omitted.'); + } + return new self(); + } + + /** + * {@inheritdoc} + */ + protected function _paramsASN1(): ?Element + { + return null; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php new file mode 100644 index 0000000..766da40 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_HMAC_WITH_SHA224; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'hmacWithSHA224'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php new file mode 100644 index 0000000..ecec77f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_HMAC_WITH_SHA256; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'hmacWithSHA256'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php new file mode 100644 index 0000000..1867ac2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_HMAC_WITH_SHA384; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'hmacWithSHA384'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php new file mode 100644 index 0000000..25f720e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_HMAC_WITH_SHA512; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'hmacWithSHA512'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php new file mode 100644 index 0000000..b592de3 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php @@ -0,0 +1,85 @@ +_oid = self::OID_MD5; + $this->_params = new NullType(); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'md5'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + $obj = new static(); + // if parameters field is present, it must be null type + if (isset($params)) { + $obj->_params = $params->asNull(); + } + return $obj; + } + + /** + * {@inheritdoc} + * + * @return null|NullType + */ + protected function _paramsASN1(): ?Element + { + return $this->_params; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php new file mode 100644 index 0000000..3a7f0bb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php @@ -0,0 +1,56 @@ +_params = $params->asNull(); + } + return $obj; + } + + /** + * {@inheritdoc} + * + * @return null|NullType + */ + protected function _paramsASN1(): ?Element + { + return $this->_params; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php new file mode 100644 index 0000000..60ce36b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php @@ -0,0 +1,81 @@ +_oid = self::OID_SHA1; + $this->_params = null; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha1'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + $obj = new static(); + // if parameters field is present, it must be null type + if (isset($params)) { + $obj->_params = $params->asNull(); + } + return $obj; + } + + /** + * {@inheritdoc} + * + * @return null|NullType + */ + protected function _paramsASN1(): ?Element + { + return $this->_params; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php new file mode 100644 index 0000000..daf566f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php @@ -0,0 +1,33 @@ +_oid = self::OID_SHA224; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha224'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php new file mode 100644 index 0000000..22677b8 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php @@ -0,0 +1,32 @@ +_oid = self::OID_SHA256; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha256'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php new file mode 100644 index 0000000..ed68edd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php @@ -0,0 +1,71 @@ +_params = null; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + $obj = new static(); + // if parameters field is present, it must be null type + if (isset($params)) { + $obj->_params = $params->asNull(); + } + return $obj; + } + + /** + * {@inheritdoc} + * + * @return null|NullType + */ + protected function _paramsASN1(): ?Element + { + return $this->_params; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php new file mode 100644 index 0000000..846adad --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php @@ -0,0 +1,32 @@ +_oid = self::OID_SHA384; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha384'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php new file mode 100644 index 0000000..a38a24c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php @@ -0,0 +1,32 @@ +_oid = self::OID_SHA512; + parent::__construct(); + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha512'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php new file mode 100644 index 0000000..509c332 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_ECDSA_WITH_SHA1; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecdsa-with-SHA1'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php new file mode 100644 index 0000000..00c38cb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_ECDSA_WITH_SHA224; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecdsa-with-SHA224'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php new file mode 100644 index 0000000..0ecef8b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_ECDSA_WITH_SHA256; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecdsa-with-SHA256'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php new file mode 100644 index 0000000..9b57697 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_ECDSA_WITH_SHA384; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecdsa-with-SHA384'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php new file mode 100644 index 0000000..4c2c2f5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_ECDSA_WITH_SHA512; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecdsa-with-SHA512'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php new file mode 100644 index 0000000..1fd0b09 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php @@ -0,0 +1,59 @@ +oid(); + } + + /** + * {@inheritdoc} + */ + protected function _paramsASN1(): ?Element + { + return null; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..ec7cb4a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_MD2_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'md2WithRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..5a3e7e2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_MD4_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'md4withRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..e50eeda --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_MD5_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'md5WithRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php new file mode 100644 index 0000000..a2de151 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php @@ -0,0 +1,51 @@ +asNull(); + return new static(); + } + + /** + * {@inheritdoc} + * + * @return NullType + */ + protected function _paramsASN1(): ?Element + { + return new NullType(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php new file mode 100644 index 0000000..001f744 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php @@ -0,0 +1,65 @@ +_params = new NullType(); + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + $obj = new static(); + // store parameters so re-encoding doesn't change + if (isset($params)) { + $obj->_params = $params->asElement(); + } + return $obj; + } + + /** + * {@inheritdoc} + */ + protected function _paramsASN1(): ?Element + { + return $this->_params; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php new file mode 100644 index 0000000..074f6a1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php @@ -0,0 +1,23 @@ +oid(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..49dca5c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_SHA1_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha1-with-rsa-signature'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..38db332 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,30 @@ +_oid = self::OID_SHA224_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha224WithRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..88fbf3c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,30 @@ +_oid = self::OID_SHA256_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha256WithRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..84f18d7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,30 @@ +_oid = self::OID_SHA384_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha384WithRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php new file mode 100644 index 0000000..e4c1eba --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php @@ -0,0 +1,30 @@ +_oid = self::OID_SHA512_WITH_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'sha512WithRSAEncryption'; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php new file mode 100644 index 0000000..8c63ff4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php @@ -0,0 +1,105 @@ + AlgorithmIdentifier::OID_MD5_WITH_RSA_ENCRYPTION, + AlgorithmIdentifier::OID_SHA1 => AlgorithmIdentifier::OID_SHA1_WITH_RSA_ENCRYPTION, + AlgorithmIdentifier::OID_SHA224 => AlgorithmIdentifier::OID_SHA224_WITH_RSA_ENCRYPTION, + AlgorithmIdentifier::OID_SHA256 => AlgorithmIdentifier::OID_SHA256_WITH_RSA_ENCRYPTION, + AlgorithmIdentifier::OID_SHA384 => AlgorithmIdentifier::OID_SHA384_WITH_RSA_ENCRYPTION, + AlgorithmIdentifier::OID_SHA512 => AlgorithmIdentifier::OID_SHA512_WITH_RSA_ENCRYPTION, + ]; + + /** + * Mapping of hash algorithm OID's to EC signature algorithm OID's. + * + * @internal + * + * @var array + */ + public const MAP_EC_OID = [ + AlgorithmIdentifier::OID_SHA1 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA1, + AlgorithmIdentifier::OID_SHA224 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA224, + AlgorithmIdentifier::OID_SHA256 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA256, + AlgorithmIdentifier::OID_SHA384 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA384, + AlgorithmIdentifier::OID_SHA512 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA512, + ]; + + /** + * Get signature algorithm identifier of given asymmetric cryptographic type + * utilizing given hash algorithm. + * + * @param AsymmetricCryptoAlgorithmIdentifier $crypto_algo Cryptographic algorithm identifier, eg. RSA or EC + * @param HashAlgorithmIdentifier $hash_algo Hash algorithm identifier + * + * @throws \UnexpectedValueException + */ + public static function algoForAsymmetricCrypto( + AsymmetricCryptoAlgorithmIdentifier $crypto_algo, + HashAlgorithmIdentifier $hash_algo): SignatureAlgorithmIdentifier + { + switch ($crypto_algo->oid()) { + case AlgorithmIdentifier::OID_RSA_ENCRYPTION: + $oid = self::_oidForRSA($hash_algo); + break; + case AlgorithmIdentifier::OID_EC_PUBLIC_KEY: + $oid = self::_oidForEC($hash_algo); + break; + default: + throw new \UnexpectedValueException( + sprintf('Crypto algorithm %s not supported.', + $crypto_algo->name())); + } + $cls = (new AlgorithmIdentifierFactory())->getClass($oid); + return new $cls(); + } + + /** + * Get RSA signature algorithm OID for the given hash algorithm identifier. + * + * @throws \UnexpectedValueException + */ + private static function _oidForRSA(HashAlgorithmIdentifier $hash_algo): string + { + if (!array_key_exists($hash_algo->oid(), self::MAP_RSA_OID)) { + throw new \UnexpectedValueException( + sprintf('No RSA signature algorithm for %s.', $hash_algo->name())); + } + return self::MAP_RSA_OID[$hash_algo->oid()]; + } + + /** + * Get EC signature algorithm OID for the given hash algorithm identifier. + * + * @throws \UnexpectedValueException + */ + private static function _oidForEC(HashAlgorithmIdentifier $hash_algo): string + { + if (!array_key_exists($hash_algo->oid(), self::MAP_EC_OID)) { + throw new \UnexpectedValueException( + sprintf('No EC signature algorithm for %s.', $hash_algo->name())); + } + return self::MAP_EC_OID[$hash_algo->oid()]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php new file mode 100644 index 0000000..f5d1320 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php @@ -0,0 +1,30 @@ +string(); + if ($bs->unusedBits()) { + // @todo pad string + throw new \RuntimeException('Unaligned bitstrings to supported'); + } + return new OctetString($str); + } + + /** + * Perform Octet-String-to-Bit-String Conversion. + * + * Defined in SEC 1 section 2.3.2. + */ + public static function octetStringToBitString(OctetString $os): BitString + { + return new BitString($os->string()); + } + + /** + * Perform Integer-to-Octet-String Conversion. + * + * Defined in SEC 1 section 2.3.7. + * + * @param int $num + * @param null|int $mlen Optional desired output length + * + * @throws \UnexpectedValueException + */ + public static function integerToOctetString(Integer $num, ?int $mlen = null): OctetString + { + $gmp = gmp_init($num->number(), 10); + $str = gmp_export($gmp, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + if (null !== $mlen) { + $len = strlen($str); + if ($len > $mlen) { + throw new \RangeException('Number is too large.'); + } + // pad with zeroes + if ($len < $mlen) { + $str = str_repeat("\0", $mlen - $len) . $str; + } + } + return new OctetString($str); + } + + /** + * Perform Octet-String-to-Integer Conversion. + * + * Defined in SEC 1 section 2.3.8. + * + * @return int + */ + public static function octetStringToInteger(OctetString $os): Integer + { + $num = gmp_import($os->string(), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); + assert($num instanceof \GMP, new \RuntimeException('gmp_import() failed.')); + return new Integer(gmp_strval($num, 10)); + } + + /** + * Convert a base-10 number to octets. + * + * This is a convenicence method for integer <-> octet string conversion + * without the need for external ASN.1 dependencies. + * + * @param int|string $num Number in base-10 + * @param null|int $mlen Optional desired output length + */ + public static function numberToOctets($num, ?int $mlen = null): string + { + return self::integerToOctetString(new Integer($num), $mlen)->string(); + } + + /** + * Convert octets to a base-10 number. + * + * This is a convenicence method for integer <-> octet string conversion + * without the need for external ASN.1 dependencies. + * + * @return string Number in base-10 + */ + public static function octetsToNumber(string $str): string + { + return self::octetStringToInteger(new OctetString($str))->number(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php new file mode 100644 index 0000000..1649ae0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php @@ -0,0 +1,223 @@ +_privateKey = $private_key; + $this->_namedCurve = $named_curve; + $this->_publicKey = $public_key; + } + + /** + * Initialize from ASN.1. + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromASN1(Sequence $seq): ECPrivateKey + { + $version = $seq->at(0)->asInteger()->intNumber(); + if (1 !== $version) { + throw new \UnexpectedValueException('Version must be 1.'); + } + $private_key = $seq->at(1)->asOctetString()->string(); + $named_curve = null; + if ($seq->hasTagged(0)) { + $params = $seq->getTagged(0)->asExplicit(); + $named_curve = $params->asObjectIdentifier()->oid(); + } + $public_key = null; + if ($seq->hasTagged(1)) { + $public_key = $seq->getTagged(1)->asExplicit() + ->asBitString()->string(); + } + return new self($private_key, $named_curve, $public_key); + } + + /** + * Initialize from DER data. + * + * @return self + */ + public static function fromDER(string $data): ECPrivateKey + { + return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); + } + + /** + * @see PrivateKey::fromPEM() + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromPEM(PEM $pem): ECPrivateKey + { + $pk = parent::fromPEM($pem); + if (!($pk instanceof self)) { + throw new \UnexpectedValueException('Not an EC private key.'); + } + return $pk; + } + + /** + * Get the EC private key value. + * + * @return string Octets of the private key + */ + public function privateKeyOctets(): string + { + return $this->_privateKey; + } + + /** + * Whether named curve is present. + */ + public function hasNamedCurve(): bool + { + return isset($this->_namedCurve); + } + + /** + * Get named curve OID. + * + * @throws \LogicException + */ + public function namedCurve(): string + { + if (!$this->hasNamedCurve()) { + throw new \LogicException('namedCurve not set.'); + } + return $this->_namedCurve; + } + + /** + * Get self with named curve. + * + * @param null|string $named_curve Named curve OID + * + * @return self + */ + public function withNamedCurve(?string $named_curve): ECPrivateKey + { + $obj = clone $this; + $obj->_namedCurve = $named_curve; + return $obj; + } + + /** + * {@inheritdoc} + */ + public function algorithmIdentifier(): AlgorithmIdentifierType + { + return new ECPublicKeyAlgorithmIdentifier($this->namedCurve()); + } + + /** + * Whether public key is present. + */ + public function hasPublicKey(): bool + { + return isset($this->_publicKey); + } + + /** + * {@inheritdoc} + * + * @return ECPublicKey + */ + public function publicKey(): PublicKey + { + if (!$this->hasPublicKey()) { + throw new \LogicException('publicKey not set.'); + } + return new ECPublicKey($this->_publicKey, $this->namedCurve()); + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): Sequence + { + $elements = [new Integer(1), new OctetString($this->_privateKey)]; + if (isset($this->_namedCurve)) { + $elements[] = new ExplicitlyTaggedType(0, + new ObjectIdentifier($this->_namedCurve)); + } + if (isset($this->_publicKey)) { + $elements[] = new ExplicitlyTaggedType(1, + new BitString($this->_publicKey)); + } + return new Sequence(...$elements); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * {@inheritdoc} + */ + public function toPEM(): PEM + { + return new PEM(PEM::TYPE_EC_PRIVATE_KEY, $this->toDER()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php new file mode 100644 index 0000000..f8b0e93 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php @@ -0,0 +1,222 @@ +_ecPoint = $ec_point; + $this->_namedCurve = $named_curve; + } + + /** + * Initialize from curve point coordinates. + * + * @param int|string $x X coordinate as a base10 number + * @param int|string $y Y coordinate as a base10 number + * @param null|string $named_curve Named curve OID + * @param null|int $bits Size of *p* in bits + * + * @return self + */ + public static function fromCoordinates($x, $y, + ?string $named_curve = null, ?int $bits = null): ECPublicKey + { + // if bitsize is not explicitly set, check from supported curves + if (!isset($bits) && isset($named_curve)) { + $bits = self::_curveSize($named_curve); + } + $mlen = null; + if (isset($bits)) { + $mlen = (int) ceil($bits / 8); + } + $x_os = ECConversion::integerToOctetString(new Integer($x), $mlen)->string(); + $y_os = ECConversion::integerToOctetString(new Integer($y), $mlen)->string(); + $ec_point = "\x4{$x_os}{$y_os}"; + return new self($ec_point, $named_curve); + } + + /** + * @see PublicKey::fromPEM() + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromPEM(PEM $pem): ECPublicKey + { + if (PEM::TYPE_PUBLIC_KEY !== $pem->type()) { + throw new \UnexpectedValueException('Not a public key.'); + } + $pki = PublicKeyInfo::fromDER($pem->data()); + $algo = $pki->algorithmIdentifier(); + if (AlgorithmIdentifier::OID_EC_PUBLIC_KEY !== $algo->oid() + || !($algo instanceof ECPublicKeyAlgorithmIdentifier)) { + throw new \UnexpectedValueException('Not an elliptic curve key.'); + } + // ECPoint is directly mapped into public key data + return new self($pki->publicKeyData()->string(), $algo->namedCurve()); + } + + /** + * Get ECPoint value. + */ + public function ECPoint(): string + { + return $this->_ecPoint; + } + + /** + * Get curve point coordinates. + * + * @return string[] Tuple of X and Y coordinates as base-10 numbers + */ + public function curvePoint(): array + { + return array_map( + function ($str) { + return ECConversion::octetsToNumber($str); + }, $this->curvePointOctets()); + } + + /** + * Get curve point coordinates in octet string representation. + * + * @return string[] tuple of X and Y field elements as a string + */ + public function curvePointOctets(): array + { + if ($this->isCompressed()) { + throw new \RuntimeException('EC point compression not supported.'); + } + $str = substr($this->_ecPoint, 1); + [$x, $y] = str_split($str, (int) floor(strlen($str) / 2)); + return [$x, $y]; + } + + /** + * Whether ECPoint is in compressed form. + */ + public function isCompressed(): bool + { + $c = ord($this->_ecPoint[0]); + return 4 !== $c; + } + + /** + * Whether named curve is present. + */ + public function hasNamedCurve(): bool + { + return isset($this->_namedCurve); + } + + /** + * Get named curve OID. + * + * @throws \LogicException + */ + public function namedCurve(): string + { + if (!$this->hasNamedCurve()) { + throw new \LogicException('namedCurve not set.'); + } + return $this->_namedCurve; + } + + /** + * {@inheritdoc} + */ + public function algorithmIdentifier(): AlgorithmIdentifierType + { + return new ECPublicKeyAlgorithmIdentifier($this->namedCurve()); + } + + /** + * Generate ASN.1 element. + */ + public function toASN1(): OctetString + { + return new OctetString($this->_ecPoint); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * {@inheritdoc} + * + * @see https://tools.ietf.org/html/rfc5480#section-2.2 + */ + public function subjectPublicKey(): BitString + { + // ECPoint is directly mapped to subjectPublicKey + return new BitString($this->_ecPoint); + } + + /** + * Get the curve size *p* in bits. + * + * @param string $oid Curve OID + */ + private static function _curveSize(string $oid): ?int + { + if (!array_key_exists($oid, ECPublicKeyAlgorithmIdentifier::MAP_CURVE_TO_SIZE)) { + return null; + } + return ECPublicKeyAlgorithmIdentifier::MAP_CURVE_TO_SIZE[$oid]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php new file mode 100644 index 0000000..5e7099e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php @@ -0,0 +1,359 @@ +_version = self::VERSION_2; + $this->_algo = $algo; + $this->_privateKeyData = $key; + $this->_attributes = $attributes; + $this->_publicKeyData = $public_key; + } + + /** + * Initialize from ASN.1. + * + * @throws \UnexpectedValueException + */ + public static function fromASN1(Sequence $seq): self + { + $version = $seq->at(0)->asInteger()->intNumber(); + if (!in_array($version, [self::VERSION_1, self::VERSION_2])) { + throw new \UnexpectedValueException( + "Version {$version} not supported."); + } + $algo = AlgorithmIdentifier::fromASN1($seq->at(1)->asSequence()); + $key = $seq->at(2)->asOctetString()->string(); + $attribs = null; + if ($seq->hasTagged(0)) { + $attribs = OneAsymmetricKeyAttributes::fromASN1($seq->getTagged(0) + ->asImplicit(Element::TYPE_SET)->asSet()); + } + $pubkey = null; + if ($seq->hasTagged(1)) { + $pubkey = $seq->getTagged(1) + ->asImplicit(Element::TYPE_BIT_STRING)->asBitString(); + } + $obj = new static($algo, $key, $attribs, $pubkey); + $obj->_version = $version; + return $obj; + } + + /** + * Initialize from DER data. + */ + public static function fromDER(string $data): self + { + return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); + } + + /** + * Initialize from a `PrivateKey`. + * + * Note that `OneAsymmetricKey` <-> `PrivateKey` conversions may not be + * bidirectional with all key types, since `OneAsymmetricKey` may include + * attributes as well the public key that are not conveyed in a specific + * `PrivateKey` object. + */ + public static function fromPrivateKey(PrivateKey $private_key): self + { + return new static( + $private_key->algorithmIdentifier(), + $private_key->privateKeyData() + ); + } + + /** + * Initialize from PEM. + * + * @throws \UnexpectedValueException If PEM type is not supported + */ + public static function fromPEM(PEM $pem): self + { + switch ($pem->type()) { + case PEM::TYPE_PRIVATE_KEY: + return self::fromDER($pem->data()); + case PEM::TYPE_RSA_PRIVATE_KEY: + return self::fromPrivateKey( + RSA\RSAPrivateKey::fromDER($pem->data())); + case PEM::TYPE_EC_PRIVATE_KEY: + return self::fromPrivateKey( + EC\ECPrivateKey::fromDER($pem->data())); + } + throw new \UnexpectedValueException('Invalid PEM type.'); + } + + /** + * Get self with version set. + */ + public function withVersion(int $version): self + { + $obj = clone $this; + $obj->_version = $version; + return $obj; + } + + /** + * Get version number. + */ + public function version(): int + { + return $this->_version; + } + + /** + * Get algorithm identifier. + */ + public function algorithmIdentifier(): AlgorithmIdentifierType + { + return $this->_algo; + } + + /** + * Get private key data. + */ + public function privateKeyData(): string + { + return $this->_privateKeyData; + } + + /** + * Get private key. + * + * @throws \RuntimeException + */ + public function privateKey(): PrivateKey + { + $algo = $this->algorithmIdentifier(); + switch ($algo->oid()) { + // RSA + case AlgorithmIdentifier::OID_RSA_ENCRYPTION: + return RSA\RSAPrivateKey::fromDER($this->_privateKeyData); + // elliptic curve + case AlgorithmIdentifier::OID_EC_PUBLIC_KEY: + $pk = EC\ECPrivateKey::fromDER($this->_privateKeyData); + // NOTE: OpenSSL strips named curve from ECPrivateKey structure + // when serializing into PrivateKeyInfo. However RFC 5915 dictates + // that parameters (NamedCurve) must always be included. + // If private key doesn't encode named curve, assign from parameters. + if (!$pk->hasNamedCurve()) { + if (!$algo instanceof ECPublicKeyAlgorithmIdentifier) { + throw new \UnexpectedValueException('Not an EC algorithm.'); + } + $pk = $pk->withNamedCurve($algo->namedCurve()); + } + return $pk; + // Ed25519 + case AlgorithmIdentifier::OID_ED25519: + $pubkey = $this->_publicKeyData ? + $this->_publicKeyData->string() : null; + // RFC 8410 defines `CurvePrivateKey ::= OCTET STRING` that + // is encoded into private key data. So Ed25519 private key + // is doubly wrapped into octet string encodings. + return RFC8410\Curve25519\Ed25519PrivateKey::fromOctetString( + OctetString::fromDER($this->_privateKeyData), $pubkey) + ->withVersion($this->_version) + ->withAttributes($this->_attributes); + // X25519 + case AlgorithmIdentifier::OID_X25519: + $pubkey = $this->_publicKeyData ? + $this->_publicKeyData->string() : null; + return RFC8410\Curve25519\X25519PrivateKey::fromOctetString( + OctetString::fromDER($this->_privateKeyData), $pubkey) + ->withVersion($this->_version) + ->withAttributes($this->_attributes); + // Ed448 + case AlgorithmIdentifier::OID_ED448: + $pubkey = $this->_publicKeyData ? + $this->_publicKeyData->string() : null; + return RFC8410\Curve448\Ed448PrivateKey::fromOctetString( + OctetString::fromDER($this->_privateKeyData), $pubkey) + ->withVersion($this->_version) + ->withAttributes($this->_attributes); + // X448 + case AlgorithmIdentifier::OID_X448: + $pubkey = $this->_publicKeyData ? + $this->_publicKeyData->string() : null; + return RFC8410\Curve448\X448PrivateKey::fromOctetString( + OctetString::fromDER($this->_privateKeyData), $pubkey) + ->withVersion($this->_version) + ->withAttributes($this->_attributes); + } + throw new \RuntimeException( + 'Private key ' . $algo->name() . ' not supported.'); + } + + /** + * Get public key info corresponding to the private key. + */ + public function publicKeyInfo(): PublicKeyInfo + { + // if public key is explicitly defined + if ($this->hasPublicKeyData()) { + return new PublicKeyInfo($this->_algo, $this->_publicKeyData); + } + // else derive from private key + return $this->privateKey()->publicKey()->publicKeyInfo(); + } + + /** + * Whether attributes are present. + */ + public function hasAttributes(): bool + { + return isset($this->_attributes); + } + + /** + * Get attributes. + * + * @throws \LogicException If attributes are not present + */ + public function attributes(): OneAsymmetricKeyAttributes + { + if (!$this->hasAttributes()) { + throw new \LogicException('Attributes not set.'); + } + return $this->_attributes; + } + + /** + * Whether explicit public key data is present. + */ + public function hasPublicKeyData(): bool + { + return isset($this->_publicKeyData); + } + + /** + * Get the explicit public key data. + * + * @return \LogicException If public key is not present + */ + public function publicKeyData(): BitString + { + if (!$this->hasPublicKeyData()) { + throw new \LogicException('No explicit public key.'); + } + return $this->_publicKeyData; + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): Sequence + { + $elements = [ + new Integer($this->_version), + $this->_algo->toASN1(), + new OctetString($this->_privateKeyData) + ]; + if ($this->_attributes) { + $elements[] = new ImplicitlyTaggedType(0, + $this->_attributes->toASN1()); + } + if ($this->_publicKeyData) { + $elements[] = new ImplicitlyTaggedType(1, $this->_publicKeyData); + } + return new Sequence(...$elements); + } + + /** + * Generate DER encoding. + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * Generate PEM. + */ + public function toPEM(): PEM + { + return new PEM(PEM::TYPE_PRIVATE_KEY, $this->toDER()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php new file mode 100644 index 0000000..c3b4bea --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php @@ -0,0 +1,74 @@ +toDER(); + } + + /** + * Get the private key as a PrivateKeyInfo type. + */ + public function privateKeyInfo(): PrivateKeyInfo + { + return PrivateKeyInfo::fromPrivateKey($this); + } + + /** + * Initialize private key from PEM. + * + * @throws \UnexpectedValueException + * + * @return PrivateKey + */ + public static function fromPEM(PEM $pem) + { + switch ($pem->type()) { + case PEM::TYPE_RSA_PRIVATE_KEY: + return RSA\RSAPrivateKey::fromDER($pem->data()); + case PEM::TYPE_EC_PRIVATE_KEY: + return EC\ECPrivateKey::fromDER($pem->data()); + case PEM::TYPE_PRIVATE_KEY: + return PrivateKeyInfo::fromDER($pem->data())->privateKey(); + } + throw new \UnexpectedValueException( + 'PEM type ' . $pem->type() . ' is not a valid private key.'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php new file mode 100644 index 0000000..f1a946e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php @@ -0,0 +1,33 @@ +_version = parent::VERSION_1; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php new file mode 100644 index 0000000..8b7e581 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php @@ -0,0 +1,60 @@ +toDER()); + } + + /** + * Get the public key as a PublicKeyInfo type. + */ + public function publicKeyInfo(): PublicKeyInfo + { + return PublicKeyInfo::fromPublicKey($this); + } + + /** + * Initialize public key from PEM. + * + * @throws \UnexpectedValueException + * + * @return PublicKey + */ + public static function fromPEM(PEM $pem) + { + switch ($pem->type()) { + case PEM::TYPE_RSA_PUBLIC_KEY: + return RSA\RSAPublicKey::fromDER($pem->data()); + case PEM::TYPE_PUBLIC_KEY: + return PublicKeyInfo::fromPEM($pem)->publicKey(); + } + throw new \UnexpectedValueException( + 'PEM type ' . $pem->type() . ' is not a valid public key.'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php new file mode 100644 index 0000000..176b57b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php @@ -0,0 +1,197 @@ +_algo = $algo; + $this->_publicKey = $key; + } + + /** + * Initialize from ASN.1. + */ + public static function fromASN1(Sequence $seq): self + { + $algo = AlgorithmIdentifier::fromASN1($seq->at(0)->asSequence()); + $key = $seq->at(1)->asBitString(); + return new self($algo, $key); + } + + /** + * Initialize from a PublicKey. + */ + public static function fromPublicKey(PublicKey $key): self + { + return new self($key->algorithmIdentifier(), $key->subjectPublicKey()); + } + + /** + * Initialize from PEM. + * + * @throws \UnexpectedValueException + */ + public static function fromPEM(PEM $pem): self + { + switch ($pem->type()) { + case PEM::TYPE_PUBLIC_KEY: + return self::fromDER($pem->data()); + case PEM::TYPE_RSA_PUBLIC_KEY: + return RSA\RSAPublicKey::fromDER($pem->data())->publicKeyInfo(); + } + throw new \UnexpectedValueException('Invalid PEM type.'); + } + + /** + * Initialize from DER data. + */ + public static function fromDER(string $data): self + { + return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); + } + + /** + * Get algorithm identifier. + */ + public function algorithmIdentifier(): AlgorithmIdentifierType + { + return $this->_algo; + } + + /** + * Get public key data. + */ + public function publicKeyData(): BitString + { + return $this->_publicKey; + } + + /** + * Get public key. + * + * @throws \RuntimeException + */ + public function publicKey(): PublicKey + { + $algo = $this->algorithmIdentifier(); + switch ($algo->oid()) { + // RSA + case AlgorithmIdentifier::OID_RSA_ENCRYPTION: + return RSA\RSAPublicKey::fromDER($this->_publicKey->string()); + // Elliptic Curve + case AlgorithmIdentifier::OID_EC_PUBLIC_KEY: + if (!$algo instanceof ECPublicKeyAlgorithmIdentifier) { + throw new \UnexpectedValueException('Not an EC algorithm.'); + } + // ECPoint is directly mapped into public key data + return new EC\ECPublicKey($this->_publicKey->string(), + $algo->namedCurve()); + // Ed25519 + case AlgorithmIdentifier::OID_ED25519: + return new RFC8410\Curve25519\Ed25519PublicKey( + $this->_publicKey->string()); + // X25519 + case AlgorithmIdentifier::OID_X25519: + return new RFC8410\Curve25519\X25519PublicKey( + $this->_publicKey->string()); + // Ed448 + case AlgorithmIdentifier::OID_ED448: + return new RFC8410\Curve448\Ed448PublicKey( + $this->_publicKey->string()); + // X448 + case AlgorithmIdentifier::OID_X448: + return new RFC8410\Curve448\X448PublicKey( + $this->_publicKey->string()); + } + throw new \RuntimeException( + 'Public key ' . $algo->name() . ' not supported.'); + } + + /** + * Get key identifier using method 1 as described by RFC 5280. + * + * @see https://tools.ietf.org/html/rfc5280#section-4.2.1.2 + * + * @return string 20 bytes (160 bits) long identifier + */ + public function keyIdentifier(): string + { + return sha1($this->_publicKey->string(), true); + } + + /** + * Get key identifier using method 2 as described by RFC 5280. + * + * @see https://tools.ietf.org/html/rfc5280#section-4.2.1.2 + * + * @return string 8 bytes (64 bits) long identifier + */ + public function keyIdentifier64(): string + { + $id = substr($this->keyIdentifier(), -8); + $c = (ord($id[0]) & 0x0f) | 0x40; + $id[0] = chr($c); + return $id; + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): Sequence + { + return new Sequence($this->_algo->toASN1(), $this->_publicKey); + } + + /** + * Generate DER encoding. + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * Generate PEM. + */ + public function toPEM(): PEM + { + return new PEM(PEM::TYPE_PUBLIC_KEY, $this->toDER()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php new file mode 100644 index 0000000..5e11fdf --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php @@ -0,0 +1,34 @@ +hasPublicKey()) { + throw new \LogicException('Public key not set.'); + } + return new Ed25519PublicKey($this->_publicKeyData); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php new file mode 100644 index 0000000..f111459 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php @@ -0,0 +1,24 @@ +hasPublicKey()) { + throw new \LogicException('Public key not set.'); + } + return new X25519PublicKey($this->_publicKeyData); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php new file mode 100644 index 0000000..b9abd45 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php @@ -0,0 +1,24 @@ +hasPublicKey()) { + throw new \LogicException('Public key not set.'); + } + return new Ed448PublicKey($this->_publicKeyData); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php new file mode 100644 index 0000000..aa499ae --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php @@ -0,0 +1,39 @@ +hasPublicKey()) { + throw new \LogicException('Public key not set.'); + } + return new X448PublicKey($this->_publicKeyData); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php new file mode 100644 index 0000000..7af5227 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php @@ -0,0 +1,39 @@ +_privateKeyData = $private_key; + $this->_publicKeyData = $public_key; + $this->_version = OneAsymmetricKey::VERSION_2; + $this->_attributes = null; + } + + /** + * Initialize from `CurvePrivateKey` OctetString. + * + * @param OctetString $str Private key data wrapped into OctetString + * @param null|string $public_key Optional public key data + */ + public static function fromOctetString(OctetString $str, + ?string $public_key = null): self + { + return new static($str->string(), $public_key); + } + + /** + * Get self with version number. + */ + public function withVersion(int $version): self + { + $obj = clone $this; + $obj->_version = $version; + return $obj; + } + + /** + * Get self with attributes. + */ + public function withAttributes(?OneAsymmetricKeyAttributes $attribs): self + { + $obj = clone $this; + $obj->_attributes = $attribs; + return $obj; + } + + /** + * {@inheritdoc} + */ + public function privateKeyData(): string + { + return $this->_privateKeyData; + } + + /** + * Whether public key is set. + */ + public function hasPublicKey(): bool + { + return isset($this->_publicKeyData); + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): OctetString + { + return new OctetString($this->_privateKeyData); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * {@inheritdoc} + */ + public function toPEM(): PEM + { + $pub = $this->_publicKeyData ? + new BitString($this->_publicKeyData) : null; + $pki = new OneAsymmetricKey($this->algorithmIdentifier(), + $this->toDER(), $this->_attributes, $pub); + return $pki->withVersion($this->_version)->toPEM(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php new file mode 100644 index 0000000..6a18542 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php @@ -0,0 +1,52 @@ +_publicKey = $public_key; + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + throw new \LogicException("RFC 8410 public key doesn't have a DER encoding."); + } + + /** + * {@inheritdoc} + */ + public function subjectPublicKey(): BitString + { + return new BitString($this->_publicKey); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php new file mode 100644 index 0000000..15bf587 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php @@ -0,0 +1,286 @@ +_modulus = strval($n); + $this->_publicExponent = strval($e); + $this->_privateExponent = strval($d); + $this->_prime1 = strval($p); + $this->_prime2 = strval($q); + $this->_exponent1 = strval($dp); + $this->_exponent2 = strval($dq); + $this->_coefficient = strval($qi); + } + + /** + * Initialize from ASN.1. + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromASN1(Sequence $seq): RSAPrivateKey + { + $version = $seq->at(0)->asInteger()->intNumber(); + if (0 !== $version) { + throw new \UnexpectedValueException('Version must be 0.'); + } + // helper function get integer from given index + $get_int = function ($idx) use ($seq) { + return $seq->at($idx)->asInteger()->number(); + }; + $n = $get_int(1); + $e = $get_int(2); + $d = $get_int(3); + $p = $get_int(4); + $q = $get_int(5); + $dp = $get_int(6); + $dq = $get_int(7); + $qi = $get_int(8); + return new self($n, $e, $d, $p, $q, $dp, $dq, $qi); + } + + /** + * Initialize from DER data. + * + * @return self + */ + public static function fromDER(string $data): RSAPrivateKey + { + return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); + } + + /** + * @see PrivateKey::fromPEM() + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromPEM(PEM $pem): RSAPrivateKey + { + $pk = parent::fromPEM($pem); + if (!($pk instanceof self)) { + throw new \UnexpectedValueException('Not an RSA private key.'); + } + return $pk; + } + + /** + * Get modulus. + * + * @return string Base 10 integer + */ + public function modulus(): string + { + return $this->_modulus; + } + + /** + * Get public exponent. + * + * @return string Base 10 integer + */ + public function publicExponent(): string + { + return $this->_publicExponent; + } + + /** + * Get private exponent. + * + * @return string Base 10 integer + */ + public function privateExponent(): string + { + return $this->_privateExponent; + } + + /** + * Get first prime factor. + * + * @return string Base 10 integer + */ + public function prime1(): string + { + return $this->_prime1; + } + + /** + * Get second prime factor. + * + * @return string Base 10 integer + */ + public function prime2(): string + { + return $this->_prime2; + } + + /** + * Get first factor exponent. + * + * @return string Base 10 integer + */ + public function exponent1(): string + { + return $this->_exponent1; + } + + /** + * Get second factor exponent. + * + * @return string Base 10 integer + */ + public function exponent2(): string + { + return $this->_exponent2; + } + + /** + * Get CRT coefficient of the second factor. + * + * @return string Base 10 integer + */ + public function coefficient(): string + { + return $this->_coefficient; + } + + /** + * {@inheritdoc} + */ + public function algorithmIdentifier(): AlgorithmIdentifierType + { + return new RSAEncryptionAlgorithmIdentifier(); + } + + /** + * {@inheritdoc} + * + * @return RSAPublicKey + */ + public function publicKey(): PublicKey + { + return new RSAPublicKey($this->_modulus, $this->_publicExponent); + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): Sequence + { + return new Sequence(new Integer(0), + new Integer($this->_modulus), + new Integer($this->_publicExponent), + new Integer($this->_privateExponent), + new Integer($this->_prime1), + new Integer($this->_prime2), + new Integer($this->_exponent1), + new Integer($this->_exponent2), + new Integer($this->_coefficient)); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * {@inheritdoc} + */ + public function toPEM(): PEM + { + return new PEM(PEM::TYPE_RSA_PRIVATE_KEY, $this->toDER()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php new file mode 100644 index 0000000..b4e55d4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php @@ -0,0 +1,147 @@ +_modulus = strval($n); + $this->_publicExponent = strval($e); + } + + /** + * Initialize from ASN.1. + * + * @return self + */ + public static function fromASN1(Sequence $seq): RSAPublicKey + { + $n = $seq->at(0)->asInteger()->number(); + $e = $seq->at(1)->asInteger()->number(); + return new self($n, $e); + } + + /** + * Initialize from DER data. + * + * @return self + */ + public static function fromDER(string $data): RSAPublicKey + { + return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); + } + + /** + * @see PublicKey::fromPEM() + * + * @throws \UnexpectedValueException + * + * @return self + */ + public static function fromPEM(PEM $pem): RSAPublicKey + { + switch ($pem->type()) { + case PEM::TYPE_RSA_PUBLIC_KEY: + return self::fromDER($pem->data()); + case PEM::TYPE_PUBLIC_KEY: + $pki = PublicKeyInfo::fromDER($pem->data()); + if (AlgorithmIdentifier::OID_RSA_ENCRYPTION !== + $pki->algorithmIdentifier()->oid()) { + throw new \UnexpectedValueException('Not an RSA public key.'); + } + return self::fromDER($pki->publicKeyData()->string()); + } + throw new \UnexpectedValueException('Invalid PEM type ' . $pem->type()); + } + + /** + * Get modulus. + * + * @return string Base 10 integer + */ + public function modulus(): string + { + return $this->_modulus; + } + + /** + * Get public exponent. + * + * @return string Base 10 integer + */ + public function publicExponent(): string + { + return $this->_publicExponent; + } + + /** + * {@inheritdoc} + */ + public function algorithmIdentifier(): AlgorithmIdentifierType + { + return new RSAEncryptionAlgorithmIdentifier(); + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): Sequence + { + return new Sequence(new Integer($this->_modulus), + new Integer($this->_publicExponent)); + } + + /** + * {@inheritdoc} + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * Generate PEM. + */ + public function toPEM(): PEM + { + return new PEM(PEM::TYPE_RSA_PUBLIC_KEY, $this->toDER()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php new file mode 100644 index 0000000..808f8e6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php @@ -0,0 +1,108 @@ +_r = strval($r); + $this->_s = strval($s); + } + + /** + * Initialize from ASN.1. + */ + public static function fromASN1(Sequence $seq): self + { + $r = $seq->at(0)->asInteger()->number(); + $s = $seq->at(1)->asInteger()->number(); + return new self($r, $s); + } + + /** + * Initialize from DER. + */ + public static function fromDER(string $data): self + { + return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); + } + + /** + * Get the r-value. + * + * @return string Base 10 integer string + */ + public function r(): string + { + return $this->_r; + } + + /** + * Get the s-value. + * + * @return string Base 10 integer string + */ + public function s(): string + { + return $this->_s; + } + + /** + * Generate ASN.1 structure. + */ + public function toASN1(): Sequence + { + return new Sequence(new Integer($this->_r), new Integer($this->_s)); + } + + /** + * Get DER encoding of the signature. + */ + public function toDER(): string + { + return $this->toASN1()->toDER(); + } + + /** + * {@inheritdoc} + */ + public function bitString(): BitString + { + return new BitString($this->toDER()); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php new file mode 100644 index 0000000..4d50108 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php @@ -0,0 +1,44 @@ +_signature = $signature; + } + + /** + * {@inheritdoc} + */ + public function bitString(): BitString + { + return new BitString($this->_signature); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php new file mode 100644 index 0000000..9090a38 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php @@ -0,0 +1,44 @@ +_signature = $signature; + } + + /** + * {@inheritdoc} + */ + public function bitString(): BitString + { + return new BitString($this->_signature); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php new file mode 100644 index 0000000..4e6635a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php @@ -0,0 +1,56 @@ +_signature = $signature; + $this->_signatureAlgorithm = $algo; + } + + /** + * Get the signature algorithm. + */ + public function signatureAlgorithm(): AlgorithmIdentifierType + { + return $this->_signatureAlgorithm; + } + + /** + * {@inheritdoc} + */ + public function bitString(): BitString + { + return $this->_signature; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php new file mode 100644 index 0000000..cf3710d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php @@ -0,0 +1,58 @@ +_signature = strval($signature); + return $obj; + } + + /** + * {@inheritdoc} + */ + public function bitString(): BitString + { + return new BitString($this->_signature); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php new file mode 100644 index 0000000..75ad8c0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php @@ -0,0 +1,49 @@ +=7.2 +- intl +- mbstring +- [sop/asn1](https://github.com/sop/asn1) + +## Installation + +This library is available on +[Packagist](https://packagist.org/packages/sop/x501). + + composer require sop/x501 + +## License + +This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/composer.json b/utilities/signing_and_verification/php/vendor/sop/x501/composer.json new file mode 100644 index 0000000..0901490 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/composer.json @@ -0,0 +1,38 @@ +{ + "name": "sop/x501", + "description": "A PHP library for X.501 ASN.1 types, X.520 attributes and DN parsing.", + "homepage": "https://github.com/sop/x501", + "license": "MIT", + "type": "library", + "keywords": [ + "x501", + "x.501", + "x520", + "x.520", + "ldap", + "dn", + "rdn", + "attribute" + ], + "authors": [ + { + "name": "Joni Eskelinen", + "email": "jonieske@gmail.com", + "role": "Developer" + } + ], + "require": { + "php": ">=7.2", + "ext-intl": "*", + "ext-mbstring": "*", + "sop/asn1": "^4.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.1" + }, + "autoload": { + "psr-4": { + "Sop\\X501\\": "lib/X501/" + } + } +} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php new file mode 100644 index 0000000..9b3c08a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php @@ -0,0 +1,176 @@ +oid() !== $type->oid()) { + throw new \LogicException('Attribute OID mismatch.'); + } + } + $this->_type = $type; + $this->_values = $values; + } + + /** + * Initialize from ASN.1. + * + * @param Sequence $seq + * + * @return self + */ + public static function fromASN1(Sequence $seq): self + { + $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier()); + $values = array_map( + function (UnspecifiedType $el) use ($type) { + return AttributeValue::fromASN1ByOID($type->oid(), $el); + }, $seq->at(1)->asSet()->elements()); + return new self($type, ...$values); + } + + /** + * Convenience method to initialize from attribute values. + * + * @param AttributeValue ...$values One or more values + * + * @throws \LogicException + * + * @return self + */ + public static function fromAttributeValues(AttributeValue ...$values): self + { + // we need at least one value to determine OID + if (!count($values)) { + throw new \LogicException('No values.'); + } + $oid = reset($values)->oid(); + return new self(new AttributeType($oid), ...$values); + } + + /** + * Get first value of the attribute. + * + * @throws \LogicException + * + * @return AttributeValue + */ + public function first(): AttributeValue + { + if (!count($this->_values)) { + throw new \LogicException('Attribute contains no values.'); + } + return $this->_values[0]; + } + + /** + * Get all values. + * + * @return AttributeValue[] + */ + public function values(): array + { + return $this->_values; + } + + /** + * Generate ASN.1 structure. + * + * @return Sequence + */ + public function toASN1(): Sequence + { + $values = array_map( + function (AttributeValue $value) { + return $value->toASN1(); + }, $this->_values); + $valueset = new Set(...$values); + return new Sequence($this->_type->toASN1(), $valueset->sortedSetOf()); + } + + /** + * Cast attribute values to another AttributeValue class. + * + * This method is generally used to cast UnknownAttributeValue values + * to specific objects when class is declared outside this package. + * + * The new class must be derived from AttributeValue and have the same OID + * as current attribute values. + * + * @param string $cls AttributeValue class name + * + * @throws \LogicException + * + * @return self + */ + public function castValues(string $cls): self + { + // check that target class derives from AttributeValue + if (!is_subclass_of($cls, AttributeValue::class)) { + throw new \LogicException(sprintf( + '%s must be derived from %s.', $cls, AttributeValue::class)); + } + $values = array_map( + function (AttributeValue $value) use ($cls) { + /** @var AttributeValue $cls Class name as a string */ + $value = $cls::fromSelf($value); + if ($value->oid() !== $this->oid()) { + throw new \LogicException('Attribute OID mismatch.'); + } + return $value; + }, $this->_values); + return self::fromAttributeValues(...$values); + } + + /** + * @see \Countable::count() + * + * @return int + */ + public function count(): int + { + return count($this->_values); + } + + /** + * @see \IteratorAggregate::getIterator() + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->_values); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php new file mode 100644 index 0000000..c9c58d4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php @@ -0,0 +1,457 @@ + Element::TYPE_PRINTABLE_STRING, + self::OID_COUNTRY_NAME => Element::TYPE_PRINTABLE_STRING, + self::OID_SERIAL_NUMBER => Element::TYPE_PRINTABLE_STRING, + ]; + + /** + * OID to attribute names mapping. + * + * First name is the primary name. If there's more than one name, others may + * be used as an alias. + * + * Generated using ldap-attribs.py. + * + * @internal + * + * @var array + */ + const MAP_OID_TO_NAME = [ + '0.9.2342.19200300.100.1.1' => ['uid', 'userid'], + '0.9.2342.19200300.100.1.2' => ['textEncodedORAddress'], + '0.9.2342.19200300.100.1.3' => ['mail', 'rfc822Mailbox'], + '0.9.2342.19200300.100.1.4' => ['info'], + '0.9.2342.19200300.100.1.5' => ['drink', 'favouriteDrink'], + '0.9.2342.19200300.100.1.6' => ['roomNumber'], + '0.9.2342.19200300.100.1.7' => ['photo'], + '0.9.2342.19200300.100.1.8' => ['userClass'], + '0.9.2342.19200300.100.1.9' => ['host'], + '0.9.2342.19200300.100.1.10' => ['manager'], + '0.9.2342.19200300.100.1.11' => ['documentIdentifier'], + '0.9.2342.19200300.100.1.12' => ['documentTitle'], + '0.9.2342.19200300.100.1.13' => ['documentVersion'], + '0.9.2342.19200300.100.1.14' => ['documentAuthor'], + '0.9.2342.19200300.100.1.15' => ['documentLocation'], + '0.9.2342.19200300.100.1.20' => ['homePhone', 'homeTelephoneNumber'], + '0.9.2342.19200300.100.1.21' => ['secretary'], + '0.9.2342.19200300.100.1.22' => ['otherMailbox'], + '0.9.2342.19200300.100.1.25' => ['dc', 'domainComponent'], + '0.9.2342.19200300.100.1.26' => ['aRecord'], + '0.9.2342.19200300.100.1.27' => ['mDRecord'], + '0.9.2342.19200300.100.1.28' => ['mXRecord'], + '0.9.2342.19200300.100.1.29' => ['nSRecord'], + '0.9.2342.19200300.100.1.30' => ['sOARecord'], + '0.9.2342.19200300.100.1.31' => ['cNAMERecord'], + '0.9.2342.19200300.100.1.37' => ['associatedDomain'], + '0.9.2342.19200300.100.1.38' => ['associatedName'], + '0.9.2342.19200300.100.1.39' => ['homePostalAddress'], + '0.9.2342.19200300.100.1.40' => ['personalTitle'], + '0.9.2342.19200300.100.1.41' => ['mobile', 'mobileTelephoneNumber'], + '0.9.2342.19200300.100.1.42' => ['pager', 'pagerTelephoneNumber'], + '0.9.2342.19200300.100.1.43' => ['co', 'friendlyCountryName'], + '0.9.2342.19200300.100.1.44' => ['uniqueIdentifier'], + '0.9.2342.19200300.100.1.45' => ['organizationalStatus'], + '0.9.2342.19200300.100.1.46' => ['janetMailbox'], + '0.9.2342.19200300.100.1.47' => ['mailPreferenceOption'], + '0.9.2342.19200300.100.1.48' => ['buildingName'], + '0.9.2342.19200300.100.1.49' => ['dSAQuality'], + '0.9.2342.19200300.100.1.50' => ['singleLevelQuality'], + '0.9.2342.19200300.100.1.51' => ['subtreeMinimumQuality'], + '0.9.2342.19200300.100.1.52' => ['subtreeMaximumQuality'], + '0.9.2342.19200300.100.1.53' => ['personalSignature'], + '0.9.2342.19200300.100.1.54' => ['dITRedirect'], + '0.9.2342.19200300.100.1.55' => ['audio'], + '0.9.2342.19200300.100.1.56' => ['documentPublisher'], + '0.9.2342.19200300.100.1.60' => ['jpegPhoto'], + '1.2.840.113549.1.9.1' => ['email', 'emailAddress', 'pkcs9email'], + '1.2.840.113556.1.2.102' => ['memberOf'], + '1.3.6.1.1.1.1.0' => ['uidNumber'], + '1.3.6.1.1.1.1.1' => ['gidNumber'], + '1.3.6.1.1.1.1.2' => ['gecos'], + '1.3.6.1.1.1.1.3' => ['homeDirectory'], + '1.3.6.1.1.1.1.4' => ['loginShell'], + '1.3.6.1.1.1.1.5' => ['shadowLastChange'], + '1.3.6.1.1.1.1.6' => ['shadowMin'], + '1.3.6.1.1.1.1.7' => ['shadowMax'], + '1.3.6.1.1.1.1.8' => ['shadowWarning'], + '1.3.6.1.1.1.1.9' => ['shadowInactive'], + '1.3.6.1.1.1.1.10' => ['shadowExpire'], + '1.3.6.1.1.1.1.11' => ['shadowFlag'], + '1.3.6.1.1.1.1.12' => ['memberUid'], + '1.3.6.1.1.1.1.13' => ['memberNisNetgroup'], + '1.3.6.1.1.1.1.14' => ['nisNetgroupTriple'], + '1.3.6.1.1.1.1.15' => ['ipServicePort'], + '1.3.6.1.1.1.1.16' => ['ipServiceProtocol'], + '1.3.6.1.1.1.1.17' => ['ipProtocolNumber'], + '1.3.6.1.1.1.1.18' => ['oncRpcNumber'], + '1.3.6.1.1.1.1.19' => ['ipHostNumber'], + '1.3.6.1.1.1.1.20' => ['ipNetworkNumber'], + '1.3.6.1.1.1.1.21' => ['ipNetmaskNumber'], + '1.3.6.1.1.1.1.22' => ['macAddress'], + '1.3.6.1.1.1.1.23' => ['bootParameter'], + '1.3.6.1.1.1.1.24' => ['bootFile'], + '1.3.6.1.1.1.1.26' => ['nisMapName'], + '1.3.6.1.1.1.1.27' => ['nisMapEntry'], + '1.3.6.1.1.4' => ['vendorName'], + '1.3.6.1.1.5' => ['vendorVersion'], + '1.3.6.1.1.16.4' => ['entryUUID'], + '1.3.6.1.1.20' => ['entryDN'], + '2.5.4.0' => ['objectClass'], + '2.5.4.1' => ['aliasedObjectName', 'aliasedEntryName'], + '2.5.4.2' => ['knowledgeInformation'], + '2.5.4.3' => ['cn', 'commonName'], + '2.5.4.4' => ['sn', 'surname'], + '2.5.4.5' => ['serialNumber'], + '2.5.4.6' => ['c', 'countryName'], + '2.5.4.7' => ['l', 'localityName'], + '2.5.4.8' => ['st', 'stateOrProvinceName'], + '2.5.4.9' => ['street', 'streetAddress'], + '2.5.4.10' => ['o', 'organizationName'], + '2.5.4.11' => ['ou', 'organizationalUnitName'], + '2.5.4.12' => ['title'], + '2.5.4.13' => ['description'], + '2.5.4.14' => ['searchGuide'], + '2.5.4.15' => ['businessCategory'], + '2.5.4.16' => ['postalAddress'], + '2.5.4.17' => ['postalCode'], + '2.5.4.18' => ['postOfficeBox'], + '2.5.4.19' => ['physicalDeliveryOfficeName'], + '2.5.4.20' => ['telephoneNumber'], + '2.5.4.21' => ['telexNumber'], + '2.5.4.22' => ['teletexTerminalIdentifier'], + '2.5.4.23' => ['facsimileTelephoneNumber', 'fax'], + '2.5.4.24' => ['x121Address'], + '2.5.4.25' => ['internationaliSDNNumber'], + '2.5.4.26' => ['registeredAddress'], + '2.5.4.27' => ['destinationIndicator'], + '2.5.4.28' => ['preferredDeliveryMethod'], + '2.5.4.29' => ['presentationAddress'], + '2.5.4.30' => ['supportedApplicationContext'], + '2.5.4.31' => ['member'], + '2.5.4.32' => ['owner'], + '2.5.4.33' => ['roleOccupant'], + '2.5.4.34' => ['seeAlso'], + '2.5.4.35' => ['userPassword'], + '2.5.4.36' => ['userCertificate'], + '2.5.4.37' => ['cACertificate'], + '2.5.4.38' => ['authorityRevocationList'], + '2.5.4.39' => ['certificateRevocationList'], + '2.5.4.40' => ['crossCertificatePair'], + '2.5.4.41' => ['name'], + '2.5.4.42' => ['givenName', 'gn'], + '2.5.4.43' => ['initials'], + '2.5.4.44' => ['generationQualifier'], + '2.5.4.45' => ['x500UniqueIdentifier'], + '2.5.4.46' => ['dnQualifier'], + '2.5.4.47' => ['enhancedSearchGuide'], + '2.5.4.48' => ['protocolInformation'], + '2.5.4.49' => ['distinguishedName'], + '2.5.4.50' => ['uniqueMember'], + '2.5.4.51' => ['houseIdentifier'], + '2.5.4.52' => ['supportedAlgorithms'], + '2.5.4.53' => ['deltaRevocationList'], + '2.5.4.54' => ['dmdName'], + '2.5.4.65' => ['pseudonym'], + '2.5.18.1' => ['createTimestamp'], + '2.5.18.2' => ['modifyTimestamp'], + '2.5.18.3' => ['creatorsName'], + '2.5.18.4' => ['modifiersName'], + '2.5.18.5' => ['administrativeRole'], + '2.5.18.6' => ['subtreeSpecification'], + '2.5.18.9' => ['hasSubordinates'], + '2.5.18.10' => ['subschemaSubentry'], + '2.5.21.1' => ['dITStructureRules'], + '2.5.21.2' => ['dITContentRules'], + '2.5.21.4' => ['matchingRules'], + '2.5.21.5' => ['attributeTypes'], + '2.5.21.6' => ['objectClasses'], + '2.5.21.7' => ['nameForms'], + '2.5.21.8' => ['matchingRuleUse'], + '2.5.21.9' => ['structuralObjectClass'], + '2.16.840.1.113730.3.1.1' => ['carLicense'], + '2.16.840.1.113730.3.1.2' => ['departmentNumber'], + '2.16.840.1.113730.3.1.3' => ['employeeNumber'], + '2.16.840.1.113730.3.1.4' => ['employeeType'], + '2.16.840.1.113730.3.1.34' => ['ref'], + '2.16.840.1.113730.3.1.39' => ['preferredLanguage'], + '2.16.840.1.113730.3.1.40' => ['userSMIMECertificate'], + '2.16.840.1.113730.3.1.216' => ['userPKCS12'], + '2.16.840.1.113730.3.1.241' => ['displayName'], + ]; + + /** + * OID of the attribute. + * + * @var string + */ + protected $_oid; + + /** + * Constructor. + * + * @param string $oid OID in dotted format + */ + public function __construct(string $oid) + { + $this->_oid = $oid; + } + + /** + * Initialize from ASN.1. + * + * @param ObjectIdentifier $oi + * + * @return self + */ + public static function fromASN1(ObjectIdentifier $oi): self + { + return new self($oi->oid()); + } + + /** + * Initialize from attribute name. + * + * @param string $name + * + * @return self + */ + public static function fromName(string $name): self + { + $oid = self::attrNameToOID($name); + return new self($oid); + } + + /** + * Get OID of the attribute. + * + * @return string OID in dotted format + */ + public function oid(): string + { + return $this->_oid; + } + + /** + * Get name of the attribute. + * + * @return string + */ + public function typeName(): string + { + if (array_key_exists($this->_oid, self::MAP_OID_TO_NAME)) { + return self::MAP_OID_TO_NAME[$this->_oid][0]; + } + return $this->_oid; + } + + /** + * Generate ASN.1 element. + * + * @return ObjectIdentifier + */ + public function toASN1(): ObjectIdentifier + { + return new ObjectIdentifier($this->_oid); + } + + /** + * Convert attribute name to OID. + * + * @param string $name Primary attribute name or an alias + * + * @throws \OutOfBoundsException + * + * @return string OID in dotted format + */ + public static function attrNameToOID(string $name): string + { + // if already in OID form + if (preg_match('/^[0-9]+(?:\.[0-9]+)*$/', $name)) { + return $name; + } + $map = self::_oidReverseMap(); + $k = strtolower($name); + if (!isset($map[$k])) { + throw new \OutOfBoundsException("No OID for {$name}."); + } + return $map[$k]; + } + + /** + * Get ASN.1 string for given attribute type. + * + * @param string $oid Attribute OID + * @param string $str String + * + * @throws \LogicException + * + * @return StringType + */ + public static function asn1StringForType(string $oid, string $str): StringType + { + if (!array_key_exists($oid, self::MAP_ATTR_TO_STR_TYPE)) { + return new UTF8String($str); + } + switch (self::MAP_ATTR_TO_STR_TYPE[$oid]) { + case Element::TYPE_PRINTABLE_STRING: + return new PrintableString($str); + // @codeCoverageIgnoreStart + default: + // only reachable during development + throw new \LogicException(); + } + // @codeCoverageIgnoreEnd + } + + /** + * Get name to OID lookup map. + * + * @return array + */ + private static function _oidReverseMap(): array + { + static $map; + if (!isset($map)) { + $map = []; + // for each attribute type + foreach (self::MAP_OID_TO_NAME as $oid => $names) { + // for primary name and aliases + foreach ($names as $name) { + $map[strtolower($name)] = $oid; + } + } + } + return $map; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php new file mode 100644 index 0000000..6806d4a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php @@ -0,0 +1,128 @@ +_type = $type; + $this->_value = $value; + } + + /** + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Initialize from ASN.1. + * + * @param Sequence $seq + * + * @return self + */ + public static function fromASN1(Sequence $seq): self + { + $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier()); + $value = AttributeValue::fromASN1ByOID($type->oid(), $seq->at(1)); + return new self($type, $value); + } + + /** + * Convenience method to initialize from attribute value. + * + * @param AttributeValue $value Attribute value + * + * @return self + */ + public static function fromAttributeValue(AttributeValue $value): self + { + return new self(new AttributeType($value->oid()), $value); + } + + /** + * Get attribute value. + * + * @return AttributeValue + */ + public function value(): AttributeValue + { + return $this->_value; + } + + /** + * Generate ASN.1 structure. + * + * @return Sequence + */ + public function toASN1(): Sequence + { + return new Sequence($this->_type->toASN1(), $this->_value->toASN1()); + } + + /** + * Get attributeTypeAndValue string conforming to RFC 2253. + * + * @see https://tools.ietf.org/html/rfc2253#section-2.3 + * + * @return string + */ + public function toString(): string + { + return $this->_type->typeName() . '=' . $this->_value->rfc2253String(); + } + + /** + * Check whether attribute is semantically equal to other. + * + * @param AttributeTypeAndValue $other Object to compare to + * + * @return bool + */ + public function equals(AttributeTypeAndValue $other): bool + { + // check that attribute types match + if ($this->oid() !== $other->oid()) { + return false; + } + $matcher = $this->_value->equalityMatchingRule(); + $result = $matcher->compare($this->_value->stringValue(), + $other->_value->stringValue()); + // match + if ($result) { + return true; + } + // no match or Undefined + return false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php new file mode 100644 index 0000000..89f061d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php @@ -0,0 +1,174 @@ + CommonNameValue::class, + AttributeType::OID_SURNAME => SurnameValue::class, + AttributeType::OID_SERIAL_NUMBER => SerialNumberValue::class, + AttributeType::OID_COUNTRY_NAME => CountryNameValue::class, + AttributeType::OID_LOCALITY_NAME => LocalityNameValue::class, + AttributeType::OID_STATE_OR_PROVINCE_NAME => StateOrProvinceNameValue::class, + AttributeType::OID_ORGANIZATION_NAME => OrganizationNameValue::class, + AttributeType::OID_ORGANIZATIONAL_UNIT_NAME => OrganizationalUnitNameValue::class, + AttributeType::OID_TITLE => TitleValue::class, + AttributeType::OID_DESCRIPTION => DescriptionValue::class, + AttributeType::OID_NAME => NameValue::class, + AttributeType::OID_GIVEN_NAME => GivenNameValue::class, + AttributeType::OID_PSEUDONYM => PseudonymValue::class, + ]; + + /** + * OID of the attribute type. + * + * @var string + */ + protected $_oid; + + /** + * Get attribute value as an UTF-8 encoded string. + * + * @return string + */ + public function __toString() + { + return $this->_transcodedString(); + } + + /** + * Generate ASN.1 element. + * + * @return Element + */ + abstract public function toASN1(): Element; + + /** + * Get attribute value as a string. + * + * @return string + */ + abstract public function stringValue(): string; + + /** + * Get matching rule for equality comparison. + * + * @return MatchingRule + */ + abstract public function equalityMatchingRule(): MatchingRule; + + /** + * Get attribute value as a string conforming to RFC 2253. + * + * @see https://tools.ietf.org/html/rfc2253#section-2.4 + * + * @return string + */ + abstract public function rfc2253String(): string; + + /** + * Initialize from ASN.1. + * + * @param UnspecifiedType $el + * + * @return self + */ + public static function fromASN1(UnspecifiedType $el): AttributeValue + { + throw new \BadMethodCallException( + 'ASN.1 parsing must be implemented in a concrete class.'); + } + + /** + * Initialize from ASN.1 with given OID hint. + * + * @param string $oid Attribute's OID + * @param UnspecifiedType $el + * + * @return self + */ + public static function fromASN1ByOID(string $oid, UnspecifiedType $el): self + { + if (!array_key_exists($oid, self::MAP_OID_TO_CLASS)) { + return new UnknownAttributeValue($oid, $el->asElement()); + } + $cls = self::MAP_OID_TO_CLASS[$oid]; + return $cls::fromASN1($el); + } + + /** + * Initialize from another AttributeValue. + * + * This method is generally used to cast UnknownAttributeValue to + * specific object when class is declared outside this package. + * + * @param self $obj Instance of AttributeValue + * + * @return self + */ + public static function fromSelf(self $obj): self + { + return static::fromASN1($obj->toASN1()->asUnspecified()); + } + + /** + * Get attribute type's OID. + * + * @return string + */ + public function oid(): string + { + return $this->_oid; + } + + /** + * Get Attribute object with this as a single value. + * + * @return Attribute + */ + public function toAttribute(): Attribute + { + return Attribute::fromAttributeValues($this); + } + + /** + * Get AttributeTypeAndValue object with this as a value. + * + * @return AttributeTypeAndValue + */ + public function toAttributeTypeAndValue(): AttributeTypeAndValue + { + return AttributeTypeAndValue::fromAttributeValue($this); + } + + /** + * Get attribute value as an UTF-8 string conforming to RFC 4518. + * + * @see https://tools.ietf.org/html/rfc4518#section-2.1 + * + * @return string + */ + abstract protected function _transcodedString(): string; +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php new file mode 100644 index 0000000..924aa52 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_COMMON_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php new file mode 100644 index 0000000..4d4f3b1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php @@ -0,0 +1,27 @@ +_oid = AttributeType::OID_COUNTRY_NAME; + parent::__construct($value); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php new file mode 100644 index 0000000..025b19e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_DESCRIPTION; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php new file mode 100644 index 0000000..1d26453 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php @@ -0,0 +1,179 @@ + T61String::class, + self::PRINTABLE => PrintableString::class, + self::UNIVERSAL => UniversalString::class, + self::UTF8 => UTF8String::class, + self::BMP => BMPString::class, + ]; + + /** + * ASN.1 type tag for the chosen syntax. + * + * @var int + */ + protected $_stringTag; + + /** + * String value. + * + * @var string + */ + protected $_string; + + /** + * Constructor. + * + * @param string $value String value + * @param int $string_tag Syntax choice + */ + public function __construct(string $value, int $string_tag) + { + $this->_string = $value; + $this->_stringTag = $string_tag; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1(UnspecifiedType $el): AttributeValue + { + $tag = $el->tag(); + self::_tagToASN1Class($tag); + return new static($el->asString()->string(), $tag); + } + + /** + * {@inheritdoc} + */ + public function toASN1(): Element + { + $cls = self::_tagToASN1Class($this->_stringTag); + return new $cls($this->_string); + } + + /** + * {@inheritdoc} + */ + public function stringValue(): string + { + return $this->_string; + } + + /** + * {@inheritdoc} + */ + public function equalityMatchingRule(): MatchingRule + { + return new CaseIgnoreMatch($this->_stringTag); + } + + /** + * {@inheritdoc} + */ + public function rfc2253String(): string + { + // TeletexString is encoded as binary + if (self::TELETEX === $this->_stringTag) { + return $this->_transcodedString(); + } + return DNParser::escapeString($this->_transcodedString()); + } + + /** + * {@inheritdoc} + */ + protected function _transcodedString(): string + { + $step = new TranscodeStep($this->_stringTag); + return $step->apply($this->_string); + } + + /** + * Get ASN.1 class name for given DirectoryString type tag. + * + * @param int $tag + * + * @throws \UnexpectedValueException + * + * @return string + */ + private static function _tagToASN1Class(int $tag): string + { + if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) { + throw new \UnexpectedValueException( + 'Type ' . Element::tagToName($tag) . + ' is not valid DirectoryString.'); + } + return self::MAP_TAG_TO_CLASS[$tag]; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php new file mode 100644 index 0000000..f9c3e69 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php @@ -0,0 +1,88 @@ +_string = $value; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1(UnspecifiedType $el): AttributeValue + { + return new static($el->asPrintableString()->string()); + } + + /** + * {@inheritdoc} + */ + public function toASN1(): Element + { + return new PrintableString($this->_string); + } + + /** + * {@inheritdoc} + */ + public function stringValue(): string + { + return $this->_string; + } + + /** + * {@inheritdoc} + */ + public function equalityMatchingRule(): MatchingRule + { + // default to caseIgnoreMatch + return new CaseIgnoreMatch(Element::TYPE_PRINTABLE_STRING); + } + + /** + * {@inheritdoc} + */ + public function rfc2253String(): string + { + return DNParser::escapeString($this->_transcodedString()); + } + + /** + * {@inheritdoc} + */ + protected function _transcodedString(): string + { + // PrintableString maps directly to UTF-8 + return $this->_string; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php new file mode 100644 index 0000000..593f3b6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_GIVEN_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php new file mode 100644 index 0000000..a316b7c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_LOCALITY_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php new file mode 100644 index 0000000..de6792d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php new file mode 100644 index 0000000..71fd859 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_ORGANIZATION_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php new file mode 100644 index 0000000..a8743d5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_ORGANIZATIONAL_UNIT_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php new file mode 100644 index 0000000..674befb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_PSEUDONYM; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php new file mode 100644 index 0000000..8ff3d65 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php @@ -0,0 +1,27 @@ +_oid = AttributeType::OID_SERIAL_NUMBER; + parent::__construct($value); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php new file mode 100644 index 0000000..7759013 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_STATE_OR_PROVINCE_NAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php new file mode 100644 index 0000000..17b3eac --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_SURNAME; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php new file mode 100644 index 0000000..9467035 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php @@ -0,0 +1,29 @@ +_oid = AttributeType::OID_TITLE; + parent::__construct($value, $string_tag); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php new file mode 100644 index 0000000..c8d0e49 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php @@ -0,0 +1,75 @@ +_oid = $oid; + $this->_element = $el; + } + + /** + * {@inheritdoc} + */ + public function toASN1(): Element + { + return $this->_element; + } + + /** + * {@inheritdoc} + */ + public function stringValue(): string + { + // return DER encoding as a hexstring + return '#' . bin2hex($this->_element->toDER()); + } + + /** + * {@inheritdoc} + */ + public function equalityMatchingRule(): MatchingRule + { + return new BinaryMatch(); + } + + /** + * {@inheritdoc} + */ + public function rfc2253String(): string + { + return $this->stringValue(); + } + + /** + * {@inheritdoc} + */ + protected function _transcodedString(): string + { + return $this->stringValue(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php new file mode 100644 index 0000000..14114e6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php @@ -0,0 +1,221 @@ +_attributes = $attribs; + } + + /** + * Initialize from attribute values. + * + * @param AttributeValue ...$values List of attribute values + * + * @return static + */ + public static function fromAttributeValues(AttributeValue ...$values): self + { + return new static(...array_map( + function (AttributeValue $value) { + return $value->toAttribute(); + }, $values)); + } + + /** + * Check whether attribute is present. + * + * @param string $name OID or attribute name + * + * @return bool + */ + public function has(string $name): bool + { + return null !== $this->_findFirst($name); + } + + /** + * Get first attribute by OID or attribute name. + * + * @param string $name OID or attribute name + * + * @throws \UnexpectedValueException if attribute is not present + * + * @return Attribute + */ + public function firstOf(string $name): Attribute + { + $attr = $this->_findFirst($name); + if (!$attr) { + throw new \UnexpectedValueException("No {$name} attribute."); + } + return $attr; + } + + /** + * Get all attributes of given name. + * + * @param string $name OID or attribute name + * + * @return Attribute[] + */ + public function allOf(string $name): array + { + $oid = AttributeType::attrNameToOID($name); + return array_values( + array_filter($this->_attributes, + function (Attribute $attr) use ($oid) { + return $attr->oid() === $oid; + })); + } + + /** + * Get all attributes. + * + * @return Attribute[] + */ + public function all(): array + { + return $this->_attributes; + } + + /** + * Get self with additional attributes added. + * + * @param Attribute ...$attribs List of attributes to add + * + * @return self + */ + public function withAdditional(Attribute ...$attribs): self + { + $obj = clone $this; + foreach ($attribs as $attr) { + $obj->_attributes[] = $attr; + } + return $obj; + } + + /** + * Get self with single unique attribute added. + * + * All previous attributes of the same type are removed. + * + * @param Attribute $attr Attribute to add + * + * @return self + */ + public function withUnique(Attribute $attr): self + { + $attribs = array_values( + array_filter($this->_attributes, + function (Attribute $a) use ($attr) { + return $a->oid() !== $attr->oid(); + })); + $attribs[] = $attr; + $obj = clone $this; + $obj->_attributes = $attribs; + return $obj; + } + + /** + * Get number of attributes. + * + * @see \Countable::count() + * + * @return int + */ + public function count(): int + { + return count($this->_attributes); + } + + /** + * Get iterator for attributes. + * + * @see \IteratorAggregate::getIterator() + * + * @return \ArrayIterator|Attribute[] + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->_attributes); + } + + /** + * Find first attribute of given name or OID. + * + * @param string $name OID or attribute name + * + * @return null|Attribute + */ + protected function _findFirst(string $name): ?Attribute + { + $oid = AttributeType::attrNameToOID($name); + foreach ($this->_attributes as $attr) { + if ($attr->oid() === $oid) { + return $attr; + } + } + return null; + } + + /** + * Initialize from ASN.1 constructed element. + * + * @param Structure $struct ASN.1 structure + * + * @return static + */ + protected static function _fromASN1Structure(Structure $struct): self + { + return new static(...array_map( + function (UnspecifiedType $el) { + return static::_castAttributeValues( + Attribute::fromASN1($el->asSequence())); + }, $struct->elements())); + } + + /** + * Cast Attribute's AttributeValues to implementation specific objects. + * + * Overridden in derived classes. + * + * @param Attribute $attribute Attribute to cast + * + * @return Attribute + */ + protected static function _castAttributeValues(Attribute $attribute): Attribute + { + // pass through by default + return $attribute; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php new file mode 100644 index 0000000..9da1419 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php @@ -0,0 +1,44 @@ +toASN1(); + }, $this->_attributes)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php new file mode 100644 index 0000000..e38506c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php @@ -0,0 +1,45 @@ +toASN1(); + }, $this->_attributes)); + return $set->sortedSetOf(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php new file mode 100644 index 0000000..36c020d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php @@ -0,0 +1,40 @@ +_type; + } + + /** + * Get OID of the attribute. + * + * @return string + */ + public function oid(): string + { + return $this->_type->oid(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php new file mode 100644 index 0000000..f527c2a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php @@ -0,0 +1,227 @@ +_rdns = $rdns; + } + + /** + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Initialize from ASN.1. + * + * @param Sequence $seq + * + * @return self + */ + public static function fromASN1(Sequence $seq): self + { + $rdns = array_map( + function (UnspecifiedType $el) { + return RDN::fromASN1($el->asSet()); + }, $seq->elements()); + return new self(...$rdns); + } + + /** + * Initialize from distinguished name string. + * + * @see https://tools.ietf.org/html/rfc1779 + * + * @param string $str + * + * @return self + */ + public static function fromString(string $str): self + { + $rdns = []; + foreach (DNParser::parseString($str) as $nameComponent) { + $attribs = []; + foreach ($nameComponent as [$name, $val]) { + $type = AttributeType::fromName($name); + // hexstrings are parsed to ASN.1 elements + if ($val instanceof Element) { + $el = $val; + } else { + $el = AttributeType::asn1StringForType($type->oid(), $val); + } + $value = AttributeValue::fromASN1ByOID($type->oid(), + $el->asUnspecified()); + $attribs[] = new AttributeTypeAndValue($type, $value); + } + $rdns[] = new RDN(...$attribs); + } + return new self(...$rdns); + } + + /** + * Generate ASN.1 structure. + * + * @return Sequence + */ + public function toASN1(): Sequence + { + $elements = array_map( + function (RDN $rdn) { + return $rdn->toASN1(); + }, $this->_rdns); + return new Sequence(...$elements); + } + + /** + * Get distinguised name string conforming to RFC 2253. + * + * @see https://tools.ietf.org/html/rfc2253#section-2.1 + * + * @return string + */ + public function toString(): string + { + $parts = array_map( + function (RDN $rdn) { + return $rdn->toString(); + }, array_reverse($this->_rdns)); + return implode(',', $parts); + } + + /** + * Whether name is semantically equal to other. + * + * Comparison conforms to RFC 4518 string preparation algorithm. + * + * @see https://tools.ietf.org/html/rfc4518 + * + * @param Name $other Object to compare to + * + * @return bool + */ + public function equals(Name $other): bool + { + // if RDN count doesn't match + if (count($this) !== count($other)) { + return false; + } + for ($i = count($this) - 1; $i >= 0; --$i) { + $rdn1 = $this->_rdns[$i]; + $rdn2 = $other->_rdns[$i]; + if (!$rdn1->equals($rdn2)) { + return false; + } + } + return true; + } + + /** + * Get all RDN objects. + * + * @return RDN[] + */ + public function all(): array + { + return $this->_rdns; + } + + /** + * Get the first AttributeValue of given type. + * + * Relative name components shall be traversed in encoding order, which is + * reversed in regards to the string representation. + * Multi-valued RDN with multiple attributes of the requested type is + * ambiguous and shall throw an exception. + * + * @param string $name Attribute OID or name + * + * @throws \RuntimeException If attribute cannot be resolved + * + * @return AttributeValue + */ + public function firstValueOf(string $name): AttributeValue + { + $oid = AttributeType::attrNameToOID($name); + foreach ($this->_rdns as $rdn) { + $tvs = $rdn->allOf($oid); + if (count($tvs) > 1) { + throw new \RangeException("RDN with multiple {$name} attributes."); + } + if (1 === count($tvs)) { + return $tvs[0]->value(); + } + } + throw new \RangeException("Attribute {$name} not found."); + } + + /** + * @see \Countable::count() + * + * @return int + */ + public function count(): int + { + return count($this->_rdns); + } + + /** + * Get the number of attributes of given type. + * + * @param string $name Attribute OID or name + * + * @return int + */ + public function countOfType(string $name): int + { + $oid = AttributeType::attrNameToOID($name); + return (int) array_sum( + array_map( + function (RDN $rdn) use ($oid): int { + return count($rdn->allOf($oid)); + }, $this->_rdns)); + } + + /** + * @see \IteratorAggregate::getIterator() + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->_rdns); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php new file mode 100644 index 0000000..2a8b099 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php @@ -0,0 +1,187 @@ +_attribs = $attribs; + } + + /** + * @return string + */ + public function __toString() + { + return $this->toString(); + } + + /** + * Convenience method to initialize RDN from AttributeValue objects. + * + * @param AttributeValue ...$values One or more attributes + * + * @return self + */ + public static function fromAttributeValues(AttributeValue ...$values): self + { + $attribs = array_map( + function (AttributeValue $value) { + return new AttributeTypeAndValue( + new AttributeType($value->oid()), $value); + }, $values); + return new self(...$attribs); + } + + /** + * Initialize from ASN.1. + * + * @param Set $set + * + * @return self + */ + public static function fromASN1(Set $set): self + { + $attribs = array_map( + function (UnspecifiedType $el) { + return AttributeTypeAndValue::fromASN1($el->asSequence()); + }, $set->elements()); + return new self(...$attribs); + } + + /** + * Generate ASN.1 structure. + * + * @return Set + */ + public function toASN1(): Set + { + $elements = array_map( + function (AttributeTypeAndValue $tv) { + return $tv->toASN1(); + }, $this->_attribs); + $set = new Set(...$elements); + return $set->sortedSetOf(); + } + + /** + * Get name-component string conforming to RFC 2253. + * + * @see https://tools.ietf.org/html/rfc2253#section-2.2 + * + * @return string + */ + public function toString(): string + { + $parts = array_map( + function (AttributeTypeAndValue $tv) { + return $tv->toString(); + }, $this->_attribs); + return implode('+', $parts); + } + + /** + * Check whether RDN is semantically equal to other. + * + * @param RDN $other Object to compare to + * + * @return bool + */ + public function equals(RDN $other): bool + { + // if attribute count doesn't match + if (count($this) !== count($other)) { + return false; + } + $attribs1 = $this->_attribs; + $attribs2 = $other->_attribs; + // if there's multiple attributes, sort using SET OF rules + if (count($attribs1) > 1) { + $attribs1 = self::fromASN1($this->toASN1())->_attribs; + $attribs2 = self::fromASN1($other->toASN1())->_attribs; + } + for ($i = count($attribs1) - 1; $i >= 0; --$i) { + $tv1 = $attribs1[$i]; + $tv2 = $attribs2[$i]; + if (!$tv1->equals($tv2)) { + return false; + } + } + return true; + } + + /** + * Get all AttributeTypeAndValue objects. + * + * @return AttributeTypeAndValue[] + */ + public function all(): array + { + return $this->_attribs; + } + + /** + * Get all AttributeTypeAndValue objects of the given attribute type. + * + * @param string $name Attribute OID or name + * + * @return AttributeTypeAndValue[] + */ + public function allOf(string $name): array + { + $oid = AttributeType::attrNameToOID($name); + $attribs = array_filter($this->_attribs, + function (AttributeTypeAndValue $tv) use ($oid) { + return $tv->oid() === $oid; + }); + return array_values($attribs); + } + + /** + * @see \Countable::count() + * + * @return int + */ + public function count(): int + { + return count($this->_attribs); + } + + /** + * @see \IteratorAggregate::getIterator() + * + * @return \ArrayIterator + */ + public function getIterator(): \ArrayIterator + { + return new \ArrayIterator($this->_attribs); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php new file mode 100644 index 0000000..32b3228 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php @@ -0,0 +1,428 @@ +#;'; + + /** + * DN string. + * + * @var string + */ + private $_dn; + + /** + * DN string length. + * + * @var int + */ + private $_len; + + /** + * Constructor. + * + * @param string $dn Distinguised name + */ + protected function __construct(string $dn) + { + $this->_dn = $dn; + $this->_len = strlen($dn); + } + + /** + * Parse distinguished name string to name-components. + * + * @param string $dn + * + * @return array + */ + public static function parseString(string $dn): array + { + $parser = new self($dn); + return $parser->parse(); + } + + /** + * Escape a AttributeValue string conforming to RFC 2253. + * + * @see https://tools.ietf.org/html/rfc2253#section-2.4 + * + * @param string $str + * + * @return string + */ + public static function escapeString(string $str): string + { + // one of the characters ",", "+", """, "\", "<", ">" or ";" + $str = preg_replace('/([,\+"\\\<\>;])/u', '\\\\$1', $str); + // a space character occurring at the end of the string + $str = preg_replace('/( )$/u', '\\\\$1', $str); + // a space or "#" character occurring at the beginning of the string + $str = preg_replace('/^([ #])/u', '\\\\$1', $str); + // implementation specific special characters + $str = preg_replace_callback('/([\pC])/u', + function ($m) { + $octets = str_split(bin2hex($m[1]), 2); + return implode('', + array_map( + function ($octet) { + return '\\' . strtoupper($octet); + }, $octets)); + }, $str); + return $str; + } + + /** + * Parse DN to name-components. + * + * @throws \RuntimeException + * + * @return array + */ + protected function parse(): array + { + $offset = 0; + $name = $this->_parseName($offset); + if ($offset < $this->_len) { + $remains = substr($this->_dn, $offset); + throw new \UnexpectedValueException( + 'Parser finished before the end of string' . + ", remaining: '{$remains}'."); + } + return $name; + } + + /** + * Parse 'name'. + * + * name-component *("," name-component) + * + * @param int $offset + * + * @return array Array of name-components + */ + private function _parseName(int &$offset): array + { + $idx = $offset; + $names = []; + while ($idx < $this->_len) { + $names[] = $this->_parseNameComponent($idx); + if ($idx >= $this->_len) { + break; + } + $this->_skipWs($idx); + if (',' != $this->_dn[$idx] && ';' != $this->_dn[$idx]) { + break; + } + ++$idx; + $this->_skipWs($idx); + } + $offset = $idx; + return array_reverse($names); + } + + /** + * Parse 'name-component'. + * + * attributeTypeAndValue *("+" attributeTypeAndValue) + * + * @param int $offset + * + * @return array Array of [type, value] tuples + */ + private function _parseNameComponent(int &$offset): array + { + $idx = $offset; + $tvpairs = []; + while ($idx < $this->_len) { + $tvpairs[] = $this->_parseAttrTypeAndValue($idx); + $this->_skipWs($idx); + if ($idx >= $this->_len || '+' != $this->_dn[$idx]) { + break; + } + ++$idx; + $this->_skipWs($idx); + } + $offset = $idx; + return $tvpairs; + } + + /** + * Parse 'attributeTypeAndValue'. + * + * attributeType "=" attributeValue + * + * @param int $offset + * + * @throws \UnexpectedValueException + * + * @return array A tuple of [type, value]. Value may be either a string or + * an Element, if it's encoded as hexstring. + */ + private function _parseAttrTypeAndValue(int &$offset): array + { + $idx = $offset; + $type = $this->_parseAttrType($idx); + $this->_skipWs($idx); + if ($idx >= $this->_len || '=' != $this->_dn[$idx++]) { + throw new \UnexpectedValueException('Invalid type and value pair.'); + } + $this->_skipWs($idx); + // hexstring + if ($idx < $this->_len && '#' == $this->_dn[$idx]) { + ++$idx; + $data = $this->_parseAttrHexValue($idx); + try { + $value = Element::fromDER($data); + } catch (DecodeException $e) { + throw new \UnexpectedValueException( + 'Invalid DER encoding from hexstring.', 0, $e); + } + } else { + $value = $this->_parseAttrStringValue($idx); + } + $offset = $idx; + return [$type, $value]; + } + + /** + * Parse 'attributeType'. + * + * (ALPHA 1*keychar) / oid + * + * @param int $offset + * + * @throws \UnexpectedValueException + * + * @return string + */ + private function _parseAttrType(int &$offset): string + { + $idx = $offset; + // dotted OID + $type = $this->_regexMatch('/^(?:oid\.)?([0-9]+(?:\.[0-9]+)*)/i', $idx); + if (null === $type) { + // name + $type = $this->_regexMatch('/^[a-z][a-z0-9\-]*/i', $idx); + if (null === $type) { + throw new \UnexpectedValueException('Invalid attribute type.'); + } + } + $offset = $idx; + return $type; + } + + /** + * Parse 'attributeValue' of string type. + * + * @param int $offset + * + * @throws \UnexpectedValueException + * + * @return string + */ + private function _parseAttrStringValue(int &$offset): string + { + $idx = $offset; + if ($idx >= $this->_len) { + return ''; + } + if ('"' == $this->_dn[$idx]) { // quoted string + $val = $this->_parseQuotedAttrString($idx); + } else { // string + $val = $this->_parseAttrString($idx); + } + $offset = $idx; + return $val; + } + + /** + * Parse plain 'attributeValue' string. + * + * @param int $offset + * + * @throws \UnexpectedValueException + * + * @return string + */ + private function _parseAttrString(int &$offset): string + { + $idx = $offset; + $val = ''; + $wsidx = null; + while ($idx < $this->_len) { + $c = $this->_dn[$idx]; + // pair (escape sequence) + if ('\\' == $c) { + ++$idx; + $val .= $this->_parsePairAfterSlash($idx); + $wsidx = null; + continue; + } + if ('"' == $c) { + throw new \UnexpectedValueException('Unexpected quotation.'); + } + if (false !== strpos(self::SPECIAL_CHARS, $c)) { + break; + } + // keep track of the first consecutive whitespace + if (' ' == $c) { + if (null === $wsidx) { + $wsidx = $idx; + } + } else { + $wsidx = null; + } + // stringchar + $val .= $c; + ++$idx; + } + // if there was non-escaped whitespace in the end of the value + if (null !== $wsidx) { + $val = substr($val, 0, -($idx - $wsidx)); + } + $offset = $idx; + return $val; + } + + /** + * Parse quoted 'attributeValue' string. + * + * @param int $offset Offset to starting quote + * + * @throws \UnexpectedValueException + * + * @return string + */ + private function _parseQuotedAttrString(int &$offset): string + { + $idx = $offset + 1; + $val = ''; + while ($idx < $this->_len) { + $c = $this->_dn[$idx]; + if ('\\' == $c) { // pair + ++$idx; + $val .= $this->_parsePairAfterSlash($idx); + continue; + } + if ('"' == $c) { + ++$idx; + break; + } + $val .= $c; + ++$idx; + } + $offset = $idx; + return $val; + } + + /** + * Parse 'attributeValue' of binary type. + * + * @param int $offset + * + * @throws \UnexpectedValueException + * + * @return string + */ + private function _parseAttrHexValue(int &$offset): string + { + $idx = $offset; + $hexstr = $this->_regexMatch('/^(?:[0-9a-f]{2})+/i', $idx); + if (null === $hexstr) { + throw new \UnexpectedValueException('Invalid hexstring.'); + } + $data = hex2bin($hexstr); + $offset = $idx; + return $data; + } + + /** + * Parse 'pair' after leading slash. + * + * @param int $offset + * + * @throws \UnexpectedValueException + * + * @return string + */ + private function _parsePairAfterSlash(int &$offset): string + { + $idx = $offset; + if ($idx >= $this->_len) { + throw new \UnexpectedValueException( + 'Unexpected end of escape sequence.'); + } + $c = $this->_dn[$idx++]; + // special | \ | " | SPACE + if (false !== strpos(self::SPECIAL_CHARS . '\\" ', $c)) { + $val = $c; + } else { // hexpair + if ($idx >= $this->_len) { + throw new \UnexpectedValueException('Unexpected end of hexpair.'); + } + $val = @hex2bin($c . $this->_dn[$idx++]); + if (false === $val) { + throw new \UnexpectedValueException('Invalid hexpair.'); + } + } + $offset = $idx; + return $val; + } + + /** + * Match DN to pattern and extract the last capture group. + * + * Updates offset to fully matched pattern. + * + * @param string $pattern + * @param int $offset + * + * @return null|string Null if pattern doesn't match + */ + private function _regexMatch(string $pattern, int &$offset): ?string + { + $idx = $offset; + if (!preg_match($pattern, substr($this->_dn, $idx), $match)) { + return null; + } + $idx += strlen($match[0]); + $offset = $idx; + return end($match); + } + + /** + * Skip consecutive spaces. + * + * @param int $offset + */ + private function _skipWs(int &$offset): void + { + $idx = $offset; + while ($idx < $this->_len) { + if (' ' != $this->_dn[$idx]) { + break; + } + ++$idx; + } + $offset = $idx; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php new file mode 100644 index 0000000..34af3c6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php @@ -0,0 +1,21 @@ +withCaseFolding(true)); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php new file mode 100644 index 0000000..9997547 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php @@ -0,0 +1,24 @@ +_prep = $preparer; + } + + /** + * {@inheritdoc} + */ + public function compare($assertion, $value): ?bool + { + $assertion = $this->_prep->prepare($assertion); + $value = $this->_prep->prepare($value); + return 0 === strcmp($assertion, $value); + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php new file mode 100644 index 0000000..9f65487 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php @@ -0,0 +1,25 @@ +_fold = $fold_case; + } + + /** + * @param string $string UTF-8 encoded string + * + * @return string + */ + public function apply(string $string): string + { + // @todo Implement character mappings + if ($this->_fold) { + $string = mb_convert_case($string, MB_CASE_LOWER, 'UTF-8'); + } + return $string; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php new file mode 100644 index 0000000..fbca4fb --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php @@ -0,0 +1,24 @@ +_steps = $steps; + } + + /** + * Get default instance for given string type. + * + * @param int $string_type ASN.1 string type tag. + * + * @return self + */ + public static function forStringType(int $string_type): self + { + $steps = [ + self::STEP_TRANSCODE => new TranscodeStep($string_type), + self::STEP_MAP => new MapStep(), + self::STEP_NORMALIZE => new NormalizeStep(), + self::STEP_PROHIBIT => new ProhibitStep(), + self::STEP_CHECK_BIDI => new CheckBidiStep(), + // @todo Vary by string type + self::STEP_INSIGNIFICANT_CHARS => new InsignificantNonSubstringSpaceStep(), + ]; + return new self($steps); + } + + /** + * Get self with case folding set. + * + * @param bool $fold True to apply case folding + * + * @return self + */ + public function withCaseFolding(bool $fold): self + { + $obj = clone $this; + $obj->_steps[self::STEP_MAP] = new MapStep($fold); + return $obj; + } + + /** + * Prepare string. + * + * @param string $string + * + * @return string + */ + public function prepare(string $string): string + { + foreach ($this->_steps as $step) { + $string = $step->apply($string); + } + return $string; + } +} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php new file mode 100644 index 0000000..3d29fc6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php @@ -0,0 +1,66 @@ +_type = $type; + } + + /** + * @param string $string String to prepare + * + * @throws \LogicException If string type is not supported + * + * @return string UTF-8 encoded string + */ + public function apply(string $string): string + { + switch ($this->_type) { + // UTF-8 string as is + case Element::TYPE_UTF8_STRING: + return $string; + // PrintableString maps directly to UTF-8 + case Element::TYPE_PRINTABLE_STRING: + return $string; + // UCS-2 to UTF-8 + case Element::TYPE_BMP_STRING: + return mb_convert_encoding($string, 'UTF-8', 'UCS-2BE'); + // UCS-4 to UTF-8 + case Element::TYPE_UNIVERSAL_STRING: + return mb_convert_encoding($string, 'UTF-8', 'UCS-4BE'); + // TeletexString mapping is a local matter. + // We take a shortcut here and encode it as a hexstring. + case Element::TYPE_T61_STRING: + $el = new T61String($string); + return '#' . bin2hex($el->toDER()); + } + throw new \LogicException( + 'Unsupported string type ' . Element::tagToName($this->_type) . '.'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php new file mode 100644 index 0000000..ba75a2c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php @@ -0,0 +1,232 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Ctype; + +/** + * Ctype implementation through regex. + * + * @internal + * + * @author Gert de Pagter + */ +final class Ctype +{ + /** + * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. + * + * @see https://php.net/ctype-alnum + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_alnum($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is a letter, FALSE otherwise. + * + * @see https://php.net/ctype-alpha + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_alpha($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); + } + + /** + * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. + * + * @see https://php.net/ctype-cntrl + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_cntrl($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); + } + + /** + * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. + * + * @see https://php.net/ctype-digit + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_digit($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); + } + + /** + * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. + * + * @see https://php.net/ctype-graph + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_graph($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); + } + + /** + * Returns TRUE if every character in text is a lowercase letter. + * + * @see https://php.net/ctype-lower + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_lower($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); + } + + /** + * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. + * + * @see https://php.net/ctype-print + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_print($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); + } + + /** + * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. + * + * @see https://php.net/ctype-punct + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_punct($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); + } + + /** + * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. + * + * @see https://php.net/ctype-space + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_space($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); + } + + /** + * Returns TRUE if every character in text is an uppercase letter. + * + * @see https://php.net/ctype-upper + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_upper($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); + } + + /** + * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. + * + * @see https://php.net/ctype-xdigit + * + * @param mixed $text + * + * @return bool + */ + public static function ctype_xdigit($text) + { + $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); + + return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); + } + + /** + * Converts integers to their char versions according to normal ctype behaviour, if needed. + * + * If an integer between -128 and 255 inclusive is provided, + * it is interpreted as the ASCII value of a single character + * (negative values have 256 added in order to allow characters in the Extended ASCII range). + * Any other integer is interpreted as a string containing the decimal digits of the integer. + * + * @param mixed $int + * @param string $function + * + * @return mixed + */ + private static function convert_int_to_char_for_ctype($int, $function) + { + if (!\is_int($int)) { + return $int; + } + + if ($int < -128 || $int > 255) { + return (string) $int; + } + + if (\PHP_VERSION_ID >= 80100) { + @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); + } + + if ($int < 0) { + $int += 256; + } + + return \chr($int); + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE new file mode 100644 index 0000000..7536cae --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md new file mode 100644 index 0000000..b144d03 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md @@ -0,0 +1,12 @@ +Symfony Polyfill / Ctype +======================== + +This component provides `ctype_*` functions to users who run php versions without the ctype extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php new file mode 100644 index 0000000..d54524b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('ctype_alnum')) { + function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit($text) { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph($text) { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower($text) { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print($text) { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct($text) { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space($text) { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper($text) { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php new file mode 100644 index 0000000..ab2f861 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Ctype as p; + +if (!function_exists('ctype_alnum')) { + function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } +} +if (!function_exists('ctype_alpha')) { + function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } +} +if (!function_exists('ctype_cntrl')) { + function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } +} +if (!function_exists('ctype_digit')) { + function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } +} +if (!function_exists('ctype_graph')) { + function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } +} +if (!function_exists('ctype_lower')) { + function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } +} +if (!function_exists('ctype_print')) { + function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } +} +if (!function_exists('ctype_punct')) { + function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } +} +if (!function_exists('ctype_space')) { + function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } +} +if (!function_exists('ctype_upper')) { + function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } +} +if (!function_exists('ctype_xdigit')) { + function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json new file mode 100644 index 0000000..e5c978f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json @@ -0,0 +1,41 @@ +{ + "name": "symfony/polyfill-ctype", + "type": "library", + "description": "Symfony polyfill for ctype functions", + "keywords": ["polyfill", "compatibility", "portable", "ctype"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE new file mode 100644 index 0000000..6e3afce --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2015-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php new file mode 100644 index 0000000..2e0b969 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -0,0 +1,947 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Mbstring; + +/** + * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. + * + * Implemented: + * - mb_chr - Returns a specific character from its Unicode code point + * - mb_convert_encoding - Convert character encoding + * - mb_convert_variables - Convert character code in variable(s) + * - mb_decode_mimeheader - Decode string in MIME header field + * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED + * - mb_decode_numericentity - Decode HTML numeric string reference to character + * - mb_encode_numericentity - Encode character to HTML numeric string reference + * - mb_convert_case - Perform case folding on a string + * - mb_detect_encoding - Detect character encoding + * - mb_get_info - Get internal settings of mbstring + * - mb_http_input - Detect HTTP input character encoding + * - mb_http_output - Set/Get HTTP output character encoding + * - mb_internal_encoding - Set/Get internal character encoding + * - mb_list_encodings - Returns an array of all supported encodings + * - mb_ord - Returns the Unicode code point of a character + * - mb_output_handler - Callback function converts character encoding in output buffer + * - mb_scrub - Replaces ill-formed byte sequences with substitute characters + * - mb_strlen - Get string length + * - mb_strpos - Find position of first occurrence of string in a string + * - mb_strrpos - Find position of last occurrence of a string in a string + * - mb_str_split - Convert a string to an array + * - mb_strtolower - Make a string lowercase + * - mb_strtoupper - Make a string uppercase + * - mb_substitute_character - Set/Get substitution character + * - mb_substr - Get part of string + * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive + * - mb_stristr - Finds first occurrence of a string within another, case insensitive + * - mb_strrchr - Finds the last occurrence of a character in a string within another + * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive + * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive + * - mb_strstr - Finds first occurrence of a string within another + * - mb_strwidth - Return width of string + * - mb_substr_count - Count the number of substring occurrences + * + * Not implemented: + * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) + * - mb_ereg_* - Regular expression with multibyte support + * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable + * - mb_preferred_mime_name - Get MIME charset string + * - mb_regex_encoding - Returns current encoding for multibyte regex as string + * - mb_regex_set_options - Set/Get the default options for mbregex functions + * - mb_send_mail - Send encoded mail + * - mb_split - Split multibyte string using regular expression + * - mb_strcut - Get part of string + * - mb_strimwidth - Get truncated string with specified width + * + * @author Nicolas Grekas + * + * @internal + */ +final class Mbstring +{ + public const MB_CASE_FOLD = \PHP_INT_MAX; + + private const SIMPLE_CASE_FOLD = [ + ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], + ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], + ]; + + private static $encodingList = ['ASCII', 'UTF-8']; + private static $language = 'neutral'; + private static $internalEncoding = 'UTF-8'; + + public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) + { + if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { + $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); + } else { + $fromEncoding = self::getEncoding($fromEncoding); + } + + $toEncoding = self::getEncoding($toEncoding); + + if ('BASE64' === $fromEncoding) { + $s = base64_decode($s); + $fromEncoding = $toEncoding; + } + + if ('BASE64' === $toEncoding) { + return base64_encode($s); + } + + if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { + if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { + $fromEncoding = 'Windows-1252'; + } + if ('UTF-8' !== $fromEncoding) { + $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); + } + + return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); + } + + if ('HTML-ENTITIES' === $fromEncoding) { + $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); + $fromEncoding = 'UTF-8'; + } + + return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); + } + + public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) + { + $ok = true; + array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { + if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { + $ok = false; + } + }); + + return $ok ? $fromEncoding : false; + } + + public static function mb_decode_mimeheader($s) + { + return iconv_mime_decode($s, 2, self::$internalEncoding); + } + + public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) + { + trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING); + } + + public static function mb_decode_numericentity($s, $convmap, $encoding = null) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { + trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); + + return null; + } + + if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { + return false; + } + + if (null !== $encoding && !\is_scalar($encoding)) { + trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); + + return ''; // Instead of null (cf. mb_encode_numericentity). + } + + $s = (string) $s; + if ('' === $s) { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + $cnt = floor(\count($convmap) / 4) * 4; + + for ($i = 0; $i < $cnt; $i += 4) { + // collector_decode_htmlnumericentity ignores $convmap[$i + 3] + $convmap[$i] += $convmap[$i + 2]; + $convmap[$i + 1] += $convmap[$i + 2]; + } + + $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) { + $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1]; + for ($i = 0; $i < $cnt; $i += 4) { + if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { + return self::mb_chr($c - $convmap[$i + 2]); + } + } + + return $m[0]; + }, $s); + + if (null === $encoding) { + return $s; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $s); + } + + public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) + { + if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { + trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); + + return null; + } + + if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { + return false; + } + + if (null !== $encoding && !\is_scalar($encoding)) { + trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); + + return null; // Instead of '' (cf. mb_decode_numericentity). + } + + if (null !== $is_hex && !\is_scalar($is_hex)) { + trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING); + + return null; + } + + $s = (string) $s; + if ('' === $s) { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; + + $cnt = floor(\count($convmap) / 4) * 4; + $i = 0; + $len = \strlen($s); + $result = ''; + + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + $i += $ulen; + $c = self::mb_ord($uchr); + + for ($j = 0; $j < $cnt; $j += 4) { + if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) { + $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3]; + $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';'; + continue 2; + } + } + $result .= $uchr; + } + + if (null === $encoding) { + return $result; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $result); + } + + public static function mb_convert_case($s, $mode, $encoding = null) + { + $s = (string) $s; + if ('' === $s) { + return ''; + } + + $encoding = self::getEncoding($encoding); + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $s)) { + $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); + } + } else { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + if (\MB_CASE_TITLE == $mode) { + static $titleRegexp = null; + if (null === $titleRegexp) { + $titleRegexp = self::getData('titleCaseRegexp'); + } + $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s); + } else { + if (\MB_CASE_UPPER == $mode) { + static $upper = null; + if (null === $upper) { + $upper = self::getData('upperCase'); + } + $map = $upper; + } else { + if (self::MB_CASE_FOLD === $mode) { + static $caseFolding = null; + if (null === $caseFolding) { + $caseFolding = self::getData('caseFolding'); + } + $s = strtr($s, $caseFolding); + } + + static $lower = null; + if (null === $lower) { + $lower = self::getData('lowerCase'); + } + $map = $lower; + } + + static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; + + $i = 0; + $len = \strlen($s); + + while ($i < $len) { + $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; + $uchr = substr($s, $i, $ulen); + $i += $ulen; + + if (isset($map[$uchr])) { + $uchr = $map[$uchr]; + $nlen = \strlen($uchr); + + if ($nlen == $ulen) { + $nlen = $i; + do { + $s[--$nlen] = $uchr[--$ulen]; + } while ($ulen); + } else { + $s = substr_replace($s, $uchr, $i - $ulen, $ulen); + $len += $nlen - $ulen; + $i += $nlen - $ulen; + } + } + } + } + + if (null === $encoding) { + return $s; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $s); + } + + public static function mb_internal_encoding($encoding = null) + { + if (null === $encoding) { + return self::$internalEncoding; + } + + $normalizedEncoding = self::getEncoding($encoding); + + if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { + self::$internalEncoding = $normalizedEncoding; + + return true; + } + + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + + public static function mb_language($lang = null) + { + if (null === $lang) { + return self::$language; + } + + switch ($normalizedLang = strtolower($lang)) { + case 'uni': + case 'neutral': + self::$language = $normalizedLang; + + return true; + } + + if (80000 > \PHP_VERSION_ID) { + return false; + } + + throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); + } + + public static function mb_list_encodings() + { + return ['UTF-8']; + } + + public static function mb_encoding_aliases($encoding) + { + switch (strtoupper($encoding)) { + case 'UTF8': + case 'UTF-8': + return ['utf8']; + } + + return false; + } + + public static function mb_check_encoding($var = null, $encoding = null) + { + if (PHP_VERSION_ID < 70200 && \is_array($var)) { + trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); + + return null; + } + + if (null === $encoding) { + if (null === $var) { + return false; + } + $encoding = self::$internalEncoding; + } + + if (!\is_array($var)) { + return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); + } + + foreach ($var as $key => $value) { + if (!self::mb_check_encoding($key, $encoding)) { + return false; + } + if (!self::mb_check_encoding($value, $encoding)) { + return false; + } + } + + return true; + + } + + public static function mb_detect_encoding($str, $encodingList = null, $strict = false) + { + if (null === $encodingList) { + $encodingList = self::$encodingList; + } else { + if (!\is_array($encodingList)) { + $encodingList = array_map('trim', explode(',', $encodingList)); + } + $encodingList = array_map('strtoupper', $encodingList); + } + + foreach ($encodingList as $enc) { + switch ($enc) { + case 'ASCII': + if (!preg_match('/[\x80-\xFF]/', $str)) { + return $enc; + } + break; + + case 'UTF8': + case 'UTF-8': + if (preg_match('//u', $str)) { + return 'UTF-8'; + } + break; + + default: + if (0 === strncmp($enc, 'ISO-8859-', 9)) { + return $enc; + } + } + } + + return false; + } + + public static function mb_detect_order($encodingList = null) + { + if (null === $encodingList) { + return self::$encodingList; + } + + if (!\is_array($encodingList)) { + $encodingList = array_map('trim', explode(',', $encodingList)); + } + $encodingList = array_map('strtoupper', $encodingList); + + foreach ($encodingList as $enc) { + switch ($enc) { + default: + if (strncmp($enc, 'ISO-8859-', 9)) { + return false; + } + // no break + case 'ASCII': + case 'UTF8': + case 'UTF-8': + } + } + + self::$encodingList = $encodingList; + + return true; + } + + public static function mb_strlen($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return \strlen($s); + } + + return @iconv_strlen($s, $encoding); + } + + public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strpos($haystack, $needle, $offset); + } + + $needle = (string) $needle; + if ('' === $needle) { + if (80000 > \PHP_VERSION_ID) { + trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING); + + return false; + } + + return 0; + } + + return iconv_strpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return strrpos($haystack, $needle, $offset); + } + + if ($offset != (int) $offset) { + $offset = 0; + } elseif ($offset = (int) $offset) { + if ($offset < 0) { + if (0 > $offset += self::mb_strlen($needle)) { + $haystack = self::mb_substr($haystack, 0, $offset, $encoding); + } + $offset = 0; + } else { + $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); + } + } + + $pos = '' !== $needle || 80000 > \PHP_VERSION_ID + ? iconv_strrpos($haystack, $needle, $encoding) + : self::mb_strlen($haystack, $encoding); + + return false !== $pos ? $offset + $pos : false; + } + + public static function mb_str_split($string, $split_length = 1, $encoding = null) + { + if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) { + trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING); + + return null; + } + + if (1 > $split_length = (int) $split_length) { + if (80000 > \PHP_VERSION_ID) { + trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); + + return false; + } + + throw new \ValueError('Argument #2 ($length) must be greater than 0'); + } + + if (null === $encoding) { + $encoding = mb_internal_encoding(); + } + + if ('UTF-8' === $encoding = self::getEncoding($encoding)) { + $rx = '/('; + while (65535 < $split_length) { + $rx .= '.{65535}'; + $split_length -= 65535; + } + $rx .= '.{'.$split_length.'})/us'; + + return preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); + } + + $result = []; + $length = mb_strlen($string, $encoding); + + for ($i = 0; $i < $length; $i += $split_length) { + $result[] = mb_substr($string, $i, $split_length, $encoding); + } + + return $result; + } + + public static function mb_strtolower($s, $encoding = null) + { + return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding); + } + + public static function mb_strtoupper($s, $encoding = null) + { + return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding); + } + + public static function mb_substitute_character($c = null) + { + if (null === $c) { + return 'none'; + } + if (0 === strcasecmp($c, 'none')) { + return true; + } + if (80000 > \PHP_VERSION_ID) { + return false; + } + if (\is_int($c) || 'long' === $c || 'entity' === $c) { + return false; + } + + throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); + } + + public static function mb_substr($s, $start, $length = null, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + return (string) substr($s, $start, null === $length ? 2147483647 : $length); + } + + if ($start < 0) { + $start = iconv_strlen($s, $encoding) + $start; + if ($start < 0) { + $start = 0; + } + } + + if (null === $length) { + $length = 2147483647; + } elseif ($length < 0) { + $length = iconv_strlen($s, $encoding) + $length - $start; + if ($length < 0) { + return ''; + } + } + + return (string) iconv_substr($s, $start, $length, $encoding); + } + + public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) + { + [$haystack, $needle] = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [ + self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), + self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding), + ]); + + return self::mb_strpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_stristr($haystack, $needle, $part = false, $encoding = null) + { + $pos = self::mb_stripos($haystack, $needle, 0, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) + { + $encoding = self::getEncoding($encoding); + if ('CP850' === $encoding || 'ASCII' === $encoding) { + $pos = strrpos($haystack, $needle); + } else { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = iconv_strrpos($haystack, $needle, $encoding); + } + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null) + { + $needle = self::mb_substr($needle, 0, 1, $encoding); + $pos = self::mb_strripos($haystack, $needle, $encoding); + + return self::getSubpart($pos, $part, $haystack, $encoding); + } + + public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) + { + $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding); + $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); + + $haystack = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); + $needle = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); + + return self::mb_strrpos($haystack, $needle, $offset, $encoding); + } + + public static function mb_strstr($haystack, $needle, $part = false, $encoding = null) + { + $pos = strpos($haystack, $needle); + if (false === $pos) { + return false; + } + if ($part) { + return substr($haystack, 0, $pos); + } + + return substr($haystack, $pos); + } + + public static function mb_get_info($type = 'all') + { + $info = [ + 'internal_encoding' => self::$internalEncoding, + 'http_output' => 'pass', + 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', + 'func_overload' => 0, + 'func_overload_list' => 'no overload', + 'mail_charset' => 'UTF-8', + 'mail_header_encoding' => 'BASE64', + 'mail_body_encoding' => 'BASE64', + 'illegal_chars' => 0, + 'encoding_translation' => 'Off', + 'language' => self::$language, + 'detect_order' => self::$encodingList, + 'substitute_character' => 'none', + 'strict_detection' => 'Off', + ]; + + if ('all' === $type) { + return $info; + } + if (isset($info[$type])) { + return $info[$type]; + } + + return false; + } + + public static function mb_http_input($type = '') + { + return false; + } + + public static function mb_http_output($encoding = null) + { + return null !== $encoding ? 'pass' === $encoding : 'pass'; + } + + public static function mb_strwidth($s, $encoding = null) + { + $encoding = self::getEncoding($encoding); + + if ('UTF-8' !== $encoding) { + $s = iconv($encoding, 'UTF-8//IGNORE', $s); + } + + $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); + + return ($wide << 1) + iconv_strlen($s, 'UTF-8'); + } + + public static function mb_substr_count($haystack, $needle, $encoding = null) + { + return substr_count($haystack, $needle); + } + + public static function mb_output_handler($contents, $status) + { + return $contents; + } + + public static function mb_chr($code, $encoding = null) + { + if (0x80 > $code %= 0x200000) { + $s = \chr($code); + } elseif (0x800 > $code) { + $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); + } elseif (0x10000 > $code) { + $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } else { + $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); + } + + if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { + $s = mb_convert_encoding($s, $encoding, 'UTF-8'); + } + + return $s; + } + + public static function mb_ord($s, $encoding = null) + { + if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { + $s = mb_convert_encoding($s, 'UTF-8', $encoding); + } + + if (1 === \strlen($s)) { + return \ord($s); + } + + $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; + if (0xF0 <= $code) { + return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; + } + if (0xE0 <= $code) { + return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; + } + if (0xC0 <= $code) { + return (($code - 0xC0) << 6) + $s[2] - 0x80; + } + + return $code; + } + + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string + { + if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { + throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); + } + + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } + + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } + + if (self::mb_strlen($pad_string, $encoding) <= 0) { + throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); + } + + $paddingRequired = $length - self::mb_strlen($string, $encoding); + + if ($paddingRequired < 1) { + return $string; + } + + switch ($pad_type) { + case \STR_PAD_LEFT: + return self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding).$string; + case \STR_PAD_RIGHT: + return $string.self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); + default: + $leftPaddingLength = floor($paddingRequired / 2); + $rightPaddingLength = $paddingRequired - $leftPaddingLength; + + return self::mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.self::mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); + } + } + + private static function getSubpart($pos, $part, $haystack, $encoding) + { + if (false === $pos) { + return false; + } + if ($part) { + return self::mb_substr($haystack, 0, $pos, $encoding); + } + + return self::mb_substr($haystack, $pos, null, $encoding); + } + + private static function html_encoding_callback(array $m) + { + $i = 1; + $entities = ''; + $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); + + while (isset($m[$i])) { + if (0x80 > $m[$i]) { + $entities .= \chr($m[$i++]); + continue; + } + if (0xF0 <= $m[$i]) { + $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; + } elseif (0xE0 <= $m[$i]) { + $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; + } else { + $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80; + } + + $entities .= '&#'.$c.';'; + } + + return $entities; + } + + private static function title_case(array $s) + { + return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); + } + + private static function getData($file) + { + if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { + return require $file; + } + + return false; + } + + private static function getEncoding($encoding) + { + if (null === $encoding) { + return self::$internalEncoding; + } + + if ('UTF-8' === $encoding) { + return 'UTF-8'; + } + + $encoding = strtoupper($encoding); + + if ('8BIT' === $encoding || 'BINARY' === $encoding) { + return 'CP850'; + } + + if ('UTF8' === $encoding) { + return 'UTF-8'; + } + + return $encoding; + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md new file mode 100644 index 0000000..478b40d --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md @@ -0,0 +1,13 @@ +Symfony Polyfill / Mbstring +=========================== + +This component provides a partial, native PHP implementation for the +[Mbstring](https://php.net/mbstring) extension. + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php new file mode 100644 index 0000000..512bba0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php @@ -0,0 +1,119 @@ + 'i̇', + 'µ' => 'μ', + 'ſ' => 's', + 'ͅ' => 'ι', + 'ς' => 'σ', + 'ϐ' => 'β', + 'ϑ' => 'θ', + 'ϕ' => 'φ', + 'ϖ' => 'π', + 'ϰ' => 'κ', + 'ϱ' => 'ρ', + 'ϵ' => 'ε', + 'ẛ' => 'ṡ', + 'ι' => 'ι', + 'ß' => 'ss', + 'ʼn' => 'ʼn', + 'ǰ' => 'ǰ', + 'ΐ' => 'ΐ', + 'ΰ' => 'ΰ', + 'և' => 'եւ', + 'ẖ' => 'ẖ', + 'ẗ' => 'ẗ', + 'ẘ' => 'ẘ', + 'ẙ' => 'ẙ', + 'ẚ' => 'aʾ', + 'ẞ' => 'ss', + 'ὐ' => 'ὐ', + 'ὒ' => 'ὒ', + 'ὔ' => 'ὔ', + 'ὖ' => 'ὖ', + 'ᾀ' => 'ἀι', + 'ᾁ' => 'ἁι', + 'ᾂ' => 'ἂι', + 'ᾃ' => 'ἃι', + 'ᾄ' => 'ἄι', + 'ᾅ' => 'ἅι', + 'ᾆ' => 'ἆι', + 'ᾇ' => 'ἇι', + 'ᾈ' => 'ἀι', + 'ᾉ' => 'ἁι', + 'ᾊ' => 'ἂι', + 'ᾋ' => 'ἃι', + 'ᾌ' => 'ἄι', + 'ᾍ' => 'ἅι', + 'ᾎ' => 'ἆι', + 'ᾏ' => 'ἇι', + 'ᾐ' => 'ἠι', + 'ᾑ' => 'ἡι', + 'ᾒ' => 'ἢι', + 'ᾓ' => 'ἣι', + 'ᾔ' => 'ἤι', + 'ᾕ' => 'ἥι', + 'ᾖ' => 'ἦι', + 'ᾗ' => 'ἧι', + 'ᾘ' => 'ἠι', + 'ᾙ' => 'ἡι', + 'ᾚ' => 'ἢι', + 'ᾛ' => 'ἣι', + 'ᾜ' => 'ἤι', + 'ᾝ' => 'ἥι', + 'ᾞ' => 'ἦι', + 'ᾟ' => 'ἧι', + 'ᾠ' => 'ὠι', + 'ᾡ' => 'ὡι', + 'ᾢ' => 'ὢι', + 'ᾣ' => 'ὣι', + 'ᾤ' => 'ὤι', + 'ᾥ' => 'ὥι', + 'ᾦ' => 'ὦι', + 'ᾧ' => 'ὧι', + 'ᾨ' => 'ὠι', + 'ᾩ' => 'ὡι', + 'ᾪ' => 'ὢι', + 'ᾫ' => 'ὣι', + 'ᾬ' => 'ὤι', + 'ᾭ' => 'ὥι', + 'ᾮ' => 'ὦι', + 'ᾯ' => 'ὧι', + 'ᾲ' => 'ὰι', + 'ᾳ' => 'αι', + 'ᾴ' => 'άι', + 'ᾶ' => 'ᾶ', + 'ᾷ' => 'ᾶι', + 'ᾼ' => 'αι', + 'ῂ' => 'ὴι', + 'ῃ' => 'ηι', + 'ῄ' => 'ήι', + 'ῆ' => 'ῆ', + 'ῇ' => 'ῆι', + 'ῌ' => 'ηι', + 'ῒ' => 'ῒ', + 'ῖ' => 'ῖ', + 'ῗ' => 'ῗ', + 'ῢ' => 'ῢ', + 'ῤ' => 'ῤ', + 'ῦ' => 'ῦ', + 'ῧ' => 'ῧ', + 'ῲ' => 'ὼι', + 'ῳ' => 'ωι', + 'ῴ' => 'ώι', + 'ῶ' => 'ῶ', + 'ῷ' => 'ῶι', + 'ῼ' => 'ωι', + 'ff' => 'ff', + 'fi' => 'fi', + 'fl' => 'fl', + 'ffi' => 'ffi', + 'ffl' => 'ffl', + 'ſt' => 'st', + 'st' => 'st', + 'ﬓ' => 'մն', + 'ﬔ' => 'մե', + 'ﬕ' => 'մի', + 'ﬖ' => 'վն', + 'ﬗ' => 'մխ', +]; diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php new file mode 100644 index 0000000..fac60b0 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php @@ -0,0 +1,1397 @@ + 'a', + 'B' => 'b', + 'C' => 'c', + 'D' => 'd', + 'E' => 'e', + 'F' => 'f', + 'G' => 'g', + 'H' => 'h', + 'I' => 'i', + 'J' => 'j', + 'K' => 'k', + 'L' => 'l', + 'M' => 'm', + 'N' => 'n', + 'O' => 'o', + 'P' => 'p', + 'Q' => 'q', + 'R' => 'r', + 'S' => 's', + 'T' => 't', + 'U' => 'u', + 'V' => 'v', + 'W' => 'w', + 'X' => 'x', + 'Y' => 'y', + 'Z' => 'z', + 'À' => 'à', + 'Á' => 'á', + 'Â' => 'â', + 'Ã' => 'ã', + 'Ä' => 'ä', + 'Å' => 'å', + 'Æ' => 'æ', + 'Ç' => 'ç', + 'È' => 'è', + 'É' => 'é', + 'Ê' => 'ê', + 'Ë' => 'ë', + 'Ì' => 'ì', + 'Í' => 'í', + 'Î' => 'î', + 'Ï' => 'ï', + 'Ð' => 'ð', + 'Ñ' => 'ñ', + 'Ò' => 'ò', + 'Ó' => 'ó', + 'Ô' => 'ô', + 'Õ' => 'õ', + 'Ö' => 'ö', + 'Ø' => 'ø', + 'Ù' => 'ù', + 'Ú' => 'ú', + 'Û' => 'û', + 'Ü' => 'ü', + 'Ý' => 'ý', + 'Þ' => 'þ', + 'Ā' => 'ā', + 'Ă' => 'ă', + 'Ą' => 'ą', + 'Ć' => 'ć', + 'Ĉ' => 'ĉ', + 'Ċ' => 'ċ', + 'Č' => 'č', + 'Ď' => 'ď', + 'Đ' => 'đ', + 'Ē' => 'ē', + 'Ĕ' => 'ĕ', + 'Ė' => 'ė', + 'Ę' => 'ę', + 'Ě' => 'ě', + 'Ĝ' => 'ĝ', + 'Ğ' => 'ğ', + 'Ġ' => 'ġ', + 'Ģ' => 'ģ', + 'Ĥ' => 'ĥ', + 'Ħ' => 'ħ', + 'Ĩ' => 'ĩ', + 'Ī' => 'ī', + 'Ĭ' => 'ĭ', + 'Į' => 'į', + 'İ' => 'i̇', + 'IJ' => 'ij', + 'Ĵ' => 'ĵ', + 'Ķ' => 'ķ', + 'Ĺ' => 'ĺ', + 'Ļ' => 'ļ', + 'Ľ' => 'ľ', + 'Ŀ' => 'ŀ', + 'Ł' => 'ł', + 'Ń' => 'ń', + 'Ņ' => 'ņ', + 'Ň' => 'ň', + 'Ŋ' => 'ŋ', + 'Ō' => 'ō', + 'Ŏ' => 'ŏ', + 'Ő' => 'ő', + 'Œ' => 'œ', + 'Ŕ' => 'ŕ', + 'Ŗ' => 'ŗ', + 'Ř' => 'ř', + 'Ś' => 'ś', + 'Ŝ' => 'ŝ', + 'Ş' => 'ş', + 'Š' => 'š', + 'Ţ' => 'ţ', + 'Ť' => 'ť', + 'Ŧ' => 'ŧ', + 'Ũ' => 'ũ', + 'Ū' => 'ū', + 'Ŭ' => 'ŭ', + 'Ů' => 'ů', + 'Ű' => 'ű', + 'Ų' => 'ų', + 'Ŵ' => 'ŵ', + 'Ŷ' => 'ŷ', + 'Ÿ' => 'ÿ', + 'Ź' => 'ź', + 'Ż' => 'ż', + 'Ž' => 'ž', + 'Ɓ' => 'ɓ', + 'Ƃ' => 'ƃ', + 'Ƅ' => 'ƅ', + 'Ɔ' => 'ɔ', + 'Ƈ' => 'ƈ', + 'Ɖ' => 'ɖ', + 'Ɗ' => 'ɗ', + 'Ƌ' => 'ƌ', + 'Ǝ' => 'ǝ', + 'Ə' => 'ə', + 'Ɛ' => 'ɛ', + 'Ƒ' => 'ƒ', + 'Ɠ' => 'ɠ', + 'Ɣ' => 'ɣ', + 'Ɩ' => 'ɩ', + 'Ɨ' => 'ɨ', + 'Ƙ' => 'ƙ', + 'Ɯ' => 'ɯ', + 'Ɲ' => 'ɲ', + 'Ɵ' => 'ɵ', + 'Ơ' => 'ơ', + 'Ƣ' => 'ƣ', + 'Ƥ' => 'ƥ', + 'Ʀ' => 'ʀ', + 'Ƨ' => 'ƨ', + 'Ʃ' => 'ʃ', + 'Ƭ' => 'ƭ', + 'Ʈ' => 'ʈ', + 'Ư' => 'ư', + 'Ʊ' => 'ʊ', + 'Ʋ' => 'ʋ', + 'Ƴ' => 'ƴ', + 'Ƶ' => 'ƶ', + 'Ʒ' => 'ʒ', + 'Ƹ' => 'ƹ', + 'Ƽ' => 'ƽ', + 'DŽ' => 'dž', + 'Dž' => 'dž', + 'LJ' => 'lj', + 'Lj' => 'lj', + 'NJ' => 'nj', + 'Nj' => 'nj', + 'Ǎ' => 'ǎ', + 'Ǐ' => 'ǐ', + 'Ǒ' => 'ǒ', + 'Ǔ' => 'ǔ', + 'Ǖ' => 'ǖ', + 'Ǘ' => 'ǘ', + 'Ǚ' => 'ǚ', + 'Ǜ' => 'ǜ', + 'Ǟ' => 'ǟ', + 'Ǡ' => 'ǡ', + 'Ǣ' => 'ǣ', + 'Ǥ' => 'ǥ', + 'Ǧ' => 'ǧ', + 'Ǩ' => 'ǩ', + 'Ǫ' => 'ǫ', + 'Ǭ' => 'ǭ', + 'Ǯ' => 'ǯ', + 'DZ' => 'dz', + 'Dz' => 'dz', + 'Ǵ' => 'ǵ', + 'Ƕ' => 'ƕ', + 'Ƿ' => 'ƿ', + 'Ǹ' => 'ǹ', + 'Ǻ' => 'ǻ', + 'Ǽ' => 'ǽ', + 'Ǿ' => 'ǿ', + 'Ȁ' => 'ȁ', + 'Ȃ' => 'ȃ', + 'Ȅ' => 'ȅ', + 'Ȇ' => 'ȇ', + 'Ȉ' => 'ȉ', + 'Ȋ' => 'ȋ', + 'Ȍ' => 'ȍ', + 'Ȏ' => 'ȏ', + 'Ȑ' => 'ȑ', + 'Ȓ' => 'ȓ', + 'Ȕ' => 'ȕ', + 'Ȗ' => 'ȗ', + 'Ș' => 'ș', + 'Ț' => 'ț', + 'Ȝ' => 'ȝ', + 'Ȟ' => 'ȟ', + 'Ƞ' => 'ƞ', + 'Ȣ' => 'ȣ', + 'Ȥ' => 'ȥ', + 'Ȧ' => 'ȧ', + 'Ȩ' => 'ȩ', + 'Ȫ' => 'ȫ', + 'Ȭ' => 'ȭ', + 'Ȯ' => 'ȯ', + 'Ȱ' => 'ȱ', + 'Ȳ' => 'ȳ', + 'Ⱥ' => 'ⱥ', + 'Ȼ' => 'ȼ', + 'Ƚ' => 'ƚ', + 'Ⱦ' => 'ⱦ', + 'Ɂ' => 'ɂ', + 'Ƀ' => 'ƀ', + 'Ʉ' => 'ʉ', + 'Ʌ' => 'ʌ', + 'Ɇ' => 'ɇ', + 'Ɉ' => 'ɉ', + 'Ɋ' => 'ɋ', + 'Ɍ' => 'ɍ', + 'Ɏ' => 'ɏ', + 'Ͱ' => 'ͱ', + 'Ͳ' => 'ͳ', + 'Ͷ' => 'ͷ', + 'Ϳ' => 'ϳ', + 'Ά' => 'ά', + 'Έ' => 'έ', + 'Ή' => 'ή', + 'Ί' => 'ί', + 'Ό' => 'ό', + 'Ύ' => 'ύ', + 'Ώ' => 'ώ', + 'Α' => 'α', + 'Β' => 'β', + 'Γ' => 'γ', + 'Δ' => 'δ', + 'Ε' => 'ε', + 'Ζ' => 'ζ', + 'Η' => 'η', + 'Θ' => 'θ', + 'Ι' => 'ι', + 'Κ' => 'κ', + 'Λ' => 'λ', + 'Μ' => 'μ', + 'Ν' => 'ν', + 'Ξ' => 'ξ', + 'Ο' => 'ο', + 'Π' => 'π', + 'Ρ' => 'ρ', + 'Σ' => 'σ', + 'Τ' => 'τ', + 'Υ' => 'υ', + 'Φ' => 'φ', + 'Χ' => 'χ', + 'Ψ' => 'ψ', + 'Ω' => 'ω', + 'Ϊ' => 'ϊ', + 'Ϋ' => 'ϋ', + 'Ϗ' => 'ϗ', + 'Ϙ' => 'ϙ', + 'Ϛ' => 'ϛ', + 'Ϝ' => 'ϝ', + 'Ϟ' => 'ϟ', + 'Ϡ' => 'ϡ', + 'Ϣ' => 'ϣ', + 'Ϥ' => 'ϥ', + 'Ϧ' => 'ϧ', + 'Ϩ' => 'ϩ', + 'Ϫ' => 'ϫ', + 'Ϭ' => 'ϭ', + 'Ϯ' => 'ϯ', + 'ϴ' => 'θ', + 'Ϸ' => 'ϸ', + 'Ϲ' => 'ϲ', + 'Ϻ' => 'ϻ', + 'Ͻ' => 'ͻ', + 'Ͼ' => 'ͼ', + 'Ͽ' => 'ͽ', + 'Ѐ' => 'ѐ', + 'Ё' => 'ё', + 'Ђ' => 'ђ', + 'Ѓ' => 'ѓ', + 'Є' => 'є', + 'Ѕ' => 'ѕ', + 'І' => 'і', + 'Ї' => 'ї', + 'Ј' => 'ј', + 'Љ' => 'љ', + 'Њ' => 'њ', + 'Ћ' => 'ћ', + 'Ќ' => 'ќ', + 'Ѝ' => 'ѝ', + 'Ў' => 'ў', + 'Џ' => 'џ', + 'А' => 'а', + 'Б' => 'б', + 'В' => 'в', + 'Г' => 'г', + 'Д' => 'д', + 'Е' => 'е', + 'Ж' => 'ж', + 'З' => 'з', + 'И' => 'и', + 'Й' => 'й', + 'К' => 'к', + 'Л' => 'л', + 'М' => 'м', + 'Н' => 'н', + 'О' => 'о', + 'П' => 'п', + 'Р' => 'р', + 'С' => 'с', + 'Т' => 'т', + 'У' => 'у', + 'Ф' => 'ф', + 'Х' => 'х', + 'Ц' => 'ц', + 'Ч' => 'ч', + 'Ш' => 'ш', + 'Щ' => 'щ', + 'Ъ' => 'ъ', + 'Ы' => 'ы', + 'Ь' => 'ь', + 'Э' => 'э', + 'Ю' => 'ю', + 'Я' => 'я', + 'Ѡ' => 'ѡ', + 'Ѣ' => 'ѣ', + 'Ѥ' => 'ѥ', + 'Ѧ' => 'ѧ', + 'Ѩ' => 'ѩ', + 'Ѫ' => 'ѫ', + 'Ѭ' => 'ѭ', + 'Ѯ' => 'ѯ', + 'Ѱ' => 'ѱ', + 'Ѳ' => 'ѳ', + 'Ѵ' => 'ѵ', + 'Ѷ' => 'ѷ', + 'Ѹ' => 'ѹ', + 'Ѻ' => 'ѻ', + 'Ѽ' => 'ѽ', + 'Ѿ' => 'ѿ', + 'Ҁ' => 'ҁ', + 'Ҋ' => 'ҋ', + 'Ҍ' => 'ҍ', + 'Ҏ' => 'ҏ', + 'Ґ' => 'ґ', + 'Ғ' => 'ғ', + 'Ҕ' => 'ҕ', + 'Җ' => 'җ', + 'Ҙ' => 'ҙ', + 'Қ' => 'қ', + 'Ҝ' => 'ҝ', + 'Ҟ' => 'ҟ', + 'Ҡ' => 'ҡ', + 'Ң' => 'ң', + 'Ҥ' => 'ҥ', + 'Ҧ' => 'ҧ', + 'Ҩ' => 'ҩ', + 'Ҫ' => 'ҫ', + 'Ҭ' => 'ҭ', + 'Ү' => 'ү', + 'Ұ' => 'ұ', + 'Ҳ' => 'ҳ', + 'Ҵ' => 'ҵ', + 'Ҷ' => 'ҷ', + 'Ҹ' => 'ҹ', + 'Һ' => 'һ', + 'Ҽ' => 'ҽ', + 'Ҿ' => 'ҿ', + 'Ӏ' => 'ӏ', + 'Ӂ' => 'ӂ', + 'Ӄ' => 'ӄ', + 'Ӆ' => 'ӆ', + 'Ӈ' => 'ӈ', + 'Ӊ' => 'ӊ', + 'Ӌ' => 'ӌ', + 'Ӎ' => 'ӎ', + 'Ӑ' => 'ӑ', + 'Ӓ' => 'ӓ', + 'Ӕ' => 'ӕ', + 'Ӗ' => 'ӗ', + 'Ә' => 'ә', + 'Ӛ' => 'ӛ', + 'Ӝ' => 'ӝ', + 'Ӟ' => 'ӟ', + 'Ӡ' => 'ӡ', + 'Ӣ' => 'ӣ', + 'Ӥ' => 'ӥ', + 'Ӧ' => 'ӧ', + 'Ө' => 'ө', + 'Ӫ' => 'ӫ', + 'Ӭ' => 'ӭ', + 'Ӯ' => 'ӯ', + 'Ӱ' => 'ӱ', + 'Ӳ' => 'ӳ', + 'Ӵ' => 'ӵ', + 'Ӷ' => 'ӷ', + 'Ӹ' => 'ӹ', + 'Ӻ' => 'ӻ', + 'Ӽ' => 'ӽ', + 'Ӿ' => 'ӿ', + 'Ԁ' => 'ԁ', + 'Ԃ' => 'ԃ', + 'Ԅ' => 'ԅ', + 'Ԇ' => 'ԇ', + 'Ԉ' => 'ԉ', + 'Ԋ' => 'ԋ', + 'Ԍ' => 'ԍ', + 'Ԏ' => 'ԏ', + 'Ԑ' => 'ԑ', + 'Ԓ' => 'ԓ', + 'Ԕ' => 'ԕ', + 'Ԗ' => 'ԗ', + 'Ԙ' => 'ԙ', + 'Ԛ' => 'ԛ', + 'Ԝ' => 'ԝ', + 'Ԟ' => 'ԟ', + 'Ԡ' => 'ԡ', + 'Ԣ' => 'ԣ', + 'Ԥ' => 'ԥ', + 'Ԧ' => 'ԧ', + 'Ԩ' => 'ԩ', + 'Ԫ' => 'ԫ', + 'Ԭ' => 'ԭ', + 'Ԯ' => 'ԯ', + 'Ա' => 'ա', + 'Բ' => 'բ', + 'Գ' => 'գ', + 'Դ' => 'դ', + 'Ե' => 'ե', + 'Զ' => 'զ', + 'Է' => 'է', + 'Ը' => 'ը', + 'Թ' => 'թ', + 'Ժ' => 'ժ', + 'Ի' => 'ի', + 'Լ' => 'լ', + 'Խ' => 'խ', + 'Ծ' => 'ծ', + 'Կ' => 'կ', + 'Հ' => 'հ', + 'Ձ' => 'ձ', + 'Ղ' => 'ղ', + 'Ճ' => 'ճ', + 'Մ' => 'մ', + 'Յ' => 'յ', + 'Ն' => 'ն', + 'Շ' => 'շ', + 'Ո' => 'ո', + 'Չ' => 'չ', + 'Պ' => 'պ', + 'Ջ' => 'ջ', + 'Ռ' => 'ռ', + 'Ս' => 'ս', + 'Վ' => 'վ', + 'Տ' => 'տ', + 'Ր' => 'ր', + 'Ց' => 'ց', + 'Ւ' => 'ւ', + 'Փ' => 'փ', + 'Ք' => 'ք', + 'Օ' => 'օ', + 'Ֆ' => 'ֆ', + 'Ⴀ' => 'ⴀ', + 'Ⴁ' => 'ⴁ', + 'Ⴂ' => 'ⴂ', + 'Ⴃ' => 'ⴃ', + 'Ⴄ' => 'ⴄ', + 'Ⴅ' => 'ⴅ', + 'Ⴆ' => 'ⴆ', + 'Ⴇ' => 'ⴇ', + 'Ⴈ' => 'ⴈ', + 'Ⴉ' => 'ⴉ', + 'Ⴊ' => 'ⴊ', + 'Ⴋ' => 'ⴋ', + 'Ⴌ' => 'ⴌ', + 'Ⴍ' => 'ⴍ', + 'Ⴎ' => 'ⴎ', + 'Ⴏ' => 'ⴏ', + 'Ⴐ' => 'ⴐ', + 'Ⴑ' => 'ⴑ', + 'Ⴒ' => 'ⴒ', + 'Ⴓ' => 'ⴓ', + 'Ⴔ' => 'ⴔ', + 'Ⴕ' => 'ⴕ', + 'Ⴖ' => 'ⴖ', + 'Ⴗ' => 'ⴗ', + 'Ⴘ' => 'ⴘ', + 'Ⴙ' => 'ⴙ', + 'Ⴚ' => 'ⴚ', + 'Ⴛ' => 'ⴛ', + 'Ⴜ' => 'ⴜ', + 'Ⴝ' => 'ⴝ', + 'Ⴞ' => 'ⴞ', + 'Ⴟ' => 'ⴟ', + 'Ⴠ' => 'ⴠ', + 'Ⴡ' => 'ⴡ', + 'Ⴢ' => 'ⴢ', + 'Ⴣ' => 'ⴣ', + 'Ⴤ' => 'ⴤ', + 'Ⴥ' => 'ⴥ', + 'Ⴧ' => 'ⴧ', + 'Ⴭ' => 'ⴭ', + 'Ꭰ' => 'ꭰ', + 'Ꭱ' => 'ꭱ', + 'Ꭲ' => 'ꭲ', + 'Ꭳ' => 'ꭳ', + 'Ꭴ' => 'ꭴ', + 'Ꭵ' => 'ꭵ', + 'Ꭶ' => 'ꭶ', + 'Ꭷ' => 'ꭷ', + 'Ꭸ' => 'ꭸ', + 'Ꭹ' => 'ꭹ', + 'Ꭺ' => 'ꭺ', + 'Ꭻ' => 'ꭻ', + 'Ꭼ' => 'ꭼ', + 'Ꭽ' => 'ꭽ', + 'Ꭾ' => 'ꭾ', + 'Ꭿ' => 'ꭿ', + 'Ꮀ' => 'ꮀ', + 'Ꮁ' => 'ꮁ', + 'Ꮂ' => 'ꮂ', + 'Ꮃ' => 'ꮃ', + 'Ꮄ' => 'ꮄ', + 'Ꮅ' => 'ꮅ', + 'Ꮆ' => 'ꮆ', + 'Ꮇ' => 'ꮇ', + 'Ꮈ' => 'ꮈ', + 'Ꮉ' => 'ꮉ', + 'Ꮊ' => 'ꮊ', + 'Ꮋ' => 'ꮋ', + 'Ꮌ' => 'ꮌ', + 'Ꮍ' => 'ꮍ', + 'Ꮎ' => 'ꮎ', + 'Ꮏ' => 'ꮏ', + 'Ꮐ' => 'ꮐ', + 'Ꮑ' => 'ꮑ', + 'Ꮒ' => 'ꮒ', + 'Ꮓ' => 'ꮓ', + 'Ꮔ' => 'ꮔ', + 'Ꮕ' => 'ꮕ', + 'Ꮖ' => 'ꮖ', + 'Ꮗ' => 'ꮗ', + 'Ꮘ' => 'ꮘ', + 'Ꮙ' => 'ꮙ', + 'Ꮚ' => 'ꮚ', + 'Ꮛ' => 'ꮛ', + 'Ꮜ' => 'ꮜ', + 'Ꮝ' => 'ꮝ', + 'Ꮞ' => 'ꮞ', + 'Ꮟ' => 'ꮟ', + 'Ꮠ' => 'ꮠ', + 'Ꮡ' => 'ꮡ', + 'Ꮢ' => 'ꮢ', + 'Ꮣ' => 'ꮣ', + 'Ꮤ' => 'ꮤ', + 'Ꮥ' => 'ꮥ', + 'Ꮦ' => 'ꮦ', + 'Ꮧ' => 'ꮧ', + 'Ꮨ' => 'ꮨ', + 'Ꮩ' => 'ꮩ', + 'Ꮪ' => 'ꮪ', + 'Ꮫ' => 'ꮫ', + 'Ꮬ' => 'ꮬ', + 'Ꮭ' => 'ꮭ', + 'Ꮮ' => 'ꮮ', + 'Ꮯ' => 'ꮯ', + 'Ꮰ' => 'ꮰ', + 'Ꮱ' => 'ꮱ', + 'Ꮲ' => 'ꮲ', + 'Ꮳ' => 'ꮳ', + 'Ꮴ' => 'ꮴ', + 'Ꮵ' => 'ꮵ', + 'Ꮶ' => 'ꮶ', + 'Ꮷ' => 'ꮷ', + 'Ꮸ' => 'ꮸ', + 'Ꮹ' => 'ꮹ', + 'Ꮺ' => 'ꮺ', + 'Ꮻ' => 'ꮻ', + 'Ꮼ' => 'ꮼ', + 'Ꮽ' => 'ꮽ', + 'Ꮾ' => 'ꮾ', + 'Ꮿ' => 'ꮿ', + 'Ᏸ' => 'ᏸ', + 'Ᏹ' => 'ᏹ', + 'Ᏺ' => 'ᏺ', + 'Ᏻ' => 'ᏻ', + 'Ᏼ' => 'ᏼ', + 'Ᏽ' => 'ᏽ', + 'Ა' => 'ა', + 'Ბ' => 'ბ', + 'Გ' => 'გ', + 'Დ' => 'დ', + 'Ე' => 'ე', + 'Ვ' => 'ვ', + 'Ზ' => 'ზ', + 'Თ' => 'თ', + 'Ი' => 'ი', + 'Კ' => 'კ', + 'Ლ' => 'ლ', + 'Მ' => 'მ', + 'Ნ' => 'ნ', + 'Ო' => 'ო', + 'Პ' => 'პ', + 'Ჟ' => 'ჟ', + 'Რ' => 'რ', + 'Ს' => 'ს', + 'Ტ' => 'ტ', + 'Უ' => 'უ', + 'Ფ' => 'ფ', + 'Ქ' => 'ქ', + 'Ღ' => 'ღ', + 'Ყ' => 'ყ', + 'Შ' => 'შ', + 'Ჩ' => 'ჩ', + 'Ც' => 'ც', + 'Ძ' => 'ძ', + 'Წ' => 'წ', + 'Ჭ' => 'ჭ', + 'Ხ' => 'ხ', + 'Ჯ' => 'ჯ', + 'Ჰ' => 'ჰ', + 'Ჱ' => 'ჱ', + 'Ჲ' => 'ჲ', + 'Ჳ' => 'ჳ', + 'Ჴ' => 'ჴ', + 'Ჵ' => 'ჵ', + 'Ჶ' => 'ჶ', + 'Ჷ' => 'ჷ', + 'Ჸ' => 'ჸ', + 'Ჹ' => 'ჹ', + 'Ჺ' => 'ჺ', + 'Ჽ' => 'ჽ', + 'Ჾ' => 'ჾ', + 'Ჿ' => 'ჿ', + 'Ḁ' => 'ḁ', + 'Ḃ' => 'ḃ', + 'Ḅ' => 'ḅ', + 'Ḇ' => 'ḇ', + 'Ḉ' => 'ḉ', + 'Ḋ' => 'ḋ', + 'Ḍ' => 'ḍ', + 'Ḏ' => 'ḏ', + 'Ḑ' => 'ḑ', + 'Ḓ' => 'ḓ', + 'Ḕ' => 'ḕ', + 'Ḗ' => 'ḗ', + 'Ḙ' => 'ḙ', + 'Ḛ' => 'ḛ', + 'Ḝ' => 'ḝ', + 'Ḟ' => 'ḟ', + 'Ḡ' => 'ḡ', + 'Ḣ' => 'ḣ', + 'Ḥ' => 'ḥ', + 'Ḧ' => 'ḧ', + 'Ḩ' => 'ḩ', + 'Ḫ' => 'ḫ', + 'Ḭ' => 'ḭ', + 'Ḯ' => 'ḯ', + 'Ḱ' => 'ḱ', + 'Ḳ' => 'ḳ', + 'Ḵ' => 'ḵ', + 'Ḷ' => 'ḷ', + 'Ḹ' => 'ḹ', + 'Ḻ' => 'ḻ', + 'Ḽ' => 'ḽ', + 'Ḿ' => 'ḿ', + 'Ṁ' => 'ṁ', + 'Ṃ' => 'ṃ', + 'Ṅ' => 'ṅ', + 'Ṇ' => 'ṇ', + 'Ṉ' => 'ṉ', + 'Ṋ' => 'ṋ', + 'Ṍ' => 'ṍ', + 'Ṏ' => 'ṏ', + 'Ṑ' => 'ṑ', + 'Ṓ' => 'ṓ', + 'Ṕ' => 'ṕ', + 'Ṗ' => 'ṗ', + 'Ṙ' => 'ṙ', + 'Ṛ' => 'ṛ', + 'Ṝ' => 'ṝ', + 'Ṟ' => 'ṟ', + 'Ṡ' => 'ṡ', + 'Ṣ' => 'ṣ', + 'Ṥ' => 'ṥ', + 'Ṧ' => 'ṧ', + 'Ṩ' => 'ṩ', + 'Ṫ' => 'ṫ', + 'Ṭ' => 'ṭ', + 'Ṯ' => 'ṯ', + 'Ṱ' => 'ṱ', + 'Ṳ' => 'ṳ', + 'Ṵ' => 'ṵ', + 'Ṷ' => 'ṷ', + 'Ṹ' => 'ṹ', + 'Ṻ' => 'ṻ', + 'Ṽ' => 'ṽ', + 'Ṿ' => 'ṿ', + 'Ẁ' => 'ẁ', + 'Ẃ' => 'ẃ', + 'Ẅ' => 'ẅ', + 'Ẇ' => 'ẇ', + 'Ẉ' => 'ẉ', + 'Ẋ' => 'ẋ', + 'Ẍ' => 'ẍ', + 'Ẏ' => 'ẏ', + 'Ẑ' => 'ẑ', + 'Ẓ' => 'ẓ', + 'Ẕ' => 'ẕ', + 'ẞ' => 'ß', + 'Ạ' => 'ạ', + 'Ả' => 'ả', + 'Ấ' => 'ấ', + 'Ầ' => 'ầ', + 'Ẩ' => 'ẩ', + 'Ẫ' => 'ẫ', + 'Ậ' => 'ậ', + 'Ắ' => 'ắ', + 'Ằ' => 'ằ', + 'Ẳ' => 'ẳ', + 'Ẵ' => 'ẵ', + 'Ặ' => 'ặ', + 'Ẹ' => 'ẹ', + 'Ẻ' => 'ẻ', + 'Ẽ' => 'ẽ', + 'Ế' => 'ế', + 'Ề' => 'ề', + 'Ể' => 'ể', + 'Ễ' => 'ễ', + 'Ệ' => 'ệ', + 'Ỉ' => 'ỉ', + 'Ị' => 'ị', + 'Ọ' => 'ọ', + 'Ỏ' => 'ỏ', + 'Ố' => 'ố', + 'Ồ' => 'ồ', + 'Ổ' => 'ổ', + 'Ỗ' => 'ỗ', + 'Ộ' => 'ộ', + 'Ớ' => 'ớ', + 'Ờ' => 'ờ', + 'Ở' => 'ở', + 'Ỡ' => 'ỡ', + 'Ợ' => 'ợ', + 'Ụ' => 'ụ', + 'Ủ' => 'ủ', + 'Ứ' => 'ứ', + 'Ừ' => 'ừ', + 'Ử' => 'ử', + 'Ữ' => 'ữ', + 'Ự' => 'ự', + 'Ỳ' => 'ỳ', + 'Ỵ' => 'ỵ', + 'Ỷ' => 'ỷ', + 'Ỹ' => 'ỹ', + 'Ỻ' => 'ỻ', + 'Ỽ' => 'ỽ', + 'Ỿ' => 'ỿ', + 'Ἀ' => 'ἀ', + 'Ἁ' => 'ἁ', + 'Ἂ' => 'ἂ', + 'Ἃ' => 'ἃ', + 'Ἄ' => 'ἄ', + 'Ἅ' => 'ἅ', + 'Ἆ' => 'ἆ', + 'Ἇ' => 'ἇ', + 'Ἐ' => 'ἐ', + 'Ἑ' => 'ἑ', + 'Ἒ' => 'ἒ', + 'Ἓ' => 'ἓ', + 'Ἔ' => 'ἔ', + 'Ἕ' => 'ἕ', + 'Ἠ' => 'ἠ', + 'Ἡ' => 'ἡ', + 'Ἢ' => 'ἢ', + 'Ἣ' => 'ἣ', + 'Ἤ' => 'ἤ', + 'Ἥ' => 'ἥ', + 'Ἦ' => 'ἦ', + 'Ἧ' => 'ἧ', + 'Ἰ' => 'ἰ', + 'Ἱ' => 'ἱ', + 'Ἲ' => 'ἲ', + 'Ἳ' => 'ἳ', + 'Ἴ' => 'ἴ', + 'Ἵ' => 'ἵ', + 'Ἶ' => 'ἶ', + 'Ἷ' => 'ἷ', + 'Ὀ' => 'ὀ', + 'Ὁ' => 'ὁ', + 'Ὂ' => 'ὂ', + 'Ὃ' => 'ὃ', + 'Ὄ' => 'ὄ', + 'Ὅ' => 'ὅ', + 'Ὑ' => 'ὑ', + 'Ὓ' => 'ὓ', + 'Ὕ' => 'ὕ', + 'Ὗ' => 'ὗ', + 'Ὠ' => 'ὠ', + 'Ὡ' => 'ὡ', + 'Ὢ' => 'ὢ', + 'Ὣ' => 'ὣ', + 'Ὤ' => 'ὤ', + 'Ὥ' => 'ὥ', + 'Ὦ' => 'ὦ', + 'Ὧ' => 'ὧ', + 'ᾈ' => 'ᾀ', + 'ᾉ' => 'ᾁ', + 'ᾊ' => 'ᾂ', + 'ᾋ' => 'ᾃ', + 'ᾌ' => 'ᾄ', + 'ᾍ' => 'ᾅ', + 'ᾎ' => 'ᾆ', + 'ᾏ' => 'ᾇ', + 'ᾘ' => 'ᾐ', + 'ᾙ' => 'ᾑ', + 'ᾚ' => 'ᾒ', + 'ᾛ' => 'ᾓ', + 'ᾜ' => 'ᾔ', + 'ᾝ' => 'ᾕ', + 'ᾞ' => 'ᾖ', + 'ᾟ' => 'ᾗ', + 'ᾨ' => 'ᾠ', + 'ᾩ' => 'ᾡ', + 'ᾪ' => 'ᾢ', + 'ᾫ' => 'ᾣ', + 'ᾬ' => 'ᾤ', + 'ᾭ' => 'ᾥ', + 'ᾮ' => 'ᾦ', + 'ᾯ' => 'ᾧ', + 'Ᾰ' => 'ᾰ', + 'Ᾱ' => 'ᾱ', + 'Ὰ' => 'ὰ', + 'Ά' => 'ά', + 'ᾼ' => 'ᾳ', + 'Ὲ' => 'ὲ', + 'Έ' => 'έ', + 'Ὴ' => 'ὴ', + 'Ή' => 'ή', + 'ῌ' => 'ῃ', + 'Ῐ' => 'ῐ', + 'Ῑ' => 'ῑ', + 'Ὶ' => 'ὶ', + 'Ί' => 'ί', + 'Ῠ' => 'ῠ', + 'Ῡ' => 'ῡ', + 'Ὺ' => 'ὺ', + 'Ύ' => 'ύ', + 'Ῥ' => 'ῥ', + 'Ὸ' => 'ὸ', + 'Ό' => 'ό', + 'Ὼ' => 'ὼ', + 'Ώ' => 'ώ', + 'ῼ' => 'ῳ', + 'Ω' => 'ω', + 'K' => 'k', + 'Å' => 'å', + 'Ⅎ' => 'ⅎ', + 'Ⅰ' => 'ⅰ', + 'Ⅱ' => 'ⅱ', + 'Ⅲ' => 'ⅲ', + 'Ⅳ' => 'ⅳ', + 'Ⅴ' => 'ⅴ', + 'Ⅵ' => 'ⅵ', + 'Ⅶ' => 'ⅶ', + 'Ⅷ' => 'ⅷ', + 'Ⅸ' => 'ⅸ', + 'Ⅹ' => 'ⅹ', + 'Ⅺ' => 'ⅺ', + 'Ⅻ' => 'ⅻ', + 'Ⅼ' => 'ⅼ', + 'Ⅽ' => 'ⅽ', + 'Ⅾ' => 'ⅾ', + 'Ⅿ' => 'ⅿ', + 'Ↄ' => 'ↄ', + 'Ⓐ' => 'ⓐ', + 'Ⓑ' => 'ⓑ', + 'Ⓒ' => 'ⓒ', + 'Ⓓ' => 'ⓓ', + 'Ⓔ' => 'ⓔ', + 'Ⓕ' => 'ⓕ', + 'Ⓖ' => 'ⓖ', + 'Ⓗ' => 'ⓗ', + 'Ⓘ' => 'ⓘ', + 'Ⓙ' => 'ⓙ', + 'Ⓚ' => 'ⓚ', + 'Ⓛ' => 'ⓛ', + 'Ⓜ' => 'ⓜ', + 'Ⓝ' => 'ⓝ', + 'Ⓞ' => 'ⓞ', + 'Ⓟ' => 'ⓟ', + 'Ⓠ' => 'ⓠ', + 'Ⓡ' => 'ⓡ', + 'Ⓢ' => 'ⓢ', + 'Ⓣ' => 'ⓣ', + 'Ⓤ' => 'ⓤ', + 'Ⓥ' => 'ⓥ', + 'Ⓦ' => 'ⓦ', + 'Ⓧ' => 'ⓧ', + 'Ⓨ' => 'ⓨ', + 'Ⓩ' => 'ⓩ', + 'Ⰰ' => 'ⰰ', + 'Ⰱ' => 'ⰱ', + 'Ⰲ' => 'ⰲ', + 'Ⰳ' => 'ⰳ', + 'Ⰴ' => 'ⰴ', + 'Ⰵ' => 'ⰵ', + 'Ⰶ' => 'ⰶ', + 'Ⰷ' => 'ⰷ', + 'Ⰸ' => 'ⰸ', + 'Ⰹ' => 'ⰹ', + 'Ⰺ' => 'ⰺ', + 'Ⰻ' => 'ⰻ', + 'Ⰼ' => 'ⰼ', + 'Ⰽ' => 'ⰽ', + 'Ⰾ' => 'ⰾ', + 'Ⰿ' => 'ⰿ', + 'Ⱀ' => 'ⱀ', + 'Ⱁ' => 'ⱁ', + 'Ⱂ' => 'ⱂ', + 'Ⱃ' => 'ⱃ', + 'Ⱄ' => 'ⱄ', + 'Ⱅ' => 'ⱅ', + 'Ⱆ' => 'ⱆ', + 'Ⱇ' => 'ⱇ', + 'Ⱈ' => 'ⱈ', + 'Ⱉ' => 'ⱉ', + 'Ⱊ' => 'ⱊ', + 'Ⱋ' => 'ⱋ', + 'Ⱌ' => 'ⱌ', + 'Ⱍ' => 'ⱍ', + 'Ⱎ' => 'ⱎ', + 'Ⱏ' => 'ⱏ', + 'Ⱐ' => 'ⱐ', + 'Ⱑ' => 'ⱑ', + 'Ⱒ' => 'ⱒ', + 'Ⱓ' => 'ⱓ', + 'Ⱔ' => 'ⱔ', + 'Ⱕ' => 'ⱕ', + 'Ⱖ' => 'ⱖ', + 'Ⱗ' => 'ⱗ', + 'Ⱘ' => 'ⱘ', + 'Ⱙ' => 'ⱙ', + 'Ⱚ' => 'ⱚ', + 'Ⱛ' => 'ⱛ', + 'Ⱜ' => 'ⱜ', + 'Ⱝ' => 'ⱝ', + 'Ⱞ' => 'ⱞ', + 'Ⱡ' => 'ⱡ', + 'Ɫ' => 'ɫ', + 'Ᵽ' => 'ᵽ', + 'Ɽ' => 'ɽ', + 'Ⱨ' => 'ⱨ', + 'Ⱪ' => 'ⱪ', + 'Ⱬ' => 'ⱬ', + 'Ɑ' => 'ɑ', + 'Ɱ' => 'ɱ', + 'Ɐ' => 'ɐ', + 'Ɒ' => 'ɒ', + 'Ⱳ' => 'ⱳ', + 'Ⱶ' => 'ⱶ', + 'Ȿ' => 'ȿ', + 'Ɀ' => 'ɀ', + 'Ⲁ' => 'ⲁ', + 'Ⲃ' => 'ⲃ', + 'Ⲅ' => 'ⲅ', + 'Ⲇ' => 'ⲇ', + 'Ⲉ' => 'ⲉ', + 'Ⲋ' => 'ⲋ', + 'Ⲍ' => 'ⲍ', + 'Ⲏ' => 'ⲏ', + 'Ⲑ' => 'ⲑ', + 'Ⲓ' => 'ⲓ', + 'Ⲕ' => 'ⲕ', + 'Ⲗ' => 'ⲗ', + 'Ⲙ' => 'ⲙ', + 'Ⲛ' => 'ⲛ', + 'Ⲝ' => 'ⲝ', + 'Ⲟ' => 'ⲟ', + 'Ⲡ' => 'ⲡ', + 'Ⲣ' => 'ⲣ', + 'Ⲥ' => 'ⲥ', + 'Ⲧ' => 'ⲧ', + 'Ⲩ' => 'ⲩ', + 'Ⲫ' => 'ⲫ', + 'Ⲭ' => 'ⲭ', + 'Ⲯ' => 'ⲯ', + 'Ⲱ' => 'ⲱ', + 'Ⲳ' => 'ⲳ', + 'Ⲵ' => 'ⲵ', + 'Ⲷ' => 'ⲷ', + 'Ⲹ' => 'ⲹ', + 'Ⲻ' => 'ⲻ', + 'Ⲽ' => 'ⲽ', + 'Ⲿ' => 'ⲿ', + 'Ⳁ' => 'ⳁ', + 'Ⳃ' => 'ⳃ', + 'Ⳅ' => 'ⳅ', + 'Ⳇ' => 'ⳇ', + 'Ⳉ' => 'ⳉ', + 'Ⳋ' => 'ⳋ', + 'Ⳍ' => 'ⳍ', + 'Ⳏ' => 'ⳏ', + 'Ⳑ' => 'ⳑ', + 'Ⳓ' => 'ⳓ', + 'Ⳕ' => 'ⳕ', + 'Ⳗ' => 'ⳗ', + 'Ⳙ' => 'ⳙ', + 'Ⳛ' => 'ⳛ', + 'Ⳝ' => 'ⳝ', + 'Ⳟ' => 'ⳟ', + 'Ⳡ' => 'ⳡ', + 'Ⳣ' => 'ⳣ', + 'Ⳬ' => 'ⳬ', + 'Ⳮ' => 'ⳮ', + 'Ⳳ' => 'ⳳ', + 'Ꙁ' => 'ꙁ', + 'Ꙃ' => 'ꙃ', + 'Ꙅ' => 'ꙅ', + 'Ꙇ' => 'ꙇ', + 'Ꙉ' => 'ꙉ', + 'Ꙋ' => 'ꙋ', + 'Ꙍ' => 'ꙍ', + 'Ꙏ' => 'ꙏ', + 'Ꙑ' => 'ꙑ', + 'Ꙓ' => 'ꙓ', + 'Ꙕ' => 'ꙕ', + 'Ꙗ' => 'ꙗ', + 'Ꙙ' => 'ꙙ', + 'Ꙛ' => 'ꙛ', + 'Ꙝ' => 'ꙝ', + 'Ꙟ' => 'ꙟ', + 'Ꙡ' => 'ꙡ', + 'Ꙣ' => 'ꙣ', + 'Ꙥ' => 'ꙥ', + 'Ꙧ' => 'ꙧ', + 'Ꙩ' => 'ꙩ', + 'Ꙫ' => 'ꙫ', + 'Ꙭ' => 'ꙭ', + 'Ꚁ' => 'ꚁ', + 'Ꚃ' => 'ꚃ', + 'Ꚅ' => 'ꚅ', + 'Ꚇ' => 'ꚇ', + 'Ꚉ' => 'ꚉ', + 'Ꚋ' => 'ꚋ', + 'Ꚍ' => 'ꚍ', + 'Ꚏ' => 'ꚏ', + 'Ꚑ' => 'ꚑ', + 'Ꚓ' => 'ꚓ', + 'Ꚕ' => 'ꚕ', + 'Ꚗ' => 'ꚗ', + 'Ꚙ' => 'ꚙ', + 'Ꚛ' => 'ꚛ', + 'Ꜣ' => 'ꜣ', + 'Ꜥ' => 'ꜥ', + 'Ꜧ' => 'ꜧ', + 'Ꜩ' => 'ꜩ', + 'Ꜫ' => 'ꜫ', + 'Ꜭ' => 'ꜭ', + 'Ꜯ' => 'ꜯ', + 'Ꜳ' => 'ꜳ', + 'Ꜵ' => 'ꜵ', + 'Ꜷ' => 'ꜷ', + 'Ꜹ' => 'ꜹ', + 'Ꜻ' => 'ꜻ', + 'Ꜽ' => 'ꜽ', + 'Ꜿ' => 'ꜿ', + 'Ꝁ' => 'ꝁ', + 'Ꝃ' => 'ꝃ', + 'Ꝅ' => 'ꝅ', + 'Ꝇ' => 'ꝇ', + 'Ꝉ' => 'ꝉ', + 'Ꝋ' => 'ꝋ', + 'Ꝍ' => 'ꝍ', + 'Ꝏ' => 'ꝏ', + 'Ꝑ' => 'ꝑ', + 'Ꝓ' => 'ꝓ', + 'Ꝕ' => 'ꝕ', + 'Ꝗ' => 'ꝗ', + 'Ꝙ' => 'ꝙ', + 'Ꝛ' => 'ꝛ', + 'Ꝝ' => 'ꝝ', + 'Ꝟ' => 'ꝟ', + 'Ꝡ' => 'ꝡ', + 'Ꝣ' => 'ꝣ', + 'Ꝥ' => 'ꝥ', + 'Ꝧ' => 'ꝧ', + 'Ꝩ' => 'ꝩ', + 'Ꝫ' => 'ꝫ', + 'Ꝭ' => 'ꝭ', + 'Ꝯ' => 'ꝯ', + 'Ꝺ' => 'ꝺ', + 'Ꝼ' => 'ꝼ', + 'Ᵹ' => 'ᵹ', + 'Ꝿ' => 'ꝿ', + 'Ꞁ' => 'ꞁ', + 'Ꞃ' => 'ꞃ', + 'Ꞅ' => 'ꞅ', + 'Ꞇ' => 'ꞇ', + 'Ꞌ' => 'ꞌ', + 'Ɥ' => 'ɥ', + 'Ꞑ' => 'ꞑ', + 'Ꞓ' => 'ꞓ', + 'Ꞗ' => 'ꞗ', + 'Ꞙ' => 'ꞙ', + 'Ꞛ' => 'ꞛ', + 'Ꞝ' => 'ꞝ', + 'Ꞟ' => 'ꞟ', + 'Ꞡ' => 'ꞡ', + 'Ꞣ' => 'ꞣ', + 'Ꞥ' => 'ꞥ', + 'Ꞧ' => 'ꞧ', + 'Ꞩ' => 'ꞩ', + 'Ɦ' => 'ɦ', + 'Ɜ' => 'ɜ', + 'Ɡ' => 'ɡ', + 'Ɬ' => 'ɬ', + 'Ɪ' => 'ɪ', + 'Ʞ' => 'ʞ', + 'Ʇ' => 'ʇ', + 'Ʝ' => 'ʝ', + 'Ꭓ' => 'ꭓ', + 'Ꞵ' => 'ꞵ', + 'Ꞷ' => 'ꞷ', + 'Ꞹ' => 'ꞹ', + 'Ꞻ' => 'ꞻ', + 'Ꞽ' => 'ꞽ', + 'Ꞿ' => 'ꞿ', + 'Ꟃ' => 'ꟃ', + 'Ꞔ' => 'ꞔ', + 'Ʂ' => 'ʂ', + 'Ᶎ' => 'ᶎ', + 'Ꟈ' => 'ꟈ', + 'Ꟊ' => 'ꟊ', + 'Ꟶ' => 'ꟶ', + 'A' => 'a', + 'B' => 'b', + 'C' => 'c', + 'D' => 'd', + 'E' => 'e', + 'F' => 'f', + 'G' => 'g', + 'H' => 'h', + 'I' => 'i', + 'J' => 'j', + 'K' => 'k', + 'L' => 'l', + 'M' => 'm', + 'N' => 'n', + 'O' => 'o', + 'P' => 'p', + 'Q' => 'q', + 'R' => 'r', + 'S' => 's', + 'T' => 't', + 'U' => 'u', + 'V' => 'v', + 'W' => 'w', + 'X' => 'x', + 'Y' => 'y', + 'Z' => 'z', + '𐐀' => '𐐨', + '𐐁' => '𐐩', + '𐐂' => '𐐪', + '𐐃' => '𐐫', + '𐐄' => '𐐬', + '𐐅' => '𐐭', + '𐐆' => '𐐮', + '𐐇' => '𐐯', + '𐐈' => '𐐰', + '𐐉' => '𐐱', + '𐐊' => '𐐲', + '𐐋' => '𐐳', + '𐐌' => '𐐴', + '𐐍' => '𐐵', + '𐐎' => '𐐶', + '𐐏' => '𐐷', + '𐐐' => '𐐸', + '𐐑' => '𐐹', + '𐐒' => '𐐺', + '𐐓' => '𐐻', + '𐐔' => '𐐼', + '𐐕' => '𐐽', + '𐐖' => '𐐾', + '𐐗' => '𐐿', + '𐐘' => '𐑀', + '𐐙' => '𐑁', + '𐐚' => '𐑂', + '𐐛' => '𐑃', + '𐐜' => '𐑄', + '𐐝' => '𐑅', + '𐐞' => '𐑆', + '𐐟' => '𐑇', + '𐐠' => '𐑈', + '𐐡' => '𐑉', + '𐐢' => '𐑊', + '𐐣' => '𐑋', + '𐐤' => '𐑌', + '𐐥' => '𐑍', + '𐐦' => '𐑎', + '𐐧' => '𐑏', + '𐒰' => '𐓘', + '𐒱' => '𐓙', + '𐒲' => '𐓚', + '𐒳' => '𐓛', + '𐒴' => '𐓜', + '𐒵' => '𐓝', + '𐒶' => '𐓞', + '𐒷' => '𐓟', + '𐒸' => '𐓠', + '𐒹' => '𐓡', + '𐒺' => '𐓢', + '𐒻' => '𐓣', + '𐒼' => '𐓤', + '𐒽' => '𐓥', + '𐒾' => '𐓦', + '𐒿' => '𐓧', + '𐓀' => '𐓨', + '𐓁' => '𐓩', + '𐓂' => '𐓪', + '𐓃' => '𐓫', + '𐓄' => '𐓬', + '𐓅' => '𐓭', + '𐓆' => '𐓮', + '𐓇' => '𐓯', + '𐓈' => '𐓰', + '𐓉' => '𐓱', + '𐓊' => '𐓲', + '𐓋' => '𐓳', + '𐓌' => '𐓴', + '𐓍' => '𐓵', + '𐓎' => '𐓶', + '𐓏' => '𐓷', + '𐓐' => '𐓸', + '𐓑' => '𐓹', + '𐓒' => '𐓺', + '𐓓' => '𐓻', + '𐲀' => '𐳀', + '𐲁' => '𐳁', + '𐲂' => '𐳂', + '𐲃' => '𐳃', + '𐲄' => '𐳄', + '𐲅' => '𐳅', + '𐲆' => '𐳆', + '𐲇' => '𐳇', + '𐲈' => '𐳈', + '𐲉' => '𐳉', + '𐲊' => '𐳊', + '𐲋' => '𐳋', + '𐲌' => '𐳌', + '𐲍' => '𐳍', + '𐲎' => '𐳎', + '𐲏' => '𐳏', + '𐲐' => '𐳐', + '𐲑' => '𐳑', + '𐲒' => '𐳒', + '𐲓' => '𐳓', + '𐲔' => '𐳔', + '𐲕' => '𐳕', + '𐲖' => '𐳖', + '𐲗' => '𐳗', + '𐲘' => '𐳘', + '𐲙' => '𐳙', + '𐲚' => '𐳚', + '𐲛' => '𐳛', + '𐲜' => '𐳜', + '𐲝' => '𐳝', + '𐲞' => '𐳞', + '𐲟' => '𐳟', + '𐲠' => '𐳠', + '𐲡' => '𐳡', + '𐲢' => '𐳢', + '𐲣' => '𐳣', + '𐲤' => '𐳤', + '𐲥' => '𐳥', + '𐲦' => '𐳦', + '𐲧' => '𐳧', + '𐲨' => '𐳨', + '𐲩' => '𐳩', + '𐲪' => '𐳪', + '𐲫' => '𐳫', + '𐲬' => '𐳬', + '𐲭' => '𐳭', + '𐲮' => '𐳮', + '𐲯' => '𐳯', + '𐲰' => '𐳰', + '𐲱' => '𐳱', + '𐲲' => '𐳲', + '𑢠' => '𑣀', + '𑢡' => '𑣁', + '𑢢' => '𑣂', + '𑢣' => '𑣃', + '𑢤' => '𑣄', + '𑢥' => '𑣅', + '𑢦' => '𑣆', + '𑢧' => '𑣇', + '𑢨' => '𑣈', + '𑢩' => '𑣉', + '𑢪' => '𑣊', + '𑢫' => '𑣋', + '𑢬' => '𑣌', + '𑢭' => '𑣍', + '𑢮' => '𑣎', + '𑢯' => '𑣏', + '𑢰' => '𑣐', + '𑢱' => '𑣑', + '𑢲' => '𑣒', + '𑢳' => '𑣓', + '𑢴' => '𑣔', + '𑢵' => '𑣕', + '𑢶' => '𑣖', + '𑢷' => '𑣗', + '𑢸' => '𑣘', + '𑢹' => '𑣙', + '𑢺' => '𑣚', + '𑢻' => '𑣛', + '𑢼' => '𑣜', + '𑢽' => '𑣝', + '𑢾' => '𑣞', + '𑢿' => '𑣟', + '𖹀' => '𖹠', + '𖹁' => '𖹡', + '𖹂' => '𖹢', + '𖹃' => '𖹣', + '𖹄' => '𖹤', + '𖹅' => '𖹥', + '𖹆' => '𖹦', + '𖹇' => '𖹧', + '𖹈' => '𖹨', + '𖹉' => '𖹩', + '𖹊' => '𖹪', + '𖹋' => '𖹫', + '𖹌' => '𖹬', + '𖹍' => '𖹭', + '𖹎' => '𖹮', + '𖹏' => '𖹯', + '𖹐' => '𖹰', + '𖹑' => '𖹱', + '𖹒' => '𖹲', + '𖹓' => '𖹳', + '𖹔' => '𖹴', + '𖹕' => '𖹵', + '𖹖' => '𖹶', + '𖹗' => '𖹷', + '𖹘' => '𖹸', + '𖹙' => '𖹹', + '𖹚' => '𖹺', + '𖹛' => '𖹻', + '𖹜' => '𖹼', + '𖹝' => '𖹽', + '𖹞' => '𖹾', + '𖹟' => '𖹿', + '𞤀' => '𞤢', + '𞤁' => '𞤣', + '𞤂' => '𞤤', + '𞤃' => '𞤥', + '𞤄' => '𞤦', + '𞤅' => '𞤧', + '𞤆' => '𞤨', + '𞤇' => '𞤩', + '𞤈' => '𞤪', + '𞤉' => '𞤫', + '𞤊' => '𞤬', + '𞤋' => '𞤭', + '𞤌' => '𞤮', + '𞤍' => '𞤯', + '𞤎' => '𞤰', + '𞤏' => '𞤱', + '𞤐' => '𞤲', + '𞤑' => '𞤳', + '𞤒' => '𞤴', + '𞤓' => '𞤵', + '𞤔' => '𞤶', + '𞤕' => '𞤷', + '𞤖' => '𞤸', + '𞤗' => '𞤹', + '𞤘' => '𞤺', + '𞤙' => '𞤻', + '𞤚' => '𞤼', + '𞤛' => '𞤽', + '𞤜' => '𞤾', + '𞤝' => '𞤿', + '𞤞' => '𞥀', + '𞤟' => '𞥁', + '𞤠' => '𞥂', + '𞤡' => '𞥃', +); diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php new file mode 100644 index 0000000..2a8f6e7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php @@ -0,0 +1,5 @@ + 'A', + 'b' => 'B', + 'c' => 'C', + 'd' => 'D', + 'e' => 'E', + 'f' => 'F', + 'g' => 'G', + 'h' => 'H', + 'i' => 'I', + 'j' => 'J', + 'k' => 'K', + 'l' => 'L', + 'm' => 'M', + 'n' => 'N', + 'o' => 'O', + 'p' => 'P', + 'q' => 'Q', + 'r' => 'R', + 's' => 'S', + 't' => 'T', + 'u' => 'U', + 'v' => 'V', + 'w' => 'W', + 'x' => 'X', + 'y' => 'Y', + 'z' => 'Z', + 'µ' => 'Μ', + 'à' => 'À', + 'á' => 'Á', + 'â' => 'Â', + 'ã' => 'Ã', + 'ä' => 'Ä', + 'å' => 'Å', + 'æ' => 'Æ', + 'ç' => 'Ç', + 'è' => 'È', + 'é' => 'É', + 'ê' => 'Ê', + 'ë' => 'Ë', + 'ì' => 'Ì', + 'í' => 'Í', + 'î' => 'Î', + 'ï' => 'Ï', + 'ð' => 'Ð', + 'ñ' => 'Ñ', + 'ò' => 'Ò', + 'ó' => 'Ó', + 'ô' => 'Ô', + 'õ' => 'Õ', + 'ö' => 'Ö', + 'ø' => 'Ø', + 'ù' => 'Ù', + 'ú' => 'Ú', + 'û' => 'Û', + 'ü' => 'Ü', + 'ý' => 'Ý', + 'þ' => 'Þ', + 'ÿ' => 'Ÿ', + 'ā' => 'Ā', + 'ă' => 'Ă', + 'ą' => 'Ą', + 'ć' => 'Ć', + 'ĉ' => 'Ĉ', + 'ċ' => 'Ċ', + 'č' => 'Č', + 'ď' => 'Ď', + 'đ' => 'Đ', + 'ē' => 'Ē', + 'ĕ' => 'Ĕ', + 'ė' => 'Ė', + 'ę' => 'Ę', + 'ě' => 'Ě', + 'ĝ' => 'Ĝ', + 'ğ' => 'Ğ', + 'ġ' => 'Ġ', + 'ģ' => 'Ģ', + 'ĥ' => 'Ĥ', + 'ħ' => 'Ħ', + 'ĩ' => 'Ĩ', + 'ī' => 'Ī', + 'ĭ' => 'Ĭ', + 'į' => 'Į', + 'ı' => 'I', + 'ij' => 'IJ', + 'ĵ' => 'Ĵ', + 'ķ' => 'Ķ', + 'ĺ' => 'Ĺ', + 'ļ' => 'Ļ', + 'ľ' => 'Ľ', + 'ŀ' => 'Ŀ', + 'ł' => 'Ł', + 'ń' => 'Ń', + 'ņ' => 'Ņ', + 'ň' => 'Ň', + 'ŋ' => 'Ŋ', + 'ō' => 'Ō', + 'ŏ' => 'Ŏ', + 'ő' => 'Ő', + 'œ' => 'Œ', + 'ŕ' => 'Ŕ', + 'ŗ' => 'Ŗ', + 'ř' => 'Ř', + 'ś' => 'Ś', + 'ŝ' => 'Ŝ', + 'ş' => 'Ş', + 'š' => 'Š', + 'ţ' => 'Ţ', + 'ť' => 'Ť', + 'ŧ' => 'Ŧ', + 'ũ' => 'Ũ', + 'ū' => 'Ū', + 'ŭ' => 'Ŭ', + 'ů' => 'Ů', + 'ű' => 'Ű', + 'ų' => 'Ų', + 'ŵ' => 'Ŵ', + 'ŷ' => 'Ŷ', + 'ź' => 'Ź', + 'ż' => 'Ż', + 'ž' => 'Ž', + 'ſ' => 'S', + 'ƀ' => 'Ƀ', + 'ƃ' => 'Ƃ', + 'ƅ' => 'Ƅ', + 'ƈ' => 'Ƈ', + 'ƌ' => 'Ƌ', + 'ƒ' => 'Ƒ', + 'ƕ' => 'Ƕ', + 'ƙ' => 'Ƙ', + 'ƚ' => 'Ƚ', + 'ƞ' => 'Ƞ', + 'ơ' => 'Ơ', + 'ƣ' => 'Ƣ', + 'ƥ' => 'Ƥ', + 'ƨ' => 'Ƨ', + 'ƭ' => 'Ƭ', + 'ư' => 'Ư', + 'ƴ' => 'Ƴ', + 'ƶ' => 'Ƶ', + 'ƹ' => 'Ƹ', + 'ƽ' => 'Ƽ', + 'ƿ' => 'Ƿ', + 'Dž' => 'DŽ', + 'dž' => 'DŽ', + 'Lj' => 'LJ', + 'lj' => 'LJ', + 'Nj' => 'NJ', + 'nj' => 'NJ', + 'ǎ' => 'Ǎ', + 'ǐ' => 'Ǐ', + 'ǒ' => 'Ǒ', + 'ǔ' => 'Ǔ', + 'ǖ' => 'Ǖ', + 'ǘ' => 'Ǘ', + 'ǚ' => 'Ǚ', + 'ǜ' => 'Ǜ', + 'ǝ' => 'Ǝ', + 'ǟ' => 'Ǟ', + 'ǡ' => 'Ǡ', + 'ǣ' => 'Ǣ', + 'ǥ' => 'Ǥ', + 'ǧ' => 'Ǧ', + 'ǩ' => 'Ǩ', + 'ǫ' => 'Ǫ', + 'ǭ' => 'Ǭ', + 'ǯ' => 'Ǯ', + 'Dz' => 'DZ', + 'dz' => 'DZ', + 'ǵ' => 'Ǵ', + 'ǹ' => 'Ǹ', + 'ǻ' => 'Ǻ', + 'ǽ' => 'Ǽ', + 'ǿ' => 'Ǿ', + 'ȁ' => 'Ȁ', + 'ȃ' => 'Ȃ', + 'ȅ' => 'Ȅ', + 'ȇ' => 'Ȇ', + 'ȉ' => 'Ȉ', + 'ȋ' => 'Ȋ', + 'ȍ' => 'Ȍ', + 'ȏ' => 'Ȏ', + 'ȑ' => 'Ȑ', + 'ȓ' => 'Ȓ', + 'ȕ' => 'Ȕ', + 'ȗ' => 'Ȗ', + 'ș' => 'Ș', + 'ț' => 'Ț', + 'ȝ' => 'Ȝ', + 'ȟ' => 'Ȟ', + 'ȣ' => 'Ȣ', + 'ȥ' => 'Ȥ', + 'ȧ' => 'Ȧ', + 'ȩ' => 'Ȩ', + 'ȫ' => 'Ȫ', + 'ȭ' => 'Ȭ', + 'ȯ' => 'Ȯ', + 'ȱ' => 'Ȱ', + 'ȳ' => 'Ȳ', + 'ȼ' => 'Ȼ', + 'ȿ' => 'Ȿ', + 'ɀ' => 'Ɀ', + 'ɂ' => 'Ɂ', + 'ɇ' => 'Ɇ', + 'ɉ' => 'Ɉ', + 'ɋ' => 'Ɋ', + 'ɍ' => 'Ɍ', + 'ɏ' => 'Ɏ', + 'ɐ' => 'Ɐ', + 'ɑ' => 'Ɑ', + 'ɒ' => 'Ɒ', + 'ɓ' => 'Ɓ', + 'ɔ' => 'Ɔ', + 'ɖ' => 'Ɖ', + 'ɗ' => 'Ɗ', + 'ə' => 'Ə', + 'ɛ' => 'Ɛ', + 'ɜ' => 'Ɜ', + 'ɠ' => 'Ɠ', + 'ɡ' => 'Ɡ', + 'ɣ' => 'Ɣ', + 'ɥ' => 'Ɥ', + 'ɦ' => 'Ɦ', + 'ɨ' => 'Ɨ', + 'ɩ' => 'Ɩ', + 'ɪ' => 'Ɪ', + 'ɫ' => 'Ɫ', + 'ɬ' => 'Ɬ', + 'ɯ' => 'Ɯ', + 'ɱ' => 'Ɱ', + 'ɲ' => 'Ɲ', + 'ɵ' => 'Ɵ', + 'ɽ' => 'Ɽ', + 'ʀ' => 'Ʀ', + 'ʂ' => 'Ʂ', + 'ʃ' => 'Ʃ', + 'ʇ' => 'Ʇ', + 'ʈ' => 'Ʈ', + 'ʉ' => 'Ʉ', + 'ʊ' => 'Ʊ', + 'ʋ' => 'Ʋ', + 'ʌ' => 'Ʌ', + 'ʒ' => 'Ʒ', + 'ʝ' => 'Ʝ', + 'ʞ' => 'Ʞ', + 'ͅ' => 'Ι', + 'ͱ' => 'Ͱ', + 'ͳ' => 'Ͳ', + 'ͷ' => 'Ͷ', + 'ͻ' => 'Ͻ', + 'ͼ' => 'Ͼ', + 'ͽ' => 'Ͽ', + 'ά' => 'Ά', + 'έ' => 'Έ', + 'ή' => 'Ή', + 'ί' => 'Ί', + 'α' => 'Α', + 'β' => 'Β', + 'γ' => 'Γ', + 'δ' => 'Δ', + 'ε' => 'Ε', + 'ζ' => 'Ζ', + 'η' => 'Η', + 'θ' => 'Θ', + 'ι' => 'Ι', + 'κ' => 'Κ', + 'λ' => 'Λ', + 'μ' => 'Μ', + 'ν' => 'Ν', + 'ξ' => 'Ξ', + 'ο' => 'Ο', + 'π' => 'Π', + 'ρ' => 'Ρ', + 'ς' => 'Σ', + 'σ' => 'Σ', + 'τ' => 'Τ', + 'υ' => 'Υ', + 'φ' => 'Φ', + 'χ' => 'Χ', + 'ψ' => 'Ψ', + 'ω' => 'Ω', + 'ϊ' => 'Ϊ', + 'ϋ' => 'Ϋ', + 'ό' => 'Ό', + 'ύ' => 'Ύ', + 'ώ' => 'Ώ', + 'ϐ' => 'Β', + 'ϑ' => 'Θ', + 'ϕ' => 'Φ', + 'ϖ' => 'Π', + 'ϗ' => 'Ϗ', + 'ϙ' => 'Ϙ', + 'ϛ' => 'Ϛ', + 'ϝ' => 'Ϝ', + 'ϟ' => 'Ϟ', + 'ϡ' => 'Ϡ', + 'ϣ' => 'Ϣ', + 'ϥ' => 'Ϥ', + 'ϧ' => 'Ϧ', + 'ϩ' => 'Ϩ', + 'ϫ' => 'Ϫ', + 'ϭ' => 'Ϭ', + 'ϯ' => 'Ϯ', + 'ϰ' => 'Κ', + 'ϱ' => 'Ρ', + 'ϲ' => 'Ϲ', + 'ϳ' => 'Ϳ', + 'ϵ' => 'Ε', + 'ϸ' => 'Ϸ', + 'ϻ' => 'Ϻ', + 'а' => 'А', + 'б' => 'Б', + 'в' => 'В', + 'г' => 'Г', + 'д' => 'Д', + 'е' => 'Е', + 'ж' => 'Ж', + 'з' => 'З', + 'и' => 'И', + 'й' => 'Й', + 'к' => 'К', + 'л' => 'Л', + 'м' => 'М', + 'н' => 'Н', + 'о' => 'О', + 'п' => 'П', + 'р' => 'Р', + 'с' => 'С', + 'т' => 'Т', + 'у' => 'У', + 'ф' => 'Ф', + 'х' => 'Х', + 'ц' => 'Ц', + 'ч' => 'Ч', + 'ш' => 'Ш', + 'щ' => 'Щ', + 'ъ' => 'Ъ', + 'ы' => 'Ы', + 'ь' => 'Ь', + 'э' => 'Э', + 'ю' => 'Ю', + 'я' => 'Я', + 'ѐ' => 'Ѐ', + 'ё' => 'Ё', + 'ђ' => 'Ђ', + 'ѓ' => 'Ѓ', + 'є' => 'Є', + 'ѕ' => 'Ѕ', + 'і' => 'І', + 'ї' => 'Ї', + 'ј' => 'Ј', + 'љ' => 'Љ', + 'њ' => 'Њ', + 'ћ' => 'Ћ', + 'ќ' => 'Ќ', + 'ѝ' => 'Ѝ', + 'ў' => 'Ў', + 'џ' => 'Џ', + 'ѡ' => 'Ѡ', + 'ѣ' => 'Ѣ', + 'ѥ' => 'Ѥ', + 'ѧ' => 'Ѧ', + 'ѩ' => 'Ѩ', + 'ѫ' => 'Ѫ', + 'ѭ' => 'Ѭ', + 'ѯ' => 'Ѯ', + 'ѱ' => 'Ѱ', + 'ѳ' => 'Ѳ', + 'ѵ' => 'Ѵ', + 'ѷ' => 'Ѷ', + 'ѹ' => 'Ѹ', + 'ѻ' => 'Ѻ', + 'ѽ' => 'Ѽ', + 'ѿ' => 'Ѿ', + 'ҁ' => 'Ҁ', + 'ҋ' => 'Ҋ', + 'ҍ' => 'Ҍ', + 'ҏ' => 'Ҏ', + 'ґ' => 'Ґ', + 'ғ' => 'Ғ', + 'ҕ' => 'Ҕ', + 'җ' => 'Җ', + 'ҙ' => 'Ҙ', + 'қ' => 'Қ', + 'ҝ' => 'Ҝ', + 'ҟ' => 'Ҟ', + 'ҡ' => 'Ҡ', + 'ң' => 'Ң', + 'ҥ' => 'Ҥ', + 'ҧ' => 'Ҧ', + 'ҩ' => 'Ҩ', + 'ҫ' => 'Ҫ', + 'ҭ' => 'Ҭ', + 'ү' => 'Ү', + 'ұ' => 'Ұ', + 'ҳ' => 'Ҳ', + 'ҵ' => 'Ҵ', + 'ҷ' => 'Ҷ', + 'ҹ' => 'Ҹ', + 'һ' => 'Һ', + 'ҽ' => 'Ҽ', + 'ҿ' => 'Ҿ', + 'ӂ' => 'Ӂ', + 'ӄ' => 'Ӄ', + 'ӆ' => 'Ӆ', + 'ӈ' => 'Ӈ', + 'ӊ' => 'Ӊ', + 'ӌ' => 'Ӌ', + 'ӎ' => 'Ӎ', + 'ӏ' => 'Ӏ', + 'ӑ' => 'Ӑ', + 'ӓ' => 'Ӓ', + 'ӕ' => 'Ӕ', + 'ӗ' => 'Ӗ', + 'ә' => 'Ә', + 'ӛ' => 'Ӛ', + 'ӝ' => 'Ӝ', + 'ӟ' => 'Ӟ', + 'ӡ' => 'Ӡ', + 'ӣ' => 'Ӣ', + 'ӥ' => 'Ӥ', + 'ӧ' => 'Ӧ', + 'ө' => 'Ө', + 'ӫ' => 'Ӫ', + 'ӭ' => 'Ӭ', + 'ӯ' => 'Ӯ', + 'ӱ' => 'Ӱ', + 'ӳ' => 'Ӳ', + 'ӵ' => 'Ӵ', + 'ӷ' => 'Ӷ', + 'ӹ' => 'Ӹ', + 'ӻ' => 'Ӻ', + 'ӽ' => 'Ӽ', + 'ӿ' => 'Ӿ', + 'ԁ' => 'Ԁ', + 'ԃ' => 'Ԃ', + 'ԅ' => 'Ԅ', + 'ԇ' => 'Ԇ', + 'ԉ' => 'Ԉ', + 'ԋ' => 'Ԋ', + 'ԍ' => 'Ԍ', + 'ԏ' => 'Ԏ', + 'ԑ' => 'Ԑ', + 'ԓ' => 'Ԓ', + 'ԕ' => 'Ԕ', + 'ԗ' => 'Ԗ', + 'ԙ' => 'Ԙ', + 'ԛ' => 'Ԛ', + 'ԝ' => 'Ԝ', + 'ԟ' => 'Ԟ', + 'ԡ' => 'Ԡ', + 'ԣ' => 'Ԣ', + 'ԥ' => 'Ԥ', + 'ԧ' => 'Ԧ', + 'ԩ' => 'Ԩ', + 'ԫ' => 'Ԫ', + 'ԭ' => 'Ԭ', + 'ԯ' => 'Ԯ', + 'ա' => 'Ա', + 'բ' => 'Բ', + 'գ' => 'Գ', + 'դ' => 'Դ', + 'ե' => 'Ե', + 'զ' => 'Զ', + 'է' => 'Է', + 'ը' => 'Ը', + 'թ' => 'Թ', + 'ժ' => 'Ժ', + 'ի' => 'Ի', + 'լ' => 'Լ', + 'խ' => 'Խ', + 'ծ' => 'Ծ', + 'կ' => 'Կ', + 'հ' => 'Հ', + 'ձ' => 'Ձ', + 'ղ' => 'Ղ', + 'ճ' => 'Ճ', + 'մ' => 'Մ', + 'յ' => 'Յ', + 'ն' => 'Ն', + 'շ' => 'Շ', + 'ո' => 'Ո', + 'չ' => 'Չ', + 'պ' => 'Պ', + 'ջ' => 'Ջ', + 'ռ' => 'Ռ', + 'ս' => 'Ս', + 'վ' => 'Վ', + 'տ' => 'Տ', + 'ր' => 'Ր', + 'ց' => 'Ց', + 'ւ' => 'Ւ', + 'փ' => 'Փ', + 'ք' => 'Ք', + 'օ' => 'Օ', + 'ֆ' => 'Ֆ', + 'ა' => 'Ა', + 'ბ' => 'Ბ', + 'გ' => 'Გ', + 'დ' => 'Დ', + 'ე' => 'Ე', + 'ვ' => 'Ვ', + 'ზ' => 'Ზ', + 'თ' => 'Თ', + 'ი' => 'Ი', + 'კ' => 'Კ', + 'ლ' => 'Ლ', + 'მ' => 'Მ', + 'ნ' => 'Ნ', + 'ო' => 'Ო', + 'პ' => 'Პ', + 'ჟ' => 'Ჟ', + 'რ' => 'Რ', + 'ს' => 'Ს', + 'ტ' => 'Ტ', + 'უ' => 'Უ', + 'ფ' => 'Ფ', + 'ქ' => 'Ქ', + 'ღ' => 'Ღ', + 'ყ' => 'Ყ', + 'შ' => 'Შ', + 'ჩ' => 'Ჩ', + 'ც' => 'Ც', + 'ძ' => 'Ძ', + 'წ' => 'Წ', + 'ჭ' => 'Ჭ', + 'ხ' => 'Ხ', + 'ჯ' => 'Ჯ', + 'ჰ' => 'Ჰ', + 'ჱ' => 'Ჱ', + 'ჲ' => 'Ჲ', + 'ჳ' => 'Ჳ', + 'ჴ' => 'Ჴ', + 'ჵ' => 'Ჵ', + 'ჶ' => 'Ჶ', + 'ჷ' => 'Ჷ', + 'ჸ' => 'Ჸ', + 'ჹ' => 'Ჹ', + 'ჺ' => 'Ჺ', + 'ჽ' => 'Ჽ', + 'ჾ' => 'Ჾ', + 'ჿ' => 'Ჿ', + 'ᏸ' => 'Ᏸ', + 'ᏹ' => 'Ᏹ', + 'ᏺ' => 'Ᏺ', + 'ᏻ' => 'Ᏻ', + 'ᏼ' => 'Ᏼ', + 'ᏽ' => 'Ᏽ', + 'ᲀ' => 'В', + 'ᲁ' => 'Д', + 'ᲂ' => 'О', + 'ᲃ' => 'С', + 'ᲄ' => 'Т', + 'ᲅ' => 'Т', + 'ᲆ' => 'Ъ', + 'ᲇ' => 'Ѣ', + 'ᲈ' => 'Ꙋ', + 'ᵹ' => 'Ᵹ', + 'ᵽ' => 'Ᵽ', + 'ᶎ' => 'Ᶎ', + 'ḁ' => 'Ḁ', + 'ḃ' => 'Ḃ', + 'ḅ' => 'Ḅ', + 'ḇ' => 'Ḇ', + 'ḉ' => 'Ḉ', + 'ḋ' => 'Ḋ', + 'ḍ' => 'Ḍ', + 'ḏ' => 'Ḏ', + 'ḑ' => 'Ḑ', + 'ḓ' => 'Ḓ', + 'ḕ' => 'Ḕ', + 'ḗ' => 'Ḗ', + 'ḙ' => 'Ḙ', + 'ḛ' => 'Ḛ', + 'ḝ' => 'Ḝ', + 'ḟ' => 'Ḟ', + 'ḡ' => 'Ḡ', + 'ḣ' => 'Ḣ', + 'ḥ' => 'Ḥ', + 'ḧ' => 'Ḧ', + 'ḩ' => 'Ḩ', + 'ḫ' => 'Ḫ', + 'ḭ' => 'Ḭ', + 'ḯ' => 'Ḯ', + 'ḱ' => 'Ḱ', + 'ḳ' => 'Ḳ', + 'ḵ' => 'Ḵ', + 'ḷ' => 'Ḷ', + 'ḹ' => 'Ḹ', + 'ḻ' => 'Ḻ', + 'ḽ' => 'Ḽ', + 'ḿ' => 'Ḿ', + 'ṁ' => 'Ṁ', + 'ṃ' => 'Ṃ', + 'ṅ' => 'Ṅ', + 'ṇ' => 'Ṇ', + 'ṉ' => 'Ṉ', + 'ṋ' => 'Ṋ', + 'ṍ' => 'Ṍ', + 'ṏ' => 'Ṏ', + 'ṑ' => 'Ṑ', + 'ṓ' => 'Ṓ', + 'ṕ' => 'Ṕ', + 'ṗ' => 'Ṗ', + 'ṙ' => 'Ṙ', + 'ṛ' => 'Ṛ', + 'ṝ' => 'Ṝ', + 'ṟ' => 'Ṟ', + 'ṡ' => 'Ṡ', + 'ṣ' => 'Ṣ', + 'ṥ' => 'Ṥ', + 'ṧ' => 'Ṧ', + 'ṩ' => 'Ṩ', + 'ṫ' => 'Ṫ', + 'ṭ' => 'Ṭ', + 'ṯ' => 'Ṯ', + 'ṱ' => 'Ṱ', + 'ṳ' => 'Ṳ', + 'ṵ' => 'Ṵ', + 'ṷ' => 'Ṷ', + 'ṹ' => 'Ṹ', + 'ṻ' => 'Ṻ', + 'ṽ' => 'Ṽ', + 'ṿ' => 'Ṿ', + 'ẁ' => 'Ẁ', + 'ẃ' => 'Ẃ', + 'ẅ' => 'Ẅ', + 'ẇ' => 'Ẇ', + 'ẉ' => 'Ẉ', + 'ẋ' => 'Ẋ', + 'ẍ' => 'Ẍ', + 'ẏ' => 'Ẏ', + 'ẑ' => 'Ẑ', + 'ẓ' => 'Ẓ', + 'ẕ' => 'Ẕ', + 'ẛ' => 'Ṡ', + 'ạ' => 'Ạ', + 'ả' => 'Ả', + 'ấ' => 'Ấ', + 'ầ' => 'Ầ', + 'ẩ' => 'Ẩ', + 'ẫ' => 'Ẫ', + 'ậ' => 'Ậ', + 'ắ' => 'Ắ', + 'ằ' => 'Ằ', + 'ẳ' => 'Ẳ', + 'ẵ' => 'Ẵ', + 'ặ' => 'Ặ', + 'ẹ' => 'Ẹ', + 'ẻ' => 'Ẻ', + 'ẽ' => 'Ẽ', + 'ế' => 'Ế', + 'ề' => 'Ề', + 'ể' => 'Ể', + 'ễ' => 'Ễ', + 'ệ' => 'Ệ', + 'ỉ' => 'Ỉ', + 'ị' => 'Ị', + 'ọ' => 'Ọ', + 'ỏ' => 'Ỏ', + 'ố' => 'Ố', + 'ồ' => 'Ồ', + 'ổ' => 'Ổ', + 'ỗ' => 'Ỗ', + 'ộ' => 'Ộ', + 'ớ' => 'Ớ', + 'ờ' => 'Ờ', + 'ở' => 'Ở', + 'ỡ' => 'Ỡ', + 'ợ' => 'Ợ', + 'ụ' => 'Ụ', + 'ủ' => 'Ủ', + 'ứ' => 'Ứ', + 'ừ' => 'Ừ', + 'ử' => 'Ử', + 'ữ' => 'Ữ', + 'ự' => 'Ự', + 'ỳ' => 'Ỳ', + 'ỵ' => 'Ỵ', + 'ỷ' => 'Ỷ', + 'ỹ' => 'Ỹ', + 'ỻ' => 'Ỻ', + 'ỽ' => 'Ỽ', + 'ỿ' => 'Ỿ', + 'ἀ' => 'Ἀ', + 'ἁ' => 'Ἁ', + 'ἂ' => 'Ἂ', + 'ἃ' => 'Ἃ', + 'ἄ' => 'Ἄ', + 'ἅ' => 'Ἅ', + 'ἆ' => 'Ἆ', + 'ἇ' => 'Ἇ', + 'ἐ' => 'Ἐ', + 'ἑ' => 'Ἑ', + 'ἒ' => 'Ἒ', + 'ἓ' => 'Ἓ', + 'ἔ' => 'Ἔ', + 'ἕ' => 'Ἕ', + 'ἠ' => 'Ἠ', + 'ἡ' => 'Ἡ', + 'ἢ' => 'Ἢ', + 'ἣ' => 'Ἣ', + 'ἤ' => 'Ἤ', + 'ἥ' => 'Ἥ', + 'ἦ' => 'Ἦ', + 'ἧ' => 'Ἧ', + 'ἰ' => 'Ἰ', + 'ἱ' => 'Ἱ', + 'ἲ' => 'Ἲ', + 'ἳ' => 'Ἳ', + 'ἴ' => 'Ἴ', + 'ἵ' => 'Ἵ', + 'ἶ' => 'Ἶ', + 'ἷ' => 'Ἷ', + 'ὀ' => 'Ὀ', + 'ὁ' => 'Ὁ', + 'ὂ' => 'Ὂ', + 'ὃ' => 'Ὃ', + 'ὄ' => 'Ὄ', + 'ὅ' => 'Ὅ', + 'ὑ' => 'Ὑ', + 'ὓ' => 'Ὓ', + 'ὕ' => 'Ὕ', + 'ὗ' => 'Ὗ', + 'ὠ' => 'Ὠ', + 'ὡ' => 'Ὡ', + 'ὢ' => 'Ὢ', + 'ὣ' => 'Ὣ', + 'ὤ' => 'Ὤ', + 'ὥ' => 'Ὥ', + 'ὦ' => 'Ὦ', + 'ὧ' => 'Ὧ', + 'ὰ' => 'Ὰ', + 'ά' => 'Ά', + 'ὲ' => 'Ὲ', + 'έ' => 'Έ', + 'ὴ' => 'Ὴ', + 'ή' => 'Ή', + 'ὶ' => 'Ὶ', + 'ί' => 'Ί', + 'ὸ' => 'Ὸ', + 'ό' => 'Ό', + 'ὺ' => 'Ὺ', + 'ύ' => 'Ύ', + 'ὼ' => 'Ὼ', + 'ώ' => 'Ώ', + 'ᾀ' => 'ἈΙ', + 'ᾁ' => 'ἉΙ', + 'ᾂ' => 'ἊΙ', + 'ᾃ' => 'ἋΙ', + 'ᾄ' => 'ἌΙ', + 'ᾅ' => 'ἍΙ', + 'ᾆ' => 'ἎΙ', + 'ᾇ' => 'ἏΙ', + 'ᾐ' => 'ἨΙ', + 'ᾑ' => 'ἩΙ', + 'ᾒ' => 'ἪΙ', + 'ᾓ' => 'ἫΙ', + 'ᾔ' => 'ἬΙ', + 'ᾕ' => 'ἭΙ', + 'ᾖ' => 'ἮΙ', + 'ᾗ' => 'ἯΙ', + 'ᾠ' => 'ὨΙ', + 'ᾡ' => 'ὩΙ', + 'ᾢ' => 'ὪΙ', + 'ᾣ' => 'ὫΙ', + 'ᾤ' => 'ὬΙ', + 'ᾥ' => 'ὭΙ', + 'ᾦ' => 'ὮΙ', + 'ᾧ' => 'ὯΙ', + 'ᾰ' => 'Ᾰ', + 'ᾱ' => 'Ᾱ', + 'ᾳ' => 'ΑΙ', + 'ι' => 'Ι', + 'ῃ' => 'ΗΙ', + 'ῐ' => 'Ῐ', + 'ῑ' => 'Ῑ', + 'ῠ' => 'Ῠ', + 'ῡ' => 'Ῡ', + 'ῥ' => 'Ῥ', + 'ῳ' => 'ΩΙ', + 'ⅎ' => 'Ⅎ', + 'ⅰ' => 'Ⅰ', + 'ⅱ' => 'Ⅱ', + 'ⅲ' => 'Ⅲ', + 'ⅳ' => 'Ⅳ', + 'ⅴ' => 'Ⅴ', + 'ⅵ' => 'Ⅵ', + 'ⅶ' => 'Ⅶ', + 'ⅷ' => 'Ⅷ', + 'ⅸ' => 'Ⅸ', + 'ⅹ' => 'Ⅹ', + 'ⅺ' => 'Ⅺ', + 'ⅻ' => 'Ⅻ', + 'ⅼ' => 'Ⅼ', + 'ⅽ' => 'Ⅽ', + 'ⅾ' => 'Ⅾ', + 'ⅿ' => 'Ⅿ', + 'ↄ' => 'Ↄ', + 'ⓐ' => 'Ⓐ', + 'ⓑ' => 'Ⓑ', + 'ⓒ' => 'Ⓒ', + 'ⓓ' => 'Ⓓ', + 'ⓔ' => 'Ⓔ', + 'ⓕ' => 'Ⓕ', + 'ⓖ' => 'Ⓖ', + 'ⓗ' => 'Ⓗ', + 'ⓘ' => 'Ⓘ', + 'ⓙ' => 'Ⓙ', + 'ⓚ' => 'Ⓚ', + 'ⓛ' => 'Ⓛ', + 'ⓜ' => 'Ⓜ', + 'ⓝ' => 'Ⓝ', + 'ⓞ' => 'Ⓞ', + 'ⓟ' => 'Ⓟ', + 'ⓠ' => 'Ⓠ', + 'ⓡ' => 'Ⓡ', + 'ⓢ' => 'Ⓢ', + 'ⓣ' => 'Ⓣ', + 'ⓤ' => 'Ⓤ', + 'ⓥ' => 'Ⓥ', + 'ⓦ' => 'Ⓦ', + 'ⓧ' => 'Ⓧ', + 'ⓨ' => 'Ⓨ', + 'ⓩ' => 'Ⓩ', + 'ⰰ' => 'Ⰰ', + 'ⰱ' => 'Ⰱ', + 'ⰲ' => 'Ⰲ', + 'ⰳ' => 'Ⰳ', + 'ⰴ' => 'Ⰴ', + 'ⰵ' => 'Ⰵ', + 'ⰶ' => 'Ⰶ', + 'ⰷ' => 'Ⰷ', + 'ⰸ' => 'Ⰸ', + 'ⰹ' => 'Ⰹ', + 'ⰺ' => 'Ⰺ', + 'ⰻ' => 'Ⰻ', + 'ⰼ' => 'Ⰼ', + 'ⰽ' => 'Ⰽ', + 'ⰾ' => 'Ⰾ', + 'ⰿ' => 'Ⰿ', + 'ⱀ' => 'Ⱀ', + 'ⱁ' => 'Ⱁ', + 'ⱂ' => 'Ⱂ', + 'ⱃ' => 'Ⱃ', + 'ⱄ' => 'Ⱄ', + 'ⱅ' => 'Ⱅ', + 'ⱆ' => 'Ⱆ', + 'ⱇ' => 'Ⱇ', + 'ⱈ' => 'Ⱈ', + 'ⱉ' => 'Ⱉ', + 'ⱊ' => 'Ⱊ', + 'ⱋ' => 'Ⱋ', + 'ⱌ' => 'Ⱌ', + 'ⱍ' => 'Ⱍ', + 'ⱎ' => 'Ⱎ', + 'ⱏ' => 'Ⱏ', + 'ⱐ' => 'Ⱐ', + 'ⱑ' => 'Ⱑ', + 'ⱒ' => 'Ⱒ', + 'ⱓ' => 'Ⱓ', + 'ⱔ' => 'Ⱔ', + 'ⱕ' => 'Ⱕ', + 'ⱖ' => 'Ⱖ', + 'ⱗ' => 'Ⱗ', + 'ⱘ' => 'Ⱘ', + 'ⱙ' => 'Ⱙ', + 'ⱚ' => 'Ⱚ', + 'ⱛ' => 'Ⱛ', + 'ⱜ' => 'Ⱜ', + 'ⱝ' => 'Ⱝ', + 'ⱞ' => 'Ⱞ', + 'ⱡ' => 'Ⱡ', + 'ⱥ' => 'Ⱥ', + 'ⱦ' => 'Ⱦ', + 'ⱨ' => 'Ⱨ', + 'ⱪ' => 'Ⱪ', + 'ⱬ' => 'Ⱬ', + 'ⱳ' => 'Ⱳ', + 'ⱶ' => 'Ⱶ', + 'ⲁ' => 'Ⲁ', + 'ⲃ' => 'Ⲃ', + 'ⲅ' => 'Ⲅ', + 'ⲇ' => 'Ⲇ', + 'ⲉ' => 'Ⲉ', + 'ⲋ' => 'Ⲋ', + 'ⲍ' => 'Ⲍ', + 'ⲏ' => 'Ⲏ', + 'ⲑ' => 'Ⲑ', + 'ⲓ' => 'Ⲓ', + 'ⲕ' => 'Ⲕ', + 'ⲗ' => 'Ⲗ', + 'ⲙ' => 'Ⲙ', + 'ⲛ' => 'Ⲛ', + 'ⲝ' => 'Ⲝ', + 'ⲟ' => 'Ⲟ', + 'ⲡ' => 'Ⲡ', + 'ⲣ' => 'Ⲣ', + 'ⲥ' => 'Ⲥ', + 'ⲧ' => 'Ⲧ', + 'ⲩ' => 'Ⲩ', + 'ⲫ' => 'Ⲫ', + 'ⲭ' => 'Ⲭ', + 'ⲯ' => 'Ⲯ', + 'ⲱ' => 'Ⲱ', + 'ⲳ' => 'Ⲳ', + 'ⲵ' => 'Ⲵ', + 'ⲷ' => 'Ⲷ', + 'ⲹ' => 'Ⲹ', + 'ⲻ' => 'Ⲻ', + 'ⲽ' => 'Ⲽ', + 'ⲿ' => 'Ⲿ', + 'ⳁ' => 'Ⳁ', + 'ⳃ' => 'Ⳃ', + 'ⳅ' => 'Ⳅ', + 'ⳇ' => 'Ⳇ', + 'ⳉ' => 'Ⳉ', + 'ⳋ' => 'Ⳋ', + 'ⳍ' => 'Ⳍ', + 'ⳏ' => 'Ⳏ', + 'ⳑ' => 'Ⳑ', + 'ⳓ' => 'Ⳓ', + 'ⳕ' => 'Ⳕ', + 'ⳗ' => 'Ⳗ', + 'ⳙ' => 'Ⳙ', + 'ⳛ' => 'Ⳛ', + 'ⳝ' => 'Ⳝ', + 'ⳟ' => 'Ⳟ', + 'ⳡ' => 'Ⳡ', + 'ⳣ' => 'Ⳣ', + 'ⳬ' => 'Ⳬ', + 'ⳮ' => 'Ⳮ', + 'ⳳ' => 'Ⳳ', + 'ⴀ' => 'Ⴀ', + 'ⴁ' => 'Ⴁ', + 'ⴂ' => 'Ⴂ', + 'ⴃ' => 'Ⴃ', + 'ⴄ' => 'Ⴄ', + 'ⴅ' => 'Ⴅ', + 'ⴆ' => 'Ⴆ', + 'ⴇ' => 'Ⴇ', + 'ⴈ' => 'Ⴈ', + 'ⴉ' => 'Ⴉ', + 'ⴊ' => 'Ⴊ', + 'ⴋ' => 'Ⴋ', + 'ⴌ' => 'Ⴌ', + 'ⴍ' => 'Ⴍ', + 'ⴎ' => 'Ⴎ', + 'ⴏ' => 'Ⴏ', + 'ⴐ' => 'Ⴐ', + 'ⴑ' => 'Ⴑ', + 'ⴒ' => 'Ⴒ', + 'ⴓ' => 'Ⴓ', + 'ⴔ' => 'Ⴔ', + 'ⴕ' => 'Ⴕ', + 'ⴖ' => 'Ⴖ', + 'ⴗ' => 'Ⴗ', + 'ⴘ' => 'Ⴘ', + 'ⴙ' => 'Ⴙ', + 'ⴚ' => 'Ⴚ', + 'ⴛ' => 'Ⴛ', + 'ⴜ' => 'Ⴜ', + 'ⴝ' => 'Ⴝ', + 'ⴞ' => 'Ⴞ', + 'ⴟ' => 'Ⴟ', + 'ⴠ' => 'Ⴠ', + 'ⴡ' => 'Ⴡ', + 'ⴢ' => 'Ⴢ', + 'ⴣ' => 'Ⴣ', + 'ⴤ' => 'Ⴤ', + 'ⴥ' => 'Ⴥ', + 'ⴧ' => 'Ⴧ', + 'ⴭ' => 'Ⴭ', + 'ꙁ' => 'Ꙁ', + 'ꙃ' => 'Ꙃ', + 'ꙅ' => 'Ꙅ', + 'ꙇ' => 'Ꙇ', + 'ꙉ' => 'Ꙉ', + 'ꙋ' => 'Ꙋ', + 'ꙍ' => 'Ꙍ', + 'ꙏ' => 'Ꙏ', + 'ꙑ' => 'Ꙑ', + 'ꙓ' => 'Ꙓ', + 'ꙕ' => 'Ꙕ', + 'ꙗ' => 'Ꙗ', + 'ꙙ' => 'Ꙙ', + 'ꙛ' => 'Ꙛ', + 'ꙝ' => 'Ꙝ', + 'ꙟ' => 'Ꙟ', + 'ꙡ' => 'Ꙡ', + 'ꙣ' => 'Ꙣ', + 'ꙥ' => 'Ꙥ', + 'ꙧ' => 'Ꙧ', + 'ꙩ' => 'Ꙩ', + 'ꙫ' => 'Ꙫ', + 'ꙭ' => 'Ꙭ', + 'ꚁ' => 'Ꚁ', + 'ꚃ' => 'Ꚃ', + 'ꚅ' => 'Ꚅ', + 'ꚇ' => 'Ꚇ', + 'ꚉ' => 'Ꚉ', + 'ꚋ' => 'Ꚋ', + 'ꚍ' => 'Ꚍ', + 'ꚏ' => 'Ꚏ', + 'ꚑ' => 'Ꚑ', + 'ꚓ' => 'Ꚓ', + 'ꚕ' => 'Ꚕ', + 'ꚗ' => 'Ꚗ', + 'ꚙ' => 'Ꚙ', + 'ꚛ' => 'Ꚛ', + 'ꜣ' => 'Ꜣ', + 'ꜥ' => 'Ꜥ', + 'ꜧ' => 'Ꜧ', + 'ꜩ' => 'Ꜩ', + 'ꜫ' => 'Ꜫ', + 'ꜭ' => 'Ꜭ', + 'ꜯ' => 'Ꜯ', + 'ꜳ' => 'Ꜳ', + 'ꜵ' => 'Ꜵ', + 'ꜷ' => 'Ꜷ', + 'ꜹ' => 'Ꜹ', + 'ꜻ' => 'Ꜻ', + 'ꜽ' => 'Ꜽ', + 'ꜿ' => 'Ꜿ', + 'ꝁ' => 'Ꝁ', + 'ꝃ' => 'Ꝃ', + 'ꝅ' => 'Ꝅ', + 'ꝇ' => 'Ꝇ', + 'ꝉ' => 'Ꝉ', + 'ꝋ' => 'Ꝋ', + 'ꝍ' => 'Ꝍ', + 'ꝏ' => 'Ꝏ', + 'ꝑ' => 'Ꝑ', + 'ꝓ' => 'Ꝓ', + 'ꝕ' => 'Ꝕ', + 'ꝗ' => 'Ꝗ', + 'ꝙ' => 'Ꝙ', + 'ꝛ' => 'Ꝛ', + 'ꝝ' => 'Ꝝ', + 'ꝟ' => 'Ꝟ', + 'ꝡ' => 'Ꝡ', + 'ꝣ' => 'Ꝣ', + 'ꝥ' => 'Ꝥ', + 'ꝧ' => 'Ꝧ', + 'ꝩ' => 'Ꝩ', + 'ꝫ' => 'Ꝫ', + 'ꝭ' => 'Ꝭ', + 'ꝯ' => 'Ꝯ', + 'ꝺ' => 'Ꝺ', + 'ꝼ' => 'Ꝼ', + 'ꝿ' => 'Ꝿ', + 'ꞁ' => 'Ꞁ', + 'ꞃ' => 'Ꞃ', + 'ꞅ' => 'Ꞅ', + 'ꞇ' => 'Ꞇ', + 'ꞌ' => 'Ꞌ', + 'ꞑ' => 'Ꞑ', + 'ꞓ' => 'Ꞓ', + 'ꞔ' => 'Ꞔ', + 'ꞗ' => 'Ꞗ', + 'ꞙ' => 'Ꞙ', + 'ꞛ' => 'Ꞛ', + 'ꞝ' => 'Ꞝ', + 'ꞟ' => 'Ꞟ', + 'ꞡ' => 'Ꞡ', + 'ꞣ' => 'Ꞣ', + 'ꞥ' => 'Ꞥ', + 'ꞧ' => 'Ꞧ', + 'ꞩ' => 'Ꞩ', + 'ꞵ' => 'Ꞵ', + 'ꞷ' => 'Ꞷ', + 'ꞹ' => 'Ꞹ', + 'ꞻ' => 'Ꞻ', + 'ꞽ' => 'Ꞽ', + 'ꞿ' => 'Ꞿ', + 'ꟃ' => 'Ꟃ', + 'ꟈ' => 'Ꟈ', + 'ꟊ' => 'Ꟊ', + 'ꟶ' => 'Ꟶ', + 'ꭓ' => 'Ꭓ', + 'ꭰ' => 'Ꭰ', + 'ꭱ' => 'Ꭱ', + 'ꭲ' => 'Ꭲ', + 'ꭳ' => 'Ꭳ', + 'ꭴ' => 'Ꭴ', + 'ꭵ' => 'Ꭵ', + 'ꭶ' => 'Ꭶ', + 'ꭷ' => 'Ꭷ', + 'ꭸ' => 'Ꭸ', + 'ꭹ' => 'Ꭹ', + 'ꭺ' => 'Ꭺ', + 'ꭻ' => 'Ꭻ', + 'ꭼ' => 'Ꭼ', + 'ꭽ' => 'Ꭽ', + 'ꭾ' => 'Ꭾ', + 'ꭿ' => 'Ꭿ', + 'ꮀ' => 'Ꮀ', + 'ꮁ' => 'Ꮁ', + 'ꮂ' => 'Ꮂ', + 'ꮃ' => 'Ꮃ', + 'ꮄ' => 'Ꮄ', + 'ꮅ' => 'Ꮅ', + 'ꮆ' => 'Ꮆ', + 'ꮇ' => 'Ꮇ', + 'ꮈ' => 'Ꮈ', + 'ꮉ' => 'Ꮉ', + 'ꮊ' => 'Ꮊ', + 'ꮋ' => 'Ꮋ', + 'ꮌ' => 'Ꮌ', + 'ꮍ' => 'Ꮍ', + 'ꮎ' => 'Ꮎ', + 'ꮏ' => 'Ꮏ', + 'ꮐ' => 'Ꮐ', + 'ꮑ' => 'Ꮑ', + 'ꮒ' => 'Ꮒ', + 'ꮓ' => 'Ꮓ', + 'ꮔ' => 'Ꮔ', + 'ꮕ' => 'Ꮕ', + 'ꮖ' => 'Ꮖ', + 'ꮗ' => 'Ꮗ', + 'ꮘ' => 'Ꮘ', + 'ꮙ' => 'Ꮙ', + 'ꮚ' => 'Ꮚ', + 'ꮛ' => 'Ꮛ', + 'ꮜ' => 'Ꮜ', + 'ꮝ' => 'Ꮝ', + 'ꮞ' => 'Ꮞ', + 'ꮟ' => 'Ꮟ', + 'ꮠ' => 'Ꮠ', + 'ꮡ' => 'Ꮡ', + 'ꮢ' => 'Ꮢ', + 'ꮣ' => 'Ꮣ', + 'ꮤ' => 'Ꮤ', + 'ꮥ' => 'Ꮥ', + 'ꮦ' => 'Ꮦ', + 'ꮧ' => 'Ꮧ', + 'ꮨ' => 'Ꮨ', + 'ꮩ' => 'Ꮩ', + 'ꮪ' => 'Ꮪ', + 'ꮫ' => 'Ꮫ', + 'ꮬ' => 'Ꮬ', + 'ꮭ' => 'Ꮭ', + 'ꮮ' => 'Ꮮ', + 'ꮯ' => 'Ꮯ', + 'ꮰ' => 'Ꮰ', + 'ꮱ' => 'Ꮱ', + 'ꮲ' => 'Ꮲ', + 'ꮳ' => 'Ꮳ', + 'ꮴ' => 'Ꮴ', + 'ꮵ' => 'Ꮵ', + 'ꮶ' => 'Ꮶ', + 'ꮷ' => 'Ꮷ', + 'ꮸ' => 'Ꮸ', + 'ꮹ' => 'Ꮹ', + 'ꮺ' => 'Ꮺ', + 'ꮻ' => 'Ꮻ', + 'ꮼ' => 'Ꮼ', + 'ꮽ' => 'Ꮽ', + 'ꮾ' => 'Ꮾ', + 'ꮿ' => 'Ꮿ', + 'a' => 'A', + 'b' => 'B', + 'c' => 'C', + 'd' => 'D', + 'e' => 'E', + 'f' => 'F', + 'g' => 'G', + 'h' => 'H', + 'i' => 'I', + 'j' => 'J', + 'k' => 'K', + 'l' => 'L', + 'm' => 'M', + 'n' => 'N', + 'o' => 'O', + 'p' => 'P', + 'q' => 'Q', + 'r' => 'R', + 's' => 'S', + 't' => 'T', + 'u' => 'U', + 'v' => 'V', + 'w' => 'W', + 'x' => 'X', + 'y' => 'Y', + 'z' => 'Z', + '𐐨' => '𐐀', + '𐐩' => '𐐁', + '𐐪' => '𐐂', + '𐐫' => '𐐃', + '𐐬' => '𐐄', + '𐐭' => '𐐅', + '𐐮' => '𐐆', + '𐐯' => '𐐇', + '𐐰' => '𐐈', + '𐐱' => '𐐉', + '𐐲' => '𐐊', + '𐐳' => '𐐋', + '𐐴' => '𐐌', + '𐐵' => '𐐍', + '𐐶' => '𐐎', + '𐐷' => '𐐏', + '𐐸' => '𐐐', + '𐐹' => '𐐑', + '𐐺' => '𐐒', + '𐐻' => '𐐓', + '𐐼' => '𐐔', + '𐐽' => '𐐕', + '𐐾' => '𐐖', + '𐐿' => '𐐗', + '𐑀' => '𐐘', + '𐑁' => '𐐙', + '𐑂' => '𐐚', + '𐑃' => '𐐛', + '𐑄' => '𐐜', + '𐑅' => '𐐝', + '𐑆' => '𐐞', + '𐑇' => '𐐟', + '𐑈' => '𐐠', + '𐑉' => '𐐡', + '𐑊' => '𐐢', + '𐑋' => '𐐣', + '𐑌' => '𐐤', + '𐑍' => '𐐥', + '𐑎' => '𐐦', + '𐑏' => '𐐧', + '𐓘' => '𐒰', + '𐓙' => '𐒱', + '𐓚' => '𐒲', + '𐓛' => '𐒳', + '𐓜' => '𐒴', + '𐓝' => '𐒵', + '𐓞' => '𐒶', + '𐓟' => '𐒷', + '𐓠' => '𐒸', + '𐓡' => '𐒹', + '𐓢' => '𐒺', + '𐓣' => '𐒻', + '𐓤' => '𐒼', + '𐓥' => '𐒽', + '𐓦' => '𐒾', + '𐓧' => '𐒿', + '𐓨' => '𐓀', + '𐓩' => '𐓁', + '𐓪' => '𐓂', + '𐓫' => '𐓃', + '𐓬' => '𐓄', + '𐓭' => '𐓅', + '𐓮' => '𐓆', + '𐓯' => '𐓇', + '𐓰' => '𐓈', + '𐓱' => '𐓉', + '𐓲' => '𐓊', + '𐓳' => '𐓋', + '𐓴' => '𐓌', + '𐓵' => '𐓍', + '𐓶' => '𐓎', + '𐓷' => '𐓏', + '𐓸' => '𐓐', + '𐓹' => '𐓑', + '𐓺' => '𐓒', + '𐓻' => '𐓓', + '𐳀' => '𐲀', + '𐳁' => '𐲁', + '𐳂' => '𐲂', + '𐳃' => '𐲃', + '𐳄' => '𐲄', + '𐳅' => '𐲅', + '𐳆' => '𐲆', + '𐳇' => '𐲇', + '𐳈' => '𐲈', + '𐳉' => '𐲉', + '𐳊' => '𐲊', + '𐳋' => '𐲋', + '𐳌' => '𐲌', + '𐳍' => '𐲍', + '𐳎' => '𐲎', + '𐳏' => '𐲏', + '𐳐' => '𐲐', + '𐳑' => '𐲑', + '𐳒' => '𐲒', + '𐳓' => '𐲓', + '𐳔' => '𐲔', + '𐳕' => '𐲕', + '𐳖' => '𐲖', + '𐳗' => '𐲗', + '𐳘' => '𐲘', + '𐳙' => '𐲙', + '𐳚' => '𐲚', + '𐳛' => '𐲛', + '𐳜' => '𐲜', + '𐳝' => '𐲝', + '𐳞' => '𐲞', + '𐳟' => '𐲟', + '𐳠' => '𐲠', + '𐳡' => '𐲡', + '𐳢' => '𐲢', + '𐳣' => '𐲣', + '𐳤' => '𐲤', + '𐳥' => '𐲥', + '𐳦' => '𐲦', + '𐳧' => '𐲧', + '𐳨' => '𐲨', + '𐳩' => '𐲩', + '𐳪' => '𐲪', + '𐳫' => '𐲫', + '𐳬' => '𐲬', + '𐳭' => '𐲭', + '𐳮' => '𐲮', + '𐳯' => '𐲯', + '𐳰' => '𐲰', + '𐳱' => '𐲱', + '𐳲' => '𐲲', + '𑣀' => '𑢠', + '𑣁' => '𑢡', + '𑣂' => '𑢢', + '𑣃' => '𑢣', + '𑣄' => '𑢤', + '𑣅' => '𑢥', + '𑣆' => '𑢦', + '𑣇' => '𑢧', + '𑣈' => '𑢨', + '𑣉' => '𑢩', + '𑣊' => '𑢪', + '𑣋' => '𑢫', + '𑣌' => '𑢬', + '𑣍' => '𑢭', + '𑣎' => '𑢮', + '𑣏' => '𑢯', + '𑣐' => '𑢰', + '𑣑' => '𑢱', + '𑣒' => '𑢲', + '𑣓' => '𑢳', + '𑣔' => '𑢴', + '𑣕' => '𑢵', + '𑣖' => '𑢶', + '𑣗' => '𑢷', + '𑣘' => '𑢸', + '𑣙' => '𑢹', + '𑣚' => '𑢺', + '𑣛' => '𑢻', + '𑣜' => '𑢼', + '𑣝' => '𑢽', + '𑣞' => '𑢾', + '𑣟' => '𑢿', + '𖹠' => '𖹀', + '𖹡' => '𖹁', + '𖹢' => '𖹂', + '𖹣' => '𖹃', + '𖹤' => '𖹄', + '𖹥' => '𖹅', + '𖹦' => '𖹆', + '𖹧' => '𖹇', + '𖹨' => '𖹈', + '𖹩' => '𖹉', + '𖹪' => '𖹊', + '𖹫' => '𖹋', + '𖹬' => '𖹌', + '𖹭' => '𖹍', + '𖹮' => '𖹎', + '𖹯' => '𖹏', + '𖹰' => '𖹐', + '𖹱' => '𖹑', + '𖹲' => '𖹒', + '𖹳' => '𖹓', + '𖹴' => '𖹔', + '𖹵' => '𖹕', + '𖹶' => '𖹖', + '𖹷' => '𖹗', + '𖹸' => '𖹘', + '𖹹' => '𖹙', + '𖹺' => '𖹚', + '𖹻' => '𖹛', + '𖹼' => '𖹜', + '𖹽' => '𖹝', + '𖹾' => '𖹞', + '𖹿' => '𖹟', + '𞤢' => '𞤀', + '𞤣' => '𞤁', + '𞤤' => '𞤂', + '𞤥' => '𞤃', + '𞤦' => '𞤄', + '𞤧' => '𞤅', + '𞤨' => '𞤆', + '𞤩' => '𞤇', + '𞤪' => '𞤈', + '𞤫' => '𞤉', + '𞤬' => '𞤊', + '𞤭' => '𞤋', + '𞤮' => '𞤌', + '𞤯' => '𞤍', + '𞤰' => '𞤎', + '𞤱' => '𞤏', + '𞤲' => '𞤐', + '𞤳' => '𞤑', + '𞤴' => '𞤒', + '𞤵' => '𞤓', + '𞤶' => '𞤔', + '𞤷' => '𞤕', + '𞤸' => '𞤖', + '𞤹' => '𞤗', + '𞤺' => '𞤘', + '𞤻' => '𞤙', + '𞤼' => '𞤚', + '𞤽' => '𞤛', + '𞤾' => '𞤜', + '𞤿' => '𞤝', + '𞥀' => '𞤞', + '𞥁' => '𞤟', + '𞥂' => '𞤠', + '𞥃' => '𞤡', + 'ß' => 'SS', + 'ff' => 'FF', + 'fi' => 'FI', + 'fl' => 'FL', + 'ffi' => 'FFI', + 'ffl' => 'FFL', + 'ſt' => 'ST', + 'st' => 'ST', + 'և' => 'ԵՒ', + 'ﬓ' => 'ՄՆ', + 'ﬔ' => 'ՄԵ', + 'ﬕ' => 'ՄԻ', + 'ﬖ' => 'ՎՆ', + 'ﬗ' => 'ՄԽ', + 'ʼn' => 'ʼN', + 'ΐ' => 'Ϊ́', + 'ΰ' => 'Ϋ́', + 'ǰ' => 'J̌', + 'ẖ' => 'H̱', + 'ẗ' => 'T̈', + 'ẘ' => 'W̊', + 'ẙ' => 'Y̊', + 'ẚ' => 'Aʾ', + 'ὐ' => 'Υ̓', + 'ὒ' => 'Υ̓̀', + 'ὔ' => 'Υ̓́', + 'ὖ' => 'Υ̓͂', + 'ᾶ' => 'Α͂', + 'ῆ' => 'Η͂', + 'ῒ' => 'Ϊ̀', + 'ΐ' => 'Ϊ́', + 'ῖ' => 'Ι͂', + 'ῗ' => 'Ϊ͂', + 'ῢ' => 'Ϋ̀', + 'ΰ' => 'Ϋ́', + 'ῤ' => 'Ρ̓', + 'ῦ' => 'Υ͂', + 'ῧ' => 'Ϋ͂', + 'ῶ' => 'Ω͂', + 'ᾈ' => 'ἈΙ', + 'ᾉ' => 'ἉΙ', + 'ᾊ' => 'ἊΙ', + 'ᾋ' => 'ἋΙ', + 'ᾌ' => 'ἌΙ', + 'ᾍ' => 'ἍΙ', + 'ᾎ' => 'ἎΙ', + 'ᾏ' => 'ἏΙ', + 'ᾘ' => 'ἨΙ', + 'ᾙ' => 'ἩΙ', + 'ᾚ' => 'ἪΙ', + 'ᾛ' => 'ἫΙ', + 'ᾜ' => 'ἬΙ', + 'ᾝ' => 'ἭΙ', + 'ᾞ' => 'ἮΙ', + 'ᾟ' => 'ἯΙ', + 'ᾨ' => 'ὨΙ', + 'ᾩ' => 'ὩΙ', + 'ᾪ' => 'ὪΙ', + 'ᾫ' => 'ὫΙ', + 'ᾬ' => 'ὬΙ', + 'ᾭ' => 'ὭΙ', + 'ᾮ' => 'ὮΙ', + 'ᾯ' => 'ὯΙ', + 'ᾼ' => 'ΑΙ', + 'ῌ' => 'ΗΙ', + 'ῼ' => 'ΩΙ', + 'ᾲ' => 'ᾺΙ', + 'ᾴ' => 'ΆΙ', + 'ῂ' => 'ῊΙ', + 'ῄ' => 'ΉΙ', + 'ῲ' => 'ῺΙ', + 'ῴ' => 'ΏΙ', + 'ᾷ' => 'Α͂Ι', + 'ῇ' => 'Η͂Ι', + 'ῷ' => 'Ω͂Ι', +); diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php new file mode 100644 index 0000000..ecf1a03 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -0,0 +1,151 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (\PHP_VERSION_ID >= 80000) { + return require __DIR__.'/bootstrap80.php'; +} + +if (!function_exists('mb_convert_encoding')) { + function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language($language = null) { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } +} +if (!function_exists('mb_check_encoding')) { + function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } +} +if (!function_exists('mb_http_output')) { + function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (extension_loaded('mbstring')) { + return; +} + +if (!defined('MB_CASE_UPPER')) { + define('MB_CASE_UPPER', 0); +} +if (!defined('MB_CASE_LOWER')) { + define('MB_CASE_LOWER', 1); +} +if (!defined('MB_CASE_TITLE')) { + define('MB_CASE_TITLE', 2); +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php new file mode 100644 index 0000000..2f9fb5b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -0,0 +1,147 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Mbstring as p; + +if (!function_exists('mb_convert_encoding')) { + function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); } +} +if (!function_exists('mb_decode_mimeheader')) { + function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); } +} +if (!function_exists('mb_encode_mimeheader')) { + function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); } +} +if (!function_exists('mb_decode_numericentity')) { + function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); } +} +if (!function_exists('mb_encode_numericentity')) { + function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); } +} +if (!function_exists('mb_convert_case')) { + function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); } +} +if (!function_exists('mb_internal_encoding')) { + function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); } +} +if (!function_exists('mb_language')) { + function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); } +} +if (!function_exists('mb_list_encodings')) { + function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); } +} +if (!function_exists('mb_encoding_aliases')) { + function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); } +} +if (!function_exists('mb_check_encoding')) { + function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); } +} +if (!function_exists('mb_detect_encoding')) { + function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); } +} +if (!function_exists('mb_detect_order')) { + function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); } +} +if (!function_exists('mb_parse_str')) { + function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; } +} +if (!function_exists('mb_strlen')) { + function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); } +} +if (!function_exists('mb_strpos')) { + function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strtolower')) { + function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); } +} +if (!function_exists('mb_strtoupper')) { + function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); } +} +if (!function_exists('mb_substitute_character')) { + function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); } +} +if (!function_exists('mb_substr')) { + function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); } +} +if (!function_exists('mb_stripos')) { + function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_stristr')) { + function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strrchr')) { + function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strrichr')) { + function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_strripos')) { + function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strrpos')) { + function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } +} +if (!function_exists('mb_strstr')) { + function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } +} +if (!function_exists('mb_get_info')) { + function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } +} +if (!function_exists('mb_http_output')) { + function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } +} +if (!function_exists('mb_strwidth')) { + function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); } +} +if (!function_exists('mb_substr_count')) { + function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); } +} +if (!function_exists('mb_output_handler')) { + function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); } +} +if (!function_exists('mb_http_input')) { + function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); } +} + +if (!function_exists('mb_convert_variables')) { + function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); } +} + +if (!function_exists('mb_ord')) { + function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); } +} +if (!function_exists('mb_chr')) { + function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); } +} +if (!function_exists('mb_scrub')) { + function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); } +} +if (!function_exists('mb_str_split')) { + function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } +} + +if (!function_exists('mb_str_pad')) { + function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } +} + +if (extension_loaded('mbstring')) { + return; +} + +if (!defined('MB_CASE_UPPER')) { + define('MB_CASE_UPPER', 0); +} +if (!defined('MB_CASE_LOWER')) { + define('MB_CASE_LOWER', 1); +} +if (!defined('MB_CASE_TITLE')) { + define('MB_CASE_TITLE', 2); +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json new file mode 100644 index 0000000..943e502 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json @@ -0,0 +1,41 @@ +{ + "name": "symfony/polyfill-mbstring", + "type": "library", + "description": "Symfony polyfill for the Mbstring extension", + "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, + "files": [ "bootstrap.php" ] + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE new file mode 100644 index 0000000..0ed3a24 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2020-present Fabien Potencier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php new file mode 100644 index 0000000..362dd1a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php80; + +/** + * @author Ion Bazan + * @author Nico Oelgart + * @author Nicolas Grekas + * + * @internal + */ +final class Php80 +{ + public static function fdiv(float $dividend, float $divisor): float + { + return @($dividend / $divisor); + } + + public static function get_debug_type($value): string + { + switch (true) { + case null === $value: return 'null'; + case \is_bool($value): return 'bool'; + case \is_string($value): return 'string'; + case \is_array($value): return 'array'; + case \is_int($value): return 'int'; + case \is_float($value): return 'float'; + case \is_object($value): break; + case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class'; + default: + if (null === $type = @get_resource_type($value)) { + return 'unknown'; + } + + if ('Unknown' === $type) { + $type = 'closed'; + } + + return "resource ($type)"; + } + + $class = \get_class($value); + + if (false === strpos($class, '@')) { + return $class; + } + + return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous'; + } + + public static function get_resource_id($res): int + { + if (!\is_resource($res) && null === @get_resource_type($res)) { + throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res))); + } + + return (int) $res; + } + + public static function preg_last_error_msg(): string + { + switch (preg_last_error()) { + case \PREG_INTERNAL_ERROR: + return 'Internal error'; + case \PREG_BAD_UTF8_ERROR: + return 'Malformed UTF-8 characters, possibly incorrectly encoded'; + case \PREG_BAD_UTF8_OFFSET_ERROR: + return 'The offset did not correspond to the beginning of a valid UTF-8 code point'; + case \PREG_BACKTRACK_LIMIT_ERROR: + return 'Backtrack limit exhausted'; + case \PREG_RECURSION_LIMIT_ERROR: + return 'Recursion limit exhausted'; + case \PREG_JIT_STACKLIMIT_ERROR: + return 'JIT stack limit exhausted'; + case \PREG_NO_ERROR: + return 'No error'; + default: + return 'Unknown error'; + } + } + + public static function str_contains(string $haystack, string $needle): bool + { + return '' === $needle || false !== strpos($haystack, $needle); + } + + public static function str_starts_with(string $haystack, string $needle): bool + { + return 0 === strncmp($haystack, $needle, \strlen($needle)); + } + + public static function str_ends_with(string $haystack, string $needle): bool + { + if ('' === $needle || $needle === $haystack) { + return true; + } + + if ('' === $haystack) { + return false; + } + + $needleLength = \strlen($needle); + + return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength); + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php new file mode 100644 index 0000000..fe6e691 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php @@ -0,0 +1,103 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Polyfill\Php80; + +/** + * @author Fedonyuk Anton + * + * @internal + */ +class PhpToken implements \Stringable +{ + /** + * @var int + */ + public $id; + + /** + * @var string + */ + public $text; + + /** + * @var int + */ + public $line; + + /** + * @var int + */ + public $pos; + + public function __construct(int $id, string $text, int $line = -1, int $position = -1) + { + $this->id = $id; + $this->text = $text; + $this->line = $line; + $this->pos = $position; + } + + public function getTokenName(): ?string + { + if ('UNKNOWN' === $name = token_name($this->id)) { + $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text; + } + + return $name; + } + + /** + * @param int|string|array $kind + */ + public function is($kind): bool + { + foreach ((array) $kind as $value) { + if (\in_array($value, [$this->id, $this->text], true)) { + return true; + } + } + + return false; + } + + public function isIgnorable(): bool + { + return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true); + } + + public function __toString(): string + { + return (string) $this->text; + } + + /** + * @return static[] + */ + public static function tokenize(string $code, int $flags = 0): array + { + $line = 1; + $position = 0; + $tokens = token_get_all($code, $flags); + foreach ($tokens as $index => $token) { + if (\is_string($token)) { + $id = \ord($token); + $text = $token; + } else { + [$id, $text, $line] = $token; + } + $tokens[$index] = new static($id, $text, $line, $position); + $position += \strlen($text); + } + + return $tokens; + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md new file mode 100644 index 0000000..3816c55 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md @@ -0,0 +1,25 @@ +Symfony Polyfill / Php80 +======================== + +This component provides features added to PHP 8.0 core: + +- [`Stringable`](https://php.net/stringable) interface +- [`fdiv`](https://php.net/fdiv) +- [`ValueError`](https://php.net/valueerror) class +- [`UnhandledMatchError`](https://php.net/unhandledmatcherror) class +- `FILTER_VALIDATE_BOOL` constant +- [`get_debug_type`](https://php.net/get_debug_type) +- [`PhpToken`](https://php.net/phptoken) class +- [`preg_last_error_msg`](https://php.net/preg_last_error_msg) +- [`str_contains`](https://php.net/str_contains) +- [`str_starts_with`](https://php.net/str_starts_with) +- [`str_ends_with`](https://php.net/str_ends_with) +- [`get_resource_id`](https://php.net/get_resource_id) + +More information can be found in the +[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). + +License +======= + +This library is released under the [MIT license](LICENSE). diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php new file mode 100644 index 0000000..2b95542 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#[Attribute(Attribute::TARGET_CLASS)] +final class Attribute +{ + public const TARGET_CLASS = 1; + public const TARGET_FUNCTION = 2; + public const TARGET_METHOD = 4; + public const TARGET_PROPERTY = 8; + public const TARGET_CLASS_CONSTANT = 16; + public const TARGET_PARAMETER = 32; + public const TARGET_ALL = 63; + public const IS_REPEATABLE = 64; + + /** @var int */ + public $flags; + + public function __construct(int $flags = self::TARGET_ALL) + { + $this->flags = $flags; + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php new file mode 100644 index 0000000..bd1212f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) { + class PhpToken extends Symfony\Polyfill\Php80\PhpToken + { + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php new file mode 100644 index 0000000..7c62d75 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + interface Stringable + { + /** + * @return string + */ + public function __toString(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php new file mode 100644 index 0000000..01c6c6c --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + class UnhandledMatchError extends Error + { + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php new file mode 100644 index 0000000..783dbc2 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php @@ -0,0 +1,16 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (\PHP_VERSION_ID < 80000) { + class ValueError extends Error + { + } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php new file mode 100644 index 0000000..e5f7dbc --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use Symfony\Polyfill\Php80 as p; + +if (\PHP_VERSION_ID >= 80000) { + return; +} + +if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) { + define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN); +} + +if (!function_exists('fdiv')) { + function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); } +} +if (!function_exists('preg_last_error_msg')) { + function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); } +} +if (!function_exists('str_contains')) { + function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('str_starts_with')) { + function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('str_ends_with')) { + function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); } +} +if (!function_exists('get_debug_type')) { + function get_debug_type($value): string { return p\Php80::get_debug_type($value); } +} +if (!function_exists('get_resource_id')) { + function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); } +} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json new file mode 100644 index 0000000..f1801f4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json @@ -0,0 +1,40 @@ +{ + "name": "symfony/polyfill-php80", + "type": "library", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "keywords": ["polyfill", "shim", "compatibility", "portable"], + "homepage": "https://symfony.com", + "license": "MIT", + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "require": { + "php": ">=7.1" + }, + "autoload": { + "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, + "files": [ "bootstrap.php" ], + "classmap": [ "Resources/stubs" ] + }, + "minimum-stability": "dev", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE new file mode 100644 index 0000000..922c552 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE @@ -0,0 +1,30 @@ +BSD 3-Clause License + +Copyright (c) 2014, Graham Campbell. +Copyright (c) 2013, Vance Lucas. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json new file mode 100644 index 0000000..fb972d7 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json @@ -0,0 +1,60 @@ +{ + "name": "vlucas/phpdotenv", + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": ["env", "dotenv", "environment"], + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "require": { + "php": "^7.2.5 || ^8.0", + "ext-pcre": "*", + "graham-campbell/result-type": "^1.1.2", + "phpoption/phpoption": "^1.9.2", + "symfony/polyfill-ctype": "^1.24", + "symfony/polyfill-mbstring": "^1.24", + "symfony/polyfill-php80": "^1.24" + }, + "require-dev": { + "ext-filter": "*", + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit":"^8.5.34 || ^9.6.13 || ^10.4.2" + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Dotenv\\Tests\\": "tests/Dotenv/" + } + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "config": { + "allow-plugins": { + "bamarni/composer-bin-plugin": true + }, + "preferred-install": "dist" + }, + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, + "branch-alias": { + "dev-master": "5.6-dev" + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php new file mode 100644 index 0000000..0460ced --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php @@ -0,0 +1,267 @@ +store = $store; + $this->parser = $parser; + $this->loader = $loader; + $this->repository = $repository; + } + + /** + * Create a new dotenv instance. + * + * @param \Dotenv\Repository\RepositoryInterface $repository + * @param string|string[] $paths + * @param string|string[]|null $names + * @param bool $shortCircuit + * @param string|null $fileEncoding + * + * @return \Dotenv\Dotenv + */ + public static function create(RepositoryInterface $repository, $paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) + { + $builder = $names === null ? StoreBuilder::createWithDefaultName() : StoreBuilder::createWithNoNames(); + + foreach ((array) $paths as $path) { + $builder = $builder->addPath($path); + } + + foreach ((array) $names as $name) { + $builder = $builder->addName($name); + } + + if ($shortCircuit) { + $builder = $builder->shortCircuit(); + } + + return new self($builder->fileEncoding($fileEncoding)->make(), new Parser(), new Loader(), $repository); + } + + /** + * Create a new mutable dotenv instance with default repository. + * + * @param string|string[] $paths + * @param string|string[]|null $names + * @param bool $shortCircuit + * @param string|null $fileEncoding + * + * @return \Dotenv\Dotenv + */ + public static function createMutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) + { + $repository = RepositoryBuilder::createWithDefaultAdapters()->make(); + + return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); + } + + /** + * Create a new mutable dotenv instance with default repository with the putenv adapter. + * + * @param string|string[] $paths + * @param string|string[]|null $names + * @param bool $shortCircuit + * @param string|null $fileEncoding + * + * @return \Dotenv\Dotenv + */ + public static function createUnsafeMutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) + { + $repository = RepositoryBuilder::createWithDefaultAdapters() + ->addAdapter(PutenvAdapter::class) + ->make(); + + return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); + } + + /** + * Create a new immutable dotenv instance with default repository. + * + * @param string|string[] $paths + * @param string|string[]|null $names + * @param bool $shortCircuit + * @param string|null $fileEncoding + * + * @return \Dotenv\Dotenv + */ + public static function createImmutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) + { + $repository = RepositoryBuilder::createWithDefaultAdapters()->immutable()->make(); + + return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); + } + + /** + * Create a new immutable dotenv instance with default repository with the putenv adapter. + * + * @param string|string[] $paths + * @param string|string[]|null $names + * @param bool $shortCircuit + * @param string|null $fileEncoding + * + * @return \Dotenv\Dotenv + */ + public static function createUnsafeImmutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) + { + $repository = RepositoryBuilder::createWithDefaultAdapters() + ->addAdapter(PutenvAdapter::class) + ->immutable() + ->make(); + + return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); + } + + /** + * Create a new dotenv instance with an array backed repository. + * + * @param string|string[] $paths + * @param string|string[]|null $names + * @param bool $shortCircuit + * @param string|null $fileEncoding + * + * @return \Dotenv\Dotenv + */ + public static function createArrayBacked($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) + { + $repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make(); + + return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); + } + + /** + * Parse the given content and resolve nested variables. + * + * This method behaves just like load(), only without mutating your actual + * environment. We do this by using an array backed repository. + * + * @param string $content + * + * @throws \Dotenv\Exception\InvalidFileException + * + * @return array + */ + public static function parse(string $content) + { + $repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make(); + + $phpdotenv = new self(new StringStore($content), new Parser(), new Loader(), $repository); + + return $phpdotenv->load(); + } + + /** + * Read and load environment file(s). + * + * @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException + * + * @return array + */ + public function load() + { + $entries = $this->parser->parse($this->store->read()); + + return $this->loader->load($this->repository, $entries); + } + + /** + * Read and load environment file(s), silently failing if no files can be read. + * + * @throws \Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException + * + * @return array + */ + public function safeLoad() + { + try { + return $this->load(); + } catch (InvalidPathException $e) { + // suppressing exception + return []; + } + } + + /** + * Required ensures that the specified variables exist, and returns a new validator object. + * + * @param string|string[] $variables + * + * @return \Dotenv\Validator + */ + public function required($variables) + { + return (new Validator($this->repository, (array) $variables))->required(); + } + + /** + * Returns a new validator object that won't check if the specified variables exist. + * + * @param string|string[] $variables + * + * @return \Dotenv\Validator + */ + public function ifPresent($variables) + { + return new Validator($this->repository, (array) $variables); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php new file mode 100644 index 0000000..1e80f53 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php @@ -0,0 +1,12 @@ + + */ + public function load(RepositoryInterface $repository, array $entries) + { + return \array_reduce($entries, static function (array $vars, Entry $entry) use ($repository) { + $name = $entry->getName(); + + $value = $entry->getValue()->map(static function (Value $value) use ($repository) { + return Resolver::resolve($repository, $value); + }); + + if ($value->isDefined()) { + $inner = $value->get(); + if ($repository->set($name, $inner)) { + return \array_merge($vars, [$name => $inner]); + } + } else { + if ($repository->clear($name)) { + return \array_merge($vars, [$name => null]); + } + } + + return $vars; + }, []); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php new file mode 100644 index 0000000..275d98e --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php @@ -0,0 +1,20 @@ + + */ + public function load(RepositoryInterface $repository, array $entries); +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php new file mode 100644 index 0000000..36d7a4b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php @@ -0,0 +1,65 @@ +getVars(), static function (string $s, int $i) use ($repository) { + return Str::substr($s, 0, $i).self::resolveVariable($repository, Str::substr($s, $i)); + }, $value->getChars()); + } + + /** + * Resolve a single nested variable. + * + * @param \Dotenv\Repository\RepositoryInterface $repository + * @param string $str + * + * @return string + */ + private static function resolveVariable(RepositoryInterface $repository, string $str) + { + return Regex::replaceCallback( + '/\A\${([a-zA-Z0-9_.]+)}/', + static function (array $matches) use ($repository) { + return Option::fromValue($repository->get($matches[1])) + ->getOrElse($matches[0]); + }, + $str, + 1 + )->success()->getOrElse($str); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php new file mode 100644 index 0000000..7570f58 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php @@ -0,0 +1,59 @@ +name = $name; + $this->value = $value; + } + + /** + * Get the entry name. + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * Get the entry value. + * + * @return \PhpOption\Option<\Dotenv\Parser\Value> + */ + public function getValue() + { + /** @var \PhpOption\Option<\Dotenv\Parser\Value> */ + return Option::fromValue($this->value); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php new file mode 100644 index 0000000..e286840 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php @@ -0,0 +1,300 @@ + + */ + public static function parse(string $entry) + { + return self::splitStringIntoParts($entry)->flatMap(static function (array $parts) { + [$name, $value] = $parts; + + return self::parseName($name)->flatMap(static function (string $name) use ($value) { + /** @var Result */ + $parsedValue = $value === null ? Success::create(null) : self::parseValue($value); + + return $parsedValue->map(static function (?Value $value) use ($name) { + return new Entry($name, $value); + }); + }); + }); + } + + /** + * Split the compound string into parts. + * + * @param string $line + * + * @return \GrahamCampbell\ResultType\Result + */ + private static function splitStringIntoParts(string $line) + { + /** @var array{string,string|null} */ + $result = Str::pos($line, '=')->map(static function () use ($line) { + return \array_map('trim', \explode('=', $line, 2)); + })->getOrElse([$line, null]); + + if ($result[0] === '') { + /** @var \GrahamCampbell\ResultType\Result */ + return Error::create(self::getErrorMessage('an unexpected equals', $line)); + } + + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create($result); + } + + /** + * Parse the given variable name. + * + * That is, strip the optional quotes and leading "export" from the + * variable name. We wrap the answer in a result type. + * + * @param string $name + * + * @return \GrahamCampbell\ResultType\Result + */ + private static function parseName(string $name) + { + if (Str::len($name) > 8 && Str::substr($name, 0, 6) === 'export' && \ctype_space(Str::substr($name, 6, 1))) { + $name = \ltrim(Str::substr($name, 6)); + } + + if (self::isQuotedName($name)) { + $name = Str::substr($name, 1, -1); + } + + if (!self::isValidName($name)) { + /** @var \GrahamCampbell\ResultType\Result */ + return Error::create(self::getErrorMessage('an invalid name', $name)); + } + + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create($name); + } + + /** + * Is the given variable name quoted? + * + * @param string $name + * + * @return bool + */ + private static function isQuotedName(string $name) + { + if (Str::len($name) < 3) { + return false; + } + + $first = Str::substr($name, 0, 1); + $last = Str::substr($name, -1, 1); + + return ($first === '"' && $last === '"') || ($first === '\'' && $last === '\''); + } + + /** + * Is the given variable name valid? + * + * @param string $name + * + * @return bool + */ + private static function isValidName(string $name) + { + return Regex::matches('~(*UTF8)\A[\p{Ll}\p{Lu}\p{M}\p{N}_.]+\z~', $name)->success()->getOrElse(false); + } + + /** + * Parse the given variable value. + * + * This has the effect of stripping quotes and comments, dealing with + * special characters, and locating nested variables, but not resolving + * them. Formally, we run a finite state automaton with an output tape: a + * transducer. We wrap the answer in a result type. + * + * @param string $value + * + * @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> + */ + private static function parseValue(string $value) + { + if (\trim($value) === '') { + /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */ + return Success::create(Value::blank()); + } + + return \array_reduce(\iterator_to_array(Lexer::lex($value)), static function (Result $data, string $token) { + return $data->flatMap(static function (array $data) use ($token) { + return self::processToken($data[1], $token)->map(static function (array $val) use ($data) { + return [$data[0]->append($val[0], $val[1]), $val[2]]; + }); + }); + }, Success::create([Value::blank(), self::INITIAL_STATE]))->flatMap(static function (array $result) { + /** @psalm-suppress DocblockTypeContradiction */ + if (in_array($result[1], self::REJECT_STATES, true)) { + /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */ + return Error::create('a missing closing quote'); + } + + /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */ + return Success::create($result[0]); + })->mapError(static function (string $err) use ($value) { + return self::getErrorMessage($err, $value); + }); + } + + /** + * Process the given token. + * + * @param int $state + * @param string $token + * + * @return \GrahamCampbell\ResultType\Result + */ + private static function processToken(int $state, string $token) + { + switch ($state) { + case self::INITIAL_STATE: + if ($token === '\'') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::SINGLE_QUOTED_STATE]); + } elseif ($token === '"') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::DOUBLE_QUOTED_STATE]); + } elseif ($token === '#') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::COMMENT_STATE]); + } elseif ($token === '$') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, true, self::UNQUOTED_STATE]); + } else { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, false, self::UNQUOTED_STATE]); + } + case self::UNQUOTED_STATE: + if ($token === '#') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::COMMENT_STATE]); + } elseif (\ctype_space($token)) { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::WHITESPACE_STATE]); + } elseif ($token === '$') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, true, self::UNQUOTED_STATE]); + } else { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, false, self::UNQUOTED_STATE]); + } + case self::SINGLE_QUOTED_STATE: + if ($token === '\'') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::WHITESPACE_STATE]); + } else { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, false, self::SINGLE_QUOTED_STATE]); + } + case self::DOUBLE_QUOTED_STATE: + if ($token === '"') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::WHITESPACE_STATE]); + } elseif ($token === '\\') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::ESCAPE_SEQUENCE_STATE]); + } elseif ($token === '$') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, true, self::DOUBLE_QUOTED_STATE]); + } else { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]); + } + case self::ESCAPE_SEQUENCE_STATE: + if ($token === '"' || $token === '\\') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]); + } elseif ($token === '$') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]); + } else { + $first = Str::substr($token, 0, 1); + if (\in_array($first, ['f', 'n', 'r', 't', 'v'], true)) { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create([\stripcslashes('\\'.$first).Str::substr($token, 1), false, self::DOUBLE_QUOTED_STATE]); + } else { + /** @var \GrahamCampbell\ResultType\Result */ + return Error::create('an unexpected escape sequence'); + } + } + case self::WHITESPACE_STATE: + if ($token === '#') { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::COMMENT_STATE]); + } elseif (!\ctype_space($token)) { + /** @var \GrahamCampbell\ResultType\Result */ + return Error::create('unexpected whitespace'); + } else { + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::WHITESPACE_STATE]); + } + case self::COMMENT_STATE: + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create(['', false, self::COMMENT_STATE]); + default: + throw new \Error('Parser entered invalid state.'); + } + } + + /** + * Generate a friendly error message. + * + * @param string $cause + * @param string $subject + * + * @return string + */ + private static function getErrorMessage(string $cause, string $subject) + { + return \sprintf( + 'Encountered %s at [%s].', + $cause, + \strtok($subject, "\n") + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php new file mode 100644 index 0000000..981af24 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php @@ -0,0 +1,58 @@ + + */ + public static function lex(string $content) + { + static $regex; + + if ($regex === null) { + $regex = '(('.\implode(')|(', self::PATTERNS).'))A'; + } + + $offset = 0; + + while (isset($content[$offset])) { + if (!\preg_match($regex, $content, $matches, 0, $offset)) { + throw new \Error(\sprintf('Lexer encountered unexpected character [%s].', $content[$offset])); + } + + $offset += \strlen($matches[0]); + + yield $matches[0]; + } + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php new file mode 100644 index 0000000..6497993 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php @@ -0,0 +1,127 @@ +map(static function () use ($line) { + return self::looksLikeMultilineStop($line, true) === false; + })->getOrElse(false); + } + + /** + * Determine if the given line can be the start of a multiline variable. + * + * @param string $line + * @param bool $started + * + * @return bool + */ + private static function looksLikeMultilineStop(string $line, bool $started) + { + if ($line === '"') { + return true; + } + + return Regex::occurrences('/(?=([^\\\\]"))/', \str_replace('\\\\', '', $line))->map(static function (int $count) use ($started) { + return $started ? $count > 1 : $count >= 1; + })->success()->getOrElse(false); + } + + /** + * Determine if the line in the file is a comment or whitespace. + * + * @param string $line + * + * @return bool + */ + private static function isCommentOrWhitespace(string $line) + { + $line = \trim($line); + + return $line === '' || (isset($line[0]) && $line[0] === '#'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php new file mode 100644 index 0000000..2d30dfd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php @@ -0,0 +1,53 @@ +mapError(static function () { + return 'Could not split into separate lines.'; + })->flatMap(static function (array $lines) { + return self::process(Lines::process($lines)); + })->mapError(static function (string $error) { + throw new InvalidFileException(\sprintf('Failed to parse dotenv file. %s', $error)); + })->success()->get(); + } + + /** + * Convert the raw entries into proper entries. + * + * @param string[] $entries + * + * @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[],string> + */ + private static function process(array $entries) + { + /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[],string> */ + return \array_reduce($entries, static function (Result $result, string $raw) { + return $result->flatMap(static function (array $entries) use ($raw) { + return EntryParser::parse($raw)->map(static function (Entry $entry) use ($entries) { + /** @var \Dotenv\Parser\Entry[] */ + return \array_merge($entries, [$entry]); + }); + }); + }, Success::create([])); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php new file mode 100644 index 0000000..17cc42a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php @@ -0,0 +1,19 @@ +chars = $chars; + $this->vars = $vars; + } + + /** + * Create an empty value instance. + * + * @return \Dotenv\Parser\Value + */ + public static function blank() + { + return new self('', []); + } + + /** + * Create a new value instance, appending the characters. + * + * @param string $chars + * @param bool $var + * + * @return \Dotenv\Parser\Value + */ + public function append(string $chars, bool $var) + { + return new self( + $this->chars.$chars, + $var ? \array_merge($this->vars, [Str::len($this->chars)]) : $this->vars + ); + } + + /** + * Get the string representation of the parsed value. + * + * @return string + */ + public function getChars() + { + return $this->chars; + } + + /** + * Get the locations of the variables in the value. + * + * @return int[] + */ + public function getVars() + { + $vars = $this->vars; + + \rsort($vars); + + return $vars; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php new file mode 100644 index 0000000..5604398 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php @@ -0,0 +1,15 @@ + + */ + public static function create(); +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php new file mode 100644 index 0000000..af0aae1 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php @@ -0,0 +1,89 @@ + + */ + public static function create() + { + if (self::isSupported()) { + /** @var \PhpOption\Option */ + return Some::create(new self()); + } + + return None::create(); + } + + /** + * Determines if the adapter is supported. + * + * This happens if PHP is running as an Apache module. + * + * @return bool + */ + private static function isSupported() + { + return \function_exists('apache_getenv') && \function_exists('apache_setenv'); + } + + /** + * Read an environment variable, if it exists. + * + * @param non-empty-string $name + * + * @return \PhpOption\Option + */ + public function read(string $name) + { + /** @var \PhpOption\Option */ + return Option::fromValue(apache_getenv($name))->filter(static function ($value) { + return \is_string($value) && $value !== ''; + }); + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + return apache_setenv($name, $value); + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + return apache_setenv($name, ''); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php new file mode 100644 index 0000000..df64cf6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php @@ -0,0 +1,80 @@ + + */ + private $variables; + + /** + * Create a new array adapter instance. + * + * @return void + */ + private function __construct() + { + $this->variables = []; + } + + /** + * Create a new instance of the adapter, if it is available. + * + * @return \PhpOption\Option<\Dotenv\Repository\Adapter\AdapterInterface> + */ + public static function create() + { + /** @var \PhpOption\Option */ + return Some::create(new self()); + } + + /** + * Read an environment variable, if it exists. + * + * @param non-empty-string $name + * + * @return \PhpOption\Option + */ + public function read(string $name) + { + return Option::fromArraysValue($this->variables, $name); + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + $this->variables[$name] = $value; + + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + unset($this->variables[$name]); + + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php new file mode 100644 index 0000000..9eb1947 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php @@ -0,0 +1,89 @@ + + */ + public static function create() + { + /** @var \PhpOption\Option */ + return Some::create(new self()); + } + + /** + * Read an environment variable, if it exists. + * + * @param non-empty-string $name + * + * @return \PhpOption\Option + */ + public function read(string $name) + { + /** @var \PhpOption\Option */ + return Option::fromArraysValue($_ENV, $name) + ->filter(static function ($value) { + return \is_scalar($value); + }) + ->map(static function ($value) { + if ($value === false) { + return 'false'; + } + + if ($value === true) { + return 'true'; + } + + /** @psalm-suppress PossiblyInvalidCast */ + return (string) $value; + }); + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + $_ENV[$name] = $value; + + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + unset($_ENV[$name]); + + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php new file mode 100644 index 0000000..fed8b9b --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php @@ -0,0 +1,85 @@ +writer = $writer; + $this->allowList = $allowList; + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + // Don't set non-allowed variables + if (!$this->isAllowed($name)) { + return false; + } + + // Set the value on the inner writer + return $this->writer->write($name, $value); + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + // Don't clear non-allowed variables + if (!$this->isAllowed($name)) { + return false; + } + + // Set the value on the inner writer + return $this->writer->delete($name); + } + + /** + * Determine if the given variable is allowed. + * + * @param non-empty-string $name + * + * @return bool + */ + private function isAllowed(string $name) + { + return \in_array($name, $this->allowList, true); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php new file mode 100644 index 0000000..399e6f9 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php @@ -0,0 +1,110 @@ + + */ + private $loaded; + + /** + * Create a new immutable writer instance. + * + * @param \Dotenv\Repository\Adapter\WriterInterface $writer + * @param \Dotenv\Repository\Adapter\ReaderInterface $reader + * + * @return void + */ + public function __construct(WriterInterface $writer, ReaderInterface $reader) + { + $this->writer = $writer; + $this->reader = $reader; + $this->loaded = []; + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + // Don't overwrite existing environment variables + // Ruby's dotenv does this with `ENV[key] ||= value` + if ($this->isExternallyDefined($name)) { + return false; + } + + // Set the value on the inner writer + if (!$this->writer->write($name, $value)) { + return false; + } + + // Record that we have loaded the variable + $this->loaded[$name] = ''; + + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + // Don't clear existing environment variables + if ($this->isExternallyDefined($name)) { + return false; + } + + // Clear the value on the inner writer + if (!$this->writer->delete($name)) { + return false; + } + + // Leave the variable as fair game + unset($this->loaded[$name]); + + return true; + } + + /** + * Determine if the given variable is externally defined. + * + * That is, is it an "existing" variable. + * + * @param non-empty-string $name + * + * @return bool + */ + private function isExternallyDefined(string $name) + { + return $this->reader->read($name)->isDefined() && !isset($this->loaded[$name]); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php new file mode 100644 index 0000000..0cfda6f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php @@ -0,0 +1,48 @@ +readers = $readers; + } + + /** + * Read an environment variable, if it exists. + * + * @param non-empty-string $name + * + * @return \PhpOption\Option + */ + public function read(string $name) + { + foreach ($this->readers as $reader) { + $result = $reader->read($name); + if ($result->isDefined()) { + return $result; + } + } + + return None::create(); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php new file mode 100644 index 0000000..15a9d8f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php @@ -0,0 +1,64 @@ +writers = $writers; + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + foreach ($this->writers as $writers) { + if (!$writers->write($name, $value)) { + return false; + } + } + + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + foreach ($this->writers as $writers) { + if (!$writers->delete($name)) { + return false; + } + } + + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php new file mode 100644 index 0000000..6d017cd --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php @@ -0,0 +1,91 @@ + + */ + public static function create() + { + if (self::isSupported()) { + /** @var \PhpOption\Option */ + return Some::create(new self()); + } + + return None::create(); + } + + /** + * Determines if the adapter is supported. + * + * @return bool + */ + private static function isSupported() + { + return \function_exists('getenv') && \function_exists('putenv'); + } + + /** + * Read an environment variable, if it exists. + * + * @param non-empty-string $name + * + * @return \PhpOption\Option + */ + public function read(string $name) + { + /** @var \PhpOption\Option */ + return Option::fromValue(\getenv($name), false)->filter(static function ($value) { + return \is_string($value); + }); + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + \putenv("$name=$value"); + + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + \putenv($name); + + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php new file mode 100644 index 0000000..306a63f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php @@ -0,0 +1,17 @@ + + */ + public function read(string $name); +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php new file mode 100644 index 0000000..98c0f04 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php @@ -0,0 +1,104 @@ + + */ + private $seen; + + /** + * Create a new replacement writer instance. + * + * @param \Dotenv\Repository\Adapter\WriterInterface $writer + * @param \Dotenv\Repository\Adapter\ReaderInterface $reader + * + * @return void + */ + public function __construct(WriterInterface $writer, ReaderInterface $reader) + { + $this->writer = $writer; + $this->reader = $reader; + $this->seen = []; + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + if ($this->exists($name)) { + return $this->writer->write($name, $value); + } + + // succeed if nothing to do + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + if ($this->exists($name)) { + return $this->writer->delete($name); + } + + // succeed if nothing to do + return true; + } + + /** + * Does the given environment variable exist. + * + * Returns true if it currently exists, or existed at any point in the past + * that we are aware of. + * + * @param non-empty-string $name + * + * @return bool + */ + private function exists(string $name) + { + if (isset($this->seen[$name])) { + return true; + } + + if ($this->reader->read($name)->isDefined()) { + $this->seen[$name] = ''; + + return true; + } + + return false; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php new file mode 100644 index 0000000..f93b6e5 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php @@ -0,0 +1,89 @@ + + */ + public static function create() + { + /** @var \PhpOption\Option */ + return Some::create(new self()); + } + + /** + * Read an environment variable, if it exists. + * + * @param non-empty-string $name + * + * @return \PhpOption\Option + */ + public function read(string $name) + { + /** @var \PhpOption\Option */ + return Option::fromArraysValue($_SERVER, $name) + ->filter(static function ($value) { + return \is_scalar($value); + }) + ->map(static function ($value) { + if ($value === false) { + return 'false'; + } + + if ($value === true) { + return 'true'; + } + + /** @psalm-suppress PossiblyInvalidCast */ + return (string) $value; + }); + } + + /** + * Write to an environment variable, if possible. + * + * @param non-empty-string $name + * @param string $value + * + * @return bool + */ + public function write(string $name, string $value) + { + $_SERVER[$name] = $value; + + return true; + } + + /** + * Delete an environment variable, if possible. + * + * @param non-empty-string $name + * + * @return bool + */ + public function delete(string $name) + { + unset($_SERVER[$name]); + + return true; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php new file mode 100644 index 0000000..4cb3d61 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php @@ -0,0 +1,27 @@ +reader = $reader; + $this->writer = $writer; + } + + /** + * Determine if the given environment variable is defined. + * + * @param string $name + * + * @return bool + */ + public function has(string $name) + { + return '' !== $name && $this->reader->read($name)->isDefined(); + } + + /** + * Get an environment variable. + * + * @param string $name + * + * @throws \InvalidArgumentException + * + * @return string|null + */ + public function get(string $name) + { + if ('' === $name) { + throw new InvalidArgumentException('Expected name to be a non-empty string.'); + } + + return $this->reader->read($name)->getOrElse(null); + } + + /** + * Set an environment variable. + * + * @param string $name + * @param string $value + * + * @throws \InvalidArgumentException + * + * @return bool + */ + public function set(string $name, string $value) + { + if ('' === $name) { + throw new InvalidArgumentException('Expected name to be a non-empty string.'); + } + + return $this->writer->write($name, $value); + } + + /** + * Clear an environment variable. + * + * @param string $name + * + * @throws \InvalidArgumentException + * + * @return bool + */ + public function clear(string $name) + { + if ('' === $name) { + throw new InvalidArgumentException('Expected name to be a non-empty string.'); + } + + return $this->writer->delete($name); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php new file mode 100644 index 0000000..a042f9a --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php @@ -0,0 +1,272 @@ +readers = $readers; + $this->writers = $writers; + $this->immutable = $immutable; + $this->allowList = $allowList; + } + + /** + * Create a new repository builder instance with no adapters added. + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public static function createWithNoAdapters() + { + return new self(); + } + + /** + * Create a new repository builder instance with the default adapters added. + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public static function createWithDefaultAdapters() + { + $adapters = \iterator_to_array(self::defaultAdapters()); + + return new self($adapters, $adapters); + } + + /** + * Return the array of default adapters. + * + * @return \Generator<\Dotenv\Repository\Adapter\AdapterInterface> + */ + private static function defaultAdapters() + { + foreach (self::DEFAULT_ADAPTERS as $adapter) { + $instance = $adapter::create(); + if ($instance->isDefined()) { + yield $instance->get(); + } + } + } + + /** + * Determine if the given name if of an adapterclass. + * + * @param string $name + * + * @return bool + */ + private static function isAnAdapterClass(string $name) + { + if (!\class_exists($name)) { + return false; + } + + return (new ReflectionClass($name))->implementsInterface(AdapterInterface::class); + } + + /** + * Creates a repository builder with the given reader added. + * + * Accepts either a reader instance, or a class-string for an adapter. If + * the adapter is not supported, then we silently skip adding it. + * + * @param \Dotenv\Repository\Adapter\ReaderInterface|string $reader + * + * @throws \InvalidArgumentException + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public function addReader($reader) + { + if (!(\is_string($reader) && self::isAnAdapterClass($reader)) && !($reader instanceof ReaderInterface)) { + throw new InvalidArgumentException( + \sprintf( + 'Expected either an instance of %s or a class-string implementing %s', + ReaderInterface::class, + AdapterInterface::class + ) + ); + } + + $optional = Some::create($reader)->flatMap(static function ($reader) { + return \is_string($reader) ? $reader::create() : Some::create($reader); + }); + + $readers = \array_merge($this->readers, \iterator_to_array($optional)); + + return new self($readers, $this->writers, $this->immutable, $this->allowList); + } + + /** + * Creates a repository builder with the given writer added. + * + * Accepts either a writer instance, or a class-string for an adapter. If + * the adapter is not supported, then we silently skip adding it. + * + * @param \Dotenv\Repository\Adapter\WriterInterface|string $writer + * + * @throws \InvalidArgumentException + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public function addWriter($writer) + { + if (!(\is_string($writer) && self::isAnAdapterClass($writer)) && !($writer instanceof WriterInterface)) { + throw new InvalidArgumentException( + \sprintf( + 'Expected either an instance of %s or a class-string implementing %s', + WriterInterface::class, + AdapterInterface::class + ) + ); + } + + $optional = Some::create($writer)->flatMap(static function ($writer) { + return \is_string($writer) ? $writer::create() : Some::create($writer); + }); + + $writers = \array_merge($this->writers, \iterator_to_array($optional)); + + return new self($this->readers, $writers, $this->immutable, $this->allowList); + } + + /** + * Creates a repository builder with the given adapter added. + * + * Accepts either an adapter instance, or a class-string for an adapter. If + * the adapter is not supported, then we silently skip adding it. We will + * add the adapter as both a reader and a writer. + * + * @param \Dotenv\Repository\Adapter\WriterInterface|string $adapter + * + * @throws \InvalidArgumentException + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public function addAdapter($adapter) + { + if (!(\is_string($adapter) && self::isAnAdapterClass($adapter)) && !($adapter instanceof AdapterInterface)) { + throw new InvalidArgumentException( + \sprintf( + 'Expected either an instance of %s or a class-string implementing %s', + WriterInterface::class, + AdapterInterface::class + ) + ); + } + + $optional = Some::create($adapter)->flatMap(static function ($adapter) { + return \is_string($adapter) ? $adapter::create() : Some::create($adapter); + }); + + $readers = \array_merge($this->readers, \iterator_to_array($optional)); + $writers = \array_merge($this->writers, \iterator_to_array($optional)); + + return new self($readers, $writers, $this->immutable, $this->allowList); + } + + /** + * Creates a repository builder with mutability enabled. + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public function immutable() + { + return new self($this->readers, $this->writers, true, $this->allowList); + } + + /** + * Creates a repository builder with the given allow list. + * + * @param string[]|null $allowList + * + * @return \Dotenv\Repository\RepositoryBuilder + */ + public function allowList(array $allowList = null) + { + return new self($this->readers, $this->writers, $this->immutable, $allowList); + } + + /** + * Creates a new repository instance. + * + * @return \Dotenv\Repository\RepositoryInterface + */ + public function make() + { + $reader = new MultiReader($this->readers); + $writer = new MultiWriter($this->writers); + + if ($this->immutable) { + $writer = new ImmutableWriter($writer, $reader); + } + + if ($this->allowList !== null) { + $writer = new GuardedWriter($writer, $this->allowList); + } + + return new AdapterRepository($reader, $writer); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php new file mode 100644 index 0000000..d9b18a4 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php @@ -0,0 +1,51 @@ + + */ + public static function read(array $filePaths, bool $shortCircuit = true, string $fileEncoding = null) + { + $output = []; + + foreach ($filePaths as $filePath) { + $content = self::readFromFile($filePath, $fileEncoding); + if ($content->isDefined()) { + $output[$filePath] = $content->get(); + if ($shortCircuit) { + break; + } + } + } + + return $output; + } + + /** + * Read the given file. + * + * @param string $path + * @param string|null $encoding + * + * @throws \Dotenv\Exception\InvalidEncodingException + * + * @return \PhpOption\Option + */ + private static function readFromFile(string $path, string $encoding = null) + { + /** @var Option */ + $content = Option::fromValue(@\file_get_contents($path), false); + + return $content->flatMap(static function (string $content) use ($encoding) { + return Str::utf8($content, $encoding)->mapError(static function (string $error) { + throw new InvalidEncodingException($error); + })->success(); + }); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php new file mode 100644 index 0000000..43f6135 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php @@ -0,0 +1,72 @@ +filePaths = $filePaths; + $this->shortCircuit = $shortCircuit; + $this->fileEncoding = $fileEncoding; + } + + /** + * Read the content of the environment file(s). + * + * @throws \Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidPathException + * + * @return string + */ + public function read() + { + if ($this->filePaths === []) { + throw new InvalidPathException('At least one environment file path must be provided.'); + } + + $contents = Reader::read($this->filePaths, $this->shortCircuit, $this->fileEncoding); + + if (\count($contents) > 0) { + return \implode("\n", $contents); + } + + throw new InvalidPathException( + \sprintf('Unable to read any of the environment file(s) at [%s].', \implode(', ', $this->filePaths)) + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php new file mode 100644 index 0000000..304117f --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php @@ -0,0 +1,141 @@ +paths = $paths; + $this->names = $names; + $this->shortCircuit = $shortCircuit; + $this->fileEncoding = $fileEncoding; + } + + /** + * Create a new store builder instance with no names. + * + * @return \Dotenv\Store\StoreBuilder + */ + public static function createWithNoNames() + { + return new self(); + } + + /** + * Create a new store builder instance with the default name. + * + * @return \Dotenv\Store\StoreBuilder + */ + public static function createWithDefaultName() + { + return new self([], [self::DEFAULT_NAME]); + } + + /** + * Creates a store builder with the given path added. + * + * @param string $path + * + * @return \Dotenv\Store\StoreBuilder + */ + public function addPath(string $path) + { + return new self(\array_merge($this->paths, [$path]), $this->names, $this->shortCircuit, $this->fileEncoding); + } + + /** + * Creates a store builder with the given name added. + * + * @param string $name + * + * @return \Dotenv\Store\StoreBuilder + */ + public function addName(string $name) + { + return new self($this->paths, \array_merge($this->names, [$name]), $this->shortCircuit, $this->fileEncoding); + } + + /** + * Creates a store builder with short circuit mode enabled. + * + * @return \Dotenv\Store\StoreBuilder + */ + public function shortCircuit() + { + return new self($this->paths, $this->names, true, $this->fileEncoding); + } + + /** + * Creates a store builder with the specified file encoding. + * + * @param string|null $fileEncoding + * + * @return \Dotenv\Store\StoreBuilder + */ + public function fileEncoding(string $fileEncoding = null) + { + return new self($this->paths, $this->names, $this->shortCircuit, $fileEncoding); + } + + /** + * Creates a new store instance. + * + * @return \Dotenv\Store\StoreInterface + */ + public function make() + { + return new FileStore( + Paths::filePaths($this->paths, $this->names), + $this->shortCircuit, + $this->fileEncoding + ); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php new file mode 100644 index 0000000..6f5b986 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php @@ -0,0 +1,17 @@ +content = $content; + } + + /** + * Read the content of the environment file(s). + * + * @return string + */ + public function read() + { + return $this->content; + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php new file mode 100644 index 0000000..52c1578 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php @@ -0,0 +1,112 @@ + + */ + public static function matches(string $pattern, string $subject) + { + return self::pregAndWrap(static function (string $subject) use ($pattern) { + return @\preg_match($pattern, $subject) === 1; + }, $subject); + } + + /** + * Perform a preg match all, wrapping up the result. + * + * @param string $pattern + * @param string $subject + * + * @return \GrahamCampbell\ResultType\Result + */ + public static function occurrences(string $pattern, string $subject) + { + return self::pregAndWrap(static function (string $subject) use ($pattern) { + return (int) @\preg_match_all($pattern, $subject); + }, $subject); + } + + /** + * Perform a preg replace callback, wrapping up the result. + * + * @param string $pattern + * @param callable $callback + * @param string $subject + * @param int|null $limit + * + * @return \GrahamCampbell\ResultType\Result + */ + public static function replaceCallback(string $pattern, callable $callback, string $subject, int $limit = null) + { + return self::pregAndWrap(static function (string $subject) use ($pattern, $callback, $limit) { + return (string) @\preg_replace_callback($pattern, $callback, $subject, $limit ?? -1); + }, $subject); + } + + /** + * Perform a preg split, wrapping up the result. + * + * @param string $pattern + * @param string $subject + * + * @return \GrahamCampbell\ResultType\Result + */ + public static function split(string $pattern, string $subject) + { + return self::pregAndWrap(static function (string $subject) use ($pattern) { + /** @var string[] */ + return (array) @\preg_split($pattern, $subject); + }, $subject); + } + + /** + * Perform a preg operation, wrapping up the result. + * + * @template V + * + * @param callable(string):V $operation + * @param string $subject + * + * @return \GrahamCampbell\ResultType\Result + */ + private static function pregAndWrap(callable $operation, string $subject) + { + $result = $operation($subject); + + if (\preg_last_error() !== \PREG_NO_ERROR) { + /** @var \GrahamCampbell\ResultType\Result */ + return Error::create(\preg_last_error_msg()); + } + + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create($result); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php new file mode 100644 index 0000000..087e236 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php @@ -0,0 +1,98 @@ + + */ + public static function utf8(string $input, string $encoding = null) + { + if ($encoding !== null && !\in_array($encoding, \mb_list_encodings(), true)) { + /** @var \GrahamCampbell\ResultType\Result */ + return Error::create( + \sprintf('Illegal character encoding [%s] specified.', $encoding) + ); + } + $converted = $encoding === null ? + @\mb_convert_encoding($input, 'UTF-8') : + @\mb_convert_encoding($input, 'UTF-8', $encoding); + /** + * this is for support UTF-8 with BOM encoding + * @see https://en.wikipedia.org/wiki/Byte_order_mark + * @see https://github.com/vlucas/phpdotenv/issues/500 + */ + if (\substr($converted, 0, 3) == "\xEF\xBB\xBF") { + $converted = \substr($converted, 3); + } + /** @var \GrahamCampbell\ResultType\Result */ + return Success::create($converted); + } + + /** + * Search for a given substring of the input. + * + * @param string $haystack + * @param string $needle + * + * @return \PhpOption\Option + */ + public static function pos(string $haystack, string $needle) + { + /** @var \PhpOption\Option */ + return Option::fromValue(\mb_strpos($haystack, $needle, 0, 'UTF-8'), false); + } + + /** + * Grab the specified substring of the input. + * + * @param string $input + * @param int $start + * @param int|null $length + * + * @return string + */ + public static function substr(string $input, int $start, int $length = null) + { + return \mb_substr($input, $start, $length, 'UTF-8'); + } + + /** + * Compute the length of the given string. + * + * @param string $input + * + * @return int + */ + public static function len(string $input) + { + return \mb_strlen($input, 'UTF-8'); + } +} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php new file mode 100644 index 0000000..0c04ab6 --- /dev/null +++ b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php @@ -0,0 +1,209 @@ +repository = $repository; + $this->variables = $variables; + } + + /** + * Assert that each variable is present. + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function required() + { + return $this->assert( + static function (?string $value) { + return $value !== null; + }, + 'is missing' + ); + } + + /** + * Assert that each variable is not empty. + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function notEmpty() + { + return $this->assertNullable( + static function (string $value) { + return Str::len(\trim($value)) > 0; + }, + 'is empty' + ); + } + + /** + * Assert that each specified variable is an integer. + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function isInteger() + { + return $this->assertNullable( + static function (string $value) { + return \ctype_digit($value); + }, + 'is not an integer' + ); + } + + /** + * Assert that each specified variable is a boolean. + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function isBoolean() + { + return $this->assertNullable( + static function (string $value) { + if ($value === '') { + return false; + } + + return \filter_var($value, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE) !== null; + }, + 'is not a boolean' + ); + } + + /** + * Assert that each variable is amongst the given choices. + * + * @param string[] $choices + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function allowedValues(array $choices) + { + return $this->assertNullable( + static function (string $value) use ($choices) { + return \in_array($value, $choices, true); + }, + \sprintf('is not one of [%s]', \implode(', ', $choices)) + ); + } + + /** + * Assert that each variable matches the given regular expression. + * + * @param string $regex + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function allowedRegexValues(string $regex) + { + return $this->assertNullable( + static function (string $value) use ($regex) { + return Regex::matches($regex, $value)->success()->getOrElse(false); + }, + \sprintf('does not match "%s"', $regex) + ); + } + + /** + * Assert that the callback returns true for each variable. + * + * @param callable(?string):bool $callback + * @param string $message + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function assert(callable $callback, string $message) + { + $failing = []; + + foreach ($this->variables as $variable) { + if ($callback($this->repository->get($variable)) === false) { + $failing[] = \sprintf('%s %s', $variable, $message); + } + } + + if (\count($failing) > 0) { + throw new ValidationException(\sprintf( + 'One or more environment variables failed assertions: %s.', + \implode(', ', $failing) + )); + } + + return $this; + } + + /** + * Assert that the callback returns true for each variable. + * + * Skip checking null variable values. + * + * @param callable(string):bool $callback + * @param string $message + * + * @throws \Dotenv\Exception\ValidationException + * + * @return \Dotenv\Validator + */ + public function assertNullable(callable $callback, string $message) + { + return $this->assert( + static function (?string $value) use ($callback) { + if ($value === null) { + return true; + } + + return $callback($value); + }, + $message + ); + } +} From 988fc65ddcb6b9587b48538b522112be221f283f Mon Sep 17 00:00:00 2001 From: Charanpreet Date: Fri, 2 Feb 2024 15:07:45 +0530 Subject: [PATCH 123/228] fix: added .gitignore --- .../signing_and_verification/php/.gitignore | 473 ++++++++++++++++++ 1 file changed, 473 insertions(+) diff --git a/utilities/signing_and_verification/php/.gitignore b/utilities/signing_and_verification/php/.gitignore index e69de29..546d906 100644 --- a/utilities/signing_and_verification/php/.gitignore +++ b/utilities/signing_and_verification/php/.gitignore @@ -0,0 +1,473 @@ +##### Windows +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +##### Linux +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +##### MacOS +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +##### Backup +*.bak +*.gho +*.ori +*.orig +*.tmp + +##### GPG +secring.* + +##### Dropbox +# Dropbox settings and caches +.dropbox +.dropbox.attr +.dropbox.cache + +##### SynopsysVCS +# Waveform formats +*.vcd +*.vpd +*.evcd +*.fsdb + +# Default name of the simulation executable. A different name can be +# specified with this switch (the associated daidir database name is +# also taken from here): -o / +simv + +# Generated for Verilog and VHDL top configs +simv.daidir/ +simv.db.dir/ + +# Infrastructure necessary to co-simulate SystemC models with +# Verilog/VHDL models. An alternate directory may be specified with this +# switch: -Mdir= +csrc/ + +# Log file - the following switch allows to specify the file that will be +# used to write all messages from simulation: -l +*.log + +# Coverage results (generated with urg) and database location. The +# following switch can also be used: urg -dir .vdb +simv.vdb/ +urgReport/ + +# DVE and UCLI related files. +DVEfiles/ +ucli.key + +# When the design is elaborated for DirectC, the following file is created +# with declarations for C/C++ functions. +vc_hdrs.h + +##### SVN +.svn/ + +##### Mercurial +.hg/ +.hgignore +.hgsigs +.hgsub +.hgsubstate +.hgtags + +##### Bazaar +.bzr/ +.bzrignore + +##### CVS +/CVS/* +**/CVS/* +.cvsignore +*/.cvsignore + +##### TortoiseGit +# Project-level settings +/.tgitconfig + +##### PuTTY +# Private key +*.ppk + +##### Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +##### Emacs +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +##### SublimeText +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json +sftp-config-alt*.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +##### Notepad++ +# Notepad++ backups # +*.bak + +##### TextMate +*.tmproj +*.tmproject +tmtags + +##### VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +##### NetBeans +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +##### JetBrains +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +##### Eclipse +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +##### Dreamweaver +# DW Dreamweaver added files +_notes +_compareTemp +configs/ +dwsync.xml +dw_php_codehinting.config +*.mno + +##### CodeKit +# General CodeKit files to ignore +config.codekit +config.codekit3 +/min + +##### Gradle +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Composer +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +composer.lock + +##### PHP CodeSniffer +# gitignore for the PHP Codesniffer framework +# website: https://github.com/squizlabs/PHP_CodeSniffer +# +# Recommended template: PHP.gitignore + +/wpcs/* + +##### SASS +.sass-cache/ +*.css.map +*.sass.map \ No newline at end of file From 4b558f46ad4a966fd70ae2f14696e69863361141 Mon Sep 17 00:00:00 2001 From: Charanpreet Date: Fri, 2 Feb 2024 15:09:48 +0530 Subject: [PATCH 124/228] fix: removed vendor --- .../php/composer.lock | 940 --- .../php/vendor/autoload.php | 25 - .../php/vendor/composer/ClassLoader.php | 579 -- .../php/vendor/composer/InstalledVersions.php | 359 -- .../php/vendor/composer/LICENSE | 21 - .../php/vendor/composer/autoload_classmap.php | 15 - .../php/vendor/composer/autoload_files.php | 13 - .../vendor/composer/autoload_namespaces.php | 9 - .../php/vendor/composer/autoload_psr4.php | 22 - .../php/vendor/composer/autoload_real.php | 50 - .../php/vendor/composer/autoload_static.php | 123 - .../php/vendor/composer/installed.json | 964 --- .../php/vendor/composer/installed.php | 142 - .../php/vendor/composer/platform_check.php | 26 - .../graham-campbell/result-type/LICENSE | 21 - .../graham-campbell/result-type/composer.json | 33 - .../graham-campbell/result-type/src/Error.php | 121 - .../result-type/src/Result.php | 69 - .../result-type/src/Success.php | 120 - .../constant_time_encoding/LICENSE.txt | 48 - .../constant_time_encoding/README.md | 84 - .../constant_time_encoding/composer.json | 56 - .../constant_time_encoding/src/Base32.php | 519 -- .../constant_time_encoding/src/Base32Hex.php | 111 - .../constant_time_encoding/src/Base64.php | 314 - .../src/Base64DotSlash.php | 88 - .../src/Base64DotSlashOrdered.php | 82 - .../src/Base64UrlSafe.php | 95 - .../constant_time_encoding/src/Binary.php | 90 - .../src/EncoderInterface.php | 52 - .../constant_time_encoding/src/Encoding.php | 262 - .../constant_time_encoding/src/Hex.php | 146 - .../constant_time_encoding/src/RFC4648.php | 186 - .../vendor/paragonie/random_compat/LICENSE | 22 - .../paragonie/random_compat/build-phar.sh | 5 - .../paragonie/random_compat/composer.json | 34 - .../dist/random_compat.phar.pubkey | 5 - .../dist/random_compat.phar.pubkey.asc | 11 - .../paragonie/random_compat/lib/random.php | 32 - .../random_compat/other/build_phar.php | 57 - .../random_compat/psalm-autoload.php | 9 - .../vendor/paragonie/random_compat/psalm.xml | 19 - .../php/vendor/phpoption/phpoption/LICENSE | 201 - .../vendor/phpoption/phpoption/composer.json | 52 - .../phpoption/src/PhpOption/LazyOption.php | 175 - .../phpoption/src/PhpOption/None.php | 136 - .../phpoption/src/PhpOption/Option.php | 434 -- .../phpoption/src/PhpOption/Some.php | 169 - .../php/vendor/phpseclib/phpseclib/AUTHORS | 7 - .../php/vendor/phpseclib/phpseclib/BACKERS.md | 16 - .../php/vendor/phpseclib/phpseclib/LICENSE | 20 - .../php/vendor/phpseclib/phpseclib/README.md | 97 - .../vendor/phpseclib/phpseclib/composer.json | 84 - .../phpseclib/Common/Functions/Strings.php | 505 -- .../phpseclib/phpseclib/Crypt/AES.php | 116 - .../phpseclib/phpseclib/Crypt/Blowfish.php | 918 --- .../phpseclib/phpseclib/Crypt/ChaCha20.php | 799 --- .../phpseclib/Crypt/Common/AsymmetricKey.php | 581 -- .../phpseclib/Crypt/Common/BlockCipher.php | 24 - .../Crypt/Common/Formats/Keys/JWK.php | 69 - .../Crypt/Common/Formats/Keys/OpenSSH.php | 220 - .../Crypt/Common/Formats/Keys/PKCS.php | 72 - .../Crypt/Common/Formats/Keys/PKCS1.php | 209 - .../Crypt/Common/Formats/Keys/PKCS8.php | 725 --- .../Crypt/Common/Formats/Keys/PuTTY.php | 374 -- .../Crypt/Common/Formats/Signature/Raw.php | 60 - .../phpseclib/Crypt/Common/PrivateKey.php | 31 - .../phpseclib/Crypt/Common/PublicKey.php | 25 - .../phpseclib/Crypt/Common/StreamCipher.php | 54 - .../phpseclib/Crypt/Common/SymmetricKey.php | 3398 ----------- .../Crypt/Common/Traits/Fingerprint.php | 57 - .../Crypt/Common/Traits/PasswordProtected.php | 46 - .../phpseclib/phpseclib/Crypt/DES.php | 1392 ----- .../phpseclib/phpseclib/Crypt/DH.php | 405 -- .../phpseclib/Crypt/DH/Formats/Keys/PKCS1.php | 77 - .../phpseclib/Crypt/DH/Formats/Keys/PKCS8.php | 132 - .../phpseclib/Crypt/DH/Parameters.php | 36 - .../phpseclib/Crypt/DH/PrivateKey.php | 75 - .../phpseclib/Crypt/DH/PublicKey.php | 49 - .../phpseclib/phpseclib/Crypt/DSA.php | 337 - .../Crypt/DSA/Formats/Keys/OpenSSH.php | 118 - .../Crypt/DSA/Formats/Keys/PKCS1.php | 143 - .../Crypt/DSA/Formats/Keys/PKCS8.php | 146 - .../Crypt/DSA/Formats/Keys/PuTTY.php | 109 - .../phpseclib/Crypt/DSA/Formats/Keys/Raw.php | 85 - .../phpseclib/Crypt/DSA/Formats/Keys/XML.php | 132 - .../Crypt/DSA/Formats/Signature/ASN1.php | 62 - .../Crypt/DSA/Formats/Signature/Raw.php | 25 - .../Crypt/DSA/Formats/Signature/SSH2.php | 74 - .../phpseclib/Crypt/DSA/Parameters.php | 36 - .../phpseclib/Crypt/DSA/PrivateKey.php | 152 - .../phpseclib/Crypt/DSA/PublicKey.php | 86 - .../phpseclib/phpseclib/Crypt/EC.php | 480 -- .../phpseclib/Crypt/EC/BaseCurves/Base.php | 218 - .../phpseclib/Crypt/EC/BaseCurves/Binary.php | 373 -- .../Crypt/EC/BaseCurves/KoblitzPrime.php | 335 - .../Crypt/EC/BaseCurves/Montgomery.php | 279 - .../phpseclib/Crypt/EC/BaseCurves/Prime.php | 785 --- .../Crypt/EC/BaseCurves/TwistedEdwards.php | 215 - .../phpseclib/Crypt/EC/Curves/Curve25519.php | 81 - .../phpseclib/Crypt/EC/Curves/Curve448.php | 92 - .../phpseclib/Crypt/EC/Curves/Ed25519.php | 333 - .../phpseclib/Crypt/EC/Curves/Ed448.php | 273 - .../Crypt/EC/Curves/brainpoolP160r1.php | 34 - .../Crypt/EC/Curves/brainpoolP160t1.php | 47 - .../Crypt/EC/Curves/brainpoolP192r1.php | 34 - .../Crypt/EC/Curves/brainpoolP192t1.php | 34 - .../Crypt/EC/Curves/brainpoolP224r1.php | 34 - .../Crypt/EC/Curves/brainpoolP224t1.php | 34 - .../Crypt/EC/Curves/brainpoolP256r1.php | 34 - .../Crypt/EC/Curves/brainpoolP256t1.php | 34 - .../Crypt/EC/Curves/brainpoolP320r1.php | 40 - .../Crypt/EC/Curves/brainpoolP320t1.php | 40 - .../Crypt/EC/Curves/brainpoolP384r1.php | 58 - .../Crypt/EC/Curves/brainpoolP384t1.php | 58 - .../Crypt/EC/Curves/brainpoolP512r1.php | 58 - .../Crypt/EC/Curves/brainpoolP512t1.php | 58 - .../phpseclib/Crypt/EC/Curves/nistb233.php | 18 - .../phpseclib/Crypt/EC/Curves/nistb409.php | 18 - .../phpseclib/Crypt/EC/Curves/nistk163.php | 18 - .../phpseclib/Crypt/EC/Curves/nistk233.php | 18 - .../phpseclib/Crypt/EC/Curves/nistk283.php | 18 - .../phpseclib/Crypt/EC/Curves/nistk409.php | 18 - .../phpseclib/Crypt/EC/Curves/nistp192.php | 18 - .../phpseclib/Crypt/EC/Curves/nistp224.php | 18 - .../phpseclib/Crypt/EC/Curves/nistp256.php | 18 - .../phpseclib/Crypt/EC/Curves/nistp384.php | 18 - .../phpseclib/Crypt/EC/Curves/nistp521.php | 18 - .../phpseclib/Crypt/EC/Curves/nistt571.php | 18 - .../phpseclib/Crypt/EC/Curves/prime192v1.php | 18 - .../phpseclib/Crypt/EC/Curves/prime192v2.php | 34 - .../phpseclib/Crypt/EC/Curves/prime192v3.php | 34 - .../phpseclib/Crypt/EC/Curves/prime239v1.php | 34 - .../phpseclib/Crypt/EC/Curves/prime239v2.php | 34 - .../phpseclib/Crypt/EC/Curves/prime239v3.php | 34 - .../phpseclib/Crypt/EC/Curves/prime256v1.php | 18 - .../phpseclib/Crypt/EC/Curves/secp112r1.php | 34 - .../phpseclib/Crypt/EC/Curves/secp112r2.php | 35 - .../phpseclib/Crypt/EC/Curves/secp128r1.php | 34 - .../phpseclib/Crypt/EC/Curves/secp128r2.php | 35 - .../phpseclib/Crypt/EC/Curves/secp160k1.php | 46 - .../phpseclib/Crypt/EC/Curves/secp160r1.php | 34 - .../phpseclib/Crypt/EC/Curves/secp160r2.php | 35 - .../phpseclib/Crypt/EC/Curves/secp192k1.php | 45 - .../phpseclib/Crypt/EC/Curves/secp192r1.php | 78 - .../phpseclib/Crypt/EC/Curves/secp224k1.php | 45 - .../phpseclib/Crypt/EC/Curves/secp224r1.php | 34 - .../phpseclib/Crypt/EC/Curves/secp256k1.php | 49 - .../phpseclib/Crypt/EC/Curves/secp256r1.php | 34 - .../phpseclib/Crypt/EC/Curves/secp384r1.php | 52 - .../phpseclib/Crypt/EC/Curves/secp521r1.php | 46 - .../phpseclib/Crypt/EC/Curves/sect113r1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect113r2.php | 34 - .../phpseclib/Crypt/EC/Curves/sect131r1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect131r2.php | 34 - .../phpseclib/Crypt/EC/Curves/sect163k1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect163r1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect163r2.php | 34 - .../phpseclib/Crypt/EC/Curves/sect193r1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect193r2.php | 34 - .../phpseclib/Crypt/EC/Curves/sect233k1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect233r1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect239k1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect283k1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect283r1.php | 34 - .../phpseclib/Crypt/EC/Curves/sect409k1.php | 38 - .../phpseclib/Crypt/EC/Curves/sect409r1.php | 38 - .../phpseclib/Crypt/EC/Curves/sect571k1.php | 42 - .../phpseclib/Crypt/EC/Curves/sect571r1.php | 42 - .../Crypt/EC/Formats/Keys/Common.php | 549 -- .../phpseclib/Crypt/EC/Formats/Keys/JWK.php | 189 - .../EC/Formats/Keys/MontgomeryPrivate.php | 101 - .../EC/Formats/Keys/MontgomeryPublic.php | 71 - .../Crypt/EC/Formats/Keys/OpenSSH.php | 209 - .../phpseclib/Crypt/EC/Formats/Keys/PKCS1.php | 194 - .../phpseclib/Crypt/EC/Formats/Keys/PKCS8.php | 234 - .../phpseclib/Crypt/EC/Formats/Keys/PuTTY.php | 138 - .../phpseclib/Crypt/EC/Formats/Keys/XML.php | 485 -- .../Crypt/EC/Formats/Keys/libsodium.php | 116 - .../Crypt/EC/Formats/Signature/ASN1.php | 62 - .../Crypt/EC/Formats/Signature/IEEE.php | 66 - .../Crypt/EC/Formats/Signature/Raw.php | 25 - .../Crypt/EC/Formats/Signature/SSH2.php | 94 - .../phpseclib/Crypt/EC/Parameters.php | 36 - .../phpseclib/Crypt/EC/PrivateKey.php | 256 - .../phpseclib/Crypt/EC/PublicKey.php | 172 - .../phpseclib/phpseclib/Crypt/Hash.php | 1455 ----- .../phpseclib/Crypt/PublicKeyLoader.php | 111 - .../phpseclib/phpseclib/Crypt/RC2.php | 640 -- .../phpseclib/phpseclib/Crypt/RC4.php | 280 - .../phpseclib/phpseclib/Crypt/RSA.php | 934 --- .../phpseclib/Crypt/RSA/Formats/Keys/JWK.php | 142 - .../Crypt/RSA/Formats/Keys/MSBLOB.php | 228 - .../Crypt/RSA/Formats/Keys/OpenSSH.php | 132 - .../Crypt/RSA/Formats/Keys/PKCS1.php | 160 - .../Crypt/RSA/Formats/Keys/PKCS8.php | 122 - .../phpseclib/Crypt/RSA/Formats/Keys/PSS.php | 238 - .../Crypt/RSA/Formats/Keys/PuTTY.php | 121 - .../phpseclib/Crypt/RSA/Formats/Keys/Raw.php | 184 - .../phpseclib/Crypt/RSA/Formats/Keys/XML.php | 171 - .../phpseclib/Crypt/RSA/PrivateKey.php | 530 -- .../phpseclib/Crypt/RSA/PublicKey.php | 513 -- .../phpseclib/phpseclib/Crypt/Random.php | 222 - .../phpseclib/phpseclib/Crypt/Rijndael.php | 1036 ---- .../phpseclib/phpseclib/Crypt/Salsa20.php | 526 -- .../phpseclib/phpseclib/Crypt/TripleDES.php | 436 -- .../phpseclib/phpseclib/Crypt/Twofish.php | 816 --- .../Exception/BadConfigurationException.php | 23 - .../Exception/BadDecryptionException.php | 23 - .../phpseclib/Exception/BadModeException.php | 23 - .../Exception/ConnectionClosedException.php | 23 - .../Exception/FileNotFoundException.php | 23 - .../Exception/InconsistentSetupException.php | 23 - .../Exception/InsufficientSetupException.php | 23 - .../Exception/NoKeyLoadedException.php | 23 - .../NoSupportedAlgorithmsException.php | 23 - .../Exception/UnableToConnectException.php | 23 - .../UnsupportedAlgorithmException.php | 23 - .../Exception/UnsupportedCurveException.php | 23 - .../Exception/UnsupportedFormatException.php | 23 - .../UnsupportedOperationException.php | 23 - .../phpseclib/phpseclib/File/ANSI.php | 551 -- .../phpseclib/phpseclib/File/ASN1.php | 1508 ----- .../phpseclib/phpseclib/File/ASN1/Element.php | 43 - .../File/ASN1/Maps/AccessDescription.php | 32 - .../ASN1/Maps/AdministrationDomainName.php | 36 - .../File/ASN1/Maps/AlgorithmIdentifier.php | 35 - .../phpseclib/File/ASN1/Maps/AnotherName.php | 37 - .../phpseclib/File/ASN1/Maps/Attribute.php | 37 - .../File/ASN1/Maps/AttributeType.php | 26 - .../File/ASN1/Maps/AttributeTypeAndValue.php | 32 - .../File/ASN1/Maps/AttributeValue.php | 26 - .../phpseclib/File/ASN1/Maps/Attributes.php | 31 - .../ASN1/Maps/AuthorityInfoAccessSyntax.php | 31 - .../File/ASN1/Maps/AuthorityKeyIdentifier.php | 45 - .../phpseclib/File/ASN1/Maps/BaseDistance.php | 26 - .../File/ASN1/Maps/BasicConstraints.php | 39 - .../Maps/BuiltInDomainDefinedAttribute.php | 32 - .../Maps/BuiltInDomainDefinedAttributes.php | 31 - .../ASN1/Maps/BuiltInStandardAttributes.php | 67 - .../phpseclib/File/ASN1/Maps/CPSuri.php | 26 - .../File/ASN1/Maps/CRLDistributionPoints.php | 31 - .../phpseclib/File/ASN1/Maps/CRLNumber.php | 26 - .../phpseclib/File/ASN1/Maps/CRLReason.php | 41 - .../phpseclib/File/ASN1/Maps/CertPolicyId.php | 26 - .../phpseclib/File/ASN1/Maps/Certificate.php | 33 - .../File/ASN1/Maps/CertificateIssuer.php | 24 - .../File/ASN1/Maps/CertificateList.php | 33 - .../File/ASN1/Maps/CertificatePolicies.php | 31 - .../ASN1/Maps/CertificateSerialNumber.php | 26 - .../File/ASN1/Maps/CertificationRequest.php | 33 - .../ASN1/Maps/CertificationRequestInfo.php | 41 - .../File/ASN1/Maps/Characteristic_two.php | 36 - .../phpseclib/File/ASN1/Maps/CountryName.php | 36 - .../phpseclib/File/ASN1/Maps/Curve.php | 36 - .../phpseclib/File/ASN1/Maps/DHParameter.php | 38 - .../phpseclib/File/ASN1/Maps/DSAParams.php | 33 - .../File/ASN1/Maps/DSAPrivateKey.php | 36 - .../phpseclib/File/ASN1/Maps/DSAPublicKey.php | 26 - .../phpseclib/File/ASN1/Maps/DigestInfo.php | 34 - .../File/ASN1/Maps/DirectoryString.php | 35 - .../phpseclib/File/ASN1/Maps/DisplayText.php | 34 - .../File/ASN1/Maps/DistributionPoint.php | 45 - .../File/ASN1/Maps/DistributionPointName.php | 40 - .../phpseclib/File/ASN1/Maps/DssSigValue.php | 32 - .../phpseclib/File/ASN1/Maps/ECParameters.php | 45 - .../phpseclib/File/ASN1/Maps/ECPoint.php | 26 - .../phpseclib/File/ASN1/Maps/ECPrivateKey.php | 48 - .../phpseclib/File/ASN1/Maps/EDIPartyName.php | 42 - .../File/ASN1/Maps/EcdsaSigValue.php | 32 - .../File/ASN1/Maps/EncryptedData.php | 26 - .../ASN1/Maps/EncryptedPrivateKeyInfo.php | 32 - .../File/ASN1/Maps/ExtKeyUsageSyntax.php | 31 - .../phpseclib/File/ASN1/Maps/Extension.php | 43 - .../File/ASN1/Maps/ExtensionAttribute.php | 42 - .../File/ASN1/Maps/ExtensionAttributes.php | 31 - .../phpseclib/File/ASN1/Maps/Extensions.php | 33 - .../phpseclib/File/ASN1/Maps/FieldElement.php | 26 - .../phpseclib/File/ASN1/Maps/FieldID.php | 35 - .../phpseclib/File/ASN1/Maps/GeneralName.php | 80 - .../phpseclib/File/ASN1/Maps/GeneralNames.php | 31 - .../File/ASN1/Maps/GeneralSubtree.php | 42 - .../File/ASN1/Maps/GeneralSubtrees.php | 31 - .../File/ASN1/Maps/HashAlgorithm.php | 24 - .../File/ASN1/Maps/HoldInstructionCode.php | 26 - .../File/ASN1/Maps/InvalidityDate.php | 26 - .../File/ASN1/Maps/IssuerAltName.php | 24 - .../ASN1/Maps/IssuingDistributionPoint.php | 68 - .../File/ASN1/Maps/KeyIdentifier.php | 26 - .../phpseclib/File/ASN1/Maps/KeyPurposeId.php | 26 - .../phpseclib/File/ASN1/Maps/KeyUsage.php | 39 - .../File/ASN1/Maps/MaskGenAlgorithm.php | 24 - .../phpseclib/File/ASN1/Maps/Name.php | 31 - .../File/ASN1/Maps/NameConstraints.php | 40 - .../File/ASN1/Maps/NetworkAddress.php | 26 - .../File/ASN1/Maps/NoticeReference.php | 37 - .../File/ASN1/Maps/NumericUserIdentifier.php | 26 - .../phpseclib/File/ASN1/Maps/ORAddress.php | 33 - .../File/ASN1/Maps/OneAsymmetricKey.php | 48 - .../File/ASN1/Maps/OrganizationName.php | 26 - .../ASN1/Maps/OrganizationalUnitNames.php | 31 - .../File/ASN1/Maps/OtherPrimeInfo.php | 34 - .../File/ASN1/Maps/OtherPrimeInfos.php | 32 - .../phpseclib/File/ASN1/Maps/PBEParameter.php | 34 - .../phpseclib/File/ASN1/Maps/PBES2params.php | 34 - .../phpseclib/File/ASN1/Maps/PBKDF2params.php | 41 - .../phpseclib/File/ASN1/Maps/PBMAC1params.php | 34 - .../phpseclib/File/ASN1/Maps/PKCS9String.php | 32 - .../phpseclib/File/ASN1/Maps/Pentanomial.php | 33 - .../phpseclib/File/ASN1/Maps/PersonalName.php | 54 - .../File/ASN1/Maps/PolicyInformation.php | 38 - .../File/ASN1/Maps/PolicyMappings.php | 37 - .../File/ASN1/Maps/PolicyQualifierId.php | 26 - .../File/ASN1/Maps/PolicyQualifierInfo.php | 32 - .../File/ASN1/Maps/PostalAddress.php | 32 - .../phpseclib/File/ASN1/Maps/Prime_p.php | 26 - .../File/ASN1/Maps/PrivateDomainName.php | 32 - .../phpseclib/File/ASN1/Maps/PrivateKey.php | 26 - .../File/ASN1/Maps/PrivateKeyInfo.php | 41 - .../File/ASN1/Maps/PrivateKeyUsagePeriod.php | 40 - .../phpseclib/File/ASN1/Maps/PublicKey.php | 26 - .../File/ASN1/Maps/PublicKeyAndChallenge.php | 32 - .../File/ASN1/Maps/PublicKeyInfo.php | 35 - .../File/ASN1/Maps/RC2CBCParameter.php | 37 - .../phpseclib/File/ASN1/Maps/RDNSequence.php | 38 - .../File/ASN1/Maps/RSAPrivateKey.php | 44 - .../phpseclib/File/ASN1/Maps/RSAPublicKey.php | 32 - .../File/ASN1/Maps/RSASSA_PSS_params.php | 58 - .../phpseclib/File/ASN1/Maps/ReasonFlags.php | 39 - .../ASN1/Maps/RelativeDistinguishedName.php | 37 - .../File/ASN1/Maps/RevokedCertificate.php | 35 - .../ASN1/Maps/SignedPublicKeyAndChallenge.php | 33 - .../File/ASN1/Maps/SpecifiedECDomain.php | 45 - .../File/ASN1/Maps/SubjectAltName.php | 24 - .../ASN1/Maps/SubjectDirectoryAttributes.php | 31 - .../ASN1/Maps/SubjectInfoAccessSyntax.php | 31 - .../File/ASN1/Maps/SubjectPublicKeyInfo.php | 32 - .../phpseclib/File/ASN1/Maps/TBSCertList.php | 54 - .../File/ASN1/Maps/TBSCertificate.php | 65 - .../File/ASN1/Maps/TerminalIdentifier.php | 26 - .../phpseclib/File/ASN1/Maps/Time.php | 32 - .../phpseclib/File/ASN1/Maps/Trinomial.php | 26 - .../File/ASN1/Maps/UniqueIdentifier.php | 26 - .../phpseclib/File/ASN1/Maps/UserNotice.php | 38 - .../phpseclib/File/ASN1/Maps/Validity.php | 32 - .../File/ASN1/Maps/netscape_ca_policy_url.php | 26 - .../File/ASN1/Maps/netscape_cert_type.php | 40 - .../File/ASN1/Maps/netscape_comment.php | 26 - .../phpseclib/phpseclib/File/X509.php | 4006 ------------ .../phpseclib/phpseclib/Math/BigInteger.php | 892 --- .../Math/BigInteger/Engines/BCMath.php | 697 --- .../Math/BigInteger/Engines/BCMath/Base.php | 110 - .../BigInteger/Engines/BCMath/BuiltIn.php | 40 - .../Engines/BCMath/DefaultEngine.php | 25 - .../BigInteger/Engines/BCMath/OpenSSL.php | 25 - .../Engines/BCMath/Reductions/Barrett.php | 187 - .../Engines/BCMath/Reductions/EvalBarrett.php | 108 - .../Math/BigInteger/Engines/Engine.php | 1285 ---- .../phpseclib/Math/BigInteger/Engines/GMP.php | 694 --- .../BigInteger/Engines/GMP/DefaultEngine.php | 40 - .../Math/BigInteger/Engines/OpenSSL.php | 68 - .../phpseclib/Math/BigInteger/Engines/PHP.php | 1344 ---- .../Math/BigInteger/Engines/PHP/Base.php | 143 - .../BigInteger/Engines/PHP/DefaultEngine.php | 25 - .../BigInteger/Engines/PHP/Montgomery.php | 89 - .../Math/BigInteger/Engines/PHP/OpenSSL.php | 25 - .../Engines/PHP/Reductions/Barrett.php | 281 - .../Engines/PHP/Reductions/Classic.php | 42 - .../Engines/PHP/Reductions/EvalBarrett.php | 484 -- .../Engines/PHP/Reductions/Montgomery.php | 126 - .../Engines/PHP/Reductions/MontgomeryMult.php | 76 - .../Engines/PHP/Reductions/PowerOfTwo.php | 59 - .../Math/BigInteger/Engines/PHP32.php | 371 -- .../Math/BigInteger/Engines/PHP64.php | 372 -- .../phpseclib/phpseclib/Math/BinaryField.php | 203 - .../phpseclib/Math/BinaryField/Integer.php | 516 -- .../phpseclib/Math/Common/FiniteField.php | 22 - .../Math/Common/FiniteField/Integer.php | 44 - .../phpseclib/phpseclib/Math/PrimeField.php | 118 - .../phpseclib/Math/PrimeField/Integer.php | 419 -- .../phpseclib/phpseclib/Net/SFTP.php | 3547 ----------- .../phpseclib/phpseclib/Net/SFTP/Stream.php | 756 --- .../phpseclib/phpseclib/Net/SSH2.php | 5397 ----------------- .../phpseclib/phpseclib/System/SSH/Agent.php | 286 - .../phpseclib/System/SSH/Agent/Identity.php | 320 - .../System/SSH/Common/Traits/ReadBytes.php | 37 - .../phpseclib/phpseclib/bootstrap.php | 22 - .../phpseclib/phpseclib/phpseclib/openssl.cnf | 6 - .../php/vendor/sop/asn1/LICENSE | 21 - .../php/vendor/sop/asn1/README.md | 103 - .../php/vendor/sop/asn1/composer.json | 34 - .../asn1/lib/ASN1/Component/Identifier.php | 290 - .../sop/asn1/lib/ASN1/Component/Length.php | 225 - .../php/vendor/sop/asn1/lib/ASN1/DERData.php | 89 - .../php/vendor/sop/asn1/lib/ASN1/Element.php | 465 -- .../lib/ASN1/Exception/DecodeException.php | 12 - .../sop/asn1/lib/ASN1/Feature/ElementBase.php | 84 - .../sop/asn1/lib/ASN1/Feature/Encodable.php | 16 - .../sop/asn1/lib/ASN1/Feature/Stringable.php | 21 - .../sop/asn1/lib/ASN1/Type/BaseString.php | 59 - .../sop/asn1/lib/ASN1/Type/BaseTime.php | 107 - .../Type/Constructed/ConstructedString.php | 131 - .../lib/ASN1/Type/Constructed/Sequence.php | 25 - .../asn1/lib/ASN1/Type/Constructed/Set.php | 63 - .../lib/ASN1/Type/Primitive/BMPString.php | 40 - .../lib/ASN1/Type/Primitive/BitString.php | 201 - .../asn1/lib/ASN1/Type/Primitive/Boolean.php | 73 - .../ASN1/Type/Primitive/CharacterString.php | 25 - .../sop/asn1/lib/ASN1/Type/Primitive/EOC.php | 54 - .../lib/ASN1/Type/Primitive/Enumerated.php | 22 - .../lib/ASN1/Type/Primitive/GeneralString.php | 34 - .../ASN1/Type/Primitive/GeneralizedTime.php | 125 - .../lib/ASN1/Type/Primitive/GraphicString.php | 34 - .../lib/ASN1/Type/Primitive/IA5String.php | 33 - .../asn1/lib/ASN1/Type/Primitive/Integer.php | 105 - .../asn1/lib/ASN1/Type/Primitive/NullType.php | 54 - .../lib/ASN1/Type/Primitive/NumericString.php | 33 - .../ASN1/Type/Primitive/ObjectDescriptor.php | 33 - .../ASN1/Type/Primitive/ObjectIdentifier.php | 207 - .../lib/ASN1/Type/Primitive/OctetString.php | 25 - .../ASN1/Type/Primitive/PrintableString.php | 34 - .../sop/asn1/lib/ASN1/Type/Primitive/Real.php | 698 --- .../lib/ASN1/Type/Primitive/RelativeOID.php | 48 - .../lib/ASN1/Type/Primitive/T61String.php | 35 - .../asn1/lib/ASN1/Type/Primitive/UTCTime.php | 83 - .../lib/ASN1/Type/Primitive/UTF8String.php | 35 - .../ASN1/Type/Primitive/UniversalString.php | 39 - .../ASN1/Type/Primitive/VideotexString.php | 34 - .../lib/ASN1/Type/Primitive/VisibleString.php | 33 - .../asn1/lib/ASN1/Type/PrimitiveString.php | 53 - .../sop/asn1/lib/ASN1/Type/PrimitiveType.php | 19 - .../sop/asn1/lib/ASN1/Type/StringType.php | 16 - .../sop/asn1/lib/ASN1/Type/Structure.php | 384 -- .../lib/ASN1/Type/Tagged/ApplicationType.php | 12 - .../ASN1/Type/Tagged/ContextSpecificType.php | 12 - .../lib/ASN1/Type/Tagged/DERTaggedType.php | 156 - .../lib/ASN1/Type/Tagged/ExplicitTagging.php | 19 - .../ASN1/Type/Tagged/ExplicitlyTaggedType.php | 58 - .../lib/ASN1/Type/Tagged/ImplicitTagging.php | 25 - .../ASN1/Type/Tagged/ImplicitlyTaggedType.php | 68 - .../asn1/lib/ASN1/Type/Tagged/PrivateType.php | 12 - .../lib/ASN1/Type/Tagged/TaggedTypeWrap.php | 35 - .../sop/asn1/lib/ASN1/Type/TaggedType.php | 84 - .../sop/asn1/lib/ASN1/Type/TimeType.php | 16 - .../sop/asn1/lib/ASN1/Type/UniversalClass.php | 21 - .../asn1/lib/ASN1/Type/UnspecifiedType.php | 674 -- .../vendor/sop/asn1/lib/ASN1/Util/BigInt.php | 218 - .../vendor/sop/asn1/lib/ASN1/Util/Flags.php | 144 - .../php/vendor/sop/crypto-encoding/LICENSE | 21 - .../php/vendor/sop/crypto-encoding/README.md | 24 - .../vendor/sop/crypto-encoding/composer.json | 31 - .../lib/CryptoEncoding/PEM.php | 145 - .../lib/CryptoEncoding/PEMBundle.php | 173 - .../php/vendor/sop/crypto-types/LICENSE | 21 - .../php/vendor/sop/crypto-types/README.md | 42 - .../php/vendor/sop/crypto-types/composer.json | 39 - .../AlgorithmIdentifier.php | 116 - .../AlgorithmIdentifierFactory.php | 119 - .../AlgorithmIdentifierProvider.php | 35 - .../ECPublicKeyAlgorithmIdentifier.php | 303 - .../Asymmetric/Ed25519AlgorithmIdentifier.php | 44 - .../Asymmetric/Ed448AlgorithmIdentifier.php | 44 - .../RFC8410EdAlgorithmIdentifier.php | 59 - .../RFC8410XAlgorithmIdentifier.php | 53 - .../RSAEncryptionAlgorithmIdentifier.php | 68 - .../Asymmetric/X25519AlgorithmIdentifier.php | 29 - .../Asymmetric/X448AlgorithmIdentifier.php | 29 - .../Cipher/AES128CBCAlgorithmIdentifier.php | 42 - .../Cipher/AES192CBCAlgorithmIdentifier.php | 42 - .../Cipher/AES256CBCAlgorithmIdentifier.php | 42 - .../Cipher/AESCBCAlgorithmIdentifier.php | 82 - .../Cipher/BlockCipherAlgorithmIdentifier.php | 16 - .../Cipher/CipherAlgorithmIdentifier.php | 65 - .../Cipher/DESCBCAlgorithmIdentifier.php | 98 - .../Cipher/DESEDE3CBCAlgorithmIdentifier.php | 99 - .../Cipher/RC2CBCAlgorithmIdentifier.php | 215 - .../Feature/AlgorithmIdentifierType.php | 30 - .../AsymmetricCryptoAlgorithmIdentifier.php | 12 - .../Feature/EncryptionAlgorithmIdentifier.php | 12 - .../Feature/HashAlgorithmIdentifier.php | 12 - .../Feature/PRFAlgorithmIdentifier.php | 12 - .../Feature/SignatureAlgorithmIdentifier.php | 18 - .../GenericAlgorithmIdentifier.php | 57 - .../Hash/HMACWithSHA1AlgorithmIdentifier.php | 66 - .../HMACWithSHA224AlgorithmIdentifier.php | 29 - .../HMACWithSHA256AlgorithmIdentifier.php | 29 - .../HMACWithSHA384AlgorithmIdentifier.php | 29 - .../HMACWithSHA512AlgorithmIdentifier.php | 29 - .../Hash/MD5AlgorithmIdentifier.php | 85 - .../Hash/RFC4231HMACAlgorithmIdentifier.php | 56 - .../Hash/SHA1AlgorithmIdentifier.php | 81 - .../Hash/SHA224AlgorithmIdentifier.php | 33 - .../Hash/SHA256AlgorithmIdentifier.php | 32 - .../Hash/SHA2AlgorithmIdentifier.php | 71 - .../Hash/SHA384AlgorithmIdentifier.php | 32 - .../Hash/SHA512AlgorithmIdentifier.php | 32 - .../ECDSAWithSHA1AlgorithmIdentifier.php | 29 - .../ECDSAWithSHA224AlgorithmIdentifier.php | 29 - .../ECDSAWithSHA256AlgorithmIdentifier.php | 29 - .../ECDSAWithSHA384AlgorithmIdentifier.php | 29 - .../ECDSAWithSHA512AlgorithmIdentifier.php | 29 - .../ECSignatureAlgorithmIdentifier.php | 59 - ...D2WithRSAEncryptionAlgorithmIdentifier.php | 29 - ...D4WithRSAEncryptionAlgorithmIdentifier.php | 29 - ...D5WithRSAEncryptionAlgorithmIdentifier.php | 29 - ...RFC3279RSASignatureAlgorithmIdentifier.php | 51 - ...RFC4055RSASignatureAlgorithmIdentifier.php | 65 - .../RSASignatureAlgorithmIdentifier.php | 23 - ...A1WithRSAEncryptionAlgorithmIdentifier.php | 29 - ...24WithRSAEncryptionAlgorithmIdentifier.php | 30 - ...56WithRSAEncryptionAlgorithmIdentifier.php | 30 - ...84WithRSAEncryptionAlgorithmIdentifier.php | 30 - ...12WithRSAEncryptionAlgorithmIdentifier.php | 30 - .../SignatureAlgorithmIdentifierFactory.php | 105 - .../SpecificAlgorithmIdentifier.php | 30 - .../Attribute/OneAsymmetricKeyAttributes.php | 15 - .../Asymmetric/EC/ECConversion.php | 112 - .../Asymmetric/EC/ECPrivateKey.php | 223 - .../CryptoTypes/Asymmetric/EC/ECPublicKey.php | 222 - .../Asymmetric/OneAsymmetricKey.php | 359 -- .../lib/CryptoTypes/Asymmetric/PrivateKey.php | 74 - .../CryptoTypes/Asymmetric/PrivateKeyInfo.php | 33 - .../lib/CryptoTypes/Asymmetric/PublicKey.php | 60 - .../CryptoTypes/Asymmetric/PublicKeyInfo.php | 197 - .../Curve25519/Curve25519PrivateKey.php | 34 - .../Curve25519/Curve25519PublicKey.php | 29 - .../RFC8410/Curve25519/Ed25519PrivateKey.php | 36 - .../RFC8410/Curve25519/Ed25519PublicKey.php | 24 - .../RFC8410/Curve25519/X25519PrivateKey.php | 36 - .../RFC8410/Curve25519/X25519PublicKey.php | 24 - .../RFC8410/Curve448/Ed448PrivateKey.php | 56 - .../RFC8410/Curve448/Ed448PublicKey.php | 39 - .../RFC8410/Curve448/X448PrivateKey.php | 56 - .../RFC8410/Curve448/X448PublicKey.php | 39 - .../Asymmetric/RFC8410/RFC8410PrivateKey.php | 142 - .../Asymmetric/RFC8410/RFC8410PublicKey.php | 52 - .../Asymmetric/RSA/RSAPrivateKey.php | 286 - .../Asymmetric/RSA/RSAPublicKey.php | 147 - .../lib/CryptoTypes/Signature/ECSignature.php | 108 - .../Signature/Ed25519Signature.php | 44 - .../CryptoTypes/Signature/Ed448Signature.php | 44 - .../Signature/GenericSignature.php | 56 - .../CryptoTypes/Signature/RSASignature.php | 58 - .../lib/CryptoTypes/Signature/Signature.php | 49 - .../php/vendor/sop/x501/LICENSE | 21 - .../php/vendor/sop/x501/README.md | 26 - .../php/vendor/sop/x501/composer.json | 38 - .../sop/x501/lib/X501/ASN1/Attribute.php | 176 - .../sop/x501/lib/X501/ASN1/AttributeType.php | 457 -- .../lib/X501/ASN1/AttributeTypeAndValue.php | 128 - .../ASN1/AttributeValue/AttributeValue.php | 174 - .../ASN1/AttributeValue/CommonNameValue.php | 29 - .../ASN1/AttributeValue/CountryNameValue.php | 27 - .../ASN1/AttributeValue/DescriptionValue.php | 29 - .../Feature/DirectoryString.php | 179 - .../Feature/PrintableStringValue.php | 88 - .../ASN1/AttributeValue/GivenNameValue.php | 29 - .../ASN1/AttributeValue/LocalityNameValue.php | 29 - .../X501/ASN1/AttributeValue/NameValue.php | 29 - .../AttributeValue/OrganizationNameValue.php | 29 - .../OrganizationalUnitNameValue.php | 29 - .../ASN1/AttributeValue/PseudonymValue.php | 29 - .../ASN1/AttributeValue/SerialNumberValue.php | 27 - .../StateOrProvinceNameValue.php | 29 - .../X501/ASN1/AttributeValue/SurnameValue.php | 29 - .../X501/ASN1/AttributeValue/TitleValue.php | 29 - .../AttributeValue/UnknownAttributeValue.php | 75 - .../ASN1/Collection/AttributeCollection.php | 221 - .../ASN1/Collection/SequenceOfAttributes.php | 44 - .../X501/ASN1/Collection/SetOfAttributes.php | 45 - .../lib/X501/ASN1/Feature/TypedAttribute.php | 40 - .../vendor/sop/x501/lib/X501/ASN1/Name.php | 227 - .../php/vendor/sop/x501/lib/X501/ASN1/RDN.php | 187 - .../vendor/sop/x501/lib/X501/DN/DNParser.php | 428 -- .../lib/X501/MatchingRule/BinaryMatch.php | 21 - .../lib/X501/MatchingRule/CaseExactMatch.php | 25 - .../lib/X501/MatchingRule/CaseIgnoreMatch.php | 26 - .../lib/X501/MatchingRule/MatchingRule.php | 24 - .../MatchingRule/StringPrepMatchingRule.php | 40 - .../lib/X501/StringPrep/CheckBidiStep.php | 25 - .../InsignificantNonSubstringSpaceStep.php | 35 - .../sop/x501/lib/X501/StringPrep/MapStep.php | 45 - .../lib/X501/StringPrep/NormalizeStep.php | 24 - .../x501/lib/X501/StringPrep/PrepareStep.php | 23 - .../x501/lib/X501/StringPrep/ProhibitStep.php | 27 - .../lib/X501/StringPrep/StringPreparer.php | 87 - .../lib/X501/StringPrep/TranscodeStep.php | 66 - .../vendor/symfony/polyfill-ctype/Ctype.php | 232 - .../php/vendor/symfony/polyfill-ctype/LICENSE | 19 - .../vendor/symfony/polyfill-ctype/README.md | 12 - .../symfony/polyfill-ctype/bootstrap.php | 50 - .../symfony/polyfill-ctype/bootstrap80.php | 46 - .../symfony/polyfill-ctype/composer.json | 41 - .../vendor/symfony/polyfill-mbstring/LICENSE | 19 - .../symfony/polyfill-mbstring/Mbstring.php | 947 --- .../symfony/polyfill-mbstring/README.md | 13 - .../Resources/unidata/caseFolding.php | 119 - .../Resources/unidata/lowerCase.php | 1397 ----- .../Resources/unidata/titleCaseRegexp.php | 5 - .../Resources/unidata/upperCase.php | 1489 ----- .../symfony/polyfill-mbstring/bootstrap.php | 151 - .../symfony/polyfill-mbstring/bootstrap80.php | 147 - .../symfony/polyfill-mbstring/composer.json | 41 - .../php/vendor/symfony/polyfill-php80/LICENSE | 19 - .../vendor/symfony/polyfill-php80/Php80.php | 115 - .../symfony/polyfill-php80/PhpToken.php | 103 - .../vendor/symfony/polyfill-php80/README.md | 25 - .../Resources/stubs/Attribute.php | 31 - .../Resources/stubs/PhpToken.php | 16 - .../Resources/stubs/Stringable.php | 20 - .../Resources/stubs/UnhandledMatchError.php | 16 - .../Resources/stubs/ValueError.php | 16 - .../symfony/polyfill-php80/bootstrap.php | 42 - .../symfony/polyfill-php80/composer.json | 40 - .../php/vendor/vlucas/phpdotenv/LICENSE | 30 - .../php/vendor/vlucas/phpdotenv/composer.json | 60 - .../vendor/vlucas/phpdotenv/src/Dotenv.php | 267 - .../src/Exception/ExceptionInterface.php | 12 - .../Exception/InvalidEncodingException.php | 12 - .../src/Exception/InvalidFileException.php | 12 - .../src/Exception/InvalidPathException.php | 12 - .../src/Exception/ValidationException.php | 12 - .../vlucas/phpdotenv/src/Loader/Loader.php | 47 - .../phpdotenv/src/Loader/LoaderInterface.php | 20 - .../vlucas/phpdotenv/src/Loader/Resolver.php | 65 - .../vlucas/phpdotenv/src/Parser/Entry.php | 59 - .../phpdotenv/src/Parser/EntryParser.php | 300 - .../vlucas/phpdotenv/src/Parser/Lexer.php | 58 - .../vlucas/phpdotenv/src/Parser/Lines.php | 127 - .../vlucas/phpdotenv/src/Parser/Parser.php | 53 - .../phpdotenv/src/Parser/ParserInterface.php | 19 - .../vlucas/phpdotenv/src/Parser/Value.php | 88 - .../Repository/Adapter/AdapterInterface.php | 15 - .../src/Repository/Adapter/ApacheAdapter.php | 89 - .../src/Repository/Adapter/ArrayAdapter.php | 80 - .../Repository/Adapter/EnvConstAdapter.php | 89 - .../src/Repository/Adapter/GuardedWriter.php | 85 - .../Repository/Adapter/ImmutableWriter.php | 110 - .../src/Repository/Adapter/MultiReader.php | 48 - .../src/Repository/Adapter/MultiWriter.php | 64 - .../src/Repository/Adapter/PutenvAdapter.php | 91 - .../Repository/Adapter/ReaderInterface.php | 17 - .../Repository/Adapter/ReplacingWriter.php | 104 - .../Repository/Adapter/ServerConstAdapter.php | 89 - .../Repository/Adapter/WriterInterface.php | 27 - .../src/Repository/AdapterRepository.php | 107 - .../src/Repository/RepositoryBuilder.php | 272 - .../src/Repository/RepositoryInterface.php | 51 - .../vlucas/phpdotenv/src/Store/File/Paths.php | 44 - .../phpdotenv/src/Store/File/Reader.php | 81 - .../vlucas/phpdotenv/src/Store/FileStore.php | 72 - .../phpdotenv/src/Store/StoreBuilder.php | 141 - .../phpdotenv/src/Store/StoreInterface.php | 17 - .../phpdotenv/src/Store/StringStore.php | 37 - .../vlucas/phpdotenv/src/Util/Regex.php | 112 - .../vendor/vlucas/phpdotenv/src/Util/Str.php | 98 - .../vendor/vlucas/phpdotenv/src/Validator.php | 209 - 657 files changed, 91211 deletions(-) delete mode 100644 utilities/signing_and_verification/php/composer.lock delete mode 100644 utilities/signing_and_verification/php/vendor/autoload.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/ClassLoader.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_files.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_psr4.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_real.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/autoload_static.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/installed.json delete mode 100644 utilities/signing_and_verification/php/vendor/composer/installed.php delete mode 100644 utilities/signing_and_verification/php/vendor/composer/platform_check.php delete mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php delete mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php delete mode 100644 utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/EncoderInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Encoding.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Hex.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE delete mode 100755 utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/other/build_phar.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php delete mode 100644 utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm.xml delete mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php delete mode 100644 utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/openssl.cnf delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Feature/ElementBase.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Feature/Encodable.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Feature/Stringable.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/StringType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Structure.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ContextSpecificType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/DERTaggedType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitlyTaggedType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitlyTaggedType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/TaggedTypeWrap.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/UniversalClass.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/UnspecifiedType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/ECPublicKeyAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410XAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/CipherAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AsymmetricCryptoAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/EncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/HashAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/PRFAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/SignatureAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/GenericAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/Attribute/OneAsymmetricKeyAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECConversion.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/CaseExactMatch.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/CaseIgnoreMatch.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/StringPrepMatchingRule.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/InsignificantNonSubstringSpaceStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/MapStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/PrepareStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/ProhibitStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/StringPreparer.php delete mode 100644 utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/upperCase.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php delete mode 100644 utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/InvalidEncodingException.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/InvalidPathException.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ValidationException.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Loader.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Value.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/AdapterRepository.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/File/Paths.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/File/Reader.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StringStore.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php delete mode 100644 utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php diff --git a/utilities/signing_and_verification/php/composer.lock b/utilities/signing_and_verification/php/composer.lock deleted file mode 100644 index 1b0e924..0000000 --- a/utilities/signing_and_verification/php/composer.lock +++ /dev/null @@ -1,940 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "eec5a6c56eb5dcc64208c9c65fac635b", - "packages": [ - { - "name": "graham-campbell/result-type", - "version": "v1.1.2", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", - "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "time": "2023-11-12T22:16:48+00:00" - }, - { - "name": "paragonie/constant_time_encoding", - "version": "v2.6.3", - "source": { - "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "58c3f47f650c94ec05a151692652a868995d2938" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", - "reference": "58c3f47f650c94ec05a151692652a868995d2938", - "shasum": "" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "type": "library", - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "time": "2022-06-14T06:56:20+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "time": "2020-10-15T08:29:30+00:00" - }, - { - "name": "phpoption/phpoption", - "version": "1.9.2", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", - "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "time": "2023-11-12T21:59:55+00:00" - }, - { - "name": "phpseclib/phpseclib", - "version": "3.0.35", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe", - "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe", - "shasum": "" - }, - "require": { - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "suggest": { - "ext-dom": "Install the DOM extension to load XML formatted public keys.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "type": "library", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib3\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "support": { - "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.35" - }, - "funding": [ - { - "url": "https://github.com/terrafrost", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpseclib", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", - "type": "tidelift" - } - ], - "time": "2023-12-29T01:59:53+00:00" - }, - { - "name": "sop/asn1", - "version": "4.1.1", - "source": { - "type": "git", - "url": "https://github.com/sop/asn1.git", - "reference": "074efe8f7c353c54edc809ac3d74efda83edd776" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/asn1/zipball/074efe8f7c353c54edc809ac3d74efda83edd776", - "reference": "074efe8f7c353c54edc809ac3d74efda83edd776", - "shasum": "" - }, - "require": { - "ext-gmp": "*", - "ext-mbstring": "*", - "php": ">=7.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Sop\\ASN1\\": "lib/ASN1/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP library for X.690 ASN.1 DER encoding and decoding.", - "homepage": "https://github.com/sop/asn1", - "keywords": [ - "DER", - "asn.1", - "asn1", - "x.690", - "x690" - ], - "support": { - "issues": "https://github.com/sop/asn1/issues", - "source": "https://github.com/sop/asn1/tree/4.1.1" - }, - "time": "2022-02-17T07:08:51+00:00" - }, - { - "name": "sop/crypto-encoding", - "version": "0.3.0", - "source": { - "type": "git", - "url": "https://github.com/sop/crypto-encoding.git", - "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/crypto-encoding/zipball/07537353e1b0e76c382a58a9c6e041b7c7dc9052", - "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP implementation of textual encodings of cryptographic structures.", - "homepage": "https://github.com/sop/crypto-encoding", - "keywords": [ - "Private Key", - "certificate", - "pem", - "public key" - ], - "support": { - "issues": "https://github.com/sop/crypto-encoding/issues", - "source": "https://github.com/sop/crypto-encoding/tree/master" - }, - "time": "2019-05-22T11:46:12+00:00" - }, - { - "name": "sop/crypto-types", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sop/crypto-types.git", - "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/crypto-types/zipball/92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", - "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", - "shasum": "" - }, - "require": { - "ext-gmp": "*", - "php": ">=7.2", - "sop/asn1": "^4.0.0", - "sop/crypto-encoding": "^0.3.0", - "sop/x501": "0.6.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "default-branch": true, - "type": "library", - "autoload": { - "psr-4": { - "Sop\\CryptoTypes\\": "lib/CryptoTypes/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP library of various ASN.1 types for cryptographic applications.", - "homepage": "https://github.com/sop/crypto-types", - "keywords": [ - "Private Key", - "algorithm identifier", - "asn1", - "cryptography", - "ec", - "public key", - "rsa", - "signature" - ], - "support": { - "issues": "https://github.com/sop/crypto-types/issues", - "source": "https://github.com/sop/crypto-types/tree/master" - }, - "time": "2021-08-11T06:56:21+00:00" - }, - { - "name": "sop/x501", - "version": "0.6.1", - "source": { - "type": "git", - "url": "https://github.com/sop/x501.git", - "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/x501/zipball/7978bfac25ff73c4c20bed0794d4d88cca8f6895", - "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895", - "shasum": "" - }, - "require": { - "ext-intl": "*", - "ext-mbstring": "*", - "php": ">=7.2", - "sop/asn1": "^4.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "Sop\\X501\\": "lib/X501/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP library for X.501 ASN.1 types, X.520 attributes and DN parsing.", - "homepage": "https://github.com/sop/x501", - "keywords": [ - "attribute", - "dn", - "ldap", - "rdn", - "x.501", - "x.520", - "x501", - "x520" - ], - "support": { - "issues": "https://github.com/sop/x501/issues", - "source": "https://github.com/sop/x501/tree/0.6.1" - }, - "time": "2019-06-27T10:30:28+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-07-28T09:04:16+00:00" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2023-01-26T09:26:14+00:00" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.0", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", - "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.2", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-filter": "*", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - }, - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": [ - "dotenv", - "env", - "environment" - ], - "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "time": "2023-11-12T22:43:29+00:00" - } - ], - "packages-dev": [], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": { - "sop/crypto-types": 20 - }, - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.6.0" -} diff --git a/utilities/signing_and_verification/php/vendor/autoload.php b/utilities/signing_and_verification/php/vendor/autoload.php deleted file mode 100644 index e8ac887..0000000 --- a/utilities/signing_and_verification/php/vendor/autoload.php +++ /dev/null @@ -1,25 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - /** @var \Closure(string):void */ - private static $includeFile; - - /** @var string|null */ - private $vendorDir; - - // PSR-4 - /** - * @var array> - */ - private $prefixLengthsPsr4 = array(); - /** - * @var array> - */ - private $prefixDirsPsr4 = array(); - /** - * @var list - */ - private $fallbackDirsPsr4 = array(); - - // PSR-0 - /** - * List of PSR-0 prefixes - * - * Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2'))) - * - * @var array>> - */ - private $prefixesPsr0 = array(); - /** - * @var list - */ - private $fallbackDirsPsr0 = array(); - - /** @var bool */ - private $useIncludePath = false; - - /** - * @var array - */ - private $classMap = array(); - - /** @var bool */ - private $classMapAuthoritative = false; - - /** - * @var array - */ - private $missingClasses = array(); - - /** @var string|null */ - private $apcuPrefix; - - /** - * @var array - */ - private static $registeredLoaders = array(); - - /** - * @param string|null $vendorDir - */ - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - self::initializeIncludeClosure(); - } - - /** - * @return array> - */ - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - /** - * @return array> - */ - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - /** - * @return list - */ - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - /** - * @return list - */ - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - /** - * @return array Array of classname => path - */ - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - * - * @return void - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - * - * @return void - */ - public function add($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - $paths = (array) $paths; - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param list|string $paths The PSR-0 base directories - * - * @return void - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param list|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - * - * @return void - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - * - * @return void - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - * - * @return void - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - * - * @return void - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - * - * @return void - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return true|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - $includeFile = self::$includeFile; - $includeFile($file); - - return true; - } - - return null; - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders keyed by their corresponding vendor directories. - * - * @return array - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - /** - * @param string $class - * @param string $ext - * @return string|false - */ - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } - - /** - * @return void - */ - private static function initializeIncludeClosure() - { - if (self::$includeFile !== null) { - return; - } - - /** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - */ - self::$includeFile = \Closure::bind(static function($file) { - include $file; - }, null, null); - } -} diff --git a/utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php b/utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php deleted file mode 100644 index 51e734a..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,359 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer; - -use Composer\Autoload\ClassLoader; -use Composer\Semver\VersionParser; - -/** - * This class is copied in every Composer installed project and available to all - * - * See also https://getcomposer.org/doc/07-runtime.md#installed-versions - * - * To require its presence, you can require `composer-runtime-api ^2.0` - * - * @final - */ -class InstalledVersions -{ - /** - * @var mixed[]|null - * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null - */ - private static $installed; - - /** - * @var bool|null - */ - private static $canGetVendors; - - /** - * @var array[] - * @psalm-var array}> - */ - private static $installedByVendor = array(); - - /** - * Returns a list of all package names which are present, either by being installed, replaced or provided - * - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackages() - { - $packages = array(); - foreach (self::getInstalled() as $installed) { - $packages[] = array_keys($installed['versions']); - } - - if (1 === \count($packages)) { - return $packages[0]; - } - - return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); - } - - /** - * Returns a list of all package names with a specific type e.g. 'library' - * - * @param string $type - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackagesByType($type) - { - $packagesByType = array(); - - foreach (self::getInstalled() as $installed) { - foreach ($installed['versions'] as $name => $package) { - if (isset($package['type']) && $package['type'] === $type) { - $packagesByType[] = $name; - } - } - } - - return $packagesByType; - } - - /** - * Checks whether the given package is installed - * - * This also returns true if the package name is provided or replaced by another package - * - * @param string $packageName - * @param bool $includeDevRequirements - * @return bool - */ - public static function isInstalled($packageName, $includeDevRequirements = true) - { - foreach (self::getInstalled() as $installed) { - if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; - } - } - - return false; - } - - /** - * Checks whether the given package satisfies a version constraint - * - * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: - * - * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') - * - * @param VersionParser $parser Install composer/semver to have access to this class and functionality - * @param string $packageName - * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package - * @return bool - */ - public static function satisfies(VersionParser $parser, $packageName, $constraint) - { - $constraint = $parser->parseConstraints((string) $constraint); - $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - - return $provided->matches($constraint); - } - - /** - * Returns a version constraint representing all the range(s) which are installed for a given package - * - * It is easier to use this via isInstalled() with the $constraint argument if you need to check - * whether a given version of a package is installed, and not just whether it exists - * - * @param string $packageName - * @return string Version constraint usable with composer/semver - */ - public static function getVersionRanges($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - $ranges = array(); - if (isset($installed['versions'][$packageName]['pretty_version'])) { - $ranges[] = $installed['versions'][$packageName]['pretty_version']; - } - if (array_key_exists('aliases', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); - } - if (array_key_exists('replaced', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); - } - if (array_key_exists('provided', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); - } - - return implode(' || ', $ranges); - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['version'])) { - return null; - } - - return $installed['versions'][$packageName]['version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getPrettyVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['pretty_version'])) { - return null; - } - - return $installed['versions'][$packageName]['pretty_version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference - */ - public static function getReference($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['reference'])) { - return null; - } - - return $installed['versions'][$packageName]['reference']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. - */ - public static function getInstallPath($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @return array - * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} - */ - public static function getRootPackage() - { - $installed = self::getInstalled(); - - return $installed[0]['root']; - } - - /** - * Returns the raw installed.php data for custom implementations - * - * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. - * @return array[] - * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} - */ - public static function getRawData() - { - @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = include __DIR__ . '/installed.php'; - } else { - self::$installed = array(); - } - } - - return self::$installed; - } - - /** - * Returns the raw data of all installed.php which are currently loaded for custom implementations - * - * @return array[] - * @psalm-return list}> - */ - public static function getAllRawData() - { - return self::getInstalled(); - } - - /** - * Lets you reload the static array from another file - * - * This is only useful for complex integrations in which a project needs to use - * this class but then also needs to execute another project's autoloader in process, - * and wants to ensure both projects have access to their version of installed.php. - * - * A typical case would be PHPUnit, where it would need to make sure it reads all - * the data it needs from this class, then call reload() with - * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure - * the project in which it runs can then also use this class safely, without - * interference between PHPUnit's dependencies and the project's dependencies. - * - * @param array[] $data A vendor/composer/installed.php data set - * @return void - * - * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data - */ - public static function reload($data) - { - self::$installed = $data; - self::$installedByVendor = array(); - } - - /** - * @return array[] - * @psalm-return list}> - */ - private static function getInstalled() - { - if (null === self::$canGetVendors) { - self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); - } - - $installed = array(); - - if (self::$canGetVendors) { - foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - if (isset(self::$installedByVendor[$vendorDir])) { - $installed[] = self::$installedByVendor[$vendorDir]; - } elseif (is_file($vendorDir.'/composer/installed.php')) { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; - } - } - } - } - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require __DIR__ . '/installed.php'; - self::$installed = $required; - } else { - self::$installed = array(); - } - } - - if (self::$installed !== array()) { - $installed[] = self::$installed; - } - - return $installed; - } -} diff --git a/utilities/signing_and_verification/php/vendor/composer/LICENSE b/utilities/signing_and_verification/php/vendor/composer/LICENSE deleted file mode 100644 index f27399a..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php b/utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php deleted file mode 100644 index 5490b88..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,15 +0,0 @@ - $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', - 'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php', - 'PhpToken' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', - 'Stringable' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', - 'UnhandledMatchError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', - 'ValueError' => $vendorDir . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', -); diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_files.php b/utilities/signing_and_verification/php/vendor/composer/autoload_files.php deleted file mode 100644 index 0ad6121..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/autoload_files.php +++ /dev/null @@ -1,13 +0,0 @@ - $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', - 'decc78cc4436b1292c6c0d151b19445c' => $vendorDir . '/phpseclib/phpseclib/phpseclib/bootstrap.php', -); diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php b/utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php deleted file mode 100644 index 15a2ff3..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,9 +0,0 @@ - array($vendorDir . '/phpseclib/phpseclib/phpseclib'), - 'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'), - 'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'), - 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), - 'Sop\\X501\\' => array($vendorDir . '/sop/x501/lib/X501'), - 'Sop\\CryptoTypes\\' => array($vendorDir . '/sop/crypto-types/lib/CryptoTypes'), - 'Sop\\CryptoEncoding\\' => array($vendorDir . '/sop/crypto-encoding/lib/CryptoEncoding'), - 'Sop\\ASN1\\' => array($vendorDir . '/sop/asn1/lib/ASN1'), - 'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'), - 'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'), - 'GrahamCampbell\\ResultType\\' => array($vendorDir . '/graham-campbell/result-type/src'), - 'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'), - 'Charnpreet\\Signver\\' => array($baseDir . '/src'), -); diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_real.php b/utilities/signing_and_verification/php/vendor/composer/autoload_real.php deleted file mode 100644 index a97b0eb..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/autoload_real.php +++ /dev/null @@ -1,50 +0,0 @@ -register(true); - - $filesToLoad = \Composer\Autoload\ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$files; - $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - - require $file; - } - }, null, null); - foreach ($filesToLoad as $fileIdentifier => $file) { - $requireFile($fileIdentifier, $file); - } - - return $loader; - } -} diff --git a/utilities/signing_and_verification/php/vendor/composer/autoload_static.php b/utilities/signing_and_verification/php/vendor/composer/autoload_static.php deleted file mode 100644 index d811dba..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/autoload_static.php +++ /dev/null @@ -1,123 +0,0 @@ - __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', - 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', - 'decc78cc4436b1292c6c0d151b19445c' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/bootstrap.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'p' => - array ( - 'phpseclib3\\' => 11, - ), - 'S' => - array ( - 'Symfony\\Polyfill\\Php80\\' => 23, - 'Symfony\\Polyfill\\Mbstring\\' => 26, - 'Symfony\\Polyfill\\Ctype\\' => 23, - 'Sop\\X501\\' => 9, - 'Sop\\CryptoTypes\\' => 16, - 'Sop\\CryptoEncoding\\' => 19, - 'Sop\\ASN1\\' => 9, - ), - 'P' => - array ( - 'PhpOption\\' => 10, - 'ParagonIE\\ConstantTime\\' => 23, - ), - 'G' => - array ( - 'GrahamCampbell\\ResultType\\' => 26, - ), - 'D' => - array ( - 'Dotenv\\' => 7, - ), - 'C' => - array ( - 'Charnpreet\\Signver\\' => 19, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'phpseclib3\\' => - array ( - 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', - ), - 'Symfony\\Polyfill\\Php80\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', - ), - 'Symfony\\Polyfill\\Mbstring\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', - ), - 'Symfony\\Polyfill\\Ctype\\' => - array ( - 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', - ), - 'Sop\\X501\\' => - array ( - 0 => __DIR__ . '/..' . '/sop/x501/lib/X501', - ), - 'Sop\\CryptoTypes\\' => - array ( - 0 => __DIR__ . '/..' . '/sop/crypto-types/lib/CryptoTypes', - ), - 'Sop\\CryptoEncoding\\' => - array ( - 0 => __DIR__ . '/..' . '/sop/crypto-encoding/lib/CryptoEncoding', - ), - 'Sop\\ASN1\\' => - array ( - 0 => __DIR__ . '/..' . '/sop/asn1/lib/ASN1', - ), - 'PhpOption\\' => - array ( - 0 => __DIR__ . '/..' . '/phpoption/phpoption/src/PhpOption', - ), - 'ParagonIE\\ConstantTime\\' => - array ( - 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', - ), - 'GrahamCampbell\\ResultType\\' => - array ( - 0 => __DIR__ . '/..' . '/graham-campbell/result-type/src', - ), - 'Dotenv\\' => - array ( - 0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src', - ), - 'Charnpreet\\Signver\\' => - array ( - 0 => __DIR__ . '/../..' . '/src', - ), - ); - - public static $classMap = array ( - 'Attribute' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Attribute.php', - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - 'PhpToken' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/PhpToken.php', - 'Stringable' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/Stringable.php', - 'UnhandledMatchError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php', - 'ValueError' => __DIR__ . '/..' . '/symfony/polyfill-php80/Resources/stubs/ValueError.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInitf7682c1514c4862053b25ac22e268c1b::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/utilities/signing_and_verification/php/vendor/composer/installed.json b/utilities/signing_and_verification/php/vendor/composer/installed.json deleted file mode 100644 index a462cb6..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/installed.json +++ /dev/null @@ -1,964 +0,0 @@ -{ - "packages": [ - { - "name": "graham-campbell/result-type", - "version": "v1.1.2", - "version_normalized": "1.1.2.0", - "source": { - "type": "git", - "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862", - "reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "time": "2023-11-12T22:16:48+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "An Implementation Of The Result Type", - "keywords": [ - "Graham Campbell", - "GrahamCampbell", - "Result Type", - "Result-Type", - "result" - ], - "support": { - "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", - "type": "tidelift" - } - ], - "install-path": "../graham-campbell/result-type" - }, - { - "name": "paragonie/constant_time_encoding", - "version": "v2.6.3", - "version_normalized": "2.6.3.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/constant_time_encoding.git", - "reference": "58c3f47f650c94ec05a151692652a868995d2938" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938", - "reference": "58c3f47f650c94ec05a151692652a868995d2938", - "shasum": "" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "time": "2022-06-14T06:56:20+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base16", - "base32", - "base32_decode", - "base32_encode", - "base64", - "base64_decode", - "base64_encode", - "bin2hex", - "encoding", - "hex", - "hex2bin", - "rfc4648" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "install-path": "../paragonie/constant_time_encoding" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "version_normalized": "9.99.100.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "time": "2020-10-15T08:29:30+00:00", - "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "install-path": "../paragonie/random_compat" - }, - { - "name": "phpoption/phpoption", - "version": "1.9.2", - "version_normalized": "1.9.2.0", - "source": { - "type": "git", - "url": "https://github.com/schmittjoh/php-option.git", - "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820", - "reference": "80735db690fe4fc5c76dfa7f9b770634285fa820", - "shasum": "" - }, - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "time": "2023-11-12T21:59:55+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "Apache-2.0" - ], - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "description": "Option Type for PHP", - "keywords": [ - "language", - "option", - "php", - "type" - ], - "support": { - "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.9.2" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", - "type": "tidelift" - } - ], - "install-path": "../phpoption/phpoption" - }, - { - "name": "phpseclib/phpseclib", - "version": "3.0.35", - "version_normalized": "3.0.35.0", - "source": { - "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe", - "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe", - "shasum": "" - }, - "require": { - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99", - "php": ">=5.6.1" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "suggest": { - "ext-dom": "Install the DOM extension to load XML formatted public keys.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." - }, - "time": "2023-12-29T01:59:53+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib3\\": "phpseclib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "homepage": "http://phpseclib.sourceforge.net", - "keywords": [ - "BigInteger", - "aes", - "asn.1", - "asn1", - "blowfish", - "crypto", - "cryptography", - "encryption", - "rsa", - "security", - "sftp", - "signature", - "signing", - "ssh", - "twofish", - "x.509", - "x509" - ], - "support": { - "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.35" - }, - "funding": [ - { - "url": "https://github.com/terrafrost", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpseclib", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", - "type": "tidelift" - } - ], - "install-path": "../phpseclib/phpseclib" - }, - { - "name": "sop/asn1", - "version": "4.1.1", - "version_normalized": "4.1.1.0", - "source": { - "type": "git", - "url": "https://github.com/sop/asn1.git", - "reference": "074efe8f7c353c54edc809ac3d74efda83edd776" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/asn1/zipball/074efe8f7c353c54edc809ac3d74efda83edd776", - "reference": "074efe8f7c353c54edc809ac3d74efda83edd776", - "shasum": "" - }, - "require": { - "ext-gmp": "*", - "ext-mbstring": "*", - "php": ">=7.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "time": "2022-02-17T07:08:51+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sop\\ASN1\\": "lib/ASN1/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP library for X.690 ASN.1 DER encoding and decoding.", - "homepage": "https://github.com/sop/asn1", - "keywords": [ - "DER", - "asn.1", - "asn1", - "x.690", - "x690" - ], - "support": { - "issues": "https://github.com/sop/asn1/issues", - "source": "https://github.com/sop/asn1/tree/4.1.1" - }, - "install-path": "../sop/asn1" - }, - { - "name": "sop/crypto-encoding", - "version": "0.3.0", - "version_normalized": "0.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sop/crypto-encoding.git", - "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/crypto-encoding/zipball/07537353e1b0e76c382a58a9c6e041b7c7dc9052", - "reference": "07537353e1b0e76c382a58a9c6e041b7c7dc9052", - "shasum": "" - }, - "require": { - "php": ">=7.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "time": "2019-05-22T11:46:12+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP implementation of textual encodings of cryptographic structures.", - "homepage": "https://github.com/sop/crypto-encoding", - "keywords": [ - "Private Key", - "certificate", - "pem", - "public key" - ], - "support": { - "issues": "https://github.com/sop/crypto-encoding/issues", - "source": "https://github.com/sop/crypto-encoding/tree/master" - }, - "install-path": "../sop/crypto-encoding" - }, - { - "name": "sop/crypto-types", - "version": "dev-master", - "version_normalized": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/sop/crypto-types.git", - "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/crypto-types/zipball/92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", - "reference": "92fd19ebd5d9aecdaef919e08296a2ef79a2e80f", - "shasum": "" - }, - "require": { - "ext-gmp": "*", - "php": ">=7.2", - "sop/asn1": "^4.0.0", - "sop/crypto-encoding": "^0.3.0", - "sop/x501": "0.6.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "time": "2021-08-11T06:56:21+00:00", - "default-branch": true, - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sop\\CryptoTypes\\": "lib/CryptoTypes/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP library of various ASN.1 types for cryptographic applications.", - "homepage": "https://github.com/sop/crypto-types", - "keywords": [ - "Private Key", - "algorithm identifier", - "asn1", - "cryptography", - "ec", - "public key", - "rsa", - "signature" - ], - "support": { - "issues": "https://github.com/sop/crypto-types/issues", - "source": "https://github.com/sop/crypto-types/tree/master" - }, - "install-path": "../sop/crypto-types" - }, - { - "name": "sop/x501", - "version": "0.6.1", - "version_normalized": "0.6.1.0", - "source": { - "type": "git", - "url": "https://github.com/sop/x501.git", - "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sop/x501/zipball/7978bfac25ff73c4c20bed0794d4d88cca8f6895", - "reference": "7978bfac25ff73c4c20bed0794d4d88cca8f6895", - "shasum": "" - }, - "require": { - "ext-intl": "*", - "ext-mbstring": "*", - "php": ">=7.2", - "sop/asn1": "^4.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "time": "2019-06-27T10:30:28+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "psr-4": { - "Sop\\X501\\": "lib/X501/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "description": "A PHP library for X.501 ASN.1 types, X.520 attributes and DN parsing.", - "homepage": "https://github.com/sop/x501", - "keywords": [ - "attribute", - "dn", - "ldap", - "rdn", - "x.501", - "x.520", - "x501", - "x520" - ], - "support": { - "issues": "https://github.com/sop/x501/issues", - "source": "https://github.com/sop/x501/tree/0.6.1" - }, - "install-path": "../sop/x501" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "time": "2023-01-26T09:26:14+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-ctype" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "time": "2023-07-28T09:04:16+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-mbstring" - }, - { - "name": "symfony/polyfill-php80", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "time": "2023-01-26T09:26:14+00:00", - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "installation-source": "dist", - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "install-path": "../symfony/polyfill-php80" - }, - { - "name": "vlucas/phpdotenv", - "version": "v5.6.0", - "version_normalized": "5.6.0.0", - "source": { - "type": "git", - "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", - "reference": "2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4", - "shasum": "" - }, - "require": { - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.2", - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "ext-filter": "*", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "time": "2023-11-12T22:43:29+00:00", - "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": [ - "dotenv", - "env", - "environment" - ], - "support": { - "issues": "https://github.com/vlucas/phpdotenv/issues", - "source": "https://github.com/vlucas/phpdotenv/tree/v5.6.0" - }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", - "type": "tidelift" - } - ], - "install-path": "../vlucas/phpdotenv" - } - ], - "dev": true, - "dev-package-names": [] -} diff --git a/utilities/signing_and_verification/php/vendor/composer/installed.php b/utilities/signing_and_verification/php/vendor/composer/installed.php deleted file mode 100644 index 0b0a521..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/installed.php +++ /dev/null @@ -1,142 +0,0 @@ - array( - 'name' => 'charnpreet/signver', - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => NULL, - 'type' => 'project', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev' => true, - ), - 'versions' => array( - 'charnpreet/signver' => array( - 'pretty_version' => '1.0.0+no-version-set', - 'version' => '1.0.0.0', - 'reference' => NULL, - 'type' => 'project', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'graham-campbell/result-type' => array( - 'pretty_version' => 'v1.1.2', - 'version' => '1.1.2.0', - 'reference' => 'fbd48bce38f73f8a4ec8583362e732e4095e5862', - 'type' => 'library', - 'install_path' => __DIR__ . '/../graham-campbell/result-type', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'paragonie/constant_time_encoding' => array( - 'pretty_version' => 'v2.6.3', - 'version' => '2.6.3.0', - 'reference' => '58c3f47f650c94ec05a151692652a868995d2938', - 'type' => 'library', - 'install_path' => __DIR__ . '/../paragonie/constant_time_encoding', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'paragonie/random_compat' => array( - 'pretty_version' => 'v9.99.100', - 'version' => '9.99.100.0', - 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', - 'type' => 'library', - 'install_path' => __DIR__ . '/../paragonie/random_compat', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'phpoption/phpoption' => array( - 'pretty_version' => '1.9.2', - 'version' => '1.9.2.0', - 'reference' => '80735db690fe4fc5c76dfa7f9b770634285fa820', - 'type' => 'library', - 'install_path' => __DIR__ . '/../phpoption/phpoption', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'phpseclib/phpseclib' => array( - 'pretty_version' => '3.0.35', - 'version' => '3.0.35.0', - 'reference' => '4b1827beabce71953ca479485c0ae9c51287f2fe', - 'type' => 'library', - 'install_path' => __DIR__ . '/../phpseclib/phpseclib', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sop/asn1' => array( - 'pretty_version' => '4.1.1', - 'version' => '4.1.1.0', - 'reference' => '074efe8f7c353c54edc809ac3d74efda83edd776', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sop/asn1', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sop/crypto-encoding' => array( - 'pretty_version' => '0.3.0', - 'version' => '0.3.0.0', - 'reference' => '07537353e1b0e76c382a58a9c6e041b7c7dc9052', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sop/crypto-encoding', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'sop/crypto-types' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '92fd19ebd5d9aecdaef919e08296a2ef79a2e80f', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sop/crypto-types', - 'aliases' => array( - 0 => '9999999-dev', - ), - 'dev_requirement' => false, - ), - 'sop/x501' => array( - 'pretty_version' => '0.6.1', - 'version' => '0.6.1.0', - 'reference' => '7978bfac25ff73c4c20bed0794d4d88cca8f6895', - 'type' => 'library', - 'install_path' => __DIR__ . '/../sop/x501', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/polyfill-mbstring' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '42292d99c55abe617799667f454222c54c60e229', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'symfony/polyfill-php80' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '6caa57379c4aec19c0a12a38b59b26487dcfe4b5', - 'type' => 'library', - 'install_path' => __DIR__ . '/../symfony/polyfill-php80', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'vlucas/phpdotenv' => array( - 'pretty_version' => 'v5.6.0', - 'version' => '5.6.0.0', - 'reference' => '2cf9fb6054c2bb1d59d1f3817706ecdb9d2934c4', - 'type' => 'library', - 'install_path' => __DIR__ . '/../vlucas/phpdotenv', - 'aliases' => array(), - 'dev_requirement' => false, - ), - ), -); diff --git a/utilities/signing_and_verification/php/vendor/composer/platform_check.php b/utilities/signing_and_verification/php/vendor/composer/platform_check.php deleted file mode 100644 index a8b98d5..0000000 --- a/utilities/signing_and_verification/php/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 70205)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE deleted file mode 100644 index bbd75d1..0000000 --- a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2020-2023 Graham Campbell - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json deleted file mode 100644 index b1ba15a..0000000 --- a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/composer.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "graham-campbell/result-type", - "description": "An Implementation Of The Result Type", - "keywords": ["result", "result-type", "Result", "Result Type", "Result-Type", "Graham Campbell", "GrahamCampbell"], - "license": "MIT", - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "require": { - "php": "^7.2.5 || ^8.0", - "phpoption/phpoption": "^1.9.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "autoload": { - "psr-4": { - "GrahamCampbell\\ResultType\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "GrahamCampbell\\Tests\\ResultType\\": "tests/" - } - }, - "config": { - "preferred-install": "dist" - } -} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php deleted file mode 100644 index 2c37c3e..0000000 --- a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Error.php +++ /dev/null @@ -1,121 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace GrahamCampbell\ResultType; - -use PhpOption\None; -use PhpOption\Some; - -/** - * @template T - * @template E - * - * @extends \GrahamCampbell\ResultType\Result - */ -final class Error extends Result -{ - /** - * @var E - */ - private $value; - - /** - * Internal constructor for an error value. - * - * @param E $value - * - * @return void - */ - private function __construct($value) - { - $this->value = $value; - } - - /** - * Create a new error value. - * - * @template F - * - * @param F $value - * - * @return \GrahamCampbell\ResultType\Result - */ - public static function create($value) - { - return new self($value); - } - - /** - * Get the success option value. - * - * @return \PhpOption\Option - */ - public function success() - { - return None::create(); - } - - /** - * Map over the success value. - * - * @template S - * - * @param callable(T):S $f - * - * @return \GrahamCampbell\ResultType\Result - */ - public function map(callable $f) - { - return self::create($this->value); - } - - /** - * Flat map over the success value. - * - * @template S - * @template F - * - * @param callable(T):\GrahamCampbell\ResultType\Result $f - * - * @return \GrahamCampbell\ResultType\Result - */ - public function flatMap(callable $f) - { - /** @var \GrahamCampbell\ResultType\Result */ - return self::create($this->value); - } - - /** - * Get the error option value. - * - * @return \PhpOption\Option - */ - public function error() - { - return Some::create($this->value); - } - - /** - * Map over the error value. - * - * @template F - * - * @param callable(E):F $f - * - * @return \GrahamCampbell\ResultType\Result - */ - public function mapError(callable $f) - { - return self::create($f($this->value)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php deleted file mode 100644 index 8c67bcd..0000000 --- a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Result.php +++ /dev/null @@ -1,69 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace GrahamCampbell\ResultType; - -/** - * @template T - * @template E - */ -abstract class Result -{ - /** - * Get the success option value. - * - * @return \PhpOption\Option - */ - abstract public function success(); - - /** - * Map over the success value. - * - * @template S - * - * @param callable(T):S $f - * - * @return \GrahamCampbell\ResultType\Result - */ - abstract public function map(callable $f); - - /** - * Flat map over the success value. - * - * @template S - * @template F - * - * @param callable(T):\GrahamCampbell\ResultType\Result $f - * - * @return \GrahamCampbell\ResultType\Result - */ - abstract public function flatMap(callable $f); - - /** - * Get the error option value. - * - * @return \PhpOption\Option - */ - abstract public function error(); - - /** - * Map over the error value. - * - * @template F - * - * @param callable(E):F $f - * - * @return \GrahamCampbell\ResultType\Result - */ - abstract public function mapError(callable $f); -} diff --git a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php b/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php deleted file mode 100644 index 27cd85e..0000000 --- a/utilities/signing_and_verification/php/vendor/graham-campbell/result-type/src/Success.php +++ /dev/null @@ -1,120 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace GrahamCampbell\ResultType; - -use PhpOption\None; -use PhpOption\Some; - -/** - * @template T - * @template E - * - * @extends \GrahamCampbell\ResultType\Result - */ -final class Success extends Result -{ - /** - * @var T - */ - private $value; - - /** - * Internal constructor for a success value. - * - * @param T $value - * - * @return void - */ - private function __construct($value) - { - $this->value = $value; - } - - /** - * Create a new error value. - * - * @template S - * - * @param S $value - * - * @return \GrahamCampbell\ResultType\Result - */ - public static function create($value) - { - return new self($value); - } - - /** - * Get the success option value. - * - * @return \PhpOption\Option - */ - public function success() - { - return Some::create($this->value); - } - - /** - * Map over the success value. - * - * @template S - * - * @param callable(T):S $f - * - * @return \GrahamCampbell\ResultType\Result - */ - public function map(callable $f) - { - return self::create($f($this->value)); - } - - /** - * Flat map over the success value. - * - * @template S - * @template F - * - * @param callable(T):\GrahamCampbell\ResultType\Result $f - * - * @return \GrahamCampbell\ResultType\Result - */ - public function flatMap(callable $f) - { - return $f($this->value); - } - - /** - * Get the error option value. - * - * @return \PhpOption\Option - */ - public function error() - { - return None::create(); - } - - /** - * Map over the error value. - * - * @template F - * - * @param callable(E):F $f - * - * @return \GrahamCampbell\ResultType\Result - */ - public function mapError(callable $f) - { - return self::create($this->value); - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt deleted file mode 100644 index 91acaca..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/LICENSE.txt +++ /dev/null @@ -1,48 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 - 2022 Paragon Initiative Enterprises - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - ------------------------------------------------------------------------------- -This library was based on the work of Steve "Sc00bz" Thomas. ------------------------------------------------------------------------------- - -The MIT License (MIT) - -Copyright (c) 2014 Steve Thomas - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md deleted file mode 100644 index cedddd8..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Constant-Time Encoding - -[![Build Status](https://github.com/paragonie/constant_time_encoding/actions/workflows/ci.yml/badge.svg)](https://github.com/paragonie/constant_time_encoding/actions) -[![Latest Stable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/stable)](https://packagist.org/packages/paragonie/constant_time_encoding) -[![Latest Unstable Version](https://poser.pugx.org/paragonie/constant_time_encoding/v/unstable)](https://packagist.org/packages/paragonie/constant_time_encoding) -[![License](https://poser.pugx.org/paragonie/constant_time_encoding/license)](https://packagist.org/packages/paragonie/constant_time_encoding) -[![Downloads](https://img.shields.io/packagist/dt/paragonie/constant_time_encoding.svg)](https://packagist.org/packages/paragonie/constant_time_encoding) - -Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding), -this library aims to offer character encoding functions that do not leak -information about what you are encoding/decoding via processor cache -misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html). - -Our fork offers the following enchancements: - -* `mbstring.func_overload` resistance -* Unit tests -* Composer- and Packagist-ready -* Base16 encoding -* Base32 encoding -* Uses `pack()` and `unpack()` instead of `chr()` and `ord()` - -## PHP Version Requirements - -Version 2 of this library should work on **PHP 7** or newer. For PHP 5 -support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x). - -If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`. - -## How to Install - -```sh -composer require paragonie/constant_time_encoding -``` - -## How to Use - -```php -use ParagonIE\ConstantTime\Encoding; - -// possibly (if applicable): -// require 'vendor/autoload.php'; - -$data = random_bytes(32); -echo Encoding::base64Encode($data), "\n"; -echo Encoding::base32EncodeUpper($data), "\n"; -echo Encoding::base32Encode($data), "\n"; -echo Encoding::hexEncode($data), "\n"; -echo Encoding::hexEncodeUpper($data), "\n"; -``` - -Example output: - -``` -1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= -2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ==== -2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== -d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1 -D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1 -``` - -If you only need a particular variant, you can just reference the -required class like so: - -```php -use ParagonIE\ConstantTime\Base64; -use ParagonIE\ConstantTime\Base32; - -$data = random_bytes(32); -echo Base64::encode($data), "\n"; -echo Base32::encode($data), "\n"; -``` - -Example output: - -``` -1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE= -2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq==== -``` - -## Support Contracts - -If your company uses this library in their products or services, you may be -interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise). diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json deleted file mode 100644 index 2fe9717..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/composer.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "paragonie/constant_time_encoding", - "description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)", - "keywords": [ - "base64", - "encoding", - "rfc4648", - "base32", - "base16", - "hex", - "bin2hex", - "hex2bin", - "base64_encode", - "base64_decode", - "base32_encode", - "base32_decode" - ], - "license": "MIT", - "type": "library", - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com", - "role": "Maintainer" - }, - { - "name": "Steve 'Sc00bz' Thomas", - "email": "steve@tobtu.com", - "homepage": "https://www.tobtu.com", - "role": "Original Developer" - } - ], - "support": { - "issues": "https://github.com/paragonie/constant_time_encoding/issues", - "email": "info@paragonie.com", - "source": "https://github.com/paragonie/constant_time_encoding" - }, - "require": { - "php": "^7|^8" - }, - "require-dev": { - "phpunit/phpunit": "^6|^7|^8|^9", - "vimeo/psalm": "^1|^2|^3|^4" - }, - "autoload": { - "psr-4": { - "ParagonIE\\ConstantTime\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "ParagonIE\\ConstantTime\\Tests\\": "tests/" - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php deleted file mode 100644 index 7508b3d..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32.php +++ /dev/null @@ -1,519 +0,0 @@ - 96 && $src < 123) $ret += $src - 97 + 1; // -64 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96); - - // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 - $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 5-bit integers - * into 8-bit integers. - * - * Uppercase variant. - * - * @param int $src - * @return int - */ - protected static function decode5BitsUpper(int $src): int - { - $ret = -1; - - // if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); - - // if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23 - $ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode5Bits(int $src): string - { - $diff = 0x61; - - // if ($src > 25) $ret -= 72; - $diff -= ((25 - $src) >> 8) & 73; - - return \pack('C', $src + $diff); - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * Uppercase variant. - * - * @param int $src - * @return string - */ - protected static function encode5BitsUpper(int $src): string - { - $diff = 0x41; - - // if ($src > 25) $ret -= 40; - $diff -= ((25 - $src) >> 8) & 41; - - return \pack('C', $src + $diff); - } - - /** - * @param string $encodedString - * @param bool $upper - * @return string - */ - public static function decodeNoPadding(string $encodedString, bool $upper = false): string - { - $srcLen = Binary::safeStrlen($encodedString); - if ($srcLen === 0) { - return ''; - } - if (($srcLen & 7) === 0) { - for ($j = 0; $j < 7 && $j < $srcLen; ++$j) { - if ($encodedString[$srcLen - $j - 1] === '=') { - throw new InvalidArgumentException( - "decodeNoPadding() doesn't tolerate padding" - ); - } - } - } - return static::doDecode( - $encodedString, - $upper, - true - ); - } - - /** - * Base32 decoding - * - * @param string $src - * @param bool $upper - * @param bool $strictPadding - * @return string - * - * @throws TypeError - * @psalm-suppress RedundantCondition - */ - protected static function doDecode( - string $src, - bool $upper = false, - bool $strictPadding = false - ): string { - // We do this to reduce code duplication: - $method = $upper - ? 'decode5BitsUpper' - : 'decode5Bits'; - - // Remove padding - $srcLen = Binary::safeStrlen($src); - if ($srcLen === 0) { - return ''; - } - if ($strictPadding) { - if (($srcLen & 7) === 0) { - for ($j = 0; $j < 7; ++$j) { - if ($src[$srcLen - 1] === '=') { - $srcLen--; - } else { - break; - } - } - } - if (($srcLen & 7) === 1) { - throw new RangeException( - 'Incorrect padding' - ); - } - } else { - $src = \rtrim($src, '='); - $srcLen = Binary::safeStrlen($src); - } - - $err = 0; - $dest = ''; - // Main loop (no padding): - for ($i = 0; $i + 8 <= $srcLen; $i += 8) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8)); - /** @var int $c0 */ - $c0 = static::$method($chunk[1]); - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - /** @var int $c5 */ - $c5 = static::$method($chunk[6]); - /** @var int $c6 */ - $c6 = static::$method($chunk[7]); - /** @var int $c7 */ - $c7 = static::$method($chunk[8]); - - $dest .= \pack( - 'CCCCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff, - (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff, - (($c6 << 5) | ($c7 ) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8; - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); - /** @var int $c0 */ - $c0 = static::$method($chunk[1]); - - if ($i + 6 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - /** @var int $c5 */ - $c5 = static::$method($chunk[6]); - /** @var int $c6 */ - $c6 = static::$method($chunk[7]); - - $dest .= \pack( - 'CCCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff, - (($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8; - if ($strictPadding) { - $err |= ($c6 << 5) & 0xff; - } - } elseif ($i + 5 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - /** @var int $c5 */ - $c5 = static::$method($chunk[6]); - - $dest .= \pack( - 'CCCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff, - (($c4 << 7) | ($c5 << 2) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8; - } elseif ($i + 4 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - /** @var int $c4 */ - $c4 = static::$method($chunk[5]); - - $dest .= \pack( - 'CCC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff, - (($c3 << 4) | ($c4 >> 1) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8; - if ($strictPadding) { - $err |= ($c4 << 7) & 0xff; - } - } elseif ($i + 3 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - /** @var int $c3 */ - $c3 = static::$method($chunk[4]); - - $dest .= \pack( - 'CC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff - ); - $err |= ($c0 | $c1 | $c2 | $c3) >> 8; - if ($strictPadding) { - $err |= ($c3 << 4) & 0xff; - } - } elseif ($i + 2 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - /** @var int $c2 */ - $c2 = static::$method($chunk[3]); - - $dest .= \pack( - 'CC', - (($c0 << 3) | ($c1 >> 2) ) & 0xff, - (($c1 << 6) | ($c2 << 1) ) & 0xff - ); - $err |= ($c0 | $c1 | $c2) >> 8; - if ($strictPadding) { - $err |= ($c2 << 6) & 0xff; - } - } elseif ($i + 1 < $srcLen) { - /** @var int $c1 */ - $c1 = static::$method($chunk[2]); - - $dest .= \pack( - 'C', - (($c0 << 3) | ($c1 >> 2) ) & 0xff - ); - $err |= ($c0 | $c1) >> 8; - if ($strictPadding) { - $err |= ($c1 << 6) & 0xff; - } - } else { - $dest .= \pack( - 'C', - (($c0 << 3) ) & 0xff - ); - $err |= ($c0) >> 8; - } - } - $check = ($err === 0); - if (!$check) { - throw new RangeException( - 'Base32::doDecode() only expects characters in the correct base32 alphabet' - ); - } - return $dest; - } - - /** - * Base32 Encoding - * - * @param string $src - * @param bool $upper - * @param bool $pad - * @return string - * @throws TypeError - */ - protected static function doEncode(string $src, bool $upper = false, $pad = true): string - { - // We do this to reduce code duplication: - $method = $upper - ? 'encode5BitsUpper' - : 'encode5Bits'; - - $dest = ''; - $srcLen = Binary::safeStrlen($src); - - // Main loop (no padding): - for ($i = 0; $i + 5 <= $srcLen; $i += 5) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5)); - $b0 = $chunk[1]; - $b1 = $chunk[2]; - $b2 = $chunk[3]; - $b3 = $chunk[4]; - $b4 = $chunk[5]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . - static::$method((($b3 >> 2) ) & 31) . - static::$method((($b3 << 3) | ($b4 >> 5)) & 31) . - static::$method( $b4 & 31); - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); - $b0 = $chunk[1]; - if ($i + 3 < $srcLen) { - $b1 = $chunk[2]; - $b2 = $chunk[3]; - $b3 = $chunk[4]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) | ($b3 >> 7)) & 31) . - static::$method((($b3 >> 2) ) & 31) . - static::$method((($b3 << 3) ) & 31); - if ($pad) { - $dest .= '='; - } - } elseif ($i + 2 < $srcLen) { - $b1 = $chunk[2]; - $b2 = $chunk[3]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) | ($b2 >> 4)) & 31) . - static::$method((($b2 << 1) ) & 31); - if ($pad) { - $dest .= '==='; - } - } elseif ($i + 1 < $srcLen) { - $b1 = $chunk[2]; - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method((($b0 << 2) | ($b1 >> 6)) & 31) . - static::$method((($b1 >> 1) ) & 31) . - static::$method((($b1 << 4) ) & 31); - if ($pad) { - $dest .= '===='; - } - } else { - $dest .= - static::$method( ($b0 >> 3) & 31) . - static::$method( ($b0 << 2) & 31); - if ($pad) { - $dest .= '======'; - } - } - } - return $dest; - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php deleted file mode 100644 index b868dd0..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base32Hex.php +++ /dev/null @@ -1,111 +0,0 @@ - 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); - - // if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86 - $ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 5-bit integers - * into 8-bit integers. - * - * @param int $src - * @return int - */ - protected static function decode5BitsUpper(int $src): int - { - $ret = -1; - - // if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47); - - // if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54 - $ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode5Bits(int $src): string - { - $src += 0x30; - - // if ($src > 0x39) $src += 0x61 - 0x3a; // 39 - $src += ((0x39 - $src) >> 8) & 39; - - return \pack('C', $src); - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 5-bit integers. - * - * Uppercase variant. - * - * @param int $src - * @return string - */ - protected static function encode5BitsUpper(int $src): string - { - $src += 0x30; - - // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 - $src += ((0x39 - $src) >> 8) & 7; - - return \pack('C', $src); - } -} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php deleted file mode 100644 index f571617..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64.php +++ /dev/null @@ -1,314 +0,0 @@ - $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3)); - $b0 = $chunk[1]; - $b1 = $chunk[2]; - $b2 = $chunk[3]; - - $dest .= - static::encode6Bits( $b0 >> 2 ) . - static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . - static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) . - static::encode6Bits( $b2 & 63); - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i)); - $b0 = $chunk[1]; - if ($i + 1 < $srcLen) { - $b1 = $chunk[2]; - $dest .= - static::encode6Bits($b0 >> 2) . - static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) . - static::encode6Bits(($b1 << 2) & 63); - if ($pad) { - $dest .= '='; - } - } else { - $dest .= - static::encode6Bits( $b0 >> 2) . - static::encode6Bits(($b0 << 4) & 63); - if ($pad) { - $dest .= '=='; - } - } - } - return $dest; - } - - /** - * decode from base64 into binary - * - * Base64 character set "./[A-Z][a-z][0-9]" - * - * @param string $encodedString - * @param bool $strictPadding - * @return string - * - * @throws RangeException - * @throws TypeError - * @psalm-suppress RedundantCondition - */ - public static function decode(string $encodedString, bool $strictPadding = false): string - { - // Remove padding - $srcLen = Binary::safeStrlen($encodedString); - if ($srcLen === 0) { - return ''; - } - - if ($strictPadding) { - if (($srcLen & 3) === 0) { - if ($encodedString[$srcLen - 1] === '=') { - $srcLen--; - if ($encodedString[$srcLen - 1] === '=') { - $srcLen--; - } - } - } - if (($srcLen & 3) === 1) { - throw new RangeException( - 'Incorrect padding' - ); - } - if ($encodedString[$srcLen - 1] === '=') { - throw new RangeException( - 'Incorrect padding' - ); - } - } else { - $encodedString = \rtrim($encodedString, '='); - $srcLen = Binary::safeStrlen($encodedString); - } - - $err = 0; - $dest = ''; - // Main loop (no padding): - for ($i = 0; $i + 4 <= $srcLen; $i += 4) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4)); - $c0 = static::decode6Bits($chunk[1]); - $c1 = static::decode6Bits($chunk[2]); - $c2 = static::decode6Bits($chunk[3]); - $c3 = static::decode6Bits($chunk[4]); - - $dest .= \pack( - 'CCC', - ((($c0 << 2) | ($c1 >> 4)) & 0xff), - ((($c1 << 4) | ($c2 >> 2)) & 0xff), - ((($c2 << 6) | $c3 ) & 0xff) - ); - $err |= ($c0 | $c1 | $c2 | $c3) >> 8; - } - // The last chunk, which may have padding: - if ($i < $srcLen) { - /** @var array $chunk */ - $chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i)); - $c0 = static::decode6Bits($chunk[1]); - - if ($i + 2 < $srcLen) { - $c1 = static::decode6Bits($chunk[2]); - $c2 = static::decode6Bits($chunk[3]); - $dest .= \pack( - 'CC', - ((($c0 << 2) | ($c1 >> 4)) & 0xff), - ((($c1 << 4) | ($c2 >> 2)) & 0xff) - ); - $err |= ($c0 | $c1 | $c2) >> 8; - if ($strictPadding) { - $err |= ($c2 << 6) & 0xff; - } - } elseif ($i + 1 < $srcLen) { - $c1 = static::decode6Bits($chunk[2]); - $dest .= \pack( - 'C', - ((($c0 << 2) | ($c1 >> 4)) & 0xff) - ); - $err |= ($c0 | $c1) >> 8; - if ($strictPadding) { - $err |= ($c1 << 4) & 0xff; - } - } elseif ($strictPadding) { - $err |= 1; - } - } - $check = ($err === 0); - if (!$check) { - throw new RangeException( - 'Base64::decode() only expects characters in the correct base64 alphabet' - ); - } - return $dest; - } - - /** - * @param string $encodedString - * @return string - */ - public static function decodeNoPadding(string $encodedString): string - { - $srcLen = Binary::safeStrlen($encodedString); - if ($srcLen === 0) { - return ''; - } - if (($srcLen & 3) === 0) { - if ($encodedString[$srcLen - 1] === '=') { - throw new InvalidArgumentException( - "decodeNoPadding() doesn't tolerate padding" - ); - } - if (($srcLen & 3) > 1) { - if ($encodedString[$srcLen - 2] === '=') { - throw new InvalidArgumentException( - "decodeNoPadding() doesn't tolerate padding" - ); - } - } - } - return static::decode( - $encodedString, - true - ); - } - - /** - * Uses bitwise operators instead of table-lookups to turn 6-bit integers - * into 8-bit integers. - * - * Base64 character set: - * [A-Z] [a-z] [0-9] + / - * 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f - * - * @param int $src - * @return int - */ - protected static function decode6Bits(int $src): int - { - $ret = -1; - - // if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); - - // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); - - // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); - - // if ($src == 0x2b) $ret += 62 + 1; - $ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63; - - // if ($src == 0x2f) ret += 63 + 1; - $ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64; - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $diff = 0x41; - - // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 - $diff += ((25 - $src) >> 8) & 6; - - // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 - $diff -= ((51 - $src) >> 8) & 75; - - // if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15 - $diff -= ((61 - $src) >> 8) & 15; - - // if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3 - $diff += ((62 - $src) >> 8) & 3; - - return \pack('C', $src + $diff); - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php deleted file mode 100644 index 5e98a8f..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php +++ /dev/null @@ -1,88 +0,0 @@ - 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45 - $ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45); - - // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62); - - // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68); - - // if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $src += 0x2e; - - // if ($src > 0x2f) $src += 0x41 - 0x30; // 17 - $src += ((0x2f - $src) >> 8) & 17; - - // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 - $src += ((0x5a - $src) >> 8) & 6; - - // if ($src > 0x7a) $src += 0x30 - 0x7b; // -75 - $src -= ((0x7a - $src) >> 8) & 75; - - return \pack('C', $src); - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php deleted file mode 100644 index 9780b14..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php +++ /dev/null @@ -1,82 +0,0 @@ - 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45 - $ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45); - - // if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52); - - // if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58); - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $src += 0x2e; - - // if ($src > 0x39) $src += 0x41 - 0x3a; // 7 - $src += ((0x39 - $src) >> 8) & 7; - - // if ($src > 0x5a) $src += 0x61 - 0x5b; // 6 - $src += ((0x5a - $src) >> 8) & 6; - - return \pack('C', $src); - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php deleted file mode 100644 index 8192c63..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php +++ /dev/null @@ -1,95 +0,0 @@ - 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64 - $ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64); - - // if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70 - $ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70); - - // if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5 - $ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5); - - // if ($src == 0x2c) $ret += 62 + 1; - $ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63; - - // if ($src == 0x5f) ret += 63 + 1; - $ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64; - - return $ret; - } - - /** - * Uses bitwise operators instead of table-lookups to turn 8-bit integers - * into 6-bit integers. - * - * @param int $src - * @return string - */ - protected static function encode6Bits(int $src): string - { - $diff = 0x41; - - // if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6 - $diff += ((25 - $src) >> 8) & 6; - - // if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75 - $diff -= ((51 - $src) >> 8) & 75; - - // if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13 - $diff -= ((61 - $src) >> 8) & 13; - - // if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3 - $diff += ((62 - $src) >> 8) & 49; - - return \pack('C', $src + $diff); - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php deleted file mode 100644 index 828f3e0..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/Binary.php +++ /dev/null @@ -1,90 +0,0 @@ - $chunk */ - $chunk = \unpack('C', $binString[$i]); - $c = $chunk[1] & 0xf; - $b = $chunk[1] >> 4; - - $hex .= \pack( - 'CC', - (87 + $b + ((($b - 10) >> 8) & ~38)), - (87 + $c + ((($c - 10) >> 8) & ~38)) - ); - } - return $hex; - } - - /** - * Convert a binary string into a hexadecimal string without cache-timing - * leaks, returning uppercase letters (as per RFC 4648) - * - * @param string $binString (raw binary) - * @return string - * @throws TypeError - */ - public static function encodeUpper(string $binString): string - { - $hex = ''; - $len = Binary::safeStrlen($binString); - - for ($i = 0; $i < $len; ++$i) { - /** @var array $chunk */ - $chunk = \unpack('C', $binString[$i]); - $c = $chunk[1] & 0xf; - $b = $chunk[1] >> 4; - - $hex .= \pack( - 'CC', - (55 + $b + ((($b - 10) >> 8) & ~6)), - (55 + $c + ((($c - 10) >> 8) & ~6)) - ); - } - return $hex; - } - - /** - * Convert a hexadecimal string into a binary string without cache-timing - * leaks - * - * @param string $encodedString - * @param bool $strictPadding - * @return string (raw binary) - * @throws RangeException - */ - public static function decode( - string $encodedString, - bool $strictPadding = false - ): string { - $hex_pos = 0; - $bin = ''; - $c_acc = 0; - $hex_len = Binary::safeStrlen($encodedString); - $state = 0; - if (($hex_len & 1) !== 0) { - if ($strictPadding) { - throw new RangeException( - 'Expected an even number of hexadecimal characters' - ); - } else { - $encodedString = '0' . $encodedString; - ++$hex_len; - } - } - - /** @var array $chunk */ - $chunk = \unpack('C*', $encodedString); - while ($hex_pos < $hex_len) { - ++$hex_pos; - $c = $chunk[$hex_pos]; - $c_num = $c ^ 48; - $c_num0 = ($c_num - 10) >> 8; - $c_alpha = ($c & ~32) - 55; - $c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8; - - if (($c_num0 | $c_alpha0) === 0) { - throw new RangeException( - 'Expected hexadecimal character' - ); - } - $c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0); - if ($state === 0) { - $c_acc = $c_val * 16; - } else { - $bin .= \pack('C', $c_acc | $c_val); - } - $state ^= 1; - } - return $bin; - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php b/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php deleted file mode 100644 index f124d65..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/constant_time_encoding/src/RFC4648.php +++ /dev/null @@ -1,186 +0,0 @@ - "Zm9v" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base64Encode(string $str): string - { - return Base64::encode($str); - } - - /** - * RFC 4648 Base64 decoding - * - * "Zm9v" -> "foo" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base64Decode(string $str): string - { - return Base64::decode($str, true); - } - - /** - * RFC 4648 Base64 (URL Safe) encoding - * - * "foo" -> "Zm9v" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base64UrlSafeEncode(string $str): string - { - return Base64UrlSafe::encode($str); - } - - /** - * RFC 4648 Base64 (URL Safe) decoding - * - * "Zm9v" -> "foo" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base64UrlSafeDecode(string $str): string - { - return Base64UrlSafe::decode($str, true); - } - - /** - * RFC 4648 Base32 encoding - * - * "foo" -> "MZXW6===" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base32Encode(string $str): string - { - return Base32::encodeUpper($str); - } - - /** - * RFC 4648 Base32 encoding - * - * "MZXW6===" -> "foo" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base32Decode(string $str): string - { - return Base32::decodeUpper($str, true); - } - - /** - * RFC 4648 Base32-Hex encoding - * - * "foo" -> "CPNMU===" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base32HexEncode(string $str): string - { - return Base32::encodeUpper($str); - } - - /** - * RFC 4648 Base32-Hex decoding - * - * "CPNMU===" -> "foo" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base32HexDecode(string $str): string - { - return Base32::decodeUpper($str, true); - } - - /** - * RFC 4648 Base16 decoding - * - * "foo" -> "666F6F" - * - * @param string $str - * @return string - * - * @throws TypeError - */ - public static function base16Encode(string $str): string - { - return Hex::encodeUpper($str); - } - - /** - * RFC 4648 Base16 decoding - * - * "666F6F" -> "foo" - * - * @param string $str - * @return string - */ - public static function base16Decode(string $str): string - { - return Hex::decode($str, true); - } -} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE deleted file mode 100644 index 45c7017..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Paragon Initiative Enterprises - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh deleted file mode 100755 index b4a5ba3..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/build-phar.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) - -php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json deleted file mode 100644 index f2b9c4e..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "paragonie/random_compat", - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "random", - "polyfill", - "pseudorandom" - ], - "license": "MIT", - "type": "library", - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "support": { - "issues": "https://github.com/paragonie/random_compat/issues", - "email": "info@paragonie.com", - "source": "https://github.com/paragonie/random_compat" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "vimeo/psalm": "^1", - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey deleted file mode 100644 index eb50ebf..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm -pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p -+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc ------END PUBLIC KEY----- diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc deleted file mode 100644 index 6a1d7f3..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/dist/random_compat.phar.pubkey.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (MingW32) - -iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip -QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg -1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW -NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA -NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV -JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= -=B6+8 ------END PGP SIGNATURE----- diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php deleted file mode 100644 index c7731a5..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/lib/random.php +++ /dev/null @@ -1,32 +0,0 @@ -buildFromDirectory(dirname(__DIR__).'/lib'); -rename( - dirname(__DIR__).'/lib/index.php', - dirname(__DIR__).'/lib/random.php' -); - -/** - * If we pass an (optional) path to a private key as a second argument, we will - * sign the Phar with OpenSSL. - * - * If you leave this out, it will produce an unsigned .phar! - */ -if ($argc > 1) { - if (!@is_readable($argv[1])) { - echo 'Could not read the private key file:', $argv[1], "\n"; - exit(255); - } - $pkeyFile = file_get_contents($argv[1]); - - $private = openssl_get_privatekey($pkeyFile); - if ($private !== false) { - $pkey = ''; - openssl_pkey_export($private, $pkey); - $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); - - /** - * Save the corresponding public key to the file - */ - if (!@is_readable($dist.'/random_compat.phar.pubkey')) { - $details = openssl_pkey_get_details($private); - file_put_contents( - $dist.'/random_compat.phar.pubkey', - $details['key'] - ); - } - } else { - echo 'An error occurred reading the private key from OpenSSL.', "\n"; - exit(255); - } -} diff --git a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php b/utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php deleted file mode 100644 index d71d1b8..0000000 --- a/utilities/signing_and_verification/php/vendor/paragonie/random_compat/psalm-autoload.php +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE deleted file mode 100644 index f49a4e1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json deleted file mode 100644 index 77f50a3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/composer.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "phpoption/phpoption", - "description": "Option Type for PHP", - "keywords": ["php", "option", "language", "type"], - "license": "Apache-2.0", - "authors": [ - { - "name": "Johannes M. Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh" - }, - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - } - ], - "require": { - "php": "^7.2.5 || ^8.0" - }, - "require-dev": { - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "autoload": { - "psr-4": { - "PhpOption\\": "src/PhpOption/" - } - }, - "autoload-dev": { - "psr-4": { - "PhpOption\\Tests\\": "tests/PhpOption/Tests/" - } - }, - "config": { - "allow-plugins": { - "bamarni/composer-bin-plugin": true - }, - "preferred-install": "dist" - }, - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "1.9-dev" - } - }, - "minimum-stability": "dev", - "prefer-stable": true -} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php deleted file mode 100644 index 9cb77c8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/LazyOption.php +++ /dev/null @@ -1,175 +0,0 @@ - - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace PhpOption; - -use Traversable; - -/** - * @template T - * - * @extends Option - */ -final class LazyOption extends Option -{ - /** @var callable(mixed...):(Option) */ - private $callback; - - /** @var array */ - private $arguments; - - /** @var Option|null */ - private $option; - - /** - * @template S - * @param callable(mixed...):(Option) $callback - * @param array $arguments - * - * @return LazyOption - */ - public static function create($callback, array $arguments = []): self - { - return new self($callback, $arguments); - } - - /** - * @param callable(mixed...):(Option) $callback - * @param array $arguments - */ - public function __construct($callback, array $arguments = []) - { - if (!is_callable($callback)) { - throw new \InvalidArgumentException('Invalid callback given'); - } - - $this->callback = $callback; - $this->arguments = $arguments; - } - - public function isDefined(): bool - { - return $this->option()->isDefined(); - } - - public function isEmpty(): bool - { - return $this->option()->isEmpty(); - } - - public function get() - { - return $this->option()->get(); - } - - public function getOrElse($default) - { - return $this->option()->getOrElse($default); - } - - public function getOrCall($callable) - { - return $this->option()->getOrCall($callable); - } - - public function getOrThrow(\Exception $ex) - { - return $this->option()->getOrThrow($ex); - } - - public function orElse(Option $else) - { - return $this->option()->orElse($else); - } - - public function ifDefined($callable) - { - $this->option()->forAll($callable); - } - - public function forAll($callable) - { - return $this->option()->forAll($callable); - } - - public function map($callable) - { - return $this->option()->map($callable); - } - - public function flatMap($callable) - { - return $this->option()->flatMap($callable); - } - - public function filter($callable) - { - return $this->option()->filter($callable); - } - - public function filterNot($callable) - { - return $this->option()->filterNot($callable); - } - - public function select($value) - { - return $this->option()->select($value); - } - - public function reject($value) - { - return $this->option()->reject($value); - } - - /** - * @return Traversable - */ - public function getIterator(): Traversable - { - return $this->option()->getIterator(); - } - - public function foldLeft($initialValue, $callable) - { - return $this->option()->foldLeft($initialValue, $callable); - } - - public function foldRight($initialValue, $callable) - { - return $this->option()->foldRight($initialValue, $callable); - } - - /** - * @return Option - */ - private function option(): Option - { - if (null === $this->option) { - /** @var mixed */ - $option = call_user_func_array($this->callback, $this->arguments); - if ($option instanceof Option) { - $this->option = $option; - } else { - throw new \RuntimeException(sprintf('Expected instance of %s', Option::class)); - } - } - - return $this->option; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php deleted file mode 100644 index 4b85d22..0000000 --- a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/None.php +++ /dev/null @@ -1,136 +0,0 @@ - - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace PhpOption; - -use EmptyIterator; - -/** - * @extends Option - */ -final class None extends Option -{ - /** @var None|null */ - private static $instance; - - /** - * @return None - */ - public static function create(): self - { - if (null === self::$instance) { - self::$instance = new self(); - } - - return self::$instance; - } - - public function get() - { - throw new \RuntimeException('None has no value.'); - } - - public function getOrCall($callable) - { - return $callable(); - } - - public function getOrElse($default) - { - return $default; - } - - public function getOrThrow(\Exception $ex) - { - throw $ex; - } - - public function isEmpty(): bool - { - return true; - } - - public function isDefined(): bool - { - return false; - } - - public function orElse(Option $else) - { - return $else; - } - - public function ifDefined($callable) - { - // Just do nothing in that case. - } - - public function forAll($callable) - { - return $this; - } - - public function map($callable) - { - return $this; - } - - public function flatMap($callable) - { - return $this; - } - - public function filter($callable) - { - return $this; - } - - public function filterNot($callable) - { - return $this; - } - - public function select($value) - { - return $this; - } - - public function reject($value) - { - return $this; - } - - public function getIterator(): EmptyIterator - { - return new EmptyIterator(); - } - - public function foldLeft($initialValue, $callable) - { - return $initialValue; - } - - public function foldRight($initialValue, $callable) - { - return $initialValue; - } - - private function __construct() - { - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php deleted file mode 100644 index 172924c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Option.php +++ /dev/null @@ -1,434 +0,0 @@ - - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace PhpOption; - -use ArrayAccess; -use IteratorAggregate; - -/** - * @template T - * - * @implements IteratorAggregate - */ -abstract class Option implements IteratorAggregate -{ - /** - * Creates an option given a return value. - * - * This is intended for consuming existing APIs and allows you to easily - * convert them to an option. By default, we treat ``null`` as the None - * case, and everything else as Some. - * - * @template S - * - * @param S $value The actual return value. - * @param S $noneValue The value which should be considered "None"; null by - * default. - * - * @return Option - */ - public static function fromValue($value, $noneValue = null) - { - if ($value === $noneValue) { - return None::create(); - } - - return new Some($value); - } - - /** - * Creates an option from an array's value. - * - * If the key does not exist in the array, the array is not actually an - * array, or the array's value at the given key is null, None is returned. - * Otherwise, Some is returned wrapping the value at the given key. - * - * @template S - * - * @param array|ArrayAccess|null $array A potential array or \ArrayAccess value. - * @param string $key The key to check. - * - * @return Option - */ - public static function fromArraysValue($array, $key) - { - if (!(is_array($array) || $array instanceof ArrayAccess) || !isset($array[$key])) { - return None::create(); - } - - return new Some($array[$key]); - } - - /** - * Creates a lazy-option with the given callback. - * - * This is also a helper constructor for lazy-consuming existing APIs where - * the return value is not yet an option. By default, we treat ``null`` as - * None case, and everything else as Some. - * - * @template S - * - * @param callable $callback The callback to evaluate. - * @param array $arguments The arguments for the callback. - * @param S $noneValue The value which should be considered "None"; - * null by default. - * - * @return LazyOption - */ - public static function fromReturn($callback, array $arguments = [], $noneValue = null) - { - return new LazyOption(static function () use ($callback, $arguments, $noneValue) { - /** @var mixed */ - $return = call_user_func_array($callback, $arguments); - - if ($return === $noneValue) { - return None::create(); - } - - return new Some($return); - }); - } - - /** - * Option factory, which creates new option based on passed value. - * - * If value is already an option, it simply returns. If value is callable, - * LazyOption with passed callback created and returned. If Option - * returned from callback, it returns directly. On other case value passed - * to Option::fromValue() method. - * - * @template S - * - * @param Option|callable|S $value - * @param S $noneValue Used when $value is mixed or - * callable, for None-check. - * - * @return Option|LazyOption - */ - public static function ensure($value, $noneValue = null) - { - if ($value instanceof self) { - return $value; - } elseif (is_callable($value)) { - return new LazyOption(static function () use ($value, $noneValue) { - /** @var mixed */ - $return = $value(); - - if ($return instanceof self) { - return $return; - } else { - return self::fromValue($return, $noneValue); - } - }); - } else { - return self::fromValue($value, $noneValue); - } - } - - /** - * Lift a function so that it accepts Option as parameters. - * - * We return a new closure that wraps the original callback. If any of the - * parameters passed to the lifted function is empty, the function will - * return a value of None. Otherwise, we will pass all parameters to the - * original callback and return the value inside a new Option, unless an - * Option is returned from the function, in which case, we use that. - * - * @template S - * - * @param callable $callback - * @param mixed $noneValue - * - * @return callable - */ - public static function lift($callback, $noneValue = null) - { - return static function () use ($callback, $noneValue) { - /** @var array */ - $args = func_get_args(); - - $reduced_args = array_reduce( - $args, - /** @param bool $status */ - static function ($status, self $o) { - return $o->isEmpty() ? true : $status; - }, - false - ); - // if at least one parameter is empty, return None - if ($reduced_args) { - return None::create(); - } - - $args = array_map( - /** @return T */ - static function (self $o) { - // it is safe to do so because the fold above checked - // that all arguments are of type Some - /** @var T */ - return $o->get(); - }, - $args - ); - - return self::ensure(call_user_func_array($callback, $args), $noneValue); - }; - } - - /** - * Returns the value if available, or throws an exception otherwise. - * - * @throws \RuntimeException If value is not available. - * - * @return T - */ - abstract public function get(); - - /** - * Returns the value if available, or the default value if not. - * - * @template S - * - * @param S $default - * - * @return T|S - */ - abstract public function getOrElse($default); - - /** - * Returns the value if available, or the results of the callable. - * - * This is preferable over ``getOrElse`` if the computation of the default - * value is expensive. - * - * @template S - * - * @param callable():S $callable - * - * @return T|S - */ - abstract public function getOrCall($callable); - - /** - * Returns the value if available, or throws the passed exception. - * - * @param \Exception $ex - * - * @return T - */ - abstract public function getOrThrow(\Exception $ex); - - /** - * Returns true if no value is available, false otherwise. - * - * @return bool - */ - abstract public function isEmpty(); - - /** - * Returns true if a value is available, false otherwise. - * - * @return bool - */ - abstract public function isDefined(); - - /** - * Returns this option if non-empty, or the passed option otherwise. - * - * This can be used to try multiple alternatives, and is especially useful - * with lazy evaluating options: - * - * ```php - * $repo->findSomething() - * ->orElse(new LazyOption(array($repo, 'findSomethingElse'))) - * ->orElse(new LazyOption(array($repo, 'createSomething'))); - * ``` - * - * @param Option $else - * - * @return Option - */ - abstract public function orElse(self $else); - - /** - * This is similar to map() below except that the return value has no meaning; - * the passed callable is simply executed if the option is non-empty, and - * ignored if the option is empty. - * - * In all cases, the return value of the callable is discarded. - * - * ```php - * $comment->getMaybeFile()->ifDefined(function($file) { - * // Do something with $file here. - * }); - * ``` - * - * If you're looking for something like ``ifEmpty``, you can use ``getOrCall`` - * and ``getOrElse`` in these cases. - * - * @deprecated Use forAll() instead. - * - * @param callable(T):mixed $callable - * - * @return void - */ - abstract public function ifDefined($callable); - - /** - * This is similar to map() except that the return value of the callable has no meaning. - * - * The passed callable is simply executed if the option is non-empty, and ignored if the - * option is empty. This method is preferred for callables with side-effects, while map() - * is intended for callables without side-effects. - * - * @param callable(T):mixed $callable - * - * @return Option - */ - abstract public function forAll($callable); - - /** - * Applies the callable to the value of the option if it is non-empty, - * and returns the return value of the callable wrapped in Some(). - * - * If the option is empty, then the callable is not applied. - * - * ```php - * (new Some("foo"))->map('strtoupper')->get(); // "FOO" - * ``` - * - * @template S - * - * @param callable(T):S $callable - * - * @return Option - */ - abstract public function map($callable); - - /** - * Applies the callable to the value of the option if it is non-empty, and - * returns the return value of the callable directly. - * - * In contrast to ``map``, the return value of the callable is expected to - * be an Option itself; it is not automatically wrapped in Some(). - * - * @template S - * - * @param callable(T):Option $callable must return an Option - * - * @return Option - */ - abstract public function flatMap($callable); - - /** - * If the option is empty, it is returned immediately without applying the callable. - * - * If the option is non-empty, the callable is applied, and if it returns true, - * the option itself is returned; otherwise, None is returned. - * - * @param callable(T):bool $callable - * - * @return Option - */ - abstract public function filter($callable); - - /** - * If the option is empty, it is returned immediately without applying the callable. - * - * If the option is non-empty, the callable is applied, and if it returns false, - * the option itself is returned; otherwise, None is returned. - * - * @param callable(T):bool $callable - * - * @return Option - */ - abstract public function filterNot($callable); - - /** - * If the option is empty, it is returned immediately. - * - * If the option is non-empty, and its value does not equal the passed value - * (via a shallow comparison ===), then None is returned. Otherwise, the - * Option is returned. - * - * In other words, this will filter all but the passed value. - * - * @param T $value - * - * @return Option - */ - abstract public function select($value); - - /** - * If the option is empty, it is returned immediately. - * - * If the option is non-empty, and its value does equal the passed value (via - * a shallow comparison ===), then None is returned; otherwise, the Option is - * returned. - * - * In other words, this will let all values through except the passed value. - * - * @param T $value - * - * @return Option - */ - abstract public function reject($value); - - /** - * Binary operator for the initial value and the option's value. - * - * If empty, the initial value is returned. If non-empty, the callable - * receives the initial value and the option's value as arguments. - * - * ```php - * - * $some = new Some(5); - * $none = None::create(); - * $result = $some->foldLeft(1, function($a, $b) { return $a + $b; }); // int(6) - * $result = $none->foldLeft(1, function($a, $b) { return $a + $b; }); // int(1) - * - * // This can be used instead of something like the following: - * $option = Option::fromValue($integerOrNull); - * $result = 1; - * if ( ! $option->isEmpty()) { - * $result += $option->get(); - * } - * ``` - * - * @template S - * - * @param S $initialValue - * @param callable(S, T):S $callable - * - * @return S - */ - abstract public function foldLeft($initialValue, $callable); - - /** - * foldLeft() but with reversed arguments for the callable. - * - * @template S - * - * @param S $initialValue - * @param callable(T, S):S $callable - * - * @return S - */ - abstract public function foldRight($initialValue, $callable); -} diff --git a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php b/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php deleted file mode 100644 index 032632e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpoption/phpoption/src/PhpOption/Some.php +++ /dev/null @@ -1,169 +0,0 @@ - - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -namespace PhpOption; - -use ArrayIterator; - -/** - * @template T - * - * @extends Option - */ -final class Some extends Option -{ - /** @var T */ - private $value; - - /** - * @param T $value - */ - public function __construct($value) - { - $this->value = $value; - } - - /** - * @template U - * - * @param U $value - * - * @return Some - */ - public static function create($value): self - { - return new self($value); - } - - public function isDefined(): bool - { - return true; - } - - public function isEmpty(): bool - { - return false; - } - - public function get() - { - return $this->value; - } - - public function getOrElse($default) - { - return $this->value; - } - - public function getOrCall($callable) - { - return $this->value; - } - - public function getOrThrow(\Exception $ex) - { - return $this->value; - } - - public function orElse(Option $else) - { - return $this; - } - - public function ifDefined($callable) - { - $this->forAll($callable); - } - - public function forAll($callable) - { - $callable($this->value); - - return $this; - } - - public function map($callable) - { - return new self($callable($this->value)); - } - - public function flatMap($callable) - { - /** @var mixed */ - $rs = $callable($this->value); - if (!$rs instanceof Option) { - throw new \RuntimeException('Callables passed to flatMap() must return an Option. Maybe you should use map() instead?'); - } - - return $rs; - } - - public function filter($callable) - { - if (true === $callable($this->value)) { - return $this; - } - - return None::create(); - } - - public function filterNot($callable) - { - if (false === $callable($this->value)) { - return $this; - } - - return None::create(); - } - - public function select($value) - { - if ($this->value === $value) { - return $this; - } - - return None::create(); - } - - public function reject($value) - { - if ($this->value === $value) { - return None::create(); - } - - return $this; - } - - /** - * @return ArrayIterator - */ - public function getIterator(): ArrayIterator - { - return new ArrayIterator([$this->value]); - } - - public function foldLeft($initialValue, $callable) - { - return $callable($initialValue, $this->value); - } - - public function foldRight($initialValue, $callable) - { - return $callable($this->value, $initialValue); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS deleted file mode 100644 index 9f10d26..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/AUTHORS +++ /dev/null @@ -1,7 +0,0 @@ -phpseclib Lead Developer: TerraFrost (Jim Wigginton) - -phpseclib Developers: monnerat (Patrick Monnerat) - bantu (Andreas Fischer) - petrich (Hans-Jürgen Petrich) - GrahamCampbell (Graham Campbell) - hc-jworman \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md deleted file mode 100644 index 4ee6a4f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/BACKERS.md +++ /dev/null @@ -1,16 +0,0 @@ -# Backers - -phpseclib ongoing development is made possible by [Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) and by contributions by users like you. Thank you. - -## Backers - -- Allan Simon -- [ChargeOver](https://chargeover.com/) -- Raghu Veer Dendukuri -- Zane Hooper -- [Setasign](https://www.setasign.com/) -- [Charles Severance](https://github.com/csev) -- [Rachel Fish](https://github.com/itsrachelfish) -- Tharyrok -- [cjhaas](https://github.com/cjhaas) -- [istiak-tridip](https://github.com/istiak-tridip) \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE deleted file mode 100644 index e7214eb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2011-2019 TerraFrost and other contributors - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md deleted file mode 100644 index 98e5796..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/README.md +++ /dev/null @@ -1,97 +0,0 @@ -# phpseclib - PHP Secure Communications Library - -[![CI Status](https://github.com/phpseclib/phpseclib/actions/workflows/ci.yml/badge.svg?branch=3.0&event=push "CI Status")](https://github.com/phpseclib/phpseclib) - -## Supporting phpseclib - -- [Become a backer or sponsor on Patreon](https://www.patreon.com/phpseclib) -- [One-time donation via PayPal or crypto-currencies](http://sourceforge.net/donate/index.php?group_id=198487) -- [Subscribe to Tidelift](https://tidelift.com/subscription/pkg/packagist-phpseclib-phpseclib?utm_source=packagist-phpseclib-phpseclib&utm_medium=referral&utm_campaign=readme) - -## Introduction - -MIT-licensed pure-PHP implementations of the following: - -SSH-2, SFTP, X.509, an arbitrary-precision integer arithmetic library, Ed25519 / Ed449 / Curve25519 / Curve449, ECDSA / ECDH (with support for 66 curves), RSA (PKCS#1 v2.2 compliant), DSA / DH, DES / 3DES / RC4 / Rijndael / AES / Blowfish / Twofish / Salsa20 / ChaCha20, GCM / Poly1305 - -* [Browse Git](https://github.com/phpseclib/phpseclib) - -## Documentation - -* [Documentation / Manual](https://phpseclib.com/) -* [API Documentation](https://api.phpseclib.com/3.0/) (generated by Doctum) - -## Branches - -### master - -* Development Branch -* Unstable API -* Do not use in production - -### 3.0 - -* Long term support (LTS) release -* Major expansion of cryptographic primitives -* Minimum PHP version: 5.6.1 -* PSR-4 autoloading with namespace rooted at `\phpseclib3` -* Install via Composer: `composer require phpseclib/phpseclib:~3.0` - -### 2.0 - -* Long term support (LTS) release -* Modernized version of 1.0 -* Minimum PHP version: 5.3.3 -* PSR-4 autoloading with namespace rooted at `\phpseclib` -* Install via Composer: `composer require phpseclib/phpseclib:~2.0` - -### 1.0 - -* Long term support (LTS) release -* PHP4 compatible -* Composer compatible (PSR-0 autoloading) -* Install using Composer: `composer require phpseclib/phpseclib:~1.0` -* [Download 1.0.22 as ZIP](http://sourceforge.net/projects/phpseclib/files/phpseclib1.0.22.zip/download) - -## Security contact information - -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. - -## Support - -Need Support? - -* [Checkout Questions and Answers on Stack Overflow](http://stackoverflow.com/questions/tagged/phpseclib) -* [Create a Support Ticket on GitHub](https://github.com/phpseclib/phpseclib/issues/new) -* [Browse the Support Forum](http://www.frostjedi.com/phpbb/viewforum.php?f=46) (no longer in use) - -## Special Thanks - -Special Thanks to our $50+ sponsors!: - -- Allan Simon -- [ChargeOver](https://chargeover.com/) - -## Contributing - -1. Fork the Project - -2. Ensure you have Composer installed (see [Composer Download Instructions](https://getcomposer.org/download/)) - -3. Install Development Dependencies - ```sh - composer install - ``` - -4. Create a Feature Branch - -5. Run continuous integration checks: - ```sh - composer global require php:^8.1 squizlabs/php_codesniffer friendsofphp/php-cs-fixer vimeo/psalm - phpcs --standard=build/php_codesniffer.xml - php-cs-fixer fix --config=build/php-cs-fixer.php --diff --dry-run --using-cache=no - psalm --config=build/psalm.xml --no-cache --long-progress --report-show-info=false --output-format=text - vendor/bin/phpunit --verbose --configuration tests/phpunit.xml - ``` - -6. Send us a Pull Request diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json deleted file mode 100644 index 5052d5f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/composer.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "phpseclib/phpseclib", - "type": "library", - "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", - "keywords": [ - "security", - "crypto", - "cryptography", - "encryption", - "signature", - "signing", - "rsa", - "aes", - "blowfish", - "twofish", - "ssh", - "sftp", - "x509", - "x.509", - "asn1", - "asn.1", - "BigInteger" - ], - "homepage": "http://phpseclib.sourceforge.net", - "license": "MIT", - "authors": [ - { - "name": "Jim Wigginton", - "email": "terrafrost@php.net", - "role": "Lead Developer" - }, - { - "name": "Patrick Monnerat", - "email": "pm@datasphere.ch", - "role": "Developer" - }, - { - "name": "Andreas Fischer", - "email": "bantu@phpbb.com", - "role": "Developer" - }, - { - "name": "Hans-Jürgen Petrich", - "email": "petrich@tronic-media.com", - "role": "Developer" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com", - "role": "Developer" - } - ], - "require": { - "php": ">=5.6.1", - "paragonie/constant_time_encoding": "^1|^2", - "paragonie/random_compat": "^1.4|^2.0|^9.99.99" - }, - "require-dev": { - "phpunit/phpunit": "*" - }, - "suggest": { - "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", - "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", - "ext-dom": "Install the DOM extension to load XML formatted public keys." - }, - "autoload": { - "files": [ - "phpseclib/bootstrap.php" - ], - "psr-4": { - "phpseclib3\\": "phpseclib/" - } - }, - "autoload-dev": { - "psr-4": { - "phpseclib3\\Tests\\": "tests/" - } - }, - "config": { - "sort-packages": true - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php deleted file mode 100644 index eac793a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Common/Functions/Strings.php +++ /dev/null @@ -1,505 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Common\Functions; - -use ParagonIE\ConstantTime\Base64; -use ParagonIE\ConstantTime\Base64UrlSafe; -use ParagonIE\ConstantTime\Hex; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\Common\FiniteField; - -/** - * Common String Functions - * - * @author Jim Wigginton - */ -abstract class Strings -{ - /** - * String Shift - * - * Inspired by array_shift - * - * @param string $string - * @param int $index - * @return string - */ - public static function shift(&$string, $index = 1) - { - $substr = substr($string, 0, $index); - $string = substr($string, $index); - return $substr; - } - - /** - * String Pop - * - * Inspired by array_pop - * - * @param string $string - * @param int $index - * @return string - */ - public static function pop(&$string, $index = 1) - { - $substr = substr($string, -$index); - $string = substr($string, 0, -$index); - return $substr; - } - - /** - * Parse SSH2-style string - * - * Returns either an array or a boolean if $data is malformed. - * - * Valid characters for $format are as follows: - * - * C = byte - * b = boolean (true/false) - * N = uint32 - * Q = uint64 - * s = string - * i = mpint - * L = name-list - * - * uint64 is not supported. - * - * @param string $format - * @param string $data - * @return mixed - */ - public static function unpackSSH2($format, &$data) - { - $format = self::formatPack($format); - $result = []; - for ($i = 0; $i < strlen($format); $i++) { - switch ($format[$i]) { - case 'C': - case 'b': - if (!strlen($data)) { - throw new \LengthException('At least one byte needs to be present for successful C / b decodes'); - } - break; - case 'N': - case 'i': - case 's': - case 'L': - if (strlen($data) < 4) { - throw new \LengthException('At least four byte needs to be present for successful N / i / s / L decodes'); - } - break; - case 'Q': - if (strlen($data) < 8) { - throw new \LengthException('At least eight byte needs to be present for successful N / i / s / L decodes'); - } - break; - - default: - throw new \InvalidArgumentException('$format contains an invalid character'); - } - switch ($format[$i]) { - case 'C': - $result[] = ord(self::shift($data)); - continue 2; - case 'b': - $result[] = ord(self::shift($data)) != 0; - continue 2; - case 'N': - list(, $temp) = unpack('N', self::shift($data, 4)); - $result[] = $temp; - continue 2; - case 'Q': - // pack() added support for Q in PHP 5.6.3 and PHP 5.6 is phpseclib 3's minimum version - // so in theory we could support this BUT, "64-bit format codes are not available for - // 32-bit versions" and phpseclib works on 32-bit installs. on 32-bit installs - // 64-bit floats can be used to get larger numbers then 32-bit signed ints would allow - // for. sure, you're not gonna get the full precision of 64-bit numbers but just because - // you need > 32-bit precision doesn't mean you need the full 64-bit precision - extract(unpack('Nupper/Nlower', self::shift($data, 8))); - $temp = $upper ? 4294967296 * $upper : 0; - $temp += $lower < 0 ? ($lower & 0x7FFFFFFFF) + 0x80000000 : $lower; - // $temp = hexdec(bin2hex(self::shift($data, 8))); - $result[] = $temp; - continue 2; - } - list(, $length) = unpack('N', self::shift($data, 4)); - if (strlen($data) < $length) { - throw new \LengthException("$length bytes needed; " . strlen($data) . ' bytes available'); - } - $temp = self::shift($data, $length); - switch ($format[$i]) { - case 'i': - $result[] = new BigInteger($temp, -256); - break; - case 's': - $result[] = $temp; - break; - case 'L': - $result[] = explode(',', $temp); - } - } - - return $result; - } - - /** - * Create SSH2-style string - * - * @param string $format - * @param string|int|float|array|bool ...$elements - * @return string - */ - public static function packSSH2($format, ...$elements) - { - $format = self::formatPack($format); - if (strlen($format) != count($elements)) { - throw new \InvalidArgumentException('There must be as many arguments as there are characters in the $format string'); - } - $result = ''; - for ($i = 0; $i < strlen($format); $i++) { - $element = $elements[$i]; - switch ($format[$i]) { - case 'C': - if (!is_int($element)) { - throw new \InvalidArgumentException('Bytes must be represented as an integer between 0 and 255, inclusive.'); - } - $result .= pack('C', $element); - break; - case 'b': - if (!is_bool($element)) { - throw new \InvalidArgumentException('A boolean parameter was expected.'); - } - $result .= $element ? "\1" : "\0"; - break; - case 'Q': - if (!is_int($element) && !is_float($element)) { - throw new \InvalidArgumentException('An integer was expected.'); - } - // 4294967296 == 1 << 32 - $result .= pack('NN', $element / 4294967296, $element); - break; - case 'N': - if (is_float($element)) { - $element = (int) $element; - } - if (!is_int($element)) { - throw new \InvalidArgumentException('An integer was expected.'); - } - $result .= pack('N', $element); - break; - case 's': - if (!self::is_stringable($element)) { - throw new \InvalidArgumentException('A string was expected.'); - } - $result .= pack('Na*', strlen($element), $element); - break; - case 'i': - if (!$element instanceof BigInteger && !$element instanceof FiniteField\Integer) { - throw new \InvalidArgumentException('A phpseclib3\Math\BigInteger or phpseclib3\Math\Common\FiniteField\Integer object was expected.'); - } - $element = $element->toBytes(true); - $result .= pack('Na*', strlen($element), $element); - break; - case 'L': - if (!is_array($element)) { - throw new \InvalidArgumentException('An array was expected.'); - } - $element = implode(',', $element); - $result .= pack('Na*', strlen($element), $element); - break; - default: - throw new \InvalidArgumentException('$format contains an invalid character'); - } - } - return $result; - } - - /** - * Expand a pack string - * - * Converts C5 to CCCCC, for example. - * - * @param string $format - * @return string - */ - private static function formatPack($format) - { - $parts = preg_split('#(\d+)#', $format, -1, PREG_SPLIT_DELIM_CAPTURE); - $format = ''; - for ($i = 1; $i < count($parts); $i += 2) { - $format .= substr($parts[$i - 1], 0, -1) . str_repeat(substr($parts[$i - 1], -1), $parts[$i]); - } - $format .= $parts[$i - 1]; - - return $format; - } - - /** - * Convert binary data into bits - * - * bin2hex / hex2bin refer to base-256 encoded data as binary, whilst - * decbin / bindec refer to base-2 encoded data as binary. For the purposes - * of this function, bin refers to base-256 encoded data whilst bits refers - * to base-2 encoded data - * - * @param string $x - * @return string - */ - public static function bits2bin($x) - { - /* - // the pure-PHP approach is faster than the GMP approach - if (function_exists('gmp_export')) { - return strlen($x) ? gmp_export(gmp_init($x, 2)) : gmp_init(0); - } - */ - - if (preg_match('#[^01]#', $x)) { - throw new \RuntimeException('The only valid characters are 0 and 1'); - } - - if (!defined('PHP_INT_MIN')) { - define('PHP_INT_MIN', ~PHP_INT_MAX); - } - - $length = strlen($x); - if (!$length) { - return ''; - } - $block_size = PHP_INT_SIZE << 3; - $pad = $block_size - ($length % $block_size); - if ($pad != $block_size) { - $x = str_repeat('0', $pad) . $x; - } - - $parts = str_split($x, $block_size); - $str = ''; - foreach ($parts as $part) { - $xor = $part[0] == '1' ? PHP_INT_MIN : 0; - $part[0] = '0'; - $str .= pack( - PHP_INT_SIZE == 4 ? 'N' : 'J', - $xor ^ eval('return 0b' . $part . ';') - ); - } - return ltrim($str, "\0"); - } - - /** - * Convert bits to binary data - * - * @param string $x - * @return string - */ - public static function bin2bits($x, $trim = true) - { - /* - // the pure-PHP approach is slower than the GMP approach BUT - // i want to the pure-PHP version to be easily unit tested as well - if (function_exists('gmp_import')) { - return gmp_strval(gmp_import($x), 2); - } - */ - - $len = strlen($x); - $mod = $len % PHP_INT_SIZE; - if ($mod) { - $x = str_pad($x, $len + PHP_INT_SIZE - $mod, "\0", STR_PAD_LEFT); - } - - $bits = ''; - if (PHP_INT_SIZE == 4) { - $digits = unpack('N*', $x); - foreach ($digits as $digit) { - $bits .= sprintf('%032b', $digit); - } - } else { - $digits = unpack('J*', $x); - foreach ($digits as $digit) { - $bits .= sprintf('%064b', $digit); - } - } - - return $trim ? ltrim($bits, '0') : $bits; - } - - /** - * Switch Endianness Bit Order - * - * @param string $x - * @return string - */ - public static function switchEndianness($x) - { - $r = ''; - for ($i = strlen($x) - 1; $i >= 0; $i--) { - $b = ord($x[$i]); - if (PHP_INT_SIZE === 8) { - // 3 operations - // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith64BitsDiv - $r .= chr((($b * 0x0202020202) & 0x010884422010) % 1023); - } else { - // 7 operations - // from http://graphics.stanford.edu/~seander/bithacks.html#ReverseByteWith32Bits - $p1 = ($b * 0x0802) & 0x22110; - $p2 = ($b * 0x8020) & 0x88440; - $r .= chr( - (($p1 | $p2) * 0x10101) >> 16 - ); - } - } - return $r; - } - - /** - * Increment the current string - * - * @param string $var - * @return string - */ - public static function increment_str(&$var) - { - if (function_exists('sodium_increment')) { - $var = strrev($var); - sodium_increment($var); - $var = strrev($var); - return $var; - } - - for ($i = 4; $i <= strlen($var); $i += 4) { - $temp = substr($var, -$i, 4); - switch ($temp) { - case "\xFF\xFF\xFF\xFF": - $var = substr_replace($var, "\x00\x00\x00\x00", -$i, 4); - break; - case "\x7F\xFF\xFF\xFF": - $var = substr_replace($var, "\x80\x00\x00\x00", -$i, 4); - return $var; - default: - $temp = unpack('Nnum', $temp); - $var = substr_replace($var, pack('N', $temp['num'] + 1), -$i, 4); - return $var; - } - } - - $remainder = strlen($var) % 4; - - if ($remainder == 0) { - return $var; - } - - $temp = unpack('Nnum', str_pad(substr($var, 0, $remainder), 4, "\0", STR_PAD_LEFT)); - $temp = substr(pack('N', $temp['num'] + 1), -$remainder); - $var = substr_replace($var, $temp, 0, $remainder); - - return $var; - } - - /** - * Find whether the type of a variable is string (or could be converted to one) - * - * @param mixed $var - * @return bool - * @psalm-assert-if-true string|\Stringable $var - */ - public static function is_stringable($var) - { - return is_string($var) || (is_object($var) && method_exists($var, '__toString')); - } - - /** - * Constant Time Base64-decoding - * - * ParagoneIE\ConstantTime doesn't use libsodium if it's available so we'll do so - * ourselves. see https://github.com/paragonie/constant_time_encoding/issues/39 - * - * @param string $data - * @return string - */ - public static function base64_decode($data) - { - return function_exists('sodium_base642bin') ? - sodium_base642bin($data, SODIUM_BASE64_VARIANT_ORIGINAL_NO_PADDING, '=') : - Base64::decode($data); - } - - /** - * Constant Time Base64-decoding (URL safe) - * - * @param string $data - * @return string - */ - public static function base64url_decode($data) - { - // return self::base64_decode(str_replace(['-', '_'], ['+', '/'], $data)); - - return function_exists('sodium_base642bin') ? - sodium_base642bin($data, SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING, '=') : - Base64UrlSafe::decode($data); - } - - /** - * Constant Time Base64-encoding - * - * @param string $data - * @return string - */ - public static function base64_encode($data) - { - return function_exists('sodium_bin2base64') ? - sodium_bin2base64($data, SODIUM_BASE64_VARIANT_ORIGINAL) : - Base64::encode($data); - } - - /** - * Constant Time Base64-encoding (URL safe) - * - * @param string $data - * @return string - */ - public static function base64url_encode($data) - { - // return str_replace(['+', '/'], ['-', '_'], self::base64_encode($data)); - - return function_exists('sodium_bin2base64') ? - sodium_bin2base64($data, SODIUM_BASE64_VARIANT_URLSAFE) : - Base64UrlSafe::encode($data); - } - - /** - * Constant Time Hex Decoder - * - * @param string $data - * @return string - */ - public static function hex2bin($data) - { - return function_exists('sodium_hex2bin') ? - sodium_hex2bin($data) : - Hex::decode($data); - } - - /** - * Constant Time Hex Encoder - * - * @param string $data - * @return string - */ - public static function bin2hex($data) - { - return function_exists('sodium_bin2hex') ? - sodium_bin2hex($data) : - Hex::encode($data); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php deleted file mode 100644 index 4038716..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/AES.php +++ /dev/null @@ -1,116 +0,0 @@ - - * setKey('abcdefghijklmnop'); - * - * $size = 10 * 1024; - * $plaintext = ''; - * for ($i = 0; $i < $size; $i++) { - * $plaintext.= 'a'; - * } - * - * echo $aes->decrypt($aes->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2008 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -/** - * Pure-PHP implementation of AES. - * - * @author Jim Wigginton - */ -class AES extends Rijndael -{ - /** - * Dummy function - * - * Since \phpseclib3\Crypt\AES extends \phpseclib3\Crypt\Rijndael, this function is, technically, available, but it doesn't do anything. - * - * @see \phpseclib3\Crypt\Rijndael::setBlockLength() - * @param int $length - * @throws \BadMethodCallException anytime it's called - */ - public function setBlockLength($length) - { - throw new \BadMethodCallException('The block length cannot be set for AES.'); - } - - /** - * Sets the key length - * - * Valid key lengths are 128, 192, and 256. Set the link to bool(false) to disable a fixed key length - * - * @see \phpseclib3\Crypt\Rijndael:setKeyLength() - * @param int $length - * @throws \LengthException if the key length isn't supported - */ - public function setKeyLength($length) - { - switch ($length) { - case 128: - case 192: - case 256: - break; - default: - throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 128, 192 or 256 supported'); - } - parent::setKeyLength($length); - } - - /** - * Sets the key. - * - * Rijndael supports five different key lengths, AES only supports three. - * - * @see \phpseclib3\Crypt\Rijndael:setKey() - * @see setKeyLength() - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 24: - case 32: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); - } - - parent::setKey($key); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php deleted file mode 100644 index 1225070..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php +++ /dev/null @@ -1,918 +0,0 @@ - unpack('N*', $x), $blocks); it jumps up by an additional - * ~90MB, yielding a 106x increase in memory usage. Consequently, it bcrypt calls a different - * _encryptBlock() then the regular Blowfish does. That said, the Blowfish _encryptBlock() is - * basically just a thin wrapper around the bcrypt _encryptBlock(), so there's that. - * - * This explains 3 of the 4 _encryptBlock() implementations. the last _encryptBlock() - * implementation can best be understood by doing Ctrl + F and searching for where - * self::$use_reg_intval is defined. - * - * # phpseclib's three different _setupKey() implementations - * - * Every bcrypt round is the equivalent of encrypting 512KB of data. Since OpenSSH uses 16 - * rounds by default that's ~8MB of data that's essentially being encrypted whenever - * you use bcrypt. That's a lot of data, however, bcrypt operates within tighter constraints - * than regular Blowfish, so we can use that to our advantage. In particular, whereas Blowfish - * supports variable length keys, in bcrypt, the initial "key" is the sha512 hash of the - * password. sha512 hashes are 512 bits or 64 bytes long and thus the bcrypt keys are of a - * fixed length whereas Blowfish keys are not of a fixed length. - * - * bcrypt actually has two different key expansion steps. The first one (expandstate) is - * constantly XOR'ing every _encryptBlock() parameter against the salt prior _encryptBlock()'s - * being called. The second one (expand0state) is more similar to Blowfish's _setupKey() - * but it can still use the fixed length key optimization discussed above and can do away with - * the pack() / unpack() calls. - * - * I suppose _setupKey() could be made to be a thin wrapper around expandstate() but idk it's - * just a lot of work for very marginal benefits as _setupKey() is only called once for - * regular Blowfish vs the 128 times it's called --per round-- with bcrypt. - * - * # blowfish + bcrypt in the same class - * - * Altho there's a lot of Blowfish code that bcrypt doesn't re-use, bcrypt does re-use the - * initial S-boxes, the initial P-array and the int-only _encryptBlock() implementation. - * - * # Credit - * - * phpseclib's bcrypt implementation is based losely off of OpenSSH's implementation: - * - * https://github.com/openssh/openssh-portable/blob/master/openbsd-compat/bcrypt_pbkdf.c - * - * Here's a short example of how to use this library: - * - * setKey('12345678901234567890123456789012'); - * - * $plaintext = str_repeat('a', 1024); - * - * echo $blowfish->decrypt($blowfish->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; - -/** - * Pure-PHP implementation of Blowfish. - * - * @author Jim Wigginton - * @author Hans-Juergen Petrich - */ -class Blowfish extends BlockCipher -{ - /** - * Block Length of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size - * @var int - */ - protected $block_size = 8; - - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @var string - */ - protected $cipher_name_mcrypt = 'blowfish'; - - /** - * Optimizing value while CFB-encrypting - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len - * @var int - */ - protected $cfb_init_len = 500; - - /** - * The fixed subkeys boxes ($sbox0 - $sbox3) with 256 entries each - * - * S-Box 0 - * - * @var array - */ - private static $sbox0 = [ - 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99, - 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16, 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, - 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013, - 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e, - 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60, 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, - 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a, - 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677, - 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, - 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239, - 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0, - 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, - 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, - 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, - 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, - 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463, - 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09, - 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, - 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, - 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, - 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, - 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b, - 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, - 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, - 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, - 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1, - 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, - 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf, - 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af, - 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa, 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, - 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915, - 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915, - 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664, 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a - ]; - - /** - * S-Box 1 - * - * @var array - */ - private static $sbox1 = [ - 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266, - 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, - 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, - 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1, - 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, - 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, - 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7, - 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, - 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, - 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87, - 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, - 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, - 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, - 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, - 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, - 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, - 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, - 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, - 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf, - 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, - 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, - 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, - 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, - 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, - 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, - 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, - 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, - 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061, - 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, - 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, - 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340, - 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7 - ]; - - /** - * S-Box 2 - * - * @var array - */ - private static $sbox2 = [ - 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, - 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, - 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504, - 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, - 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, - 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b, - 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, - 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, - 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c, - 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, - 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, - 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115, - 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, - 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, - 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d, - 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, - 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, - 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c, - 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, - 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, - 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, - 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, - 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, - 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, - 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, - 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, - 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, - 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, - 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, - 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, - 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, - 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0 - ]; - - /** - * S-Box 3 - * - * @var array - */ - private static $sbox3 = [ - 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe, - 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, - 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, - 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22, - 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, - 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, - 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51, - 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, - 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, - 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, - 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, - 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, - 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, - 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, - 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb, - 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47, - 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, - 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048, - 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, - 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, - 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, - 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, - 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, - 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, - 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d, - 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, - 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, - 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, - 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, - 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060, - 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9, - 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6 - ]; - - /** - * P-Array consists of 18 32-bit subkeys - * - * @var array - */ - private static $parray = [ - 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, - 0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, - 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b - ]; - - /** - * The BCTX-working Array - * - * Holds the expanded key [p] and the key-depended s-boxes [sb] - * - * @var array - */ - private $bctx; - - /** - * Holds the last used key - * - * @var array - */ - private $kl; - - /** - * The Key Length (in bytes) - * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk - * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could - * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once.} - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() - * @var int - */ - protected $key_length = 16; - - /** - * Default Constructor. - * - * @param string $mode - * @throws \InvalidArgumentException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new \InvalidArgumentException('Block ciphers cannot be ran in stream mode'); - } - } - - /** - * Sets the key length. - * - * Key lengths can be between 32 and 448 bits. - * - * @param int $length - */ - public function setKeyLength($length) - { - if ($length < 32 || $length > 448) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes between 32 and 448 bits are supported'); - } - - $this->key_length = $length >> 3; - - parent::setKeyLength($length); - } - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - if ($engine == self::ENGINE_OPENSSL) { - if ($this->key_length < 16) { - return false; - } - // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 - // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" - // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { - return false; - } - $this->cipher_name_openssl_ecb = 'bf-ecb'; - $this->cipher_name_openssl = 'bf-' . $this->openssl_translate_mode(); - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Setup the key (expansion) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() - */ - protected function setupKey() - { - if (isset($this->kl['key']) && $this->key === $this->kl['key']) { - // already expanded - return; - } - $this->kl = ['key' => $this->key]; - - /* key-expanding p[] and S-Box building sb[] */ - $this->bctx = [ - 'p' => [], - 'sb' => [ - self::$sbox0, - self::$sbox1, - self::$sbox2, - self::$sbox3 - ] - ]; - - // unpack binary string in unsigned chars - $key = array_values(unpack('C*', $this->key)); - $keyl = count($key); - // with bcrypt $keyl will always be 16 (because the key is the sha512 of the key you provide) - for ($j = 0, $i = 0; $i < 18; ++$i) { - // xor P1 with the first 32-bits of the key, xor P2 with the second 32-bits ... - for ($data = 0, $k = 0; $k < 4; ++$k) { - $data = ($data << 8) | $key[$j]; - if (++$j >= $keyl) { - $j = 0; - } - } - $this->bctx['p'][] = self::$parray[$i] ^ intval($data); - } - - // encrypt the zero-string, replace P1 and P2 with the encrypted data, - // encrypt P3 and P4 with the new P1 and P2, do it with all P-array and subkeys - $data = "\0\0\0\0\0\0\0\0"; - for ($i = 0; $i < 18; $i += 2) { - list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); - $this->bctx['p'][$i ] = $l; - $this->bctx['p'][$i + 1] = $r; - } - for ($i = 0; $i < 4; ++$i) { - for ($j = 0; $j < 256; $j += 2) { - list($l, $r) = array_values(unpack('N*', $data = $this->encryptBlock($data))); - $this->bctx['sb'][$i][$j ] = $l; - $this->bctx['sb'][$i][$j + 1] = $r; - } - } - } - - /** - * Initialize Static Variables - */ - protected static function initialize_static_variables() - { - if (is_float(self::$sbox2[0])) { - self::$sbox0 = array_map('intval', self::$sbox0); - self::$sbox1 = array_map('intval', self::$sbox1); - self::$sbox2 = array_map('intval', self::$sbox2); - self::$sbox3 = array_map('intval', self::$sbox3); - self::$parray = array_map('intval', self::$parray); - } - - parent::initialize_static_variables(); - } - - /** - * bcrypt - * - * @param string $sha2pass - * @param string $sha2salt - * @access private - * @return string - */ - private static function bcrypt_hash($sha2pass, $sha2salt) - { - $p = self::$parray; - $sbox0 = self::$sbox0; - $sbox1 = self::$sbox1; - $sbox2 = self::$sbox2; - $sbox3 = self::$sbox3; - - $cdata = array_values(unpack('N*', 'OxychromaticBlowfishSwatDynamite')); - $sha2pass = array_values(unpack('N*', $sha2pass)); - $sha2salt = array_values(unpack('N*', $sha2salt)); - - self::expandstate($sha2salt, $sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 0; $i < 64; $i++) { - self::expand0state($sha2salt, $sbox0, $sbox1, $sbox2, $sbox3, $p); - self::expand0state($sha2pass, $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - for ($i = 0; $i < 64; $i++) { - for ($j = 0; $j < 8; $j += 2) { // count($cdata) == 8 - list($cdata[$j], $cdata[$j + 1]) = self::encryptBlockHelperFast($cdata[$j], $cdata[$j + 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - } - - return pack('L*', ...$cdata); - } - - /** - * Performs OpenSSH-style bcrypt - * - * @param string $pass - * @param string $salt - * @param int $keylen - * @param int $rounds - * @access public - * @return string - */ - public static function bcrypt_pbkdf($pass, $salt, $keylen, $rounds) - { - self::initialize_static_variables(); - - if (PHP_INT_SIZE == 4) { - throw new \RuntimeException('bcrypt is far too slow to be practical on 32-bit versions of PHP'); - } - - $sha2pass = hash('sha512', $pass, true); - $results = []; - $count = 1; - while (32 * count($results) < $keylen) { - $countsalt = $salt . pack('N', $count++); - $sha2salt = hash('sha512', $countsalt, true); - $out = $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); - for ($i = 1; $i < $rounds; $i++) { - $sha2salt = hash('sha512', $tmpout, true); - $tmpout = self::bcrypt_hash($sha2pass, $sha2salt); - $out ^= $tmpout; - } - $results[] = $out; - } - $output = ''; - for ($i = 0; $i < 32; $i++) { - foreach ($results as $result) { - $output .= $result[$i]; - } - } - return substr($output, 0, $keylen); - } - - /** - * Key expansion without salt - * - * @access private - * @param int[] $key - * @param int[] $sbox0 - * @param int[] $sbox1 - * @param int[] $sbox2 - * @param int[] $sbox3 - * @param int[] $p - * @see self::_bcrypt_hash() - */ - private static function expand0state(array $key, array &$sbox0, array &$sbox1, array &$sbox2, array &$sbox3, array &$p) - { - // expand0state is basically the same thing as this: - //return self::expandstate(array_fill(0, 16, 0), $key); - // but this separate function eliminates a bunch of XORs and array lookups - - $p = [ - $p[0] ^ $key[0], - $p[1] ^ $key[1], - $p[2] ^ $key[2], - $p[3] ^ $key[3], - $p[4] ^ $key[4], - $p[5] ^ $key[5], - $p[6] ^ $key[6], - $p[7] ^ $key[7], - $p[8] ^ $key[8], - $p[9] ^ $key[9], - $p[10] ^ $key[10], - $p[11] ^ $key[11], - $p[12] ^ $key[12], - $p[13] ^ $key[13], - $p[14] ^ $key[14], - $p[15] ^ $key[15], - $p[16] ^ $key[0], - $p[17] ^ $key[1] - ]; - - // @codingStandardsIgnoreStart - list( $p[0], $p[1]) = self::encryptBlockHelperFast( 0, 0, $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[2], $p[3]) = self::encryptBlockHelperFast($p[ 0], $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[4], $p[5]) = self::encryptBlockHelperFast($p[ 2], $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[6], $p[7]) = self::encryptBlockHelperFast($p[ 4], $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[8], $p[9]) = self::encryptBlockHelperFast($p[ 6], $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[10], $p[11]) = self::encryptBlockHelperFast($p[ 8], $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[12], $p[13]) = self::encryptBlockHelperFast($p[10], $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[14], $p[15]) = self::encryptBlockHelperFast($p[12], $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[16], $p[17]) = self::encryptBlockHelperFast($p[14], $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p); - // @codingStandardsIgnoreEnd - - list($sbox0[0], $sbox0[1]) = self::encryptBlockHelperFast($p[16], $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2; $i < 256; $i += 2) { - list($sbox0[$i], $sbox0[$i + 1]) = self::encryptBlockHelperFast($sbox0[$i - 2], $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - list($sbox1[0], $sbox1[1]) = self::encryptBlockHelperFast($sbox0[254], $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2; $i < 256; $i += 2) { - list($sbox1[$i], $sbox1[$i + 1]) = self::encryptBlockHelperFast($sbox1[$i - 2], $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - list($sbox2[0], $sbox2[1]) = self::encryptBlockHelperFast($sbox1[254], $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2; $i < 256; $i += 2) { - list($sbox2[$i], $sbox2[$i + 1]) = self::encryptBlockHelperFast($sbox2[$i - 2], $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - list($sbox3[0], $sbox3[1]) = self::encryptBlockHelperFast($sbox2[254], $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2; $i < 256; $i += 2) { - list($sbox3[$i], $sbox3[$i + 1]) = self::encryptBlockHelperFast($sbox3[$i - 2], $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - } - - /** - * Key expansion with salt - * - * @access private - * @param int[] $data - * @param int[] $key - * @param int[] $sbox0 - * @param int[] $sbox1 - * @param int[] $sbox2 - * @param int[] $sbox3 - * @param int[] $p - * @see self::_bcrypt_hash() - */ - private static function expandstate(array $data, array $key, array &$sbox0, array &$sbox1, array &$sbox2, array &$sbox3, array &$p) - { - $p = [ - $p[0] ^ $key[0], - $p[1] ^ $key[1], - $p[2] ^ $key[2], - $p[3] ^ $key[3], - $p[4] ^ $key[4], - $p[5] ^ $key[5], - $p[6] ^ $key[6], - $p[7] ^ $key[7], - $p[8] ^ $key[8], - $p[9] ^ $key[9], - $p[10] ^ $key[10], - $p[11] ^ $key[11], - $p[12] ^ $key[12], - $p[13] ^ $key[13], - $p[14] ^ $key[14], - $p[15] ^ $key[15], - $p[16] ^ $key[0], - $p[17] ^ $key[1] - ]; - - // @codingStandardsIgnoreStart - list( $p[0], $p[1]) = self::encryptBlockHelperFast($data[ 0] , $data[ 1] , $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[2], $p[3]) = self::encryptBlockHelperFast($data[ 2] ^ $p[ 0], $data[ 3] ^ $p[ 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[4], $p[5]) = self::encryptBlockHelperFast($data[ 4] ^ $p[ 2], $data[ 5] ^ $p[ 3], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[6], $p[7]) = self::encryptBlockHelperFast($data[ 6] ^ $p[ 4], $data[ 7] ^ $p[ 5], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list( $p[8], $p[9]) = self::encryptBlockHelperFast($data[ 8] ^ $p[ 6], $data[ 9] ^ $p[ 7], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[10], $p[11]) = self::encryptBlockHelperFast($data[10] ^ $p[ 8], $data[11] ^ $p[ 9], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[12], $p[13]) = self::encryptBlockHelperFast($data[12] ^ $p[10], $data[13] ^ $p[11], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[14], $p[15]) = self::encryptBlockHelperFast($data[14] ^ $p[12], $data[15] ^ $p[13], $sbox0, $sbox1, $sbox2, $sbox3, $p); - list($p[16], $p[17]) = self::encryptBlockHelperFast($data[ 0] ^ $p[14], $data[ 1] ^ $p[15], $sbox0, $sbox1, $sbox2, $sbox3, $p); - // @codingStandardsIgnoreEnd - - list($sbox0[0], $sbox0[1]) = self::encryptBlockHelperFast($data[2] ^ $p[16], $data[3] ^ $p[17], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { // instead of 16 maybe count($data) would be better? - list($sbox0[$i], $sbox0[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox0[$i - 2], $data[$j + 1] ^ $sbox0[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - list($sbox1[0], $sbox1[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox0[254], $data[3] ^ $sbox0[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { - list($sbox1[$i], $sbox1[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox1[$i - 2], $data[$j + 1] ^ $sbox1[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - list($sbox2[0], $sbox2[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox1[254], $data[3] ^ $sbox1[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { - list($sbox2[$i], $sbox2[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox2[$i - 2], $data[$j + 1] ^ $sbox2[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - - list($sbox3[0], $sbox3[1]) = self::encryptBlockHelperFast($data[2] ^ $sbox2[254], $data[3] ^ $sbox2[255], $sbox0, $sbox1, $sbox2, $sbox3, $p); - for ($i = 2, $j = 4; $i < 256; $i += 2, $j = ($j + 2) % 16) { - list($sbox3[$i], $sbox3[$i + 1]) = self::encryptBlockHelperFast($data[$j] ^ $sbox3[$i - 2], $data[$j + 1] ^ $sbox3[$i - 1], $sbox0, $sbox1, $sbox2, $sbox3, $p); - } - } - - /** - * Encrypts a block - * - * @param string $in - * @return string - */ - protected function encryptBlock($in) - { - $p = $this->bctx['p']; - // extract($this->bctx['sb'], EXTR_PREFIX_ALL, 'sb'); // slower - $sb_0 = $this->bctx['sb'][0]; - $sb_1 = $this->bctx['sb'][1]; - $sb_2 = $this->bctx['sb'][2]; - $sb_3 = $this->bctx['sb'][3]; - - $in = unpack('N*', $in); - $l = $in[1]; - $r = $in[2]; - - list($r, $l) = PHP_INT_SIZE == 4 ? - self::encryptBlockHelperSlow($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p) : - self::encryptBlockHelperFast($l, $r, $sb_0, $sb_1, $sb_2, $sb_3, $p); - - return pack("N*", $r, $l); - } - - /** - * Fast helper function for block encryption - * - * @access private - * @param int $x0 - * @param int $x1 - * @param int[] $sbox0 - * @param int[] $sbox1 - * @param int[] $sbox2 - * @param int[] $sbox3 - * @param int[] $p - * @return int[] - */ - private static function encryptBlockHelperFast($x0, $x1, array $sbox0, array $sbox1, array $sbox2, array $sbox3, array $p) - { - $x0 ^= $p[0]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; - $x1 ^= ((($sbox0[($x0 & 0xFF000000) >> 24] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; - $x0 ^= ((($sbox0[($x1 & 0xFF000000) >> 24] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; - - return [$x1 & 0xFFFFFFFF ^ $p[17], $x0 & 0xFFFFFFFF]; - } - - /** - * Slow helper function for block encryption - * - * @access private - * @param int $x0 - * @param int $x1 - * @param int[] $sbox0 - * @param int[] $sbox1 - * @param int[] $sbox2 - * @param int[] $sbox3 - * @param int[] $p - * @return int[] - */ - private static function encryptBlockHelperSlow($x0, $x1, array $sbox0, array $sbox1, array $sbox2, array $sbox3, array $p) - { - // -16777216 == intval(0xFF000000) on 32-bit PHP installs - $x0 ^= $p[0]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[1]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[2]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[3]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[4]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[5]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[6]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[7]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[8]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[9]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[10]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[11]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[12]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[13]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[14]; - $x1 ^= self::safe_intval((self::safe_intval($sbox0[(($x0 & -16777216) >> 24) & 0xFF] + $sbox1[($x0 & 0xFF0000) >> 16]) ^ $sbox2[($x0 & 0xFF00) >> 8]) + $sbox3[$x0 & 0xFF]) ^ $p[15]; - $x0 ^= self::safe_intval((self::safe_intval($sbox0[(($x1 & -16777216) >> 24) & 0xFF] + $sbox1[($x1 & 0xFF0000) >> 16]) ^ $sbox2[($x1 & 0xFF00) >> 8]) + $sbox3[$x1 & 0xFF]) ^ $p[16]; - - return [$x1 ^ $p[17], $x0]; - } - - /** - * Decrypts a block - * - * @param string $in - * @return string - */ - protected function decryptBlock($in) - { - $p = $this->bctx['p']; - $sb_0 = $this->bctx['sb'][0]; - $sb_1 = $this->bctx['sb'][1]; - $sb_2 = $this->bctx['sb'][2]; - $sb_3 = $this->bctx['sb'][3]; - - $in = unpack('N*', $in); - $l = $in[1]; - $r = $in[2]; - - for ($i = 17; $i > 2; $i -= 2) { - $l ^= $p[$i]; - $r ^= self::safe_intval((self::safe_intval($sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]) ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]); - - $r ^= $p[$i - 1]; - $l ^= self::safe_intval((self::safe_intval($sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]) ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]); - } - return pack('N*', $r ^ $p[0], $l ^ $p[1]); - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() - */ - protected function setupInlineCrypt() - { - $p = $this->bctx['p']; - $init_crypt = ' - static $sb_0, $sb_1, $sb_2, $sb_3; - if (!$sb_0) { - $sb_0 = $this->bctx["sb"][0]; - $sb_1 = $this->bctx["sb"][1]; - $sb_2 = $this->bctx["sb"][2]; - $sb_3 = $this->bctx["sb"][3]; - } - '; - - $safeint = self::safe_intval_inline(); - - // Generating encrypt code: - $encrypt_block = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - '; - for ($i = 0; $i < 16; $i += 2) { - $encrypt_block .= ' - $l^= ' . $p[$i] . '; - $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]') . '; - - $r^= ' . $p[$i + 1] . '; - $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]') . '; - '; - } - $encrypt_block .= ' - $in = pack("N*", - $r ^ ' . $p[17] . ', - $l ^ ' . $p[16] . ' - ); - '; - // Generating decrypt code: - $decrypt_block = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - '; - - for ($i = 17; $i > 2; $i -= 2) { - $decrypt_block .= ' - $l^= ' . $p[$i] . '; - $r^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$l >> 24 & 0xff] + $sb_1[$l >> 16 & 0xff]') . ' ^ - $sb_2[$l >> 8 & 0xff]) + - $sb_3[$l & 0xff]') . '; - - $r^= ' . $p[$i - 1] . '; - $l^= ' . sprintf($safeint, '(' . sprintf($safeint, '$sb_0[$r >> 24 & 0xff] + $sb_1[$r >> 16 & 0xff]') . ' ^ - $sb_2[$r >> 8 & 0xff]) + - $sb_3[$r & 0xff]') . '; - '; - } - - $decrypt_block .= ' - $in = pack("N*", - $r ^ ' . $p[0] . ', - $l ^ ' . $p[1] . ' - ); - '; - - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'init_encrypt' => '', - 'init_decrypt' => '', - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php deleted file mode 100644 index b2691b5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/ChaCha20.php +++ /dev/null @@ -1,799 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Exception\BadDecryptionException; -use phpseclib3\Exception\InsufficientSetupException; - -/** - * Pure-PHP implementation of ChaCha20. - * - * @author Jim Wigginton - */ -class ChaCha20 extends Salsa20 -{ - /** - * The OpenSSL specific name of the cipher - * - * @var string - */ - protected $cipher_name_openssl = 'chacha20'; - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - switch ($engine) { - case self::ENGINE_LIBSODIUM: - // PHP 7.2.0 (30 Nov 2017) added support for libsodium - - // we could probably make it so that if $this->counter == 0 then the first block would be done with either OpenSSL - // or PHP and then subsequent blocks would then be done with libsodium but idk - it's not a high priority atm - - // we could also make it so that if $this->counter == 0 and $this->continuousBuffer then do the first string - // with libsodium and subsequent strings with openssl or pure-PHP but again not a high priority - return function_exists('sodium_crypto_aead_chacha20poly1305_ietf_encrypt') && - $this->key_length == 32 && - (($this->usePoly1305 && !isset($this->poly1305Key) && $this->counter == 0) || $this->counter == 1) && - !$this->continuousBuffer; - case self::ENGINE_OPENSSL: - // OpenSSL 1.1.0 (released 25 Aug 2016) added support for chacha20. - // PHP didn't support OpenSSL 1.1.0 until 7.0.19 (11 May 2017) - - // if you attempt to provide openssl with a 128 bit key (as opposed to a 256 bit key) openssl will null - // pad the key to 256 bits and still use the expansion constant for 256-bit keys. the fact that - // openssl treats the IV as both the counter and nonce, however, let's us use openssl in continuous mode - // whereas libsodium does not - if ($this->key_length != 32) { - return false; - } - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Encrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::crypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - $this->setup(); - - if ($this->engine == self::ENGINE_LIBSODIUM) { - return $this->encrypt_with_libsodium($plaintext); - } - - return parent::encrypt($plaintext); - } - - /** - * Decrypts a message. - * - * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). - * At least if the continuous buffer is disabled. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::crypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - $this->setup(); - - if ($this->engine == self::ENGINE_LIBSODIUM) { - return $this->decrypt_with_libsodium($ciphertext); - } - - return parent::decrypt($ciphertext); - } - - /** - * Encrypts a message with libsodium - * - * @see self::encrypt() - * @param string $plaintext - * @return string $text - */ - private function encrypt_with_libsodium($plaintext) - { - $params = [$plaintext, $this->aad, $this->nonce, $this->key]; - $ciphertext = strlen($this->nonce) == 8 ? - sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : - sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); - if (!$this->usePoly1305) { - return substr($ciphertext, 0, strlen($plaintext)); - } - - $newciphertext = substr($ciphertext, 0, strlen($plaintext)); - - $this->newtag = $this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12 ? - substr($ciphertext, strlen($plaintext)) : - $this->poly1305($newciphertext); - - return $newciphertext; - } - - /** - * Decrypts a message with libsodium - * - * @see self::decrypt() - * @param string $ciphertext - * @return string $text - */ - private function decrypt_with_libsodium($ciphertext) - { - $params = [$ciphertext, $this->aad, $this->nonce, $this->key]; - - if (isset($this->poly1305Key)) { - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - if ($this->usingGeneratedPoly1305Key && strlen($this->nonce) == 12) { - $plaintext = sodium_crypto_aead_chacha20poly1305_ietf_decrypt(...$params); - $this->oldtag = false; - if ($plaintext === false) { - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - return $plaintext; - } - $newtag = $this->poly1305($ciphertext); - if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { - $this->oldtag = false; - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - $this->oldtag = false; - } - - $plaintext = strlen($this->nonce) == 8 ? - sodium_crypto_aead_chacha20poly1305_encrypt(...$params) : - sodium_crypto_aead_chacha20poly1305_ietf_encrypt(...$params); - - return substr($plaintext, 0, strlen($ciphertext)); - } - - /** - * Sets the nonce. - * - * @param string $nonce - */ - public function setNonce($nonce) - { - if (!is_string($nonce)) { - throw new \UnexpectedValueException('The nonce should be a string'); - } - - /* - from https://tools.ietf.org/html/rfc7539#page-7 - - "Note also that the original ChaCha had a 64-bit nonce and 64-bit - block count. We have modified this here to be more consistent with - recommendations in Section 3.2 of [RFC5116]." - */ - switch (strlen($nonce)) { - case 8: // 64 bits - case 12: // 96 bits - break; - default: - throw new \LengthException('Nonce of size ' . strlen($nonce) . ' not supported by this algorithm. Only 64-bit nonces or 96-bit nonces are supported'); - } - - $this->nonce = $nonce; - $this->changed = true; - $this->setEngine(); - } - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setNonce() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * @see self::setKey() - * @see self::setNonce() - * @see self::disableContinuousBuffer() - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; - - $this->changed = $this->nonIVChanged = false; - - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - if ($this->usePoly1305 && !isset($this->poly1305Key)) { - $this->usingGeneratedPoly1305Key = true; - if ($this->engine == self::ENGINE_LIBSODIUM) { - return; - } - $this->createPoly1305Key(); - } - - $key = $this->key; - if (strlen($key) == 16) { - $constant = 'expand 16-byte k'; - $key .= $key; - } else { - $constant = 'expand 32-byte k'; - } - - $this->p1 = $constant . $key; - $this->p2 = $this->nonce; - if (strlen($this->nonce) == 8) { - $this->p2 = "\0\0\0\0" . $this->p2; - } - } - - /** - * The quarterround function - * - * @param int $a - * @param int $b - * @param int $c - * @param int $d - */ - protected static function quarterRound(&$a, &$b, &$c, &$d) - { - // in https://datatracker.ietf.org/doc/html/rfc7539#section-2.1 the addition, - // xor'ing and rotation are all on the same line so i'm keeping it on the same - // line here as well - // @codingStandardsIgnoreStart - $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 16); - $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 12); - $a+= $b; $d = self::leftRotate(intval($d) ^ intval($a), 8); - $c+= $d; $b = self::leftRotate(intval($b) ^ intval($c), 7); - // @codingStandardsIgnoreEnd - } - - /** - * The doubleround function - * - * @param int $x0 (by reference) - * @param int $x1 (by reference) - * @param int $x2 (by reference) - * @param int $x3 (by reference) - * @param int $x4 (by reference) - * @param int $x5 (by reference) - * @param int $x6 (by reference) - * @param int $x7 (by reference) - * @param int $x8 (by reference) - * @param int $x9 (by reference) - * @param int $x10 (by reference) - * @param int $x11 (by reference) - * @param int $x12 (by reference) - * @param int $x13 (by reference) - * @param int $x14 (by reference) - * @param int $x15 (by reference) - */ - protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) - { - // columnRound - static::quarterRound($x0, $x4, $x8, $x12); - static::quarterRound($x1, $x5, $x9, $x13); - static::quarterRound($x2, $x6, $x10, $x14); - static::quarterRound($x3, $x7, $x11, $x15); - // rowRound - static::quarterRound($x0, $x5, $x10, $x15); - static::quarterRound($x1, $x6, $x11, $x12); - static::quarterRound($x2, $x7, $x8, $x13); - static::quarterRound($x3, $x4, $x9, $x14); - } - - /** - * The Salsa20 hash function function - * - * On my laptop this loop unrolled / function dereferenced version of parent::salsa20 encrypts 1mb of text in - * 0.65s vs the 0.85s that it takes with the parent method. - * - * If we were free to assume that the host OS would always be 64-bits then the if condition in leftRotate could - * be eliminated and we could knock this done to 0.60s. - * - * For comparison purposes, RC4 takes 0.16s and AES in CTR mode with the Eval engine takes 0.48s. - * AES in CTR mode with the PHP engine takes 1.19s. Salsa20 / ChaCha20 do not benefit as much from the Eval - * approach due to the fact that there are a lot less variables to de-reference, fewer loops to unroll, etc - * - * @param string $x - */ - protected static function salsa20($x) - { - list(, $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15) = unpack('V*', $x); - $z0 = $x0; - $z1 = $x1; - $z2 = $x2; - $z3 = $x3; - $z4 = $x4; - $z5 = $x5; - $z6 = $x6; - $z7 = $x7; - $z8 = $x8; - $z9 = $x9; - $z10 = $x10; - $z11 = $x11; - $z12 = $x12; - $z13 = $x13; - $z14 = $x14; - $z15 = $x15; - - // @codingStandardsIgnoreStart - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - - // columnRound - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 16); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 12); - $x0+= $x4; $x12 = self::leftRotate(intval($x12) ^ intval($x0), 8); - $x8+= $x12; $x4 = self::leftRotate(intval($x4) ^ intval($x8), 7); - - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 16); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 12); - $x1+= $x5; $x13 = self::leftRotate(intval($x13) ^ intval($x1), 8); - $x9+= $x13; $x5 = self::leftRotate(intval($x5) ^ intval($x9), 7); - - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 16); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 12); - $x2+= $x6; $x14 = self::leftRotate(intval($x14) ^ intval($x2), 8); - $x10+= $x14; $x6 = self::leftRotate(intval($x6) ^ intval($x10), 7); - - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 16); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 12); - $x3+= $x7; $x15 = self::leftRotate(intval($x15) ^ intval($x3), 8); - $x11+= $x15; $x7 = self::leftRotate(intval($x7) ^ intval($x11), 7); - - // rowRound - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 16); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 12); - $x0+= $x5; $x15 = self::leftRotate(intval($x15) ^ intval($x0), 8); - $x10+= $x15; $x5 = self::leftRotate(intval($x5) ^ intval($x10), 7); - - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 16); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 12); - $x1+= $x6; $x12 = self::leftRotate(intval($x12) ^ intval($x1), 8); - $x11+= $x12; $x6 = self::leftRotate(intval($x6) ^ intval($x11), 7); - - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 16); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 12); - $x2+= $x7; $x13 = self::leftRotate(intval($x13) ^ intval($x2), 8); - $x8+= $x13; $x7 = self::leftRotate(intval($x7) ^ intval($x8), 7); - - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 16); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 12); - $x3+= $x4; $x14 = self::leftRotate(intval($x14) ^ intval($x3), 8); - $x9+= $x14; $x4 = self::leftRotate(intval($x4) ^ intval($x9), 7); - // @codingStandardsIgnoreEnd - - $x0 += $z0; - $x1 += $z1; - $x2 += $z2; - $x3 += $z3; - $x4 += $z4; - $x5 += $z5; - $x6 += $z6; - $x7 += $z7; - $x8 += $z8; - $x9 += $z9; - $x10 += $z10; - $x11 += $z11; - $x12 += $z12; - $x13 += $z13; - $x14 += $z14; - $x15 += $z15; - - return pack('V*', $x0, $x1, $x2, $x3, $x4, $x5, $x6, $x7, $x8, $x9, $x10, $x11, $x12, $x13, $x14, $x15); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php deleted file mode 100644 index 09eb5b1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/AsymmetricKey.php +++ /dev/null @@ -1,581 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\RSA; -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Math\BigInteger; - -/** - * Base Class for all asymmetric cipher classes - * - * @author Jim Wigginton - */ -abstract class AsymmetricKey -{ - /** - * Precomputed Zero - * - * @var \phpseclib3\Math\BigInteger - */ - protected static $zero; - - /** - * Precomputed One - * - * @var \phpseclib3\Math\BigInteger - */ - protected static $one; - - /** - * Format of the loaded key - * - * @var string - */ - protected $format; - - /** - * Hash function - * - * @var \phpseclib3\Crypt\Hash - */ - protected $hash; - - /** - * HMAC function - * - * @var \phpseclib3\Crypt\Hash - */ - private $hmac; - - /** - * Supported plugins (lower case) - * - * @see self::initialize_static_variables() - * @var array - */ - private static $plugins = []; - - /** - * Invisible plugins - * - * @see self::initialize_static_variables() - * @var array - */ - private static $invisiblePlugins = []; - - /** - * Available Engines - * - * @var boolean[] - */ - protected static $engines = []; - - /** - * Key Comment - * - * @var null|string - */ - private $comment; - - /** - * @param string $type - * @return array|string - */ - abstract public function toString($type, array $options = []); - - /** - * The constructor - */ - protected function __construct() - { - self::initialize_static_variables(); - - $this->hash = new Hash('sha256'); - $this->hmac = new Hash('sha256'); - } - - /** - * Initialize static variables - */ - protected static function initialize_static_variables() - { - if (!isset(self::$zero)) { - self::$zero = new BigInteger(0); - self::$one = new BigInteger(1); - } - - self::loadPlugins('Keys'); - if (static::ALGORITHM != 'RSA' && static::ALGORITHM != 'DH') { - self::loadPlugins('Signature'); - } - } - - /** - * Load the key - * - * @param string $key - * @param string $password optional - * @return \phpseclib3\Crypt\Common\PublicKey|\phpseclib3\Crypt\Common\PrivateKey - */ - public static function load($key, $password = false) - { - self::initialize_static_variables(); - - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('load() should not be called from final classes (' . static::class . ')'); - } - - $components = false; - foreach (self::$plugins[static::ALGORITHM]['Keys'] as $format) { - if (isset(self::$invisiblePlugins[static::ALGORITHM]) && in_array($format, self::$invisiblePlugins[static::ALGORITHM])) { - continue; - } - try { - $components = $format::load($key, $password); - } catch (\Exception $e) { - $components = false; - } - if ($components !== false) { - break; - } - } - - if ($components === false) { - throw new NoKeyLoadedException('Unable to read key'); - } - - $components['format'] = $format; - $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; - $comment = isset($components['comment']) ? $components['comment'] : null; - $new = static::onLoad($components); - $new->format = $format; - $new->comment = $comment; - return $new instanceof PrivateKey ? - $new->withPassword($password) : - $new; - } - - /** - * Loads a private key - * - * @return PrivateKey - * @param string|array $key - * @param string $password optional - */ - public static function loadPrivateKey($key, $password = '') - { - $key = self::load($key, $password); - if (!$key instanceof PrivateKey) { - throw new NoKeyLoadedException('The key that was loaded was not a private key'); - } - return $key; - } - - /** - * Loads a public key - * - * @return PublicKey - * @param string|array $key - */ - public static function loadPublicKey($key) - { - $key = self::load($key); - if (!$key instanceof PublicKey) { - throw new NoKeyLoadedException('The key that was loaded was not a public key'); - } - return $key; - } - - /** - * Loads parameters - * - * @return AsymmetricKey - * @param string|array $key - */ - public static function loadParameters($key) - { - $key = self::load($key); - if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { - throw new NoKeyLoadedException('The key that was loaded was not a parameter'); - } - return $key; - } - - /** - * Load the key, assuming a specific format - * - * @param string $type - * @param string $key - * @param string $password optional - * @return static - */ - public static function loadFormat($type, $key, $password = false) - { - self::initialize_static_variables(); - - $components = false; - $format = strtolower($type); - if (isset(self::$plugins[static::ALGORITHM]['Keys'][$format])) { - $format = self::$plugins[static::ALGORITHM]['Keys'][$format]; - $components = $format::load($key, $password); - } - - if ($components === false) { - throw new NoKeyLoadedException('Unable to read key'); - } - - $components['format'] = $format; - $components['secret'] = isset($components['secret']) ? $components['secret'] : ''; - - $new = static::onLoad($components); - $new->format = $format; - return $new instanceof PrivateKey ? - $new->withPassword($password) : - $new; - } - - /** - * Loads a private key - * - * @return PrivateKey - * @param string $type - * @param string $key - * @param string $password optional - */ - public static function loadPrivateKeyFormat($type, $key, $password = false) - { - $key = self::loadFormat($type, $key, $password); - if (!$key instanceof PrivateKey) { - throw new NoKeyLoadedException('The key that was loaded was not a private key'); - } - return $key; - } - - /** - * Loads a public key - * - * @return PublicKey - * @param string $type - * @param string $key - */ - public static function loadPublicKeyFormat($type, $key) - { - $key = self::loadFormat($type, $key); - if (!$key instanceof PublicKey) { - throw new NoKeyLoadedException('The key that was loaded was not a public key'); - } - return $key; - } - - /** - * Loads parameters - * - * @return AsymmetricKey - * @param string $type - * @param string|array $key - */ - public static function loadParametersFormat($type, $key) - { - $key = self::loadFormat($type, $key); - if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { - throw new NoKeyLoadedException('The key that was loaded was not a parameter'); - } - return $key; - } - - /** - * Validate Plugin - * - * @param string $format - * @param string $type - * @param string $method optional - * @return mixed - */ - protected static function validatePlugin($format, $type, $method = null) - { - $type = strtolower($type); - if (!isset(self::$plugins[static::ALGORITHM][$format][$type])) { - throw new UnsupportedFormatException("$type is not a supported format"); - } - $type = self::$plugins[static::ALGORITHM][$format][$type]; - if (isset($method) && !method_exists($type, $method)) { - throw new UnsupportedFormatException("$type does not implement $method"); - } - - return $type; - } - - /** - * Load Plugins - * - * @param string $format - */ - private static function loadPlugins($format) - { - if (!isset(self::$plugins[static::ALGORITHM][$format])) { - self::$plugins[static::ALGORITHM][$format] = []; - foreach (new \DirectoryIterator(__DIR__ . '/../' . static::ALGORITHM . '/Formats/' . $format . '/') as $file) { - if ($file->getExtension() != 'php') { - continue; - } - $name = $file->getBasename('.php'); - if ($name[0] == '.') { - continue; - } - $type = 'phpseclib3\Crypt\\' . static::ALGORITHM . '\\Formats\\' . $format . '\\' . $name; - $reflect = new \ReflectionClass($type); - if ($reflect->isTrait()) { - continue; - } - self::$plugins[static::ALGORITHM][$format][strtolower($name)] = $type; - if ($reflect->hasConstant('IS_INVISIBLE')) { - self::$invisiblePlugins[static::ALGORITHM][] = $type; - } - } - } - } - - /** - * Returns a list of supported formats. - * - * @return array - */ - public static function getSupportedKeyFormats() - { - self::initialize_static_variables(); - - return self::$plugins[static::ALGORITHM]['Keys']; - } - - /** - * Add a fileformat plugin - * - * The plugin needs to either already be loaded or be auto-loadable. - * Loading a plugin whose shortname overwrite an existing shortname will overwrite the old plugin. - * - * @see self::load() - * @param string $fullname - * @return bool - */ - public static function addFileFormat($fullname) - { - self::initialize_static_variables(); - - if (class_exists($fullname)) { - $meta = new \ReflectionClass($fullname); - $shortname = $meta->getShortName(); - self::$plugins[static::ALGORITHM]['Keys'][strtolower($shortname)] = $fullname; - if ($meta->hasConstant('IS_INVISIBLE')) { - self::$invisiblePlugins[static::ALGORITHM][] = strtolower($shortname); - } - } - } - - /** - * Returns the format of the loaded key. - * - * If the key that was loaded wasn't in a valid or if the key was auto-generated - * with RSA::createKey() then this will throw an exception. - * - * @see self::load() - * @return mixed - */ - public function getLoadedFormat() - { - if (empty($this->format)) { - throw new NoKeyLoadedException('This key was created with createKey - it was not loaded with load. Therefore there is no "loaded format"'); - } - - $meta = new \ReflectionClass($this->format); - return $meta->getShortName(); - } - - /** - * Returns the key's comment - * - * Not all key formats support comments. If you want to set a comment use toString() - * - * @return null|string - */ - public function getComment() - { - return $this->comment; - } - - /** - * Tests engine validity - * - */ - public static function useBestEngine() - { - static::$engines = [ - 'PHP' => true, - 'OpenSSL' => extension_loaded('openssl'), - // this test can be satisfied by either of the following: - // http://php.net/manual/en/book.sodium.php - // https://github.com/paragonie/sodium_compat - 'libsodium' => function_exists('sodium_crypto_sign_keypair') - ]; - - return static::$engines; - } - - /** - * Flag to use internal engine only (useful for unit testing) - * - */ - public static function useInternalEngine() - { - static::$engines = [ - 'PHP' => true, - 'OpenSSL' => false, - 'libsodium' => false - ]; - } - - /** - * __toString() magic method - * - * @return string - */ - public function __toString() - { - return $this->toString('PKCS8'); - } - - /** - * Determines which hashing function should be used - * - * @param string $hash - */ - public function withHash($hash) - { - $new = clone $this; - - $new->hash = new Hash($hash); - $new->hmac = new Hash($hash); - - return $new; - } - - /** - * Returns the hash algorithm currently being used - * - */ - public function getHash() - { - return clone $this->hash; - } - - /** - * Compute the pseudorandom k for signature generation, - * using the process specified for deterministic DSA. - * - * @param string $h1 - * @return string - */ - protected function computek($h1) - { - $v = str_repeat("\1", strlen($h1)); - - $k = str_repeat("\0", strlen($h1)); - - $x = $this->int2octets($this->x); - $h1 = $this->bits2octets($h1); - - $this->hmac->setKey($k); - $k = $this->hmac->hash($v . "\0" . $x . $h1); - $this->hmac->setKey($k); - $v = $this->hmac->hash($v); - $k = $this->hmac->hash($v . "\1" . $x . $h1); - $this->hmac->setKey($k); - $v = $this->hmac->hash($v); - - $qlen = $this->q->getLengthInBytes(); - - while (true) { - $t = ''; - while (strlen($t) < $qlen) { - $v = $this->hmac->hash($v); - $t = $t . $v; - } - $k = $this->bits2int($t); - - if (!$k->equals(self::$zero) && $k->compare($this->q) < 0) { - break; - } - $k = $this->hmac->hash($v . "\0"); - $this->hmac->setKey($k); - $v = $this->hmac->hash($v); - } - - return $k; - } - - /** - * Integer to Octet String - * - * @param \phpseclib3\Math\BigInteger $v - * @return string - */ - private function int2octets($v) - { - $out = $v->toBytes(); - $rolen = $this->q->getLengthInBytes(); - if (strlen($out) < $rolen) { - return str_pad($out, $rolen, "\0", STR_PAD_LEFT); - } elseif (strlen($out) > $rolen) { - return substr($out, -$rolen); - } else { - return $out; - } - } - - /** - * Bit String to Integer - * - * @param string $in - * @return \phpseclib3\Math\BigInteger - */ - protected function bits2int($in) - { - $v = new BigInteger($in, 256); - $vlen = strlen($in) << 3; - $qlen = $this->q->getLength(); - if ($vlen > $qlen) { - return $v->bitwise_rightShift($vlen - $qlen); - } - return $v; - } - - /** - * Bit String to Octet String - * - * @param string $in - * @return string - */ - private function bits2octets($in) - { - $z1 = $this->bits2int($in); - $z2 = $z1->subtract($this->q); - return $z2->compare(self::$zero) < 0 ? - $this->int2octets($z1) : - $this->int2octets($z2); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php deleted file mode 100644 index b2642be..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/BlockCipher.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * Base Class for all block cipher classes - * - * @author Jim Wigginton - */ -abstract class BlockCipher extends SymmetricKey -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php deleted file mode 100644 index 4c761b8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/JWK.php +++ /dev/null @@ -1,69 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; - -/** - * JSON Web Key Formatted Key Handler - * - * @author Jim Wigginton - */ -abstract class JWK -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $key = preg_replace('#\s#', '', $key); // remove whitespace - - if (PHP_VERSION_ID >= 73000) { - $key = json_decode($key, null, 512, JSON_THROW_ON_ERROR); - } else { - $key = json_decode($key); - if (!$key) { - throw new \RuntimeException('Unable to decode JSON'); - } - } - - if (isset($key->kty)) { - return $key; - } - - if (count($key->keys) != 1) { - throw new \RuntimeException('Although the JWK key format supports multiple keys phpseclib does not'); - } - - return $key->keys[0]; - } - - /** - * Wrap a key appropriately - * - * @return string - */ - protected static function wrapKey(array $key, array $options) - { - return json_encode(['keys' => [$key + $options]]); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php deleted file mode 100644 index fe3d85b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,220 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\Random; - -/** - * OpenSSH Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class OpenSSH -{ - /** - * Default comment - * - * @var string - */ - protected static $comment = 'phpseclib-generated-key'; - - /** - * Binary key flag - * - * @var bool - */ - protected static $binary = false; - - /** - * Sets the default comment - * - * @param string $comment - */ - public static function setComment($comment) - { - self::$comment = str_replace(["\r", "\n"], '', $comment); - } - - /** - * Break a public or private key down into its constituent components - * - * $type can be either ssh-dss or ssh-rsa - * - * @param string $key - * @param string $password - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - // key format is described here: - // https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.key?annotate=HEAD - - if (strpos($key, 'BEGIN OPENSSH PRIVATE KEY') !== false) { - $key = preg_replace('#(?:^-.*?-[\r\n]*$)|\s#ms', '', $key); - $key = Strings::base64_decode($key); - $magic = Strings::shift($key, 15); - if ($magic != "openssh-key-v1\0") { - throw new \RuntimeException('Expected openssh-key-v1'); - } - list($ciphername, $kdfname, $kdfoptions, $numKeys) = Strings::unpackSSH2('sssN', $key); - if ($numKeys != 1) { - // if we wanted to support multiple keys we could update PublicKeyLoader to preview what the # of keys - // would be; it'd then call Common\Keys\OpenSSH.php::load() and get the paddedKey. it'd then pass - // that to the appropriate key loading parser $numKey times or something - throw new \RuntimeException('Although the OpenSSH private key format supports multiple keys phpseclib does not'); - } - switch ($ciphername) { - case 'none': - break; - case 'aes256-ctr': - if ($kdfname != 'bcrypt') { - throw new \RuntimeException('Only the bcrypt kdf is supported (' . $kdfname . ' encountered)'); - } - list($salt, $rounds) = Strings::unpackSSH2('sN', $kdfoptions); - $crypto = new AES('ctr'); - //$crypto->setKeyLength(256); - //$crypto->disablePadding(); - $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); - break; - default: - throw new \RuntimeException('The only supported cipherse are: none, aes256-ctr (' . $ciphername . ' is being used)'); - } - - list($publicKey, $paddedKey) = Strings::unpackSSH2('ss', $key); - list($type) = Strings::unpackSSH2('s', $publicKey); - if (isset($crypto)) { - $paddedKey = $crypto->decrypt($paddedKey); - } - list($checkint1, $checkint2) = Strings::unpackSSH2('NN', $paddedKey); - // any leftover bytes in $paddedKey are for padding? but they should be sequential bytes. eg. 1, 2, 3, etc. - if ($checkint1 != $checkint2) { - throw new \RuntimeException('The two checkints do not match'); - } - self::checkType($type); - - return compact('type', 'publicKey', 'paddedKey'); - } - - $parts = explode(' ', $key, 3); - - if (!isset($parts[1])) { - $key = base64_decode($parts[0]); - $comment = false; - } else { - $asciiType = $parts[0]; - self::checkType($parts[0]); - $key = base64_decode($parts[1]); - $comment = isset($parts[2]) ? $parts[2] : false; - } - if ($key === false) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - list($type) = Strings::unpackSSH2('s', $key); - self::checkType($type); - if (isset($asciiType) && $asciiType != $type) { - throw new \RuntimeException('Two different types of keys are claimed: ' . $asciiType . ' and ' . $type); - } - if (strlen($key) <= 4) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $publicKey = $key; - - return compact('type', 'publicKey', 'comment'); - } - - /** - * Toggle between binary and printable keys - * - * Printable keys are what are generated by default. These are the ones that go in - * $HOME/.ssh/authorized_key. - * - * @param bool $enabled - */ - public static function setBinaryOutput($enabled) - { - self::$binary = $enabled; - } - - /** - * Checks to see if the type is valid - * - * @param string $candidate - */ - private static function checkType($candidate) - { - if (!in_array($candidate, static::$types)) { - throw new \RuntimeException("The key type ($candidate) is not equal to: " . implode(',', static::$types)); - } - } - - /** - * Wrap a private key appropriately - * - * @param string $publicKey - * @param string $privateKey - * @param string $password - * @param array $options - * @return string - */ - protected static function wrapPrivateKey($publicKey, $privateKey, $password, $options) - { - list(, $checkint) = unpack('N', Random::string(4)); - - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $paddedKey = Strings::packSSH2('NN', $checkint, $checkint) . - $privateKey . - Strings::packSSH2('s', $comment); - - $usesEncryption = !empty($password) && is_string($password); - - /* - from http://tools.ietf.org/html/rfc4253#section-6 : - - Note that the length of the concatenation of 'packet_length', - 'padding_length', 'payload', and 'random padding' MUST be a multiple - of the cipher block size or 8, whichever is larger. - */ - $blockSize = $usesEncryption ? 16 : 8; - $paddingLength = (($blockSize - 1) * strlen($paddedKey)) % $blockSize; - for ($i = 1; $i <= $paddingLength; $i++) { - $paddedKey .= chr($i); - } - if (!$usesEncryption) { - $key = Strings::packSSH2('sssNss', 'none', 'none', '', 1, $publicKey, $paddedKey); - } else { - $rounds = isset($options['rounds']) ? $options['rounds'] : 16; - $salt = Random::string(16); - $kdfoptions = Strings::packSSH2('sN', $salt, $rounds); - $crypto = new AES('ctr'); - $crypto->setPassword($password, 'bcrypt', $salt, $rounds, 32); - $paddedKey = $crypto->encrypt($paddedKey); - $key = Strings::packSSH2('sssNss', 'aes256-ctr', 'bcrypt', $kdfoptions, 1, $publicKey, $paddedKey); - } - $key = "openssh-key-v1\0$key"; - - return "-----BEGIN OPENSSH PRIVATE KEY-----\n" . - chunk_split(Strings::base64_encode($key), 70, "\n") . - "-----END OPENSSH PRIVATE KEY-----\n"; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php deleted file mode 100644 index 0219400..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS.php +++ /dev/null @@ -1,72 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -/** - * PKCS1 Formatted Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS -{ - /** - * Auto-detect the format - */ - const MODE_ANY = 0; - /** - * Require base64-encoded PEM's be supplied - */ - const MODE_PEM = 1; - /** - * Require raw DER's be supplied - */ - const MODE_DER = 2; - /**#@-*/ - - /** - * Is the key a base-64 encoded PEM, DER or should it be auto-detected? - * - * @var int - */ - protected static $format = self::MODE_ANY; - - /** - * Require base64-encoded PEM's be supplied - * - */ - public static function requirePEM() - { - self::$format = self::MODE_PEM; - } - - /** - * Require raw DER's be supplied - * - */ - public static function requireDER() - { - self::$format = self::MODE_DER; - } - - /** - * Accept any format and auto detect the format - * - * This is the default setting - * - */ - public static function requireAny() - { - self::$format = self::MODE_ANY; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php deleted file mode 100644 index 4c639c0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,209 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\DES; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\TripleDES; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\File\ASN1; - -/** - * PKCS1 Formatted Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS1 extends PKCS -{ - /** - * Default encryption algorithm - * - * @var string - */ - private static $defaultEncryptionAlgorithm = 'AES-128-CBC'; - - /** - * Sets the default encryption algorithm - * - * @param string $algo - */ - public static function setEncryptionAlgorithm($algo) - { - self::$defaultEncryptionAlgorithm = $algo; - } - - /** - * Returns the mode constant corresponding to the mode string - * - * @param string $mode - * @return int - * @throws \UnexpectedValueException if the block cipher mode is unsupported - */ - private static function getEncryptionMode($mode) - { - switch ($mode) { - case 'CBC': - case 'ECB': - case 'CFB': - case 'OFB': - case 'CTR': - return $mode; - } - throw new \UnexpectedValueException('Unsupported block cipher mode of operation'); - } - - /** - * Returns a cipher object corresponding to a string - * - * @param string $algo - * @return string - * @throws \UnexpectedValueException if the encryption algorithm is unsupported - */ - private static function getEncryptionObject($algo) - { - $modes = '(CBC|ECB|CFB|OFB|CTR)'; - switch (true) { - case preg_match("#^AES-(128|192|256)-$modes$#", $algo, $matches): - $cipher = new AES(self::getEncryptionMode($matches[2])); - $cipher->setKeyLength($matches[1]); - return $cipher; - case preg_match("#^DES-EDE3-$modes$#", $algo, $matches): - return new TripleDES(self::getEncryptionMode($matches[1])); - case preg_match("#^DES-$modes$#", $algo, $matches): - return new DES(self::getEncryptionMode($matches[1])); - default: - throw new UnsupportedAlgorithmException($algo . ' is not a supported algorithm'); - } - } - - /** - * Generate a symmetric key for PKCS#1 keys - * - * @param string $password - * @param string $iv - * @param int $length - * @return string - */ - private static function generateSymmetricKey($password, $iv, $length) - { - $symkey = ''; - $iv = substr($iv, 0, 8); - while (strlen($symkey) < $length) { - $symkey .= md5($symkey . $password . $iv, true); - } - return substr($symkey, 0, $length); - } - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - protected static function load($key, $password) - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - /* Although PKCS#1 proposes a format that public and private keys can use, encrypting them is - "outside the scope" of PKCS#1. PKCS#1 then refers you to PKCS#12 and PKCS#15 if you're wanting to - protect private keys, however, that's not what OpenSSL* does. OpenSSL protects private keys by adding - two new "fields" to the key - DEK-Info and Proc-Type. These fields are discussed here: - - http://tools.ietf.org/html/rfc1421#section-4.6.1.1 - http://tools.ietf.org/html/rfc1421#section-4.6.1.3 - - DES-EDE3-CBC as an algorithm, however, is not discussed anywhere, near as I can tell. - DES-CBC and DES-EDE are discussed in RFC1423, however, DES-EDE3-CBC isn't, nor is its key derivation - function. As is, the definitive authority on this encoding scheme isn't the IETF but rather OpenSSL's - own implementation. ie. the implementation *is* the standard and any bugs that may exist in that - implementation are part of the standard, as well. - - * OpenSSL is the de facto standard. It's utilized by OpenSSH and other projects */ - if (preg_match('#DEK-Info: (.+),(.+)#', $key, $matches)) { - $iv = Strings::hex2bin(trim($matches[2])); - // remove the Proc-Type / DEK-Info sections as they're no longer needed - $key = preg_replace('#^(?:Proc-Type|DEK-Info): .*#m', '', $key); - $ciphertext = ASN1::extractBER($key); - if ($ciphertext === false) { - $ciphertext = $key; - } - $crypto = self::getEncryptionObject($matches[1]); - $crypto->setKey(self::generateSymmetricKey($password, $iv, $crypto->getKeyLength() >> 3)); - $crypto->setIV($iv); - $key = $crypto->decrypt($ciphertext); - } else { - if (self::$format != self::MODE_DER) { - $decoded = ASN1::extractBER($key); - if ($decoded !== false) { - $key = $decoded; - } elseif (self::$format == self::MODE_PEM) { - throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); - } - } - } - - return $key; - } - - /** - * Wrap a private key appropriately - * - * @param string $key - * @param string $type - * @param string $password - * @param array $options optional - * @return string - */ - protected static function wrapPrivateKey($key, $type, $password, array $options = []) - { - if (empty($password) || !is_string($password)) { - return "-----BEGIN $type PRIVATE KEY-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END $type PRIVATE KEY-----"; - } - - $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; - - $cipher = self::getEncryptionObject($encryptionAlgorithm); - $iv = Random::string($cipher->getBlockLength() >> 3); - $cipher->setKey(self::generateSymmetricKey($password, $iv, $cipher->getKeyLength() >> 3)); - $cipher->setIV($iv); - $iv = strtoupper(Strings::bin2hex($iv)); - return "-----BEGIN $type PRIVATE KEY-----\r\n" . - "Proc-Type: 4,ENCRYPTED\r\n" . - "DEK-Info: " . $encryptionAlgorithm . ",$iv\r\n" . - "\r\n" . - chunk_split(Strings::base64_encode($cipher->encrypt($key)), 64) . - "-----END $type PRIVATE KEY-----"; - } - - /** - * Wrap a public key appropriately - * - * @param string $key - * @param string $type - * @return string - */ - protected static function wrapPublicKey($key, $type) - { - return "-----BEGIN $type PUBLIC KEY-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END $type PUBLIC KEY-----"; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php deleted file mode 100644 index 7aa5548..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,725 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\DES; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RC2; -use phpseclib3\Crypt\RC4; -use phpseclib3\Crypt\TripleDES; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; - -/** - * PKCS#8 Formatted Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS8 extends PKCS -{ - /** - * Default encryption algorithm - * - * @var string - */ - private static $defaultEncryptionAlgorithm = 'id-PBES2'; - - /** - * Default encryption scheme - * - * Only used when defaultEncryptionAlgorithm is id-PBES2 - * - * @var string - */ - private static $defaultEncryptionScheme = 'aes128-CBC-PAD'; - - /** - * Default PRF - * - * Only used when defaultEncryptionAlgorithm is id-PBES2 - * - * @var string - */ - private static $defaultPRF = 'id-hmacWithSHA256'; - - /** - * Default Iteration Count - * - * @var int - */ - private static $defaultIterationCount = 2048; - - /** - * OIDs loaded - * - * @var bool - */ - private static $oidsLoaded = false; - - /** - * Sets the default encryption algorithm - * - * @param string $algo - */ - public static function setEncryptionAlgorithm($algo) - { - self::$defaultEncryptionAlgorithm = $algo; - } - - /** - * Sets the default encryption algorithm for PBES2 - * - * @param string $algo - */ - public static function setEncryptionScheme($algo) - { - self::$defaultEncryptionScheme = $algo; - } - - /** - * Sets the iteration count - * - * @param int $count - */ - public static function setIterationCount($count) - { - self::$defaultIterationCount = $count; - } - - /** - * Sets the PRF for PBES2 - * - * @param string $algo - */ - public static function setPRF($algo) - { - self::$defaultPRF = $algo; - } - - /** - * Returns a SymmetricKey object based on a PBES1 $algo - * - * @return \phpseclib3\Crypt\Common\SymmetricKey - * @param string $algo - */ - private static function getPBES1EncryptionObject($algo) - { - $algo = preg_match('#^pbeWith(?:MD2|MD5|SHA1|SHA)And(.*?)-CBC$#', $algo, $matches) ? - $matches[1] : - substr($algo, 13); // strlen('pbeWithSHAAnd') == 13 - - switch ($algo) { - case 'DES': - $cipher = new DES('cbc'); - break; - case 'RC2': - $cipher = new RC2('cbc'); - $cipher->setKeyLength(64); - break; - case '3-KeyTripleDES': - $cipher = new TripleDES('cbc'); - break; - case '2-KeyTripleDES': - $cipher = new TripleDES('cbc'); - $cipher->setKeyLength(128); - break; - case '128BitRC2': - $cipher = new RC2('cbc'); - $cipher->setKeyLength(128); - break; - case '40BitRC2': - $cipher = new RC2('cbc'); - $cipher->setKeyLength(40); - break; - case '128BitRC4': - $cipher = new RC4(); - $cipher->setKeyLength(128); - break; - case '40BitRC4': - $cipher = new RC4(); - $cipher->setKeyLength(40); - break; - default: - throw new UnsupportedAlgorithmException("$algo is not a supported algorithm"); - } - - return $cipher; - } - - /** - * Returns a hash based on a PBES1 $algo - * - * @return string - * @param string $algo - */ - private static function getPBES1Hash($algo) - { - if (preg_match('#^pbeWith(MD2|MD5|SHA1|SHA)And.*?-CBC$#', $algo, $matches)) { - return $matches[1] == 'SHA' ? 'sha1' : $matches[1]; - } - - return 'sha1'; - } - - /** - * Returns a KDF baesd on a PBES1 $algo - * - * @return string - * @param string $algo - */ - private static function getPBES1KDF($algo) - { - switch ($algo) { - case 'pbeWithMD2AndDES-CBC': - case 'pbeWithMD2AndRC2-CBC': - case 'pbeWithMD5AndDES-CBC': - case 'pbeWithMD5AndRC2-CBC': - case 'pbeWithSHA1AndDES-CBC': - case 'pbeWithSHA1AndRC2-CBC': - return 'pbkdf1'; - } - - return 'pkcs12'; - } - - /** - * Returns a SymmetricKey object baesd on a PBES2 $algo - * - * @return SymmetricKey - * @param string $algo - */ - private static function getPBES2EncryptionObject($algo) - { - switch ($algo) { - case 'desCBC': - $cipher = new DES('cbc'); - break; - case 'des-EDE3-CBC': - $cipher = new TripleDES('cbc'); - break; - case 'rc2CBC': - $cipher = new RC2('cbc'); - // in theory this can be changed - $cipher->setKeyLength(128); - break; - case 'rc5-CBC-PAD': - throw new UnsupportedAlgorithmException('rc5-CBC-PAD is not supported for PBES2 PKCS#8 keys'); - case 'aes128-CBC-PAD': - case 'aes192-CBC-PAD': - case 'aes256-CBC-PAD': - $cipher = new AES('cbc'); - $cipher->setKeyLength(substr($algo, 3, 3)); - break; - default: - throw new UnsupportedAlgorithmException("$algo is not supported"); - } - - return $cipher; - } - - /** - * Initialize static variables - * - */ - private static function initialize_static_variables() - { - if (!isset(static::$childOIDsLoaded)) { - throw new InsufficientSetupException('This class should not be called directly'); - } - - if (!static::$childOIDsLoaded) { - ASN1::loadOIDs(is_array(static::OID_NAME) ? - array_combine(static::OID_NAME, static::OID_VALUE) : - [static::OID_NAME => static::OID_VALUE]); - static::$childOIDsLoaded = true; - } - if (!self::$oidsLoaded) { - // from https://tools.ietf.org/html/rfc2898 - ASN1::loadOIDs([ - // PBES1 encryption schemes - 'pbeWithMD2AndDES-CBC' => '1.2.840.113549.1.5.1', - 'pbeWithMD2AndRC2-CBC' => '1.2.840.113549.1.5.4', - 'pbeWithMD5AndDES-CBC' => '1.2.840.113549.1.5.3', - 'pbeWithMD5AndRC2-CBC' => '1.2.840.113549.1.5.6', - 'pbeWithSHA1AndDES-CBC' => '1.2.840.113549.1.5.10', - 'pbeWithSHA1AndRC2-CBC' => '1.2.840.113549.1.5.11', - - // from PKCS#12: - // https://tools.ietf.org/html/rfc7292 - 'pbeWithSHAAnd128BitRC4' => '1.2.840.113549.1.12.1.1', - 'pbeWithSHAAnd40BitRC4' => '1.2.840.113549.1.12.1.2', - 'pbeWithSHAAnd3-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.3', - 'pbeWithSHAAnd2-KeyTripleDES-CBC' => '1.2.840.113549.1.12.1.4', - 'pbeWithSHAAnd128BitRC2-CBC' => '1.2.840.113549.1.12.1.5', - 'pbeWithSHAAnd40BitRC2-CBC' => '1.2.840.113549.1.12.1.6', - - 'id-PBKDF2' => '1.2.840.113549.1.5.12', - 'id-PBES2' => '1.2.840.113549.1.5.13', - 'id-PBMAC1' => '1.2.840.113549.1.5.14', - - // from PKCS#5 v2.1: - // http://www.rsa.com/rsalabs/pkcs/files/h11302-wp-pkcs5v2-1-password-based-cryptography-standard.pdf - 'id-hmacWithSHA1' => '1.2.840.113549.2.7', - 'id-hmacWithSHA224' => '1.2.840.113549.2.8', - 'id-hmacWithSHA256' => '1.2.840.113549.2.9', - 'id-hmacWithSHA384' => '1.2.840.113549.2.10', - 'id-hmacWithSHA512' => '1.2.840.113549.2.11', - 'id-hmacWithSHA512-224' => '1.2.840.113549.2.12', - 'id-hmacWithSHA512-256' => '1.2.840.113549.2.13', - - 'desCBC' => '1.3.14.3.2.7', - 'des-EDE3-CBC' => '1.2.840.113549.3.7', - 'rc2CBC' => '1.2.840.113549.3.2', - 'rc5-CBC-PAD' => '1.2.840.113549.3.9', - - 'aes128-CBC-PAD' => '2.16.840.1.101.3.4.1.2', - 'aes192-CBC-PAD' => '2.16.840.1.101.3.4.1.22', - 'aes256-CBC-PAD' => '2.16.840.1.101.3.4.1.42' - ]); - self::$oidsLoaded = true; - } - } - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - protected static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $isPublic = strpos($key, 'PUBLIC') !== false; - $isPrivate = strpos($key, 'PRIVATE') !== false; - - $decoded = self::preParse($key); - - $meta = []; - - $decrypted = ASN1::asn1map($decoded[0], Maps\EncryptedPrivateKeyInfo::MAP); - if (strlen($password) && is_array($decrypted)) { - $algorithm = $decrypted['encryptionAlgorithm']['algorithm']; - switch ($algorithm) { - // PBES1 - case 'pbeWithMD2AndDES-CBC': - case 'pbeWithMD2AndRC2-CBC': - case 'pbeWithMD5AndDES-CBC': - case 'pbeWithMD5AndRC2-CBC': - case 'pbeWithSHA1AndDES-CBC': - case 'pbeWithSHA1AndRC2-CBC': - case 'pbeWithSHAAnd3-KeyTripleDES-CBC': - case 'pbeWithSHAAnd2-KeyTripleDES-CBC': - case 'pbeWithSHAAnd128BitRC2-CBC': - case 'pbeWithSHAAnd40BitRC2-CBC': - case 'pbeWithSHAAnd128BitRC4': - case 'pbeWithSHAAnd40BitRC4': - $cipher = self::getPBES1EncryptionObject($algorithm); - $hash = self::getPBES1Hash($algorithm); - $kdf = self::getPBES1KDF($algorithm); - - $meta['meta']['algorithm'] = $algorithm; - - $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - if (!$temp) { - throw new \RuntimeException('Unable to decode BER'); - } - extract(ASN1::asn1map($temp[0], Maps\PBEParameter::MAP)); - $iterationCount = (int) $iterationCount->toString(); - $cipher->setPassword($password, $kdf, $hash, $salt, $iterationCount); - $key = $cipher->decrypt($decrypted['encryptedData']); - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER 2'); - } - - break; - case 'id-PBES2': - $meta['meta']['algorithm'] = $algorithm; - - $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - if (!$temp) { - throw new \RuntimeException('Unable to decode BER'); - } - $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); - extract($temp); - - $cipher = self::getPBES2EncryptionObject($encryptionScheme['algorithm']); - $meta['meta']['cipher'] = $encryptionScheme['algorithm']; - - $temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - if (!$temp) { - throw new \RuntimeException('Unable to decode BER'); - } - $temp = ASN1::asn1map($temp[0], Maps\PBES2params::MAP); - extract($temp); - - if (!$cipher instanceof RC2) { - $cipher->setIV($encryptionScheme['parameters']['octetString']); - } else { - $temp = ASN1::decodeBER($encryptionScheme['parameters']); - if (!$temp) { - throw new \RuntimeException('Unable to decode BER'); - } - extract(ASN1::asn1map($temp[0], Maps\RC2CBCParameter::MAP)); - $effectiveKeyLength = (int) $rc2ParametersVersion->toString(); - switch ($effectiveKeyLength) { - case 160: - $effectiveKeyLength = 40; - break; - case 120: - $effectiveKeyLength = 64; - break; - case 58: - $effectiveKeyLength = 128; - break; - //default: // should be >= 256 - } - $cipher->setIV($iv); - $cipher->setKeyLength($effectiveKeyLength); - } - - $meta['meta']['keyDerivationFunc'] = $keyDerivationFunc['algorithm']; - switch ($keyDerivationFunc['algorithm']) { - case 'id-PBKDF2': - $temp = ASN1::decodeBER($keyDerivationFunc['parameters']); - if (!$temp) { - throw new \RuntimeException('Unable to decode BER'); - } - $prf = ['algorithm' => 'id-hmacWithSHA1']; - $params = ASN1::asn1map($temp[0], Maps\PBKDF2params::MAP); - extract($params); - $meta['meta']['prf'] = $prf['algorithm']; - $hash = str_replace('-', '/', substr($prf['algorithm'], 11)); - $params = [ - $password, - 'pbkdf2', - $hash, - $salt, - (int) $iterationCount->toString() - ]; - if (isset($keyLength)) { - $params[] = (int) $keyLength->toString(); - } - $cipher->setPassword(...$params); - $key = $cipher->decrypt($decrypted['encryptedData']); - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER 3'); - } - break; - default: - throw new UnsupportedAlgorithmException('Only PBKDF2 is supported for PBES2 PKCS#8 keys'); - } - break; - case 'id-PBMAC1': - //$temp = ASN1::decodeBER($decrypted['encryptionAlgorithm']['parameters']); - //$value = ASN1::asn1map($temp[0], Maps\PBMAC1params::MAP); - // since i can't find any implementation that does PBMAC1 it is unsupported - throw new UnsupportedAlgorithmException('Only PBES1 and PBES2 PKCS#8 keys are supported.'); - // at this point we'll assume that the key conforms to PublicKeyInfo - } - } - - $private = ASN1::asn1map($decoded[0], Maps\OneAsymmetricKey::MAP); - if (is_array($private)) { - if ($isPublic) { - throw new \UnexpectedValueException('Human readable string claims public key but DER encoded string claims private key'); - } - - if (isset($private['privateKeyAlgorithm']['parameters']) && !$private['privateKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][1]['content'][1])) { - $temp = $decoded[0]['content'][1]['content'][1]; - $private['privateKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); - } - if (is_array(static::OID_NAME)) { - if (!in_array($private['privateKeyAlgorithm']['algorithm'], static::OID_NAME)) { - throw new UnsupportedAlgorithmException($private['privateKeyAlgorithm']['algorithm'] . ' is not a supported key type'); - } - } else { - if ($private['privateKeyAlgorithm']['algorithm'] != static::OID_NAME) { - throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $private['privateKeyAlgorithm']['algorithm'] . ' key'); - } - } - if (isset($private['publicKey'])) { - if ($private['publicKey'][0] != "\0") { - throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($private['publicKey'][0])); - } - $private['publicKey'] = substr($private['publicKey'], 1); - } - return $private + $meta; - } - - // EncryptedPrivateKeyInfo and PublicKeyInfo have largely identical "signatures". the only difference - // is that the former has an octet string and the later has a bit string. the first byte of a bit - // string represents the number of bits in the last byte that are to be ignored but, currently, - // bit strings wanting a non-zero amount of bits trimmed are not supported - $public = ASN1::asn1map($decoded[0], Maps\PublicKeyInfo::MAP); - - if (is_array($public)) { - if ($isPrivate) { - throw new \UnexpectedValueException('Human readable string claims private key but DER encoded string claims public key'); - } - - if ($public['publicKey'][0] != "\0") { - throw new \UnexpectedValueException('The first byte of the public key should be null - not ' . bin2hex($public['publicKey'][0])); - } - if (is_array(static::OID_NAME)) { - if (!in_array($public['publicKeyAlgorithm']['algorithm'], static::OID_NAME)) { - throw new UnsupportedAlgorithmException($public['publicKeyAlgorithm']['algorithm'] . ' is not a supported key type'); - } - } else { - if ($public['publicKeyAlgorithm']['algorithm'] != static::OID_NAME) { - throw new UnsupportedAlgorithmException('Only ' . static::OID_NAME . ' keys are supported; this is a ' . $public['publicKeyAlgorithm']['algorithm'] . ' key'); - } - } - if (isset($public['publicKeyAlgorithm']['parameters']) && !$public['publicKeyAlgorithm']['parameters'] instanceof ASN1\Element && isset($decoded[0]['content'][0]['content'][1])) { - $temp = $decoded[0]['content'][0]['content'][1]; - $public['publicKeyAlgorithm']['parameters'] = new ASN1\Element(substr($key, $temp['start'], $temp['length'])); - } - $public['publicKey'] = substr($public['publicKey'], 1); - return $public; - } - - throw new \RuntimeException('Unable to parse using either OneAsymmetricKey or PublicKeyInfo ASN1 maps'); - } - - /** - * Wrap a private key appropriately - * - * @param string $key - * @param string $attr - * @param mixed $params - * @param string $password - * @param string $oid optional - * @param string $publicKey optional - * @param array $options optional - * @return string - */ - protected static function wrapPrivateKey($key, $attr, $params, $password, $oid = null, $publicKey = '', array $options = []) - { - self::initialize_static_variables(); - - $key = [ - 'version' => 'v1', - 'privateKeyAlgorithm' => [ - 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid - ], - 'privateKey' => $key - ]; - if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { - $key['privateKeyAlgorithm']['parameters'] = $params; - } - if (!empty($attr)) { - $key['attributes'] = $attr; - } - if (!empty($publicKey)) { - $key['version'] = 'v2'; - $key['publicKey'] = $publicKey; - } - $key = ASN1::encodeDER($key, Maps\OneAsymmetricKey::MAP); - if (!empty($password) && is_string($password)) { - $salt = Random::string(8); - - $iterationCount = isset($options['iterationCount']) ? $options['iterationCount'] : self::$defaultIterationCount; - $encryptionAlgorithm = isset($options['encryptionAlgorithm']) ? $options['encryptionAlgorithm'] : self::$defaultEncryptionAlgorithm; - $encryptionScheme = isset($options['encryptionScheme']) ? $options['encryptionScheme'] : self::$defaultEncryptionScheme; - $prf = isset($options['PRF']) ? $options['PRF'] : self::$defaultPRF; - - if ($encryptionAlgorithm == 'id-PBES2') { - $crypto = self::getPBES2EncryptionObject($encryptionScheme); - $hash = str_replace('-', '/', substr($prf, 11)); - $kdf = 'pbkdf2'; - $iv = Random::string($crypto->getBlockLength() >> 3); - - $PBKDF2params = [ - 'salt' => $salt, - 'iterationCount' => $iterationCount, - 'prf' => ['algorithm' => $prf, 'parameters' => null] - ]; - $PBKDF2params = ASN1::encodeDER($PBKDF2params, Maps\PBKDF2params::MAP); - - if (!$crypto instanceof RC2) { - $params = ['octetString' => $iv]; - } else { - $params = [ - 'rc2ParametersVersion' => 58, - 'iv' => $iv - ]; - $params = ASN1::encodeDER($params, Maps\RC2CBCParameter::MAP); - $params = new ASN1\Element($params); - } - - $params = [ - 'keyDerivationFunc' => [ - 'algorithm' => 'id-PBKDF2', - 'parameters' => new ASN1\Element($PBKDF2params) - ], - 'encryptionScheme' => [ - 'algorithm' => $encryptionScheme, - 'parameters' => $params - ] - ]; - $params = ASN1::encodeDER($params, Maps\PBES2params::MAP); - - $crypto->setIV($iv); - } else { - $crypto = self::getPBES1EncryptionObject($encryptionAlgorithm); - $hash = self::getPBES1Hash($encryptionAlgorithm); - $kdf = self::getPBES1KDF($encryptionAlgorithm); - - $params = [ - 'salt' => $salt, - 'iterationCount' => $iterationCount - ]; - $params = ASN1::encodeDER($params, Maps\PBEParameter::MAP); - } - $crypto->setPassword($password, $kdf, $hash, $salt, $iterationCount); - $key = $crypto->encrypt($key); - - $key = [ - 'encryptionAlgorithm' => [ - 'algorithm' => $encryptionAlgorithm, - 'parameters' => new ASN1\Element($params) - ], - 'encryptedData' => $key - ]; - - $key = ASN1::encodeDER($key, Maps\EncryptedPrivateKeyInfo::MAP); - - return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END ENCRYPTED PRIVATE KEY-----"; - } - - return "-----BEGIN PRIVATE KEY-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END PRIVATE KEY-----"; - } - - /** - * Wrap a public key appropriately - * - * @param string $key - * @param mixed $params - * @param string $oid - * @return string - */ - protected static function wrapPublicKey($key, $params, $oid = null) - { - self::initialize_static_variables(); - - $key = [ - 'publicKeyAlgorithm' => [ - 'algorithm' => is_string(static::OID_NAME) ? static::OID_NAME : $oid - ], - 'publicKey' => "\0" . $key - ]; - - if ($oid != 'id-Ed25519' && $oid != 'id-Ed448') { - $key['publicKeyAlgorithm']['parameters'] = $params; - } - - $key = ASN1::encodeDER($key, Maps\PublicKeyInfo::MAP); - - return "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; - } - - /** - * Perform some preliminary parsing of the key - * - * @param string $key - * @return array - */ - private static function preParse(&$key) - { - self::initialize_static_variables(); - - if (self::$format != self::MODE_DER) { - $decoded = ASN1::extractBER($key); - if ($decoded !== false) { - $key = $decoded; - } elseif (self::$format == self::MODE_PEM) { - throw new \UnexpectedValueException('Expected base64-encoded PEM format but was unable to decode base64 text'); - } - } - - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - - return $decoded; - } - - /** - * Returns the encryption parameters used by the key - * - * @param string $key - * @return array - */ - public static function extractEncryptionAlgorithm($key) - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $decoded = self::preParse($key); - - $r = ASN1::asn1map($decoded[0], ASN1\Maps\EncryptedPrivateKeyInfo::MAP); - if (!is_array($r)) { - throw new \RuntimeException('Unable to parse using EncryptedPrivateKeyInfo map'); - } - - if ($r['encryptionAlgorithm']['algorithm'] == 'id-PBES2') { - $decoded = ASN1::decodeBER($r['encryptionAlgorithm']['parameters']->element); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - $r['encryptionAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], ASN1\Maps\PBES2params::MAP); - - $kdf = &$r['encryptionAlgorithm']['parameters']['keyDerivationFunc']; - switch ($kdf['algorithm']) { - case 'id-PBKDF2': - $decoded = ASN1::decodeBER($kdf['parameters']->element); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - $kdf['parameters'] = ASN1::asn1map($decoded[0], Maps\PBKDF2params::MAP); - } - } - - return $r['encryptionAlgorithm']; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php deleted file mode 100644 index 85da83a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,374 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\AES; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Exception\UnsupportedAlgorithmException; - -/** - * PuTTY Formatted Key Handler - * - * @author Jim Wigginton - */ -abstract class PuTTY -{ - /** - * Default comment - * - * @var string - */ - private static $comment = 'phpseclib-generated-key'; - - /** - * Default version - * - * @var int - */ - private static $version = 2; - - /** - * Sets the default comment - * - * @param string $comment - */ - public static function setComment($comment) - { - self::$comment = str_replace(["\r", "\n"], '', $comment); - } - - /** - * Sets the default version - * - * @param int $version - */ - public static function setVersion($version) - { - if ($version != 2 && $version != 3) { - throw new \RuntimeException('Only supported versions are 2 and 3'); - } - self::$version = $version; - } - - /** - * Generate a symmetric key for PuTTY v2 keys - * - * @param string $password - * @param int $length - * @return string - */ - private static function generateV2Key($password, $length) - { - $symkey = ''; - $sequence = 0; - while (strlen($symkey) < $length) { - $temp = pack('Na*', $sequence++, $password); - $symkey .= Strings::hex2bin(sha1($temp)); - } - return substr($symkey, 0, $length); - } - - /** - * Generate a symmetric key for PuTTY v3 keys - * - * @param string $password - * @param string $flavour - * @param int $memory - * @param int $passes - * @param string $salt - * @return array - */ - private static function generateV3Key($password, $flavour, $memory, $passes, $salt) - { - if (!function_exists('sodium_crypto_pwhash')) { - throw new \RuntimeException('sodium_crypto_pwhash needs to exist for Argon2 password hasing'); - } - - switch ($flavour) { - case 'Argon2i': - $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13; - break; - case 'Argon2id': - $flavour = SODIUM_CRYPTO_PWHASH_ALG_ARGON2ID13; - break; - default: - throw new UnsupportedAlgorithmException('Only Argon2i and Argon2id are supported'); - } - - $length = 80; // keylen + ivlen + mac_keylen - $temp = sodium_crypto_pwhash($length, $password, $salt, $passes, $memory << 10, $flavour); - - $symkey = substr($temp, 0, 32); - $symiv = substr($temp, 32, 16); - $hashkey = substr($temp, -32); - - return compact('symkey', 'symiv', 'hashkey'); - } - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password - * @return array - */ - public static function load($key, $password) - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'BEGIN SSH2 PUBLIC KEY') !== false) { - $lines = preg_split('#[\r\n]+#', $key); - switch (true) { - case $lines[0] != '---- BEGIN SSH2 PUBLIC KEY ----': - throw new \UnexpectedValueException('Key doesn\'t start with ---- BEGIN SSH2 PUBLIC KEY ----'); - case $lines[count($lines) - 1] != '---- END SSH2 PUBLIC KEY ----': - throw new \UnexpectedValueException('Key doesn\'t end with ---- END SSH2 PUBLIC KEY ----'); - } - $lines = array_splice($lines, 1, -1); - $lines = array_map(function ($line) { - return rtrim($line, "\r\n"); - }, $lines); - $data = $current = ''; - $values = []; - $in_value = false; - foreach ($lines as $line) { - switch (true) { - case preg_match('#^(.*?): (.*)#', $line, $match): - $in_value = $line[strlen($line) - 1] == '\\'; - $current = strtolower($match[1]); - $values[$current] = $in_value ? substr($match[2], 0, -1) : $match[2]; - break; - case $in_value: - $in_value = $line[strlen($line) - 1] == '\\'; - $values[$current] .= $in_value ? substr($line, 0, -1) : $line; - break; - default: - $data .= $line; - } - } - - $components = call_user_func([static::PUBLIC_HANDLER, 'load'], $data); - if ($components === false) { - throw new \UnexpectedValueException('Unable to decode public key'); - } - $components += $values; - $components['comment'] = str_replace(['\\\\', '\"'], ['\\', '"'], $values['comment']); - - return $components; - } - - $components = []; - - $key = preg_split('#\r\n|\r|\n#', trim($key)); - if (Strings::shift($key[0], strlen('PuTTY-User-Key-File-')) != 'PuTTY-User-Key-File-') { - return false; - } - $version = (int) Strings::shift($key[0], 3); // should be either "2: " or "3: 0" prior to int casting - if ($version != 2 && $version != 3) { - throw new \RuntimeException('Only v2 and v3 PuTTY private keys are supported'); - } - $components['type'] = $type = rtrim($key[0]); - if (!in_array($type, static::$types)) { - $error = count(static::$types) == 1 ? - 'Only ' . static::$types[0] . ' keys are supported. ' : - ''; - throw new UnsupportedAlgorithmException($error . 'This is an unsupported ' . $type . ' key'); - } - $encryption = trim(preg_replace('#Encryption: (.+)#', '$1', $key[1])); - $components['comment'] = trim(preg_replace('#Comment: (.+)#', '$1', $key[2])); - - $publicLength = trim(preg_replace('#Public-Lines: (\d+)#', '$1', $key[3])); - $public = Strings::base64_decode(implode('', array_map('trim', array_slice($key, 4, $publicLength)))); - - $source = Strings::packSSH2('ssss', $type, $encryption, $components['comment'], $public); - - extract(unpack('Nlength', Strings::shift($public, 4))); - $newtype = Strings::shift($public, $length); - if ($newtype != $type) { - throw new \RuntimeException('The binary type does not match the human readable type field'); - } - - $components['public'] = $public; - - switch ($version) { - case 3: - $hashkey = ''; - break; - case 2: - $hashkey = 'putty-private-key-file-mac-key'; - } - - $offset = $publicLength + 4; - switch ($encryption) { - case 'aes256-cbc': - $crypto = new AES('cbc'); - switch ($version) { - case 3: - $flavour = trim(preg_replace('#Key-Derivation: (.*)#', '$1', $key[$offset++])); - $memory = trim(preg_replace('#Argon2-Memory: (\d+)#', '$1', $key[$offset++])); - $passes = trim(preg_replace('#Argon2-Passes: (\d+)#', '$1', $key[$offset++])); - $parallelism = trim(preg_replace('#Argon2-Parallelism: (\d+)#', '$1', $key[$offset++])); - $salt = Strings::hex2bin(trim(preg_replace('#Argon2-Salt: ([0-9a-f]+)#', '$1', $key[$offset++]))); - - extract(self::generateV3Key($password, $flavour, $memory, $passes, $salt)); - - break; - case 2: - $symkey = self::generateV2Key($password, 32); - $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); - $hashkey .= $password; - } - } - - switch ($version) { - case 3: - $hash = new Hash('sha256'); - $hash->setKey($hashkey); - break; - case 2: - $hash = new Hash('sha1'); - $hash->setKey(sha1($hashkey, true)); - } - - $privateLength = trim(preg_replace('#Private-Lines: (\d+)#', '$1', $key[$offset++])); - $private = Strings::base64_decode(implode('', array_map('trim', array_slice($key, $offset, $privateLength)))); - - if ($encryption != 'none') { - $crypto->setKey($symkey); - $crypto->setIV($symiv); - $crypto->disablePadding(); - $private = $crypto->decrypt($private); - } - - $source .= Strings::packSSH2('s', $private); - - $hmac = trim(preg_replace('#Private-MAC: (.+)#', '$1', $key[$offset + $privateLength])); - $hmac = Strings::hex2bin($hmac); - - if (!hash_equals($hash->hash($source), $hmac)) { - throw new \UnexpectedValueException('MAC validation error'); - } - - $components['private'] = $private; - - return $components; - } - - /** - * Wrap a private key appropriately - * - * @param string $public - * @param string $private - * @param string $type - * @param string $password - * @param array $options optional - * @return string - */ - protected static function wrapPrivateKey($public, $private, $type, $password, array $options = []) - { - $encryption = (!empty($password) || is_string($password)) ? 'aes256-cbc' : 'none'; - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $version = isset($options['version']) ? $options['version'] : self::$version; - - $key = "PuTTY-User-Key-File-$version: $type\r\n"; - $key .= "Encryption: $encryption\r\n"; - $key .= "Comment: $comment\r\n"; - - $public = Strings::packSSH2('s', $type) . $public; - - $source = Strings::packSSH2('ssss', $type, $encryption, $comment, $public); - - $public = Strings::base64_encode($public); - $key .= "Public-Lines: " . ((strlen($public) + 63) >> 6) . "\r\n"; - $key .= chunk_split($public, 64); - - if (empty($password) && !is_string($password)) { - $source .= Strings::packSSH2('s', $private); - switch ($version) { - case 3: - $hash = new Hash('sha256'); - $hash->setKey(''); - break; - case 2: - $hash = new Hash('sha1'); - $hash->setKey(sha1('putty-private-key-file-mac-key', true)); - } - } else { - $private .= Random::string(16 - (strlen($private) & 15)); - $source .= Strings::packSSH2('s', $private); - $crypto = new AES('cbc'); - - switch ($version) { - case 3: - $salt = Random::string(16); - $key .= "Key-Derivation: Argon2id\r\n"; - $key .= "Argon2-Memory: 8192\r\n"; - $key .= "Argon2-Passes: 13\r\n"; - $key .= "Argon2-Parallelism: 1\r\n"; - $key .= "Argon2-Salt: " . Strings::bin2hex($salt) . "\r\n"; - extract(self::generateV3Key($password, 'Argon2id', 8192, 13, $salt)); - - $hash = new Hash('sha256'); - $hash->setKey($hashkey); - - break; - case 2: - $symkey = self::generateV2Key($password, 32); - $symiv = str_repeat("\0", $crypto->getBlockLength() >> 3); - $hashkey = 'putty-private-key-file-mac-key' . $password; - - $hash = new Hash('sha1'); - $hash->setKey(sha1($hashkey, true)); - } - - $crypto->setKey($symkey); - $crypto->setIV($symiv); - $crypto->disablePadding(); - $private = $crypto->encrypt($private); - $mac = $hash->hash($source); - } - - $private = Strings::base64_encode($private); - $key .= 'Private-Lines: ' . ((strlen($private) + 63) >> 6) . "\r\n"; - $key .= chunk_split($private, 64); - $key .= 'Private-MAC: ' . Strings::bin2hex($hash->hash($source)) . "\r\n"; - - return $key; - } - - /** - * Wrap a public key appropriately - * - * This is basically the format described in RFC 4716 (https://tools.ietf.org/html/rfc4716) - * - * @param string $key - * @param string $type - * @return string - */ - protected static function wrapPublicKey($key, $type) - { - $key = pack('Na*a*', strlen($type), $type, $key); - $key = "---- BEGIN SSH2 PUBLIC KEY ----\r\n" . - 'Comment: "' . str_replace(['\\', '"'], ['\\\\', '\"'], self::$comment) . "\"\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - '---- END SSH2 PUBLIC KEY ----'; - return $key; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php deleted file mode 100644 index ab8e7e4..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Formats/Signature/Raw.php +++ /dev/null @@ -1,60 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Formats\Signature; - -use phpseclib3\Math\BigInteger; - -/** - * Raw Signature Handler - * - * @author Jim Wigginton - */ -abstract class Raw -{ - /** - * Loads a signature - * - * @param array $sig - * @return array|bool - */ - public static function load($sig) - { - switch (true) { - case !is_array($sig): - case !isset($sig['r']) || !isset($sig['s']): - case !$sig['r'] instanceof BigInteger: - case !$sig['s'] instanceof BigInteger: - return false; - } - - return [ - 'r' => $sig['r'], - 's' => $sig['s'] - ]; - } - - /** - * Returns a signature in the appropriate format - * - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - return compact('r', 's'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php deleted file mode 100644 index a6e1eb0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PrivateKey.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * PrivateKey interface - * - * @author Jim Wigginton - */ -interface PrivateKey -{ - public function sign($message); - //public function decrypt($ciphertext); - public function getPublicKey(); - public function toString($type, array $options = []); - - /** - * @param string|false $password - * @return mixed - */ - public function withPassword($password = false); -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php deleted file mode 100644 index 48a5875..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/PublicKey.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * PublicKey interface - * - * @author Jim Wigginton - */ -interface PublicKey -{ - public function verify($message, $signature); - //public function encrypt($plaintext); - public function toString($type, array $options = []); - public function getFingerprint($algorithm); -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php deleted file mode 100644 index 0e2d6f0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/StreamCipher.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -/** - * Base Class for all stream cipher classes - * - * @author Jim Wigginton - */ -abstract class StreamCipher extends SymmetricKey -{ - /** - * Block Length of the cipher - * - * Stream ciphers do not have a block size - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size - * @var int - */ - protected $block_size = 0; - - /** - * Default Constructor. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @return \phpseclib3\Crypt\Common\StreamCipher - */ - public function __construct() - { - parent::__construct('stream'); - } - - /** - * Stream ciphers not use an IV - * - * @return bool - */ - public function usesIV() - { - return false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php deleted file mode 100644 index 175508d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/SymmetricKey.php +++ /dev/null @@ -1,3398 +0,0 @@ - - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Blowfish; -use phpseclib3\Crypt\Hash; -use phpseclib3\Exception\BadDecryptionException; -use phpseclib3\Exception\BadModeException; -use phpseclib3\Exception\InconsistentSetupException; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\BinaryField; -use phpseclib3\Math\PrimeField; - -/** - * Base Class for all \phpseclib3\Crypt\* cipher classes - * - * @author Jim Wigginton - * @author Hans-Juergen Petrich - */ -abstract class SymmetricKey -{ - /** - * Encrypt / decrypt using the Counter mode. - * - * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29 - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CTR = -1; - /** - * Encrypt / decrypt using the Electronic Code Book mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_ECB = 1; - /** - * Encrypt / decrypt using the Code Book Chaining mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29 - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CBC = 2; - /** - * Encrypt / decrypt using the Cipher Feedback mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29 - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CFB = 3; - /** - * Encrypt / decrypt using the Cipher Feedback mode (8bit) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_CFB8 = 7; - /** - * Encrypt / decrypt using the Output Feedback mode (8bit) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_OFB8 = 8; - /** - * Encrypt / decrypt using the Output Feedback mode. - * - * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29 - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_OFB = 4; - /** - * Encrypt / decrypt using Galois/Counter mode. - * - * @link https://en.wikipedia.org/wiki/Galois/Counter_Mode - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_GCM = 5; - /** - * Encrypt / decrypt using streaming mode. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - */ - const MODE_STREAM = 6; - - /** - * Mode Map - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const MODE_MAP = [ - 'ctr' => self::MODE_CTR, - 'ecb' => self::MODE_ECB, - 'cbc' => self::MODE_CBC, - 'cfb' => self::MODE_CFB, - 'cfb8' => self::MODE_CFB8, - 'ofb' => self::MODE_OFB, - 'ofb8' => self::MODE_OFB8, - 'gcm' => self::MODE_GCM, - 'stream' => self::MODE_STREAM - ]; - - /** - * Base value for the internal implementation $engine switch - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_INTERNAL = 1; - /** - * Base value for the eval() implementation $engine switch - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_EVAL = 2; - /** - * Base value for the mcrypt implementation $engine switch - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_MCRYPT = 3; - /** - * Base value for the openssl implementation $engine switch - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_OPENSSL = 4; - /** - * Base value for the libsodium implementation $engine switch - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_LIBSODIUM = 5; - /** - * Base value for the openssl / gcm implementation $engine switch - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - */ - const ENGINE_OPENSSL_GCM = 6; - - /** - * Engine Reverse Map - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::getEngine() - */ - const ENGINE_MAP = [ - self::ENGINE_INTERNAL => 'PHP', - self::ENGINE_EVAL => 'Eval', - self::ENGINE_MCRYPT => 'mcrypt', - self::ENGINE_OPENSSL => 'OpenSSL', - self::ENGINE_LIBSODIUM => 'libsodium', - self::ENGINE_OPENSSL_GCM => 'OpenSSL (GCM)' - ]; - - /** - * The Encryption Mode - * - * @see self::__construct() - * @var int - */ - protected $mode; - - /** - * The Block Length of the block cipher - * - * @var int - */ - protected $block_size = 16; - - /** - * The Key - * - * @see self::setKey() - * @var string - */ - protected $key = false; - - /** - * HMAC Key - * - * @see self::setupGCM() - * @var ?string - */ - protected $hKey = false; - - /** - * The Initialization Vector - * - * @see self::setIV() - * @var string - */ - protected $iv = false; - - /** - * A "sliding" Initialization Vector - * - * @see self::enableContinuousBuffer() - * @see self::clearBuffers() - * @var string - */ - protected $encryptIV; - - /** - * A "sliding" Initialization Vector - * - * @see self::enableContinuousBuffer() - * @see self::clearBuffers() - * @var string - */ - protected $decryptIV; - - /** - * Continuous Buffer status - * - * @see self::enableContinuousBuffer() - * @var bool - */ - protected $continuousBuffer = false; - - /** - * Encryption buffer for CTR, OFB and CFB modes - * - * @see self::encrypt() - * @see self::clearBuffers() - * @var array - */ - protected $enbuffer; - - /** - * Decryption buffer for CTR, OFB and CFB modes - * - * @see self::decrypt() - * @see self::clearBuffers() - * @var array - */ - protected $debuffer; - - /** - * mcrypt resource for encryption - * - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. - * - * @see self::encrypt() - * @var resource - */ - private $enmcrypt; - - /** - * mcrypt resource for decryption - * - * The mcrypt resource can be recreated every time something needs to be created or it can be created just once. - * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode. - * - * @see self::decrypt() - * @var resource - */ - private $demcrypt; - - /** - * Does the enmcrypt resource need to be (re)initialized? - * - * @see \phpseclib3\Crypt\Twofish::setKey() - * @see \phpseclib3\Crypt\Twofish::setIV() - * @var bool - */ - private $enchanged = true; - - /** - * Does the demcrypt resource need to be (re)initialized? - * - * @see \phpseclib3\Crypt\Twofish::setKey() - * @see \phpseclib3\Crypt\Twofish::setIV() - * @var bool - */ - private $dechanged = true; - - /** - * mcrypt resource for CFB mode - * - * mcrypt's CFB mode, in (and only in) buffered context, - * is broken, so phpseclib implements the CFB mode by it self, - * even when the mcrypt php extension is available. - * - * In order to do the CFB-mode work (fast) phpseclib - * use a separate ECB-mode mcrypt resource. - * - * @link http://phpseclib.sourceforge.net/cfb-demo.phps - * @see self::encrypt() - * @see self::decrypt() - * @see self::setupMcrypt() - * @var resource - */ - private $ecb; - - /** - * Optimizing value while CFB-encrypting - * - * Only relevant if $continuousBuffer enabled - * and $engine == self::ENGINE_MCRYPT - * - * It's faster to re-init $enmcrypt if - * $buffer bytes > $cfb_init_len than - * using the $ecb resource furthermore. - * - * This value depends of the chosen cipher - * and the time it would be needed for it's - * initialization [by mcrypt_generic_init()] - * which, typically, depends on the complexity - * on its internaly Key-expanding algorithm. - * - * @see self::encrypt() - * @var int - */ - protected $cfb_init_len = 600; - - /** - * Does internal cipher state need to be (re)initialized? - * - * @see self::setKey() - * @see self::setIV() - * @see self::disableContinuousBuffer() - * @var bool - */ - protected $changed = true; - - /** - * Does Eval engie need to be (re)initialized? - * - * @see self::setup() - * @var bool - */ - protected $nonIVChanged = true; - - /** - * Padding status - * - * @see self::enablePadding() - * @var bool - */ - private $padding = true; - - /** - * Is the mode one that is paddable? - * - * @see self::__construct() - * @var bool - */ - private $paddable = false; - - /** - * Holds which crypt engine internaly should be use, - * which will be determined automatically on __construct() - * - * Currently available $engines are: - * - self::ENGINE_LIBSODIUM (very fast, php-extension: libsodium, extension_loaded('libsodium') required) - * - self::ENGINE_OPENSSL_GCM (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - self::ENGINE_OPENSSL (very fast, php-extension: openssl, extension_loaded('openssl') required) - * - self::ENGINE_MCRYPT (fast, php-extension: mcrypt, extension_loaded('mcrypt') required) - * - self::ENGINE_EVAL (medium, pure php-engine, no php-extension required) - * - self::ENGINE_INTERNAL (slower, pure php-engine, no php-extension required) - * - * @see self::setEngine() - * @see self::encrypt() - * @see self::decrypt() - * @var int - */ - protected $engine; - - /** - * Holds the preferred crypt engine - * - * @see self::setEngine() - * @see self::setPreferredEngine() - * @var int - */ - private $preferredEngine; - - /** - * The mcrypt specific name of the cipher - * - * Only used if $engine == self::ENGINE_MCRYPT - * - * @link http://www.php.net/mcrypt_module_open - * @link http://www.php.net/mcrypt_list_algorithms - * @see self::setupMcrypt() - * @var string - */ - protected $cipher_name_mcrypt; - - /** - * The openssl specific name of the cipher - * - * Only used if $engine == self::ENGINE_OPENSSL - * - * @link http://www.php.net/openssl-get-cipher-methods - * @var string - */ - protected $cipher_name_openssl; - - /** - * The openssl specific name of the cipher in ECB mode - * - * If OpenSSL does not support the mode we're trying to use (CTR) - * it can still be emulated with ECB mode. - * - * @link http://www.php.net/openssl-get-cipher-methods - * @var string - */ - protected $cipher_name_openssl_ecb; - - /** - * The default salt used by setPassword() - * - * @see self::setPassword() - * @var string - */ - private $password_default_salt = 'phpseclib/salt'; - - /** - * The name of the performance-optimized callback function - * - * Used by encrypt() / decrypt() - * only if $engine == self::ENGINE_INTERNAL - * - * @see self::encrypt() - * @see self::decrypt() - * @see self::setupInlineCrypt() - * @var Callback - */ - protected $inline_crypt; - - /** - * If OpenSSL can be used in ECB but not in CTR we can emulate CTR - * - * @see self::openssl_ctr_process() - * @var bool - */ - private $openssl_emulate_ctr = false; - - /** - * Don't truncate / null pad key - * - * @see self::clearBuffers() - * @var bool - */ - private $skip_key_adjustment = false; - - /** - * Has the key length explicitly been set or should it be derived from the key, itself? - * - * @see self::setKeyLength() - * @var bool - */ - protected $explicit_key_length = false; - - /** - * Hash subkey for GHASH - * - * @see self::setupGCM() - * @see self::ghash() - * @var BinaryField\Integer - */ - private $h; - - /** - * Additional authenticated data - * - * @var string - */ - protected $aad = ''; - - /** - * Authentication Tag produced after a round of encryption - * - * @var string - */ - protected $newtag = false; - - /** - * Authentication Tag to be verified during decryption - * - * @var string - */ - protected $oldtag = false; - - /** - * GCM Binary Field - * - * @see self::__construct() - * @see self::ghash() - * @var BinaryField - */ - private static $gcmField; - - /** - * Poly1305 Prime Field - * - * @see self::enablePoly1305() - * @see self::poly1305() - * @var PrimeField - */ - private static $poly1305Field; - - /** - * Flag for using regular vs "safe" intval - * - * @see self::initialize_static_variables() - * @var boolean - */ - protected static $use_reg_intval; - - /** - * Poly1305 Key - * - * @see self::setPoly1305Key() - * @see self::poly1305() - * @var string - */ - protected $poly1305Key; - - /** - * Poly1305 Flag - * - * @see self::setPoly1305Key() - * @see self::enablePoly1305() - * @var boolean - */ - protected $usePoly1305 = false; - - /** - * The Original Initialization Vector - * - * GCM uses the nonce to build the IV but we want to be able to distinguish between nonce-derived - * IV's and user-set IV's - * - * @see self::setIV() - * @var string - */ - private $origIV = false; - - /** - * Nonce - * - * Only used with GCM. We could re-use setIV() but nonce's can be of a different length and - * toggling between GCM and other modes could be more complicated if we re-used setIV() - * - * @see self::setNonce() - * @var string - */ - protected $nonce = false; - - /** - * Default Constructor. - * - * $mode could be: - * - * - ecb - * - * - cbc - * - * - ctr - * - * - cfb - * - * - cfb8 - * - * - ofb - * - * - ofb8 - * - * - gcm - * - * @param string $mode - * @throws BadModeException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - $mode = strtolower($mode); - // necessary because of 5.6 compatibility; we can't do isset(self::MODE_MAP[$mode]) in 5.6 - $map = self::MODE_MAP; - if (!isset($map[$mode])) { - throw new BadModeException('No valid mode has been specified'); - } - - $mode = self::MODE_MAP[$mode]; - - // $mode dependent settings - switch ($mode) { - case self::MODE_ECB: - case self::MODE_CBC: - $this->paddable = true; - break; - case self::MODE_CTR: - case self::MODE_CFB: - case self::MODE_CFB8: - case self::MODE_OFB: - case self::MODE_OFB8: - case self::MODE_STREAM: - $this->paddable = false; - break; - case self::MODE_GCM: - if ($this->block_size != 16) { - throw new BadModeException('GCM is only valid for block ciphers with a block size of 128 bits'); - } - if (!isset(self::$gcmField)) { - self::$gcmField = new BinaryField(128, 7, 2, 1, 0); - } - $this->paddable = false; - break; - default: - throw new BadModeException('No valid mode has been specified'); - } - - $this->mode = $mode; - - static::initialize_static_variables(); - } - - /** - * Initialize static variables - */ - protected static function initialize_static_variables() - { - if (!isset(self::$use_reg_intval)) { - switch (true) { - // PHP_OS & "\xDF\xDF\xDF" == strtoupper(substr(PHP_OS, 0, 3)), but a lot faster - case (PHP_OS & "\xDF\xDF\xDF") === 'WIN': - case !function_exists('php_uname'): - case !is_string(php_uname('m')): - case (php_uname('m') & "\xDF\xDF\xDF") != 'ARM': - case defined('PHP_INT_SIZE') && PHP_INT_SIZE == 8: - self::$use_reg_intval = true; - break; - case (php_uname('m') & "\xDF\xDF\xDF") == 'ARM': - switch (true) { - /* PHP 7.0.0 introduced a bug that affected 32-bit ARM processors: - - https://github.com/php/php-src/commit/716da71446ebbd40fa6cf2cea8a4b70f504cc3cd - - altho the changelogs make no mention of it, this bug was fixed with this commit: - - https://github.com/php/php-src/commit/c1729272b17a1fe893d1a54e423d3b71470f3ee8 - - affected versions of PHP are: 7.0.x, 7.1.0 - 7.1.23 and 7.2.0 - 7.2.11 */ - case PHP_VERSION_ID >= 70000 && PHP_VERSION_ID <= 70123: - case PHP_VERSION_ID >= 70200 && PHP_VERSION_ID <= 70211: - self::$use_reg_intval = false; - break; - default: - self::$use_reg_intval = true; - } - } - } - } - - /** - * Sets the initialization vector. - * - * setIV() is not required when ecb or gcm modes are being used. - * - * {@internal Can be overwritten by a sub class, but does not have to be} - * - * @param string $iv - * @throws \LengthException if the IV length isn't equal to the block size - * @throws \BadMethodCallException if an IV is provided when one shouldn't be - */ - public function setIV($iv) - { - if ($this->mode == self::MODE_ECB) { - throw new \BadMethodCallException('This mode does not require an IV.'); - } - - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('Use setNonce instead'); - } - - if (!$this->usesIV()) { - throw new \BadMethodCallException('This algorithm does not use an IV.'); - } - - if (strlen($iv) != $this->block_size) { - throw new \LengthException('Received initialization vector of size ' . strlen($iv) . ', but size ' . $this->block_size . ' is required'); - } - - $this->iv = $this->origIV = $iv; - $this->changed = true; - } - - /** - * Enables Poly1305 mode. - * - * Once enabled Poly1305 cannot be disabled. - * - * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode - */ - public function enablePoly1305() - { - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); - } - - $this->usePoly1305 = true; - } - - /** - * Enables Poly1305 mode. - * - * Once enabled Poly1305 cannot be disabled. If $key is not passed then an attempt to call createPoly1305Key - * will be made. - * - * @param string $key optional - * @throws \LengthException if the key isn't long enough - * @throws \BadMethodCallException if Poly1305 is enabled whilst in GCM mode - */ - public function setPoly1305Key($key = null) - { - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('Poly1305 cannot be used in GCM mode'); - } - - if (!is_string($key) || strlen($key) != 32) { - throw new \LengthException('The Poly1305 key must be 32 bytes long (256 bits)'); - } - - if (!isset(self::$poly1305Field)) { - // 2^130-5 - self::$poly1305Field = new PrimeField(new BigInteger('3fffffffffffffffffffffffffffffffb', 16)); - } - - $this->poly1305Key = $key; - $this->usePoly1305 = true; - } - - /** - * Sets the nonce. - * - * setNonce() is only required when gcm is used - * - * @param string $nonce - * @throws \BadMethodCallException if an nonce is provided when one shouldn't be - */ - public function setNonce($nonce) - { - if ($this->mode != self::MODE_GCM) { - throw new \BadMethodCallException('Nonces are only used in GCM mode.'); - } - - $this->nonce = $nonce; - $this->setEngine(); - } - - /** - * Sets additional authenticated data - * - * setAAD() is only used by gcm or in poly1305 mode - * - * @param string $aad - * @throws \BadMethodCallException if mode isn't GCM or if poly1305 isn't being utilized - */ - public function setAAD($aad) - { - if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { - throw new \BadMethodCallException('Additional authenticated data is only utilized in GCM mode or with Poly1305'); - } - - $this->aad = $aad; - } - - /** - * Returns whether or not the algorithm uses an IV - * - * @return bool - */ - public function usesIV() - { - return $this->mode != self::MODE_GCM && $this->mode != self::MODE_ECB; - } - - /** - * Returns whether or not the algorithm uses a nonce - * - * @return bool - */ - public function usesNonce() - { - return $this->mode == self::MODE_GCM; - } - - /** - * Returns the current key length in bits - * - * @return int - */ - public function getKeyLength() - { - return $this->key_length << 3; - } - - /** - * Returns the current block length in bits - * - * @return int - */ - public function getBlockLength() - { - return $this->block_size << 3; - } - - /** - * Returns the current block length in bytes - * - * @return int - */ - public function getBlockLengthInBytes() - { - return $this->block_size; - } - - /** - * Sets the key length. - * - * Keys with explicitly set lengths need to be treated accordingly - * - * @param int $length - */ - public function setKeyLength($length) - { - $this->explicit_key_length = $length >> 3; - - if (is_string($this->key) && strlen($this->key) != $this->explicit_key_length) { - $this->key = false; - throw new InconsistentSetupException('Key has already been set and is not ' . $this->explicit_key_length . ' bytes long'); - } - } - - /** - * Sets the key. - * - * The min/max length(s) of the key depends on the cipher which is used. - * If the key not fits the length(s) of the cipher it will paded with null bytes - * up to the closest valid key length. If the key is more than max length, - * we trim the excess bits. - * - * If the key is not explicitly set, it'll be assumed to be all null bytes. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @param string $key - */ - public function setKey($key) - { - if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { - throw new InconsistentSetupException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); - } - - $this->key = $key; - $this->key_length = strlen($key); - $this->setEngine(); - } - - /** - * Sets the password. - * - * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows: - * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2} or pbkdf1: - * $hash, $salt, $count, $dkLen - * - * Where $hash (default = sha1) currently supports the following hashes: see: Crypt/Hash.php - * {@link https://en.wikipedia.org/wiki/Bcrypt bcypt}: - * $salt, $rounds, $keylen - * - * This is a modified version of bcrypt used by OpenSSH. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see Crypt/Hash.php - * @param string $password - * @param string $method - * @param int|string ...$func_args - * @throws \LengthException if pbkdf1 is being used and the derived key length exceeds the hash length - * @throws \RuntimeException if bcrypt is being used and a salt isn't provided - * @return bool - */ - public function setPassword($password, $method = 'pbkdf2', ...$func_args) - { - $key = ''; - - $method = strtolower($method); - switch ($method) { - case 'bcrypt': - if (!isset($func_args[2])) { - throw new \RuntimeException('A salt must be provided for bcrypt to work'); - } - - $salt = $func_args[0]; - - $rounds = isset($func_args[1]) ? $func_args[1] : 16; - $keylen = isset($func_args[2]) ? $func_args[2] : $this->key_length; - - $key = Blowfish::bcrypt_pbkdf($password, $salt, $keylen + $this->block_size, $rounds); - - $this->setKey(substr($key, 0, $keylen)); - $this->setIV(substr($key, $keylen)); - - return true; - case 'pkcs12': // from https://tools.ietf.org/html/rfc7292#appendix-B.2 - case 'pbkdf1': - case 'pbkdf2': - // Hash function - $hash = isset($func_args[0]) ? strtolower($func_args[0]) : 'sha1'; - $hashObj = new Hash(); - $hashObj->setHash($hash); - - // WPA and WPA2 use the SSID as the salt - $salt = isset($func_args[1]) ? $func_args[1] : $this->password_default_salt; - - // RFC2898#section-4.2 uses 1,000 iterations by default - // WPA and WPA2 use 4,096. - $count = isset($func_args[2]) ? $func_args[2] : 1000; - - // Keylength - if (isset($func_args[3])) { - if ($func_args[3] <= 0) { - throw new \LengthException('Derived key length cannot be longer 0 or less'); - } - $dkLen = $func_args[3]; - } else { - $key_length = $this->explicit_key_length !== false ? $this->explicit_key_length : $this->key_length; - $dkLen = $method == 'pbkdf1' ? 2 * $key_length : $key_length; - } - - switch (true) { - case $method == 'pkcs12': - /* - In this specification, however, all passwords are created from - BMPStrings with a NULL terminator. This means that each character in - the original BMPString is encoded in 2 bytes in big-endian format - (most-significant byte first). There are no Unicode byte order - marks. The 2 bytes produced from the last character in the BMPString - are followed by 2 additional bytes with the value 0x00. - - -- https://tools.ietf.org/html/rfc7292#appendix-B.1 - */ - $password = "\0" . chunk_split($password, 1, "\0") . "\0"; - - /* - This standard specifies 3 different values for the ID byte mentioned - above: - - 1. If ID=1, then the pseudorandom bits being produced are to be used - as key material for performing encryption or decryption. - - 2. If ID=2, then the pseudorandom bits being produced are to be used - as an IV (Initial Value) for encryption or decryption. - - 3. If ID=3, then the pseudorandom bits being produced are to be used - as an integrity key for MACing. - */ - // Construct a string, D (the "diversifier"), by concatenating v/8 - // copies of ID. - $blockLength = $hashObj->getBlockLengthInBytes(); - $d1 = str_repeat(chr(1), $blockLength); - $d2 = str_repeat(chr(2), $blockLength); - $s = ''; - if (strlen($salt)) { - while (strlen($s) < $blockLength) { - $s .= $salt; - } - } - $s = substr($s, 0, $blockLength); - - $p = ''; - if (strlen($password)) { - while (strlen($p) < $blockLength) { - $p .= $password; - } - } - $p = substr($p, 0, $blockLength); - - $i = $s . $p; - - $this->setKey(self::pkcs12helper($dkLen, $hashObj, $i, $d1, $count)); - if ($this->usesIV()) { - $this->setIV(self::pkcs12helper($this->block_size, $hashObj, $i, $d2, $count)); - } - - return true; - case $method == 'pbkdf1': - if ($dkLen > $hashObj->getLengthInBytes()) { - throw new \LengthException('Derived key length cannot be longer than the hash length'); - } - $t = $password . $salt; - for ($i = 0; $i < $count; ++$i) { - $t = $hashObj->hash($t); - } - $key = substr($t, 0, $dkLen); - - $this->setKey(substr($key, 0, $dkLen >> 1)); - if ($this->usesIV()) { - $this->setIV(substr($key, $dkLen >> 1)); - } - - return true; - case !in_array($hash, hash_algos()): - $i = 1; - $hashObj->setKey($password); - while (strlen($key) < $dkLen) { - $f = $u = $hashObj->hash($salt . pack('N', $i++)); - for ($j = 2; $j <= $count; ++$j) { - $u = $hashObj->hash($u); - $f ^= $u; - } - $key .= $f; - } - $key = substr($key, 0, $dkLen); - break; - default: - $key = hash_pbkdf2($hash, $password, $salt, $count, $dkLen, true); - } - break; - default: - throw new UnsupportedAlgorithmException($method . ' is not a supported password hashing method'); - } - - $this->setKey($key); - - return true; - } - - /** - * PKCS#12 KDF Helper Function - * - * As discussed here: - * - * {@link https://tools.ietf.org/html/rfc7292#appendix-B} - * - * @see self::setPassword() - * @param int $n - * @param \phpseclib3\Crypt\Hash $hashObj - * @param string $i - * @param string $d - * @param int $count - * @return string $a - */ - private static function pkcs12helper($n, $hashObj, $i, $d, $count) - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $blockLength = $hashObj->getBlockLength() >> 3; - - $c = ceil($n / $hashObj->getLengthInBytes()); - $a = ''; - for ($j = 1; $j <= $c; $j++) { - $ai = $d . $i; - for ($k = 0; $k < $count; $k++) { - $ai = $hashObj->hash($ai); - } - $b = ''; - while (strlen($b) < $blockLength) { - $b .= $ai; - } - $b = substr($b, 0, $blockLength); - $b = new BigInteger($b, 256); - $newi = ''; - for ($k = 0; $k < strlen($i); $k += $blockLength) { - $temp = substr($i, $k, $blockLength); - $temp = new BigInteger($temp, 256); - $temp->setPrecision($blockLength << 3); - $temp = $temp->add($b); - $temp = $temp->add($one); - $newi .= $temp->toBytes(false); - } - $i = $newi; - $a .= $ai; - } - - return substr($a, 0, $n); - } - - /** - * Encrypts a message. - * - * $plaintext will be padded with additional bytes such that it's length is a multiple of the block size. Other cipher - * implementations may or may not pad in the same manner. Other common approaches to padding and the reasons why it's - * necessary are discussed in the following - * URL: - * - * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html} - * - * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does. - * strlen($plaintext) will still need to be a multiple of the block size, however, arbitrary values can be added to make it that - * length. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::decrypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - if ($this->paddable) { - $plaintext = $this->pad($plaintext); - } - - $this->setup(); - - if ($this->mode == self::MODE_GCM) { - $oldIV = $this->iv; - Strings::increment_str($this->iv); - $cipher = new static('ctr'); - $cipher->setKey($this->key); - $cipher->setIV($this->iv); - $ciphertext = $cipher->encrypt($plaintext); - - $s = $this->ghash( - self::nullPad128($this->aad) . - self::nullPad128($ciphertext) . - self::len64($this->aad) . - self::len64($ciphertext) - ); - $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; - $this->newtag = $cipher->encrypt($s); - return $ciphertext; - } - - if (isset($this->poly1305Key)) { - $cipher = clone $this; - unset($cipher->poly1305Key); - $this->usePoly1305 = false; - $ciphertext = $cipher->encrypt($plaintext); - $this->newtag = $this->poly1305($ciphertext); - return $ciphertext; - } - - if ($this->engine === self::ENGINE_OPENSSL) { - switch ($this->mode) { - case self::MODE_STREAM: - return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - case self::MODE_ECB: - return openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - case self::MODE_CBC: - $result = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); - if ($this->continuousBuffer) { - $this->encryptIV = substr($result, -$this->block_size); - } - return $result; - case self::MODE_CTR: - return $this->openssl_ctr_process($plaintext, $this->encryptIV, $this->enbuffer); - case self::MODE_CFB: - // cfb loosely routines inspired by openssl's: - // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} - $ciphertext = ''; - if ($this->continuousBuffer) { - $iv = &$this->encryptIV; - $pos = &$this->enbuffer['pos']; - } else { - $iv = $this->encryptIV; - $pos = 0; - } - $len = strlen($plaintext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $this->block_size - $pos; - if ($len >= $max) { - $i = $max; - $len -= $max; - $pos = 0; - } else { - $i = $len; - $pos += $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $ciphertext = substr($iv, $orig_pos) ^ $plaintext; - $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); - $plaintext = substr($plaintext, $i); - } - - $overflow = $len % $this->block_size; - - if ($overflow) { - $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $iv = Strings::pop($ciphertext, $this->block_size); - - $size = $len - $overflow; - $block = $iv ^ substr($plaintext, -$overflow); - $iv = substr_replace($iv, $block, 0, $overflow); - $ciphertext .= $block; - $pos = $overflow; - } elseif ($len) { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $iv = substr($ciphertext, -$this->block_size); - } - - return $ciphertext; - case self::MODE_CFB8: - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->encryptIV); - if ($this->continuousBuffer) { - if (($len = strlen($ciphertext)) >= $this->block_size) { - $this->encryptIV = substr($ciphertext, -$this->block_size); - } else { - $this->encryptIV = substr($this->encryptIV, $len - $this->block_size) . substr($ciphertext, -$len); - } - } - return $ciphertext; - case self::MODE_OFB8: - $ciphertext = ''; - $len = strlen($plaintext); - $iv = $this->encryptIV; - - for ($i = 0; $i < $len; ++$i) { - $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); - $ciphertext .= $plaintext[$i] ^ $xor; - $iv = substr($iv, 1) . $xor[0]; - } - - if ($this->continuousBuffer) { - $this->encryptIV = $iv; - } - break; - case self::MODE_OFB: - return $this->openssl_ofb_process($plaintext, $this->encryptIV, $this->enbuffer); - } - } - - if ($this->engine === self::ENGINE_MCRYPT) { - set_error_handler(function () { - }); - if ($this->enchanged) { - mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); - $this->enchanged = false; - } - - // re: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} - // using mcrypt's default handing of CFB the above would output two different things. using phpseclib's - // rewritten CFB implementation the above outputs the same thing twice. - if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { - $block_size = $this->block_size; - $iv = &$this->encryptIV; - $pos = &$this->enbuffer['pos']; - $len = strlen($plaintext); - $ciphertext = ''; - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len -= $max; - $pos = 0; - } else { - $i = $len; - $pos += $len; - $len = 0; - } - $ciphertext = substr($iv, $orig_pos) ^ $plaintext; - $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); - $this->enbuffer['enmcrypt_init'] = true; - } - if ($len >= $block_size) { - if ($this->enbuffer['enmcrypt_init'] === false || $len > $this->cfb_init_len) { - if ($this->enbuffer['enmcrypt_init'] === true) { - mcrypt_generic_init($this->enmcrypt, $this->key, $iv); - $this->enbuffer['enmcrypt_init'] = false; - } - $ciphertext .= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % $block_size)); - $iv = substr($ciphertext, -$block_size); - $len %= $block_size; - } else { - while ($len >= $block_size) { - $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, $block_size); - $ciphertext .= $iv; - $len -= $block_size; - $i += $block_size; - } - } - } - - if ($len) { - $iv = mcrypt_generic($this->ecb, $iv); - $block = $iv ^ substr($plaintext, -$len); - $iv = substr_replace($iv, $block, 0, $len); - $ciphertext .= $block; - $pos = $len; - } - - restore_error_handler(); - - return $ciphertext; - } - - $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext); - - if (!$this->continuousBuffer) { - mcrypt_generic_init($this->enmcrypt, $this->key, $this->getIV($this->encryptIV)); - } - - restore_error_handler(); - - return $ciphertext; - } - - if ($this->engine === self::ENGINE_EVAL) { - $inline = $this->inline_crypt; - return $inline('encrypt', $plaintext); - } - - $buffer = &$this->enbuffer; - $block_size = $this->block_size; - $ciphertext = ''; - switch ($this->mode) { - case self::MODE_ECB: - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $ciphertext .= $this->encryptBlock(substr($plaintext, $i, $block_size)); - } - break; - case self::MODE_CBC: - $xor = $this->encryptIV; - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $block = substr($plaintext, $i, $block_size); - $block = $this->encryptBlock($block ^ $xor); - $xor = $block; - $ciphertext .= $block; - } - if ($this->continuousBuffer) { - $this->encryptIV = $xor; - } - break; - case self::MODE_CTR: - $xor = $this->encryptIV; - if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'] .= $this->encryptBlock($xor); - Strings::increment_str($xor); - } - $key = Strings::shift($buffer['ciphertext'], $block_size); - $ciphertext .= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $block = substr($plaintext, $i, $block_size); - $key = $this->encryptBlock($xor); - Strings::increment_str($xor); - $ciphertext .= $block ^ $key; - } - } - if ($this->continuousBuffer) { - $this->encryptIV = $xor; - if ($start = strlen($plaintext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; - } - } - break; - case self::MODE_CFB: - // cfb loosely routines inspired by openssl's: - // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} - if ($this->continuousBuffer) { - $iv = &$this->encryptIV; - $pos = &$buffer['pos']; - } else { - $iv = $this->encryptIV; - $pos = 0; - } - $len = strlen($plaintext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len -= $max; - $pos = 0; - } else { - $i = $len; - $pos += $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $ciphertext = substr($iv, $orig_pos) ^ $plaintext; - $iv = substr_replace($iv, $ciphertext, $orig_pos, $i); - } - while ($len >= $block_size) { - $iv = $this->encryptBlock($iv) ^ substr($plaintext, $i, $block_size); - $ciphertext .= $iv; - $len -= $block_size; - $i += $block_size; - } - if ($len) { - $iv = $this->encryptBlock($iv); - $block = $iv ^ substr($plaintext, $i); - $iv = substr_replace($iv, $block, 0, $len); - $ciphertext .= $block; - $pos = $len; - } - break; - case self::MODE_CFB8: - $ciphertext = ''; - $len = strlen($plaintext); - $iv = $this->encryptIV; - - for ($i = 0; $i < $len; ++$i) { - $ciphertext .= ($c = $plaintext[$i] ^ $this->encryptBlock($iv)); - $iv = substr($iv, 1) . $c; - } - - if ($this->continuousBuffer) { - if ($len >= $block_size) { - $this->encryptIV = substr($ciphertext, -$block_size); - } else { - $this->encryptIV = substr($this->encryptIV, $len - $block_size) . substr($ciphertext, -$len); - } - } - break; - case self::MODE_OFB8: - $ciphertext = ''; - $len = strlen($plaintext); - $iv = $this->encryptIV; - - for ($i = 0; $i < $len; ++$i) { - $xor = $this->encryptBlock($iv); - $ciphertext .= $plaintext[$i] ^ $xor; - $iv = substr($iv, 1) . $xor[0]; - } - - if ($this->continuousBuffer) { - $this->encryptIV = $iv; - } - break; - case self::MODE_OFB: - $xor = $this->encryptIV; - if (strlen($buffer['xor'])) { - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['xor'])) { - $xor = $this->encryptBlock($xor); - $buffer['xor'] .= $xor; - } - $key = Strings::shift($buffer['xor'], $block_size); - $ciphertext .= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $xor = $this->encryptBlock($xor); - $ciphertext .= substr($plaintext, $i, $block_size) ^ $xor; - } - $key = $xor; - } - if ($this->continuousBuffer) { - $this->encryptIV = $xor; - if ($start = strlen($plaintext) % $block_size) { - $buffer['xor'] = substr($key, $start) . $buffer['xor']; - } - } - break; - case self::MODE_STREAM: - $ciphertext = $this->encryptBlock($plaintext); - break; - } - - return $ciphertext; - } - - /** - * Decrypts a message. - * - * If strlen($ciphertext) is not a multiple of the block size, null bytes will be added to the end of the string until - * it is. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::encrypt() - * @param string $ciphertext - * @return string $plaintext - * @throws \LengthException if we're inside a block cipher and the ciphertext length is not a multiple of the block size - */ - public function decrypt($ciphertext) - { - if ($this->paddable && strlen($ciphertext) % $this->block_size) { - throw new \LengthException('The ciphertext length (' . strlen($ciphertext) . ') needs to be a multiple of the block size (' . $this->block_size . ')'); - } - $this->setup(); - - if ($this->mode == self::MODE_GCM || isset($this->poly1305Key)) { - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - - if (isset($this->poly1305Key)) { - $newtag = $this->poly1305($ciphertext); - } else { - $oldIV = $this->iv; - Strings::increment_str($this->iv); - $cipher = new static('ctr'); - $cipher->setKey($this->key); - $cipher->setIV($this->iv); - $plaintext = $cipher->decrypt($ciphertext); - - $s = $this->ghash( - self::nullPad128($this->aad) . - self::nullPad128($ciphertext) . - self::len64($this->aad) . - self::len64($ciphertext) - ); - $cipher->encryptIV = $this->iv = $this->encryptIV = $this->decryptIV = $oldIV; - $newtag = $cipher->encrypt($s); - } - if ($this->oldtag != substr($newtag, 0, strlen($newtag))) { - $cipher = clone $this; - unset($cipher->poly1305Key); - $this->usePoly1305 = false; - $plaintext = $cipher->decrypt($ciphertext); - $this->oldtag = false; - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - $this->oldtag = false; - return $plaintext; - } - - if ($this->engine === self::ENGINE_OPENSSL) { - switch ($this->mode) { - case self::MODE_STREAM: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - break; - case self::MODE_ECB: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - break; - case self::MODE_CBC: - $offset = $this->block_size; - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); - if ($this->continuousBuffer) { - $this->decryptIV = substr($ciphertext, -$offset, $this->block_size); - } - break; - case self::MODE_CTR: - $plaintext = $this->openssl_ctr_process($ciphertext, $this->decryptIV, $this->debuffer); - break; - case self::MODE_CFB: - // cfb loosely routines inspired by openssl's: - // {@link http://cvs.openssl.org/fileview?f=openssl/crypto/modes/cfb128.c&v=1.3.2.2.2.1} - $plaintext = ''; - if ($this->continuousBuffer) { - $iv = &$this->decryptIV; - $pos = &$this->debuffer['pos']; - } else { - $iv = $this->decryptIV; - $pos = 0; - } - $len = strlen($ciphertext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $this->block_size - $pos; - if ($len >= $max) { - $i = $max; - $len -= $max; - $pos = 0; - } else { - $i = $len; - $pos += $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $this->blocksize - $plaintext = substr($iv, $orig_pos) ^ $ciphertext; - $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); - $ciphertext = substr($ciphertext, $i); - } - $overflow = $len % $this->block_size; - if ($overflow) { - $plaintext .= openssl_decrypt(substr($ciphertext, 0, -$overflow), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - if ($len - $overflow) { - $iv = substr($ciphertext, -$overflow - $this->block_size, -$overflow); - } - $iv = openssl_encrypt(str_repeat("\0", $this->block_size), $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $plaintext .= $iv ^ substr($ciphertext, -$overflow); - $iv = substr_replace($iv, substr($ciphertext, -$overflow), 0, $overflow); - $pos = $overflow; - } elseif ($len) { - $plaintext .= openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv); - $iv = substr($ciphertext, -$this->block_size); - } - break; - case self::MODE_CFB8: - $plaintext = openssl_decrypt($ciphertext, $this->cipher_name_openssl, $this->key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $this->decryptIV); - if ($this->continuousBuffer) { - if (($len = strlen($ciphertext)) >= $this->block_size) { - $this->decryptIV = substr($ciphertext, -$this->block_size); - } else { - $this->decryptIV = substr($this->decryptIV, $len - $this->block_size) . substr($ciphertext, -$len); - } - } - break; - case self::MODE_OFB8: - $plaintext = ''; - $len = strlen($ciphertext); - $iv = $this->decryptIV; - - for ($i = 0; $i < $len; ++$i) { - $xor = openssl_encrypt($iv, $this->cipher_name_openssl_ecb, $this->key, $this->openssl_options, $this->decryptIV); - $plaintext .= $ciphertext[$i] ^ $xor; - $iv = substr($iv, 1) . $xor[0]; - } - - if ($this->continuousBuffer) { - $this->decryptIV = $iv; - } - break; - case self::MODE_OFB: - $plaintext = $this->openssl_ofb_process($ciphertext, $this->decryptIV, $this->debuffer); - } - - return $this->paddable ? $this->unpad($plaintext) : $plaintext; - } - - if ($this->engine === self::ENGINE_MCRYPT) { - set_error_handler(function () { - }); - $block_size = $this->block_size; - if ($this->dechanged) { - mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); - $this->dechanged = false; - } - - if ($this->mode == self::MODE_CFB && $this->continuousBuffer) { - $iv = &$this->decryptIV; - $pos = &$this->debuffer['pos']; - $len = strlen($ciphertext); - $plaintext = ''; - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len -= $max; - $pos = 0; - } else { - $i = $len; - $pos += $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $plaintext = substr($iv, $orig_pos) ^ $ciphertext; - $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); - } - if ($len >= $block_size) { - $cb = substr($ciphertext, $i, $len - $len % $block_size); - $plaintext .= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb; - $iv = substr($cb, -$block_size); - $len %= $block_size; - } - if ($len) { - $iv = mcrypt_generic($this->ecb, $iv); - $plaintext .= $iv ^ substr($ciphertext, -$len); - $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len); - $pos = $len; - } - - restore_error_handler(); - - return $plaintext; - } - - $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext); - - if (!$this->continuousBuffer) { - mcrypt_generic_init($this->demcrypt, $this->key, $this->getIV($this->decryptIV)); - } - - restore_error_handler(); - - return $this->paddable ? $this->unpad($plaintext) : $plaintext; - } - - if ($this->engine === self::ENGINE_EVAL) { - $inline = $this->inline_crypt; - return $inline('decrypt', $ciphertext); - } - - $block_size = $this->block_size; - - $buffer = &$this->debuffer; - $plaintext = ''; - switch ($this->mode) { - case self::MODE_ECB: - for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { - $plaintext .= $this->decryptBlock(substr($ciphertext, $i, $block_size)); - } - break; - case self::MODE_CBC: - $xor = $this->decryptIV; - for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { - $block = substr($ciphertext, $i, $block_size); - $plaintext .= $this->decryptBlock($block) ^ $xor; - $xor = $block; - } - if ($this->continuousBuffer) { - $this->decryptIV = $xor; - } - break; - case self::MODE_CTR: - $xor = $this->decryptIV; - if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { - $block = substr($ciphertext, $i, $block_size); - if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'] .= $this->encryptBlock($xor); - Strings::increment_str($xor); - } - $key = Strings::shift($buffer['ciphertext'], $block_size); - $plaintext .= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { - $block = substr($ciphertext, $i, $block_size); - $key = $this->encryptBlock($xor); - Strings::increment_str($xor); - $plaintext .= $block ^ $key; - } - } - if ($this->continuousBuffer) { - $this->decryptIV = $xor; - if ($start = strlen($ciphertext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; - } - } - break; - case self::MODE_CFB: - if ($this->continuousBuffer) { - $iv = &$this->decryptIV; - $pos = &$buffer['pos']; - } else { - $iv = $this->decryptIV; - $pos = 0; - } - $len = strlen($ciphertext); - $i = 0; - if ($pos) { - $orig_pos = $pos; - $max = $block_size - $pos; - if ($len >= $max) { - $i = $max; - $len -= $max; - $pos = 0; - } else { - $i = $len; - $pos += $len; - $len = 0; - } - // ie. $i = min($max, $len), $len-= $i, $pos+= $i, $pos%= $blocksize - $plaintext = substr($iv, $orig_pos) ^ $ciphertext; - $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i); - } - while ($len >= $block_size) { - $iv = $this->encryptBlock($iv); - $cb = substr($ciphertext, $i, $block_size); - $plaintext .= $iv ^ $cb; - $iv = $cb; - $len -= $block_size; - $i += $block_size; - } - if ($len) { - $iv = $this->encryptBlock($iv); - $plaintext .= $iv ^ substr($ciphertext, $i); - $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len); - $pos = $len; - } - break; - case self::MODE_CFB8: - $plaintext = ''; - $len = strlen($ciphertext); - $iv = $this->decryptIV; - - for ($i = 0; $i < $len; ++$i) { - $plaintext .= $ciphertext[$i] ^ $this->encryptBlock($iv); - $iv = substr($iv, 1) . $ciphertext[$i]; - } - - if ($this->continuousBuffer) { - if ($len >= $block_size) { - $this->decryptIV = substr($ciphertext, -$block_size); - } else { - $this->decryptIV = substr($this->decryptIV, $len - $block_size) . substr($ciphertext, -$len); - } - } - break; - case self::MODE_OFB8: - $plaintext = ''; - $len = strlen($ciphertext); - $iv = $this->decryptIV; - - for ($i = 0; $i < $len; ++$i) { - $xor = $this->encryptBlock($iv); - $plaintext .= $ciphertext[$i] ^ $xor; - $iv = substr($iv, 1) . $xor[0]; - } - - if ($this->continuousBuffer) { - $this->decryptIV = $iv; - } - break; - case self::MODE_OFB: - $xor = $this->decryptIV; - if (strlen($buffer['xor'])) { - for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { - $block = substr($ciphertext, $i, $block_size); - if (strlen($block) > strlen($buffer['xor'])) { - $xor = $this->encryptBlock($xor); - $buffer['xor'] .= $xor; - } - $key = Strings::shift($buffer['xor'], $block_size); - $plaintext .= $block ^ $key; - } - } else { - for ($i = 0; $i < strlen($ciphertext); $i += $block_size) { - $xor = $this->encryptBlock($xor); - $plaintext .= substr($ciphertext, $i, $block_size) ^ $xor; - } - $key = $xor; - } - if ($this->continuousBuffer) { - $this->decryptIV = $xor; - if ($start = strlen($ciphertext) % $block_size) { - $buffer['xor'] = substr($key, $start) . $buffer['xor']; - } - } - break; - case self::MODE_STREAM: - $plaintext = $this->decryptBlock($ciphertext); - break; - } - return $this->paddable ? $this->unpad($plaintext) : $plaintext; - } - - /** - * Get the authentication tag - * - * Only used in GCM or Poly1305 mode - * - * @see self::encrypt() - * @param int $length optional - * @return string - * @throws \LengthException if $length isn't of a sufficient length - * @throws \RuntimeException if GCM mode isn't being used - */ - public function getTag($length = 16) - { - if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { - throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); - } - - if ($this->newtag === false) { - throw new \BadMethodCallException('A tag can only be returned after a round of encryption has been performed'); - } - - // the tag is 128-bits. it can't be greater than 16 bytes because that's bigger than the tag is. if it - // were 0 you might as well be doing CTR and less than 4 provides minimal security that could be trivially - // easily brute forced. - // see https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=36 - // for more info - if ($length < 4 || $length > 16) { - throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); - } - - return $length == 16 ? - $this->newtag : - substr($this->newtag, 0, $length); - } - - /** - * Sets the authentication tag - * - * Only used in GCM mode - * - * @see self::decrypt() - * @param string $tag - * @throws \LengthException if $length isn't of a sufficient length - * @throws \RuntimeException if GCM mode isn't being used - */ - public function setTag($tag) - { - if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { - $this->createPoly1305Key(); - } - - if ($this->mode != self::MODE_GCM && !$this->usePoly1305) { - throw new \BadMethodCallException('Authentication tags are only utilized in GCM mode or with Poly1305'); - } - - $length = strlen($tag); - if ($length < 4 || $length > 16) { - throw new \LengthException('The authentication tag must be between 4 and 16 bytes long'); - } - $this->oldtag = $tag; - } - - /** - * Get the IV - * - * mcrypt requires an IV even if ECB is used - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $iv - * @return string - */ - protected function getIV($iv) - { - return $this->mode == self::MODE_ECB ? str_repeat("\0", $this->block_size) : $iv; - } - - /** - * OpenSSL CTR Processor - * - * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream - * for CTR is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() - * and SymmetricKey::decrypt(). Also, OpenSSL doesn't implement CTR for all of it's symmetric ciphers so this - * function will emulate CTR with ECB when necessary. - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $plaintext - * @param string $encryptIV - * @param array $buffer - * @return string - */ - private function openssl_ctr_process($plaintext, &$encryptIV, &$buffer) - { - $ciphertext = ''; - - $block_size = $this->block_size; - $key = $this->key; - - if ($this->openssl_emulate_ctr) { - $xor = $encryptIV; - if (strlen($buffer['ciphertext'])) { - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $block = substr($plaintext, $i, $block_size); - if (strlen($block) > strlen($buffer['ciphertext'])) { - $buffer['ciphertext'] .= openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - } - Strings::increment_str($xor); - $otp = Strings::shift($buffer['ciphertext'], $block_size); - $ciphertext .= $block ^ $otp; - } - } else { - for ($i = 0; $i < strlen($plaintext); $i += $block_size) { - $block = substr($plaintext, $i, $block_size); - $otp = openssl_encrypt($xor, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - Strings::increment_str($xor); - $ciphertext .= $block ^ $otp; - } - } - if ($this->continuousBuffer) { - $encryptIV = $xor; - if ($start = strlen($plaintext) % $block_size) { - $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext']; - } - } - - return $ciphertext; - } - - if (strlen($buffer['ciphertext'])) { - $ciphertext = $plaintext ^ Strings::shift($buffer['ciphertext'], strlen($plaintext)); - $plaintext = substr($plaintext, strlen($ciphertext)); - - if (!strlen($plaintext)) { - return $ciphertext; - } - } - - $overflow = strlen($plaintext) % $block_size; - if ($overflow) { - $plaintext2 = Strings::pop($plaintext, $overflow); // ie. trim $plaintext to a multiple of $block_size and put rest of $plaintext in $plaintext2 - $encrypted = openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - $temp = Strings::pop($encrypted, $block_size); - $ciphertext .= $encrypted . ($plaintext2 ^ $temp); - if ($this->continuousBuffer) { - $buffer['ciphertext'] = substr($temp, $overflow); - $encryptIV = $temp; - } - } elseif (!strlen($buffer['ciphertext'])) { - $ciphertext .= openssl_encrypt($plaintext . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - $temp = Strings::pop($ciphertext, $block_size); - if ($this->continuousBuffer) { - $encryptIV = $temp; - } - } - if ($this->continuousBuffer) { - $encryptIV = openssl_decrypt($encryptIV, $this->cipher_name_openssl_ecb, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); - if ($overflow) { - Strings::increment_str($encryptIV); - } - } - - return $ciphertext; - } - - /** - * OpenSSL OFB Processor - * - * PHP's OpenSSL bindings do not operate in continuous mode so we'll wrap around it. Since the keystream - * for OFB is the same for both encrypting and decrypting this function is re-used by both SymmetricKey::encrypt() - * and SymmetricKey::decrypt(). - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $plaintext - * @param string $encryptIV - * @param array $buffer - * @return string - */ - private function openssl_ofb_process($plaintext, &$encryptIV, &$buffer) - { - if (strlen($buffer['xor'])) { - $ciphertext = $plaintext ^ $buffer['xor']; - $buffer['xor'] = substr($buffer['xor'], strlen($ciphertext)); - $plaintext = substr($plaintext, strlen($ciphertext)); - } else { - $ciphertext = ''; - } - - $block_size = $this->block_size; - - $len = strlen($plaintext); - $key = $this->key; - $overflow = $len % $block_size; - - if (strlen($plaintext)) { - if ($overflow) { - $ciphertext .= openssl_encrypt(substr($plaintext, 0, -$overflow) . str_repeat("\0", $block_size), $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - $xor = Strings::pop($ciphertext, $block_size); - if ($this->continuousBuffer) { - $encryptIV = $xor; - } - $ciphertext .= Strings::shift($xor, $overflow) ^ substr($plaintext, -$overflow); - if ($this->continuousBuffer) { - $buffer['xor'] = $xor; - } - } else { - $ciphertext = openssl_encrypt($plaintext, $this->cipher_name_openssl, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $encryptIV); - if ($this->continuousBuffer) { - $encryptIV = substr($ciphertext, -$block_size) ^ substr($plaintext, -$block_size); - } - } - } - - return $ciphertext; - } - - /** - * phpseclib <-> OpenSSL Mode Mapper - * - * May need to be overwritten by classes extending this one in some cases - * - * @return string - */ - protected function openssl_translate_mode() - { - switch ($this->mode) { - case self::MODE_ECB: - return 'ecb'; - case self::MODE_CBC: - return 'cbc'; - case self::MODE_CTR: - case self::MODE_GCM: - return 'ctr'; - case self::MODE_CFB: - return 'cfb'; - case self::MODE_CFB8: - return 'cfb8'; - case self::MODE_OFB: - return 'ofb'; - } - } - - /** - * Pad "packets". - * - * Block ciphers working by encrypting between their specified [$this->]block_size at a time - * If you ever need to encrypt or decrypt something that isn't of the proper length, it becomes necessary to - * pad the input so that it is of the proper length. - * - * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH, - * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping - * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is - * transmitted separately) - * - * @see self::disablePadding() - */ - public function enablePadding() - { - $this->padding = true; - } - - /** - * Do not pad packets. - * - * @see self::enablePadding() - */ - public function disablePadding() - { - $this->padding = false; - } - - /** - * Treat consecutive "packets" as if they are a continuous buffer. - * - * Say you have a 32-byte plaintext $plaintext. Using the default behavior, the two following code snippets - * will yield different outputs: - * - * - * echo $rijndael->encrypt(substr($plaintext, 0, 16)); - * echo $rijndael->encrypt(substr($plaintext, 16, 16)); - * - * - * echo $rijndael->encrypt($plaintext); - * - * - * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates - * another, as demonstrated with the following: - * - * - * $rijndael->encrypt(substr($plaintext, 0, 16)); - * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); - * - * - * echo $rijndael->decrypt($rijndael->encrypt(substr($plaintext, 16, 16))); - * - * - * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different - * outputs. The reason is due to the fact that the initialization vector's change after every encryption / - * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. - * - * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\*() object changes after each - * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that - * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), - * however, they are also less intuitive and more likely to cause you problems. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::disableContinuousBuffer() - */ - public function enableContinuousBuffer() - { - if ($this->mode == self::MODE_ECB) { - return; - } - - if ($this->mode == self::MODE_GCM) { - throw new \BadMethodCallException('This mode does not run in continuous mode'); - } - - $this->continuousBuffer = true; - - $this->setEngine(); - } - - /** - * Treat consecutive packets as if they are a discontinuous buffer. - * - * The default behavior. - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::enableContinuousBuffer() - */ - public function disableContinuousBuffer() - { - if ($this->mode == self::MODE_ECB) { - return; - } - if (!$this->continuousBuffer) { - return; - } - - $this->continuousBuffer = false; - - $this->setEngine(); - } - - /** - * Test for engine validity - * - * @see self::__construct() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - switch ($engine) { - case self::ENGINE_OPENSSL: - $this->openssl_emulate_ctr = false; - $result = $this->cipher_name_openssl && - extension_loaded('openssl'); - if (!$result) { - return false; - } - - $methods = openssl_get_cipher_methods(); - if (in_array($this->cipher_name_openssl, $methods)) { - return true; - } - // not all of openssl's symmetric cipher's support ctr. for those - // that don't we'll emulate it - switch ($this->mode) { - case self::MODE_CTR: - if (in_array($this->cipher_name_openssl_ecb, $methods)) { - $this->openssl_emulate_ctr = true; - return true; - } - } - return false; - case self::ENGINE_MCRYPT: - set_error_handler(function () { - }); - $result = $this->cipher_name_mcrypt && - extension_loaded('mcrypt') && - in_array($this->cipher_name_mcrypt, mcrypt_list_algorithms()); - restore_error_handler(); - return $result; - case self::ENGINE_EVAL: - return method_exists($this, 'setupInlineCrypt'); - case self::ENGINE_INTERNAL: - return true; - } - - return false; - } - - /** - * Test for engine validity - * - * @see self::__construct() - * @param string $engine - * @return bool - */ - public function isValidEngine($engine) - { - static $reverseMap; - if (!isset($reverseMap)) { - $reverseMap = array_map('strtolower', self::ENGINE_MAP); - $reverseMap = array_flip($reverseMap); - } - $engine = strtolower($engine); - if (!isset($reverseMap[$engine])) { - return false; - } - - return $this->isValidEngineHelper($reverseMap[$engine]); - } - - /** - * Sets the preferred crypt engine - * - * Currently, $engine could be: - * - * - libsodium[very fast] - * - * - OpenSSL [very fast] - * - * - mcrypt [fast] - * - * - Eval [slow] - * - * - PHP [slowest] - * - * If the preferred crypt engine is not available the fastest available one will be used - * - * @see self::__construct() - * @param string $engine - */ - public function setPreferredEngine($engine) - { - static $reverseMap; - if (!isset($reverseMap)) { - $reverseMap = array_map('strtolower', self::ENGINE_MAP); - $reverseMap = array_flip($reverseMap); - } - $engine = is_string($engine) ? strtolower($engine) : ''; - $this->preferredEngine = isset($reverseMap[$engine]) ? $reverseMap[$engine] : self::ENGINE_LIBSODIUM; - - $this->setEngine(); - } - - /** - * Returns the engine currently being utilized - * - * @see self::setEngine() - */ - public function getEngine() - { - return self::ENGINE_MAP[$this->engine]; - } - - /** - * Sets the engine as appropriate - * - * @see self::__construct() - */ - protected function setEngine() - { - $this->engine = null; - - $candidateEngines = [ - self::ENGINE_LIBSODIUM, - self::ENGINE_OPENSSL_GCM, - self::ENGINE_OPENSSL, - self::ENGINE_MCRYPT, - self::ENGINE_EVAL - ]; - if (isset($this->preferredEngine)) { - $temp = [$this->preferredEngine]; - $candidateEngines = array_merge( - $temp, - array_diff($candidateEngines, $temp) - ); - } - foreach ($candidateEngines as $engine) { - if ($this->isValidEngineHelper($engine)) { - $this->engine = $engine; - break; - } - } - if (!$this->engine) { - $this->engine = self::ENGINE_INTERNAL; - } - - if ($this->engine != self::ENGINE_MCRYPT && $this->enmcrypt) { - set_error_handler(function () { - }); - // Closing the current mcrypt resource(s). _mcryptSetup() will, if needed, - // (re)open them with the module named in $this->cipher_name_mcrypt - mcrypt_module_close($this->enmcrypt); - mcrypt_module_close($this->demcrypt); - $this->enmcrypt = null; - $this->demcrypt = null; - - if ($this->ecb) { - mcrypt_module_close($this->ecb); - $this->ecb = null; - } - restore_error_handler(); - } - - $this->changed = $this->nonIVChanged = true; - } - - /** - * Encrypts a block - * - * Note: Must be extended by the child \phpseclib3\Crypt\* class - * - * @param string $in - * @return string - */ - abstract protected function encryptBlock($in); - - /** - * Decrypts a block - * - * Note: Must be extended by the child \phpseclib3\Crypt\* class - * - * @param string $in - * @return string - */ - abstract protected function decryptBlock($in); - - /** - * Setup the key (expansion) - * - * Only used if $engine == self::ENGINE_INTERNAL - * - * Note: Must extend by the child \phpseclib3\Crypt\* class - * - * @see self::setup() - */ - abstract protected function setupKey(); - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine and flush all $buffers - * Used (only) if $engine == self::ENGINE_INTERNAL - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setIV() - * - * - disableContinuousBuffer() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * {@internal setup() is always called before en/decryption.} - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::setKey() - * @see self::setIV() - * @see self::disableContinuousBuffer() - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - $this->changed = false; - - if ($this->usePoly1305 && !isset($this->poly1305Key) && method_exists($this, 'createPoly1305Key')) { - $this->createPoly1305Key(); - } - - $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true]; - //$this->newtag = $this->oldtag = false; - - if ($this->usesNonce()) { - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - if ($this->mode == self::MODE_GCM && !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { - $this->setupGCM(); - } - } else { - $this->iv = $this->origIV; - } - - if ($this->iv === false && !in_array($this->mode, [self::MODE_STREAM, self::MODE_ECB])) { - if ($this->mode != self::MODE_GCM || !in_array($this->engine, [self::ENGINE_LIBSODIUM, self::ENGINE_OPENSSL_GCM])) { - throw new InsufficientSetupException('No IV has been defined'); - } - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - $this->encryptIV = $this->decryptIV = $this->iv; - - switch ($this->engine) { - case self::ENGINE_MCRYPT: - $this->enchanged = $this->dechanged = true; - - set_error_handler(function () { - }); - - if (!isset($this->enmcrypt)) { - static $mcrypt_modes = [ - self::MODE_CTR => 'ctr', - self::MODE_ECB => MCRYPT_MODE_ECB, - self::MODE_CBC => MCRYPT_MODE_CBC, - self::MODE_CFB => 'ncfb', - self::MODE_CFB8 => MCRYPT_MODE_CFB, - self::MODE_OFB => MCRYPT_MODE_NOFB, - self::MODE_OFB8 => MCRYPT_MODE_OFB, - self::MODE_STREAM => MCRYPT_MODE_STREAM, - ]; - - $this->demcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - $this->enmcrypt = mcrypt_module_open($this->cipher_name_mcrypt, '', $mcrypt_modes[$this->mode], ''); - - // we need the $ecb mcrypt resource (only) in MODE_CFB with enableContinuousBuffer() - // to workaround mcrypt's broken ncfb implementation in buffered mode - // see: {@link http://phpseclib.sourceforge.net/cfb-demo.phps} - if ($this->mode == self::MODE_CFB) { - $this->ecb = mcrypt_module_open($this->cipher_name_mcrypt, '', MCRYPT_MODE_ECB, ''); - } - } // else should mcrypt_generic_deinit be called? - - if ($this->mode == self::MODE_CFB) { - mcrypt_generic_init($this->ecb, $this->key, str_repeat("\0", $this->block_size)); - } - - restore_error_handler(); - - break; - case self::ENGINE_INTERNAL: - $this->setupKey(); - break; - case self::ENGINE_EVAL: - if ($this->nonIVChanged) { - $this->setupKey(); - $this->setupInlineCrypt(); - } - } - - $this->nonIVChanged = false; - } - - /** - * Pads a string - * - * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize. - * $this->block_size - (strlen($text) % $this->block_size) bytes are added, each of which is equal to - * chr($this->block_size - (strlen($text) % $this->block_size) - * - * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless - * and padding will, hence forth, be enabled. - * - * @see self::unpad() - * @param string $text - * @throws \LengthException if padding is disabled and the plaintext's length is not a multiple of the block size - * @return string - */ - protected function pad($text) - { - $length = strlen($text); - - if (!$this->padding) { - if ($length % $this->block_size == 0) { - return $text; - } else { - throw new \LengthException("The plaintext's length ($length) is not a multiple of the block size ({$this->block_size}). Try enabling padding."); - } - } - - $pad = $this->block_size - ($length % $this->block_size); - - return str_pad($text, $length + $pad, chr($pad)); - } - - /** - * Unpads a string. - * - * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong - * and false will be returned. - * - * @see self::pad() - * @param string $text - * @throws \LengthException if the ciphertext's length is not a multiple of the block size - * @return string - */ - protected function unpad($text) - { - if (!$this->padding) { - return $text; - } - - $length = ord($text[strlen($text) - 1]); - - if (!$length || $length > $this->block_size) { - throw new BadDecryptionException("The ciphertext has an invalid padding length ($length) compared to the block size ({$this->block_size})"); - } - - return substr($text, 0, -$length); - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * Stores the created (or existing) callback function-name - * in $this->inline_crypt - * - * Internally for phpseclib developers: - * - * _setupInlineCrypt() would be called only if: - * - * - $this->engine === self::ENGINE_EVAL - * - * - each time on _setup(), after(!) _setupKey() - * - * - * This ensures that _setupInlineCrypt() has always a - * full ready2go initializated internal cipher $engine state - * where, for example, the keys already expanded, - * keys/block_size calculated and such. - * - * It is, each time if called, the responsibility of _setupInlineCrypt(): - * - * - to set $this->inline_crypt to a valid and fully working callback function - * as a (faster) replacement for encrypt() / decrypt() - * - * - NOT to create unlimited callback functions (for memory reasons!) - * no matter how often _setupInlineCrypt() would be called. At some - * point of amount they must be generic re-useable. - * - * - the code of _setupInlineCrypt() it self, - * and the generated callback code, - * must be, in following order: - * - 100% safe - * - 100% compatible to encrypt()/decrypt() - * - using only php5+ features/lang-constructs/php-extensions if - * compatibility (down to php4) or fallback is provided - * - readable/maintainable/understandable/commented and... not-cryptic-styled-code :-) - * - >= 10% faster than encrypt()/decrypt() [which is, by the way, - * the reason for the existence of _setupInlineCrypt() :-)] - * - memory-nice - * - short (as good as possible) - * - * Note: - _setupInlineCrypt() is using _createInlineCryptFunction() to create the full callback function code. - * - In case of using inline crypting, _setupInlineCrypt() must extend by the child \phpseclib3\Crypt\* class. - * - The following variable names are reserved: - * - $_* (all variable names prefixed with an underscore) - * - $self (object reference to it self. Do not use $this, but $self instead) - * - $in (the content of $in has to en/decrypt by the generated code) - * - The callback function should not use the 'return' statement, but en/decrypt'ing the content of $in only - * - * {@internal If a Crypt_* class providing inline crypting it must extend _setupInlineCrypt()} - * - * @see self::setup() - * @see self::createInlineCryptFunction() - * @see self::encrypt() - * @see self::decrypt() - */ - //protected function setupInlineCrypt(); - - /** - * Creates the performance-optimized function for en/decrypt() - * - * Internally for phpseclib developers: - * - * _createInlineCryptFunction(): - * - * - merge the $cipher_code [setup'ed by _setupInlineCrypt()] - * with the current [$this->]mode of operation code - * - * - create the $inline function, which called by encrypt() / decrypt() - * as its replacement to speed up the en/decryption operations. - * - * - return the name of the created $inline callback function - * - * - used to speed up en/decryption - * - * - * - * The main reason why can speed up things [up to 50%] this way are: - * - * - using variables more effective then regular. - * (ie no use of expensive arrays but integers $k_0, $k_1 ... - * or even, for example, the pure $key[] values hardcoded) - * - * - avoiding 1000's of function calls of ie _encryptBlock() - * but inlining the crypt operations. - * in the mode of operation for() loop. - * - * - full loop unroll the (sometimes key-dependent) rounds - * avoiding this way ++$i counters and runtime-if's etc... - * - * The basic code architectur of the generated $inline en/decrypt() - * lambda function, in pseudo php, is: - * - * - * +----------------------------------------------------------------------------------------------+ - * | callback $inline = create_function: | - * | lambda_function_0001_crypt_ECB($action, $text) | - * | { | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_crypt']; // general init code. | - * | // ie: $sbox'es declarations used for | - * | // encrypt and decrypt'ing. | - * | | - * | switch ($action) { | - * | case 'encrypt': | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_encrypt']; // encrypt sepcific init code. | - * | ie: specified $key or $box | - * | declarations for encrypt'ing. | - * | | - * | foreach ($ciphertext) { | - * | $in = $block_size of $ciphertext; | - * | | - * | INSERT PHP CODE OF: | - * | $cipher_code['encrypt_block']; // encrypt's (string) $in, which is always: | - * | // strlen($in) == $this->block_size | - * | // here comes the cipher algorithm in action | - * | // for encryption. | - * | // $cipher_code['encrypt_block'] has to | - * | // encrypt the content of the $in variable | - * | | - * | $plaintext .= $in; | - * | } | - * | return $plaintext; | - * | | - * | case 'decrypt': | - * | INSERT PHP CODE OF: | - * | $cipher_code['init_decrypt']; // decrypt sepcific init code | - * | ie: specified $key or $box | - * | declarations for decrypt'ing. | - * | foreach ($plaintext) { | - * | $in = $block_size of $plaintext; | - * | | - * | INSERT PHP CODE OF: | - * | $cipher_code['decrypt_block']; // decrypt's (string) $in, which is always | - * | // strlen($in) == $this->block_size | - * | // here comes the cipher algorithm in action | - * | // for decryption. | - * | // $cipher_code['decrypt_block'] has to | - * | // decrypt the content of the $in variable | - * | $ciphertext .= $in; | - * | } | - * | return $ciphertext; | - * | } | - * | } | - * +----------------------------------------------------------------------------------------------+ - * - * - * See also the \phpseclib3\Crypt\*::_setupInlineCrypt()'s for - * productive inline $cipher_code's how they works. - * - * Structure of: - * - * $cipher_code = [ - * 'init_crypt' => (string) '', // optional - * 'init_encrypt' => (string) '', // optional - * 'init_decrypt' => (string) '', // optional - * 'encrypt_block' => (string) '', // required - * 'decrypt_block' => (string) '' // required - * ]; - * - * - * @see self::setupInlineCrypt() - * @see self::encrypt() - * @see self::decrypt() - * @param array $cipher_code - * @return string (the name of the created callback function) - */ - protected function createInlineCryptFunction($cipher_code) - { - $block_size = $this->block_size; - - // optional - $init_crypt = isset($cipher_code['init_crypt']) ? $cipher_code['init_crypt'] : ''; - $init_encrypt = isset($cipher_code['init_encrypt']) ? $cipher_code['init_encrypt'] : ''; - $init_decrypt = isset($cipher_code['init_decrypt']) ? $cipher_code['init_decrypt'] : ''; - // required - $encrypt_block = $cipher_code['encrypt_block']; - $decrypt_block = $cipher_code['decrypt_block']; - - // Generating mode of operation inline code, - // merged with the $cipher_code algorithm - // for encrypt- and decryption. - switch ($this->mode) { - case self::MODE_ECB: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - - for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { - $in = substr($_text, $_i, ' . $block_size . '); - ' . $encrypt_block . ' - $_ciphertext.= $in; - } - - return $_ciphertext; - '; - - $decrypt = $init_decrypt . ' - $_plaintext = ""; - $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); - $_ciphertext_len = strlen($_text); - - for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { - $in = substr($_text, $_i, ' . $block_size . '); - ' . $decrypt_block . ' - $_plaintext.= $in; - } - - return $this->unpad($_plaintext); - '; - break; - case self::MODE_CTR: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - $_xor = $this->encryptIV; - $_buffer = &$this->enbuffer; - if (strlen($_buffer["ciphertext"])) { - for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { - $_block = substr($_text, $_i, ' . $block_size . '); - if (strlen($_block) > strlen($_buffer["ciphertext"])) { - $in = $_xor; - ' . $encrypt_block . ' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_buffer["ciphertext"].= $in; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); - $_ciphertext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { - $_block = substr($_text, $_i, ' . $block_size . '); - $in = $_xor; - ' . $encrypt_block . ' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_key = $in; - $_ciphertext.= $_block ^ $_key; - } - } - if ($this->continuousBuffer) { - $this->encryptIV = $_xor; - if ($_start = $_plaintext_len % ' . $block_size . ') { - $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; - } - } - - return $_ciphertext; - '; - - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_ciphertext_len = strlen($_text); - $_xor = $this->decryptIV; - $_buffer = &$this->debuffer; - - if (strlen($_buffer["ciphertext"])) { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { - $_block = substr($_text, $_i, ' . $block_size . '); - if (strlen($_block) > strlen($_buffer["ciphertext"])) { - $in = $_xor; - ' . $encrypt_block . ' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_buffer["ciphertext"].= $in; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["ciphertext"], ' . $block_size . '); - $_plaintext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { - $_block = substr($_text, $_i, ' . $block_size . '); - $in = $_xor; - ' . $encrypt_block . ' - \phpseclib3\Common\Functions\Strings::increment_str($_xor); - $_key = $in; - $_plaintext.= $_block ^ $_key; - } - } - if ($this->continuousBuffer) { - $this->decryptIV = $_xor; - if ($_start = $_ciphertext_len % ' . $block_size . ') { - $_buffer["ciphertext"] = substr($_key, $_start) . $_buffer["ciphertext"]; - } - } - - return $_plaintext; - '; - break; - case self::MODE_CFB: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_buffer = &$this->enbuffer; - - if ($this->continuousBuffer) { - $_iv = &$this->encryptIV; - $_pos = &$_buffer["pos"]; - } else { - $_iv = $this->encryptIV; - $_pos = 0; - } - $_len = strlen($_text); - $_i = 0; - if ($_pos) { - $_orig_pos = $_pos; - $_max = ' . $block_size . ' - $_pos; - if ($_len >= $_max) { - $_i = $_max; - $_len-= $_max; - $_pos = 0; - } else { - $_i = $_len; - $_pos+= $_len; - $_len = 0; - } - $_ciphertext = substr($_iv, $_orig_pos) ^ $_text; - $_iv = substr_replace($_iv, $_ciphertext, $_orig_pos, $_i); - } - while ($_len >= ' . $block_size . ') { - $in = $_iv; - ' . $encrypt_block . '; - $_iv = $in ^ substr($_text, $_i, ' . $block_size . '); - $_ciphertext.= $_iv; - $_len-= ' . $block_size . '; - $_i+= ' . $block_size . '; - } - if ($_len) { - $in = $_iv; - ' . $encrypt_block . ' - $_iv = $in; - $_block = $_iv ^ substr($_text, $_i); - $_iv = substr_replace($_iv, $_block, 0, $_len); - $_ciphertext.= $_block; - $_pos = $_len; - } - return $_ciphertext; - '; - - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_buffer = &$this->debuffer; - - if ($this->continuousBuffer) { - $_iv = &$this->decryptIV; - $_pos = &$_buffer["pos"]; - } else { - $_iv = $this->decryptIV; - $_pos = 0; - } - $_len = strlen($_text); - $_i = 0; - if ($_pos) { - $_orig_pos = $_pos; - $_max = ' . $block_size . ' - $_pos; - if ($_len >= $_max) { - $_i = $_max; - $_len-= $_max; - $_pos = 0; - } else { - $_i = $_len; - $_pos+= $_len; - $_len = 0; - } - $_plaintext = substr($_iv, $_orig_pos) ^ $_text; - $_iv = substr_replace($_iv, substr($_text, 0, $_i), $_orig_pos, $_i); - } - while ($_len >= ' . $block_size . ') { - $in = $_iv; - ' . $encrypt_block . ' - $_iv = $in; - $cb = substr($_text, $_i, ' . $block_size . '); - $_plaintext.= $_iv ^ $cb; - $_iv = $cb; - $_len-= ' . $block_size . '; - $_i+= ' . $block_size . '; - } - if ($_len) { - $in = $_iv; - ' . $encrypt_block . ' - $_iv = $in; - $_plaintext.= $_iv ^ substr($_text, $_i); - $_iv = substr_replace($_iv, substr($_text, $_i), 0, $_len); - $_pos = $_len; - } - - return $_plaintext; - '; - break; - case self::MODE_CFB8: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_len = strlen($_text); - $_iv = $this->encryptIV; - - for ($_i = 0; $_i < $_len; ++$_i) { - $in = $_iv; - ' . $encrypt_block . ' - $_ciphertext .= ($_c = $_text[$_i] ^ $in); - $_iv = substr($_iv, 1) . $_c; - } - - if ($this->continuousBuffer) { - if ($_len >= ' . $block_size . ') { - $this->encryptIV = substr($_ciphertext, -' . $block_size . '); - } else { - $this->encryptIV = substr($this->encryptIV, $_len - ' . $block_size . ') . substr($_ciphertext, -$_len); - } - } - - return $_ciphertext; - '; - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_len = strlen($_text); - $_iv = $this->decryptIV; - - for ($_i = 0; $_i < $_len; ++$_i) { - $in = $_iv; - ' . $encrypt_block . ' - $_plaintext .= $_text[$_i] ^ $in; - $_iv = substr($_iv, 1) . $_text[$_i]; - } - - if ($this->continuousBuffer) { - if ($_len >= ' . $block_size . ') { - $this->decryptIV = substr($_text, -' . $block_size . '); - } else { - $this->decryptIV = substr($this->decryptIV, $_len - ' . $block_size . ') . substr($_text, -$_len); - } - } - - return $_plaintext; - '; - break; - case self::MODE_OFB8: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_len = strlen($_text); - $_iv = $this->encryptIV; - - for ($_i = 0; $_i < $_len; ++$_i) { - $in = $_iv; - ' . $encrypt_block . ' - $_ciphertext.= $_text[$_i] ^ $in; - $_iv = substr($_iv, 1) . $in[0]; - } - - if ($this->continuousBuffer) { - $this->encryptIV = $_iv; - } - - return $_ciphertext; - '; - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_len = strlen($_text); - $_iv = $this->decryptIV; - - for ($_i = 0; $_i < $_len; ++$_i) { - $in = $_iv; - ' . $encrypt_block . ' - $_plaintext.= $_text[$_i] ^ $in; - $_iv = substr($_iv, 1) . $in[0]; - } - - if ($this->continuousBuffer) { - $this->decryptIV = $_iv; - } - - return $_plaintext; - '; - break; - case self::MODE_OFB: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - $_xor = $this->encryptIV; - $_buffer = &$this->enbuffer; - - if (strlen($_buffer["xor"])) { - for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { - $_block = substr($_text, $_i, ' . $block_size . '); - if (strlen($_block) > strlen($_buffer["xor"])) { - $in = $_xor; - ' . $encrypt_block . ' - $_xor = $in; - $_buffer["xor"].= $_xor; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); - $_ciphertext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { - $in = $_xor; - ' . $encrypt_block . ' - $_xor = $in; - $_ciphertext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; - } - $_key = $_xor; - } - if ($this->continuousBuffer) { - $this->encryptIV = $_xor; - if ($_start = $_plaintext_len % ' . $block_size . ') { - $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; - } - } - return $_ciphertext; - '; - - $decrypt = $init_encrypt . ' - $_plaintext = ""; - $_ciphertext_len = strlen($_text); - $_xor = $this->decryptIV; - $_buffer = &$this->debuffer; - - if (strlen($_buffer["xor"])) { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { - $_block = substr($_text, $_i, ' . $block_size . '); - if (strlen($_block) > strlen($_buffer["xor"])) { - $in = $_xor; - ' . $encrypt_block . ' - $_xor = $in; - $_buffer["xor"].= $_xor; - } - $_key = \phpseclib3\Common\Functions\Strings::shift($_buffer["xor"], ' . $block_size . '); - $_plaintext.= $_block ^ $_key; - } - } else { - for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { - $in = $_xor; - ' . $encrypt_block . ' - $_xor = $in; - $_plaintext.= substr($_text, $_i, ' . $block_size . ') ^ $_xor; - } - $_key = $_xor; - } - if ($this->continuousBuffer) { - $this->decryptIV = $_xor; - if ($_start = $_ciphertext_len % ' . $block_size . ') { - $_buffer["xor"] = substr($_key, $_start) . $_buffer["xor"]; - } - } - return $_plaintext; - '; - break; - case self::MODE_STREAM: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - ' . $encrypt_block . ' - return $_ciphertext; - '; - $decrypt = $init_decrypt . ' - $_plaintext = ""; - ' . $decrypt_block . ' - return $_plaintext; - '; - break; - // case self::MODE_CBC: - default: - $encrypt = $init_encrypt . ' - $_ciphertext = ""; - $_plaintext_len = strlen($_text); - - $in = $this->encryptIV; - - for ($_i = 0; $_i < $_plaintext_len; $_i+= ' . $block_size . ') { - $in = substr($_text, $_i, ' . $block_size . ') ^ $in; - ' . $encrypt_block . ' - $_ciphertext.= $in; - } - - if ($this->continuousBuffer) { - $this->encryptIV = $in; - } - - return $_ciphertext; - '; - - $decrypt = $init_decrypt . ' - $_plaintext = ""; - $_text = str_pad($_text, strlen($_text) + (' . $block_size . ' - strlen($_text) % ' . $block_size . ') % ' . $block_size . ', chr(0)); - $_ciphertext_len = strlen($_text); - - $_iv = $this->decryptIV; - - for ($_i = 0; $_i < $_ciphertext_len; $_i+= ' . $block_size . ') { - $in = $_block = substr($_text, $_i, ' . $block_size . '); - ' . $decrypt_block . ' - $_plaintext.= $in ^ $_iv; - $_iv = $_block; - } - - if ($this->continuousBuffer) { - $this->decryptIV = $_iv; - } - - return $this->unpad($_plaintext); - '; - break; - } - - // Before discrediting this, please read the following: - // @see https://github.com/phpseclib/phpseclib/issues/1293 - // @see https://github.com/phpseclib/phpseclib/pull/1143 - eval('$func = function ($_action, $_text) { ' . $init_crypt . 'if ($_action == "encrypt") { ' . $encrypt . ' } else { ' . $decrypt . ' }};'); - - return \Closure::bind($func, $this, static::class); - } - - /** - * Convert float to int - * - * On ARM CPUs converting floats to ints doesn't always work - * - * @param string $x - * @return int - */ - protected static function safe_intval($x) - { - if (is_int($x)) { - return $x; - } - - if (self::$use_reg_intval) { - return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? intval($x) : $x; - } - - return (fmod($x, 0x80000000) & 0x7FFFFFFF) | - ((fmod(floor($x / 0x80000000), 2) & 1) << 31); - } - - /** - * eval()'able string for in-line float to int - * - * @return string - */ - protected static function safe_intval_inline() - { - if (self::$use_reg_intval) { - return PHP_INT_SIZE == 4 && PHP_VERSION_ID >= 80100 ? 'intval(%s)' : '%s'; - } - - $safeint = '(is_int($temp = %s) ? $temp : (fmod($temp, 0x80000000) & 0x7FFFFFFF) | '; - return $safeint . '((fmod(floor($temp / 0x80000000), 2) & 1) << 31))'; - } - - /** - * Sets up GCM parameters - * - * See steps 1-2 of https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=23 - * for more info - * - */ - private function setupGCM() - { - // don't keep on re-calculating $this->h - if (!$this->h || $this->hKey != $this->key) { - $cipher = new static('ecb'); - $cipher->setKey($this->key); - $cipher->disablePadding(); - - $this->h = self::$gcmField->newInteger( - Strings::switchEndianness($cipher->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")) - ); - $this->hKey = $this->key; - } - - if (strlen($this->nonce) == 12) { - $this->iv = $this->nonce . "\0\0\0\1"; - } else { - $this->iv = $this->ghash( - self::nullPad128($this->nonce) . str_repeat("\0", 8) . self::len64($this->nonce) - ); - } - } - - /** - * Performs GHASH operation - * - * See https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=20 - * for more info - * - * @see self::decrypt() - * @see self::encrypt() - * @param string $x - * @return string - */ - private function ghash($x) - { - $h = $this->h; - $y = ["\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"]; - $x = str_split($x, 16); - $n = 0; - // the switchEndianness calls are necessary because the multiplication algorithm in BinaryField/Integer - // interprets strings as polynomials in big endian order whereas in GCM they're interpreted in little - // endian order per https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf#page=19. - // big endian order is what binary field elliptic curves use per http://www.secg.org/sec1-v2.pdf#page=18. - - // we could switchEndianness here instead of in the while loop but doing so in the while loop seems like it - // might be slightly more performant - //$x = Strings::switchEndianness($x); - foreach ($x as $xn) { - $xn = Strings::switchEndianness($xn); - $t = $y[$n] ^ $xn; - $temp = self::$gcmField->newInteger($t); - $y[++$n] = $temp->multiply($h)->toBytes(); - $y[$n] = substr($y[$n], 1); - } - $y[$n] = Strings::switchEndianness($y[$n]); - return $y[$n]; - } - - /** - * Returns the bit length of a string in a packed format - * - * @see self::decrypt() - * @see self::encrypt() - * @see self::setupGCM() - * @param string $str - * @return string - */ - private static function len64($str) - { - return "\0\0\0\0" . pack('N', 8 * strlen($str)); - } - - /** - * NULL pads a string to be a multiple of 128 - * - * @see self::decrypt() - * @see self::encrypt() - * @see self::setupGCM() - * @param string $str - * @return string - */ - protected static function nullPad128($str) - { - $len = strlen($str); - return $str . str_repeat("\0", 16 * ceil($len / 16) - $len); - } - - /** - * Calculates Poly1305 MAC - * - * On my system ChaCha20, with libsodium, takes 0.5s. With this custom Poly1305 implementation - * it takes 1.2s. - * - * @see self::decrypt() - * @see self::encrypt() - * @param string $text - * @return string - */ - protected function poly1305($text) - { - $s = $this->poly1305Key; // strlen($this->poly1305Key) == 32 - $r = Strings::shift($s, 16); - $r = strrev($r); - $r &= "\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xfc\x0f\xff\xff\xff"; - $s = strrev($s); - - $r = self::$poly1305Field->newInteger(new BigInteger($r, 256)); - $s = self::$poly1305Field->newInteger(new BigInteger($s, 256)); - $a = self::$poly1305Field->newInteger(new BigInteger()); - - $blocks = str_split($text, 16); - foreach ($blocks as $block) { - $n = strrev($block . chr(1)); - $n = self::$poly1305Field->newInteger(new BigInteger($n, 256)); - $a = $a->add($n); - $a = $a->multiply($r); - } - $r = $a->toBigInteger()->add($s->toBigInteger()); - $mask = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; - return strrev($r->toBytes()) & $mask; - } - - /** - * Return the mode - * - * You can do $obj instanceof AES or whatever to get the cipher but you can't do that to get the mode - * - * @return string - */ - public function getMode() - { - return array_flip(self::MODE_MAP)[$this->mode]; - } - - /** - * Is the continuous buffer enabled? - * - * @return boolean - */ - public function continuousBufferEnabled() - { - return $this->continuousBuffer; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php deleted file mode 100644 index 9ca8926..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/Fingerprint.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Traits; - -use phpseclib3\Crypt\Hash; - -/** - * Fingerprint Trait for Private Keys - * - * @author Jim Wigginton - */ -trait Fingerprint -{ - /** - * Returns the public key's fingerprint - * - * The public key's fingerprint is returned, which is equivalent to running `ssh-keygen -lf rsa.pub`. If there is - * no public key currently loaded, false is returned. - * Example output (md5): "c1:b1:30:29:d7:b8:de:6c:97:77:10:d7:46:41:63:87" (as specified by RFC 4716) - * - * @param string $algorithm The hashing algorithm to be used. Valid options are 'md5' and 'sha256'. False is returned - * for invalid values. - * @return mixed - */ - public function getFingerprint($algorithm = 'md5') - { - $type = self::validatePlugin('Keys', 'OpenSSH', 'savePublicKey'); - if ($type === false) { - return false; - } - $key = $this->toString('OpenSSH', ['binary' => true]); - if ($key === false) { - return false; - } - switch ($algorithm) { - case 'sha256': - $hash = new Hash('sha256'); - $base = base64_encode($hash->hash($key)); - return substr($base, 0, strlen($base) - 1); - case 'md5': - return substr(chunk_split(md5($key), 2, ':'), 0, -1); - default: - return false; - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php deleted file mode 100644 index 0ac274e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Common/Traits/PasswordProtected.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\Common\Traits; - -/** - * Password Protected Trait for Private Keys - * - * @author Jim Wigginton - */ -trait PasswordProtected -{ - /** - * Password - * - * @var string|bool - */ - private $password = false; - - /** - * Sets the password - * - * Private keys can be encrypted with a password. To unset the password, pass in the empty string or false. - * Or rather, pass in $password such that empty($password) && !is_string($password) is true. - * - * @see self::createKey() - * @see self::load() - * @param string|bool $password - */ - public function withPassword($password = false) - { - $new = clone $this; - $new->password = $password; - return $new; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php deleted file mode 100644 index 3b03830..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DES.php +++ /dev/null @@ -1,1392 +0,0 @@ - - * setKey('abcdefgh'); - * - * $size = 10 * 1024; - * $plaintext = ''; - * for ($i = 0; $i < $size; $i++) { - * $plaintext.= 'a'; - * } - * - * echo $des->decrypt($des->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadModeException; - -/** - * Pure-PHP implementation of DES. - * - * @author Jim Wigginton - */ -class DES extends BlockCipher -{ - /** - * Contains $keys[self::ENCRYPT] - * - * @see \phpseclib3\Crypt\DES::setupKey() - * @see \phpseclib3\Crypt\DES::processBlock() - */ - const ENCRYPT = 0; - /** - * Contains $keys[self::DECRYPT] - * - * @see \phpseclib3\Crypt\DES::setupKey() - * @see \phpseclib3\Crypt\DES::processBlock() - */ - const DECRYPT = 1; - - /** - * Block Length of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size - * @var int - */ - protected $block_size = 8; - - /** - * Key Length (in bytes) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKeyLength() - * @var int - */ - protected $key_length = 8; - - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @var string - */ - protected $cipher_name_mcrypt = 'des'; - - /** - * The OpenSSL names of the cipher / modes - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::openssl_mode_names - * @var array - */ - protected $openssl_mode_names = [ - self::MODE_ECB => 'des-ecb', - self::MODE_CBC => 'des-cbc', - self::MODE_CFB => 'des-cfb', - self::MODE_OFB => 'des-ofb' - // self::MODE_CTR is undefined for DES - ]; - - /** - * Optimizing value while CFB-encrypting - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len - * @var int - */ - protected $cfb_init_len = 500; - - /** - * Switch for DES/3DES encryption - * - * Used only if $engine == self::ENGINE_INTERNAL - * - * @see self::setupKey() - * @see self::processBlock() - * @var int - */ - protected $des_rounds = 1; - - /** - * max possible size of $key - * - * @see self::setKey() - * @var string - */ - protected $key_length_max = 8; - - /** - * The Key Schedule - * - * @see self::setupKey() - * @var array - */ - private $keys; - - /** - * Key Cache "key" - * - * @see self::setupKey() - * @var array - */ - private $kl; - - /** - * Shuffle table. - * - * For each byte value index, the entry holds an 8-byte string - * with each byte containing all bits in the same state as the - * corresponding bit in the index value. - * - * @see self::processBlock() - * @see self::setupKey() - * @var array - */ - protected static $shuffle = [ - "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF", - "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF", - "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF", - "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF", - "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF", - "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF", - "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF", - "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF", - "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF", - "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF", - "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF", - "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF", - "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF", - "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF", - "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF", - "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF", - "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF", - "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF", - "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF", - "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF", - "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF", - "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF", - "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF", - "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF", - "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF", - "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF", - "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF", - "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF", - "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF", - "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF", - "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF", - "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF", - "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF", - "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF", - "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF", - "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF", - "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF", - "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF", - "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF", - "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF", - "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF", - "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF", - "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF", - "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF", - "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF", - "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF", - "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF", - "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF", - "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF", - "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF", - "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF", - "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF", - "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF", - "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF", - "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF", - "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF", - "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF", - "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF", - "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF", - "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF", - "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF", - "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF", - "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF", - "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF", - "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF", - "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF", - "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF", - "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF", - "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF", - "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF", - "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF", - "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF", - "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF", - "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF", - "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF", - "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF", - "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF", - "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF", - "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF", - "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF", - "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF", - "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF", - "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF", - "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF", - "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF", - "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF", - "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF", - "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF", - "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF", - "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF", - "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF", - "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF", - "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF", - "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF", - "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF", - "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF", - "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF", - "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF", - "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF", - "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF", - "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF", - "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF", - "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF", - "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF", - "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF", - "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF", - "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF", - "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF", - "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF", - "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF", - "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF", - "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF", - "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF", - "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF", - "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF", - "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF", - "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF", - "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF", - "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF", - "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF", - "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF", - "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF", - "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF", - "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF", - "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF", - "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF", - "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF", - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - ]; - - /** - * IP mapping helper table. - * - * Indexing this table with each source byte performs the initial bit permutation. - * - * @var array - */ - protected static $ipmap = [ - 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31, - 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33, - 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71, - 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73, - 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35, - 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37, - 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75, - 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77, - 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1, - 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3, - 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1, - 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3, - 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5, - 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7, - 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5, - 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7, - 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39, - 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B, - 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79, - 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B, - 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D, - 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F, - 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D, - 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F, - 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9, - 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB, - 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9, - 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB, - 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD, - 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF, - 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD, - 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF - ]; - - /** - * Inverse IP mapping helper table. - * Indexing this table with a byte value reverses the bit order. - * - * @var array - */ - protected static $invipmap = [ - 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, - 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0, - 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, - 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, - 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, - 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4, - 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, - 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC, - 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, - 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, - 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, - 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA, - 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, - 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6, - 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, - 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, - 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, - 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1, - 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, - 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9, - 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, - 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, - 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, - 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD, - 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, - 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3, - 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, - 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, - 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, - 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7, - 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, - 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF - ]; - - /** - * Pre-permuted S-box1 - * - * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the - * P table: concatenation can then be replaced by exclusive ORs. - * - * @var array - */ - protected static $sbox1 = [ - 0x00808200, 0x00000000, 0x00008000, 0x00808202, - 0x00808002, 0x00008202, 0x00000002, 0x00008000, - 0x00000200, 0x00808200, 0x00808202, 0x00000200, - 0x00800202, 0x00808002, 0x00800000, 0x00000002, - 0x00000202, 0x00800200, 0x00800200, 0x00008200, - 0x00008200, 0x00808000, 0x00808000, 0x00800202, - 0x00008002, 0x00800002, 0x00800002, 0x00008002, - 0x00000000, 0x00000202, 0x00008202, 0x00800000, - 0x00008000, 0x00808202, 0x00000002, 0x00808000, - 0x00808200, 0x00800000, 0x00800000, 0x00000200, - 0x00808002, 0x00008000, 0x00008200, 0x00800002, - 0x00000200, 0x00000002, 0x00800202, 0x00008202, - 0x00808202, 0x00008002, 0x00808000, 0x00800202, - 0x00800002, 0x00000202, 0x00008202, 0x00808200, - 0x00000202, 0x00800200, 0x00800200, 0x00000000, - 0x00008002, 0x00008200, 0x00000000, 0x00808002 - ]; - - /** - * Pre-permuted S-box2 - * - * @var array - */ - protected static $sbox2 = [ - 0x40084010, 0x40004000, 0x00004000, 0x00084010, - 0x00080000, 0x00000010, 0x40080010, 0x40004010, - 0x40000010, 0x40084010, 0x40084000, 0x40000000, - 0x40004000, 0x00080000, 0x00000010, 0x40080010, - 0x00084000, 0x00080010, 0x40004010, 0x00000000, - 0x40000000, 0x00004000, 0x00084010, 0x40080000, - 0x00080010, 0x40000010, 0x00000000, 0x00084000, - 0x00004010, 0x40084000, 0x40080000, 0x00004010, - 0x00000000, 0x00084010, 0x40080010, 0x00080000, - 0x40004010, 0x40080000, 0x40084000, 0x00004000, - 0x40080000, 0x40004000, 0x00000010, 0x40084010, - 0x00084010, 0x00000010, 0x00004000, 0x40000000, - 0x00004010, 0x40084000, 0x00080000, 0x40000010, - 0x00080010, 0x40004010, 0x40000010, 0x00080010, - 0x00084000, 0x00000000, 0x40004000, 0x00004010, - 0x40000000, 0x40080010, 0x40084010, 0x00084000 - ]; - - /** - * Pre-permuted S-box3 - * - * @var array - */ - protected static $sbox3 = [ - 0x00000104, 0x04010100, 0x00000000, 0x04010004, - 0x04000100, 0x00000000, 0x00010104, 0x04000100, - 0x00010004, 0x04000004, 0x04000004, 0x00010000, - 0x04010104, 0x00010004, 0x04010000, 0x00000104, - 0x04000000, 0x00000004, 0x04010100, 0x00000100, - 0x00010100, 0x04010000, 0x04010004, 0x00010104, - 0x04000104, 0x00010100, 0x00010000, 0x04000104, - 0x00000004, 0x04010104, 0x00000100, 0x04000000, - 0x04010100, 0x04000000, 0x00010004, 0x00000104, - 0x00010000, 0x04010100, 0x04000100, 0x00000000, - 0x00000100, 0x00010004, 0x04010104, 0x04000100, - 0x04000004, 0x00000100, 0x00000000, 0x04010004, - 0x04000104, 0x00010000, 0x04000000, 0x04010104, - 0x00000004, 0x00010104, 0x00010100, 0x04000004, - 0x04010000, 0x04000104, 0x00000104, 0x04010000, - 0x00010104, 0x00000004, 0x04010004, 0x00010100 - ]; - - /** - * Pre-permuted S-box4 - * - * @var array - */ - protected static $sbox4 = [ - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x00401040, 0x80400040, 0x80400000, 0x80001000, - 0x00000000, 0x00401000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00400040, 0x80400000, - 0x80000000, 0x00001000, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x80001000, 0x00001040, - 0x80400040, 0x80000000, 0x00001040, 0x00400040, - 0x00001000, 0x00401040, 0x80401040, 0x80000040, - 0x00400040, 0x80400000, 0x00401000, 0x80401040, - 0x80000040, 0x00000000, 0x00000000, 0x00401000, - 0x00001040, 0x00400040, 0x80400040, 0x80000000, - 0x80401000, 0x80001040, 0x80001040, 0x00000040, - 0x80401040, 0x80000040, 0x80000000, 0x00001000, - 0x80400000, 0x80001000, 0x00401040, 0x80400040, - 0x80001000, 0x00001040, 0x00400000, 0x80401000, - 0x00000040, 0x00400000, 0x00001000, 0x00401040 - ]; - - /** - * Pre-permuted S-box5 - * - * @var array - */ - protected static $sbox5 = [ - 0x00000080, 0x01040080, 0x01040000, 0x21000080, - 0x00040000, 0x00000080, 0x20000000, 0x01040000, - 0x20040080, 0x00040000, 0x01000080, 0x20040080, - 0x21000080, 0x21040000, 0x00040080, 0x20000000, - 0x01000000, 0x20040000, 0x20040000, 0x00000000, - 0x20000080, 0x21040080, 0x21040080, 0x01000080, - 0x21040000, 0x20000080, 0x00000000, 0x21000000, - 0x01040080, 0x01000000, 0x21000000, 0x00040080, - 0x00040000, 0x21000080, 0x00000080, 0x01000000, - 0x20000000, 0x01040000, 0x21000080, 0x20040080, - 0x01000080, 0x20000000, 0x21040000, 0x01040080, - 0x20040080, 0x00000080, 0x01000000, 0x21040000, - 0x21040080, 0x00040080, 0x21000000, 0x21040080, - 0x01040000, 0x00000000, 0x20040000, 0x21000000, - 0x00040080, 0x01000080, 0x20000080, 0x00040000, - 0x00000000, 0x20040000, 0x01040080, 0x20000080 - ]; - - /** - * Pre-permuted S-box6 - * - * @var array - */ - protected static $sbox6 = [ - 0x10000008, 0x10200000, 0x00002000, 0x10202008, - 0x10200000, 0x00000008, 0x10202008, 0x00200000, - 0x10002000, 0x00202008, 0x00200000, 0x10000008, - 0x00200008, 0x10002000, 0x10000000, 0x00002008, - 0x00000000, 0x00200008, 0x10002008, 0x00002000, - 0x00202000, 0x10002008, 0x00000008, 0x10200008, - 0x10200008, 0x00000000, 0x00202008, 0x10202000, - 0x00002008, 0x00202000, 0x10202000, 0x10000000, - 0x10002000, 0x00000008, 0x10200008, 0x00202000, - 0x10202008, 0x00200000, 0x00002008, 0x10000008, - 0x00200000, 0x10002000, 0x10000000, 0x00002008, - 0x10000008, 0x10202008, 0x00202000, 0x10200000, - 0x00202008, 0x10202000, 0x00000000, 0x10200008, - 0x00000008, 0x00002000, 0x10200000, 0x00202008, - 0x00002000, 0x00200008, 0x10002008, 0x00000000, - 0x10202000, 0x10000000, 0x00200008, 0x10002008 - ]; - - /** - * Pre-permuted S-box7 - * - * @var array - */ - protected static $sbox7 = [ - 0x00100000, 0x02100001, 0x02000401, 0x00000000, - 0x00000400, 0x02000401, 0x00100401, 0x02100400, - 0x02100401, 0x00100000, 0x00000000, 0x02000001, - 0x00000001, 0x02000000, 0x02100001, 0x00000401, - 0x02000400, 0x00100401, 0x00100001, 0x02000400, - 0x02000001, 0x02100000, 0x02100400, 0x00100001, - 0x02100000, 0x00000400, 0x00000401, 0x02100401, - 0x00100400, 0x00000001, 0x02000000, 0x00100400, - 0x02000000, 0x00100400, 0x00100000, 0x02000401, - 0x02000401, 0x02100001, 0x02100001, 0x00000001, - 0x00100001, 0x02000000, 0x02000400, 0x00100000, - 0x02100400, 0x00000401, 0x00100401, 0x02100400, - 0x00000401, 0x02000001, 0x02100401, 0x02100000, - 0x00100400, 0x00000000, 0x00000001, 0x02100401, - 0x00000000, 0x00100401, 0x02100000, 0x00000400, - 0x02000001, 0x02000400, 0x00000400, 0x00100001 - ]; - - /** - * Pre-permuted S-box8 - * - * @var array - */ - protected static $sbox8 = [ - 0x08000820, 0x00000800, 0x00020000, 0x08020820, - 0x08000000, 0x08000820, 0x00000020, 0x08000000, - 0x00020020, 0x08020000, 0x08020820, 0x00020800, - 0x08020800, 0x00020820, 0x00000800, 0x00000020, - 0x08020000, 0x08000020, 0x08000800, 0x00000820, - 0x00020800, 0x00020020, 0x08020020, 0x08020800, - 0x00000820, 0x00000000, 0x00000000, 0x08020020, - 0x08000020, 0x08000800, 0x00020820, 0x00020000, - 0x00020820, 0x00020000, 0x08020800, 0x00000800, - 0x00000020, 0x08020020, 0x00000800, 0x00020820, - 0x08000800, 0x00000020, 0x08000020, 0x08020000, - 0x08020020, 0x08000000, 0x00020000, 0x08000820, - 0x00000000, 0x08020820, 0x00020020, 0x08000020, - 0x08020000, 0x08000800, 0x08000820, 0x00000000, - 0x08020820, 0x00020800, 0x00020800, 0x00000820, - 0x00000820, 0x00020020, 0x08000000, 0x08020800 - ]; - - /** - * Default Constructor. - * - * @param string $mode - * @throws BadModeException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - if ($this->key_length_max == 8) { - if ($engine == self::ENGINE_OPENSSL) { - // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 - // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" - // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { - return false; - } - $this->cipher_name_openssl_ecb = 'des-ecb'; - $this->cipher_name_openssl = 'des-' . $this->openssl_translate_mode(); - } - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Sets the key. - * - * Keys must be 64-bits long or 8 bytes long. - * - * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() - * @param string $key - */ - public function setKey($key) - { - if (!($this instanceof TripleDES) && strlen($key) != 8) { - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of size 8 are supported'); - } - - // Sets the key - parent::setKey($key); - } - - /** - * Encrypts a block - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::encrypt() - * @param string $in - * @return string - */ - protected function encryptBlock($in) - { - return $this->processBlock($in, self::ENCRYPT); - } - - /** - * Decrypts a block - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::decrypt() - * @param string $in - * @return string - */ - protected function decryptBlock($in) - { - return $this->processBlock($in, self::DECRYPT); - } - - /** - * Encrypts or decrypts a 64-bit block - * - * $mode should be either self::ENCRYPT or self::DECRYPT. See - * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general - * idea of what this function does. - * - * @see self::encryptBlock() - * @see self::decryptBlock() - * @param string $block - * @param int $mode - * @return string - */ - private function processBlock($block, $mode) - { - static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; - if (!$sbox1) { - $sbox1 = array_map('intval', self::$sbox1); - $sbox2 = array_map('intval', self::$sbox2); - $sbox3 = array_map('intval', self::$sbox3); - $sbox4 = array_map('intval', self::$sbox4); - $sbox5 = array_map('intval', self::$sbox5); - $sbox6 = array_map('intval', self::$sbox6); - $sbox7 = array_map('intval', self::$sbox7); - $sbox8 = array_map('intval', self::$sbox8); - /* Merge $shuffle with $[inv]ipmap */ - for ($i = 0; $i < 256; ++$i) { - $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; - $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; - } - } - - $keys = $this->keys[$mode]; - $ki = -1; - - // Do the initial IP permutation. - $t = unpack('Nl/Nr', $block); - list($l, $r) = [$t['l'], $t['r']]; - $block = ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); - - // Extract L0 and R0. - $t = unpack('Nl/Nr', $block); - list($l, $r) = [$t['l'], $t['r']]; - - for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { - // Perform the 16 steps. - for ($i = 0; $i < 16; $i++) { - // start of "the Feistel (F) function" - see the following URL: - // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png - // Merge key schedule. - $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[++$ki]; - $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[++$ki]; - - // S-box indexing. - $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ - $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ - $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ - $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $l; - // end of "the Feistel (F) function" - - $l = $r; - $r = $t; - } - - // Last step should not permute L & R. - $t = $l; - $l = $r; - $r = $t; - } - - // Perform the inverse IP permutation. - return ($shuffleinvip[($r >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleinvip[($l >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleinvip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleinvip[($l >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleinvip[($r >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleinvip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleinvip[ $r & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleinvip[ $l & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); - } - - /** - * Creates the key schedule - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() - */ - protected function setupKey() - { - if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->des_rounds === $this->kl['des_rounds']) { - // already expanded - return; - } - $this->kl = ['key' => $this->key, 'des_rounds' => $this->des_rounds]; - - static $shifts = [ // number of key bits shifted per round - 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 - ]; - - static $pc1map = [ - 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C, - 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E, - 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C, - 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E, - 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C, - 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E, - 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C, - 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E, - 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C, - 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E, - 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C, - 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E, - 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C, - 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E, - 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C, - 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E, - 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C, - 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E, - 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C, - 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E, - 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC, - 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE, - 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC, - 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE, - 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC, - 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE, - 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC, - 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE, - 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC, - 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE, - 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC, - 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE - ]; - - // Mapping tables for the PC-2 transformation. - static $pc2mapc1 = [ - 0x00000000, 0x00000400, 0x00200000, 0x00200400, - 0x00000001, 0x00000401, 0x00200001, 0x00200401, - 0x02000000, 0x02000400, 0x02200000, 0x02200400, - 0x02000001, 0x02000401, 0x02200001, 0x02200401 - ]; - static $pc2mapc2 = [ - 0x00000000, 0x00000800, 0x08000000, 0x08000800, - 0x00010000, 0x00010800, 0x08010000, 0x08010800, - 0x00000000, 0x00000800, 0x08000000, 0x08000800, - 0x00010000, 0x00010800, 0x08010000, 0x08010800, - 0x00000100, 0x00000900, 0x08000100, 0x08000900, - 0x00010100, 0x00010900, 0x08010100, 0x08010900, - 0x00000100, 0x00000900, 0x08000100, 0x08000900, - 0x00010100, 0x00010900, 0x08010100, 0x08010900, - 0x00000010, 0x00000810, 0x08000010, 0x08000810, - 0x00010010, 0x00010810, 0x08010010, 0x08010810, - 0x00000010, 0x00000810, 0x08000010, 0x08000810, - 0x00010010, 0x00010810, 0x08010010, 0x08010810, - 0x00000110, 0x00000910, 0x08000110, 0x08000910, - 0x00010110, 0x00010910, 0x08010110, 0x08010910, - 0x00000110, 0x00000910, 0x08000110, 0x08000910, - 0x00010110, 0x00010910, 0x08010110, 0x08010910, - 0x00040000, 0x00040800, 0x08040000, 0x08040800, - 0x00050000, 0x00050800, 0x08050000, 0x08050800, - 0x00040000, 0x00040800, 0x08040000, 0x08040800, - 0x00050000, 0x00050800, 0x08050000, 0x08050800, - 0x00040100, 0x00040900, 0x08040100, 0x08040900, - 0x00050100, 0x00050900, 0x08050100, 0x08050900, - 0x00040100, 0x00040900, 0x08040100, 0x08040900, - 0x00050100, 0x00050900, 0x08050100, 0x08050900, - 0x00040010, 0x00040810, 0x08040010, 0x08040810, - 0x00050010, 0x00050810, 0x08050010, 0x08050810, - 0x00040010, 0x00040810, 0x08040010, 0x08040810, - 0x00050010, 0x00050810, 0x08050010, 0x08050810, - 0x00040110, 0x00040910, 0x08040110, 0x08040910, - 0x00050110, 0x00050910, 0x08050110, 0x08050910, - 0x00040110, 0x00040910, 0x08040110, 0x08040910, - 0x00050110, 0x00050910, 0x08050110, 0x08050910, - 0x01000000, 0x01000800, 0x09000000, 0x09000800, - 0x01010000, 0x01010800, 0x09010000, 0x09010800, - 0x01000000, 0x01000800, 0x09000000, 0x09000800, - 0x01010000, 0x01010800, 0x09010000, 0x09010800, - 0x01000100, 0x01000900, 0x09000100, 0x09000900, - 0x01010100, 0x01010900, 0x09010100, 0x09010900, - 0x01000100, 0x01000900, 0x09000100, 0x09000900, - 0x01010100, 0x01010900, 0x09010100, 0x09010900, - 0x01000010, 0x01000810, 0x09000010, 0x09000810, - 0x01010010, 0x01010810, 0x09010010, 0x09010810, - 0x01000010, 0x01000810, 0x09000010, 0x09000810, - 0x01010010, 0x01010810, 0x09010010, 0x09010810, - 0x01000110, 0x01000910, 0x09000110, 0x09000910, - 0x01010110, 0x01010910, 0x09010110, 0x09010910, - 0x01000110, 0x01000910, 0x09000110, 0x09000910, - 0x01010110, 0x01010910, 0x09010110, 0x09010910, - 0x01040000, 0x01040800, 0x09040000, 0x09040800, - 0x01050000, 0x01050800, 0x09050000, 0x09050800, - 0x01040000, 0x01040800, 0x09040000, 0x09040800, - 0x01050000, 0x01050800, 0x09050000, 0x09050800, - 0x01040100, 0x01040900, 0x09040100, 0x09040900, - 0x01050100, 0x01050900, 0x09050100, 0x09050900, - 0x01040100, 0x01040900, 0x09040100, 0x09040900, - 0x01050100, 0x01050900, 0x09050100, 0x09050900, - 0x01040010, 0x01040810, 0x09040010, 0x09040810, - 0x01050010, 0x01050810, 0x09050010, 0x09050810, - 0x01040010, 0x01040810, 0x09040010, 0x09040810, - 0x01050010, 0x01050810, 0x09050010, 0x09050810, - 0x01040110, 0x01040910, 0x09040110, 0x09040910, - 0x01050110, 0x01050910, 0x09050110, 0x09050910, - 0x01040110, 0x01040910, 0x09040110, 0x09040910, - 0x01050110, 0x01050910, 0x09050110, 0x09050910 - ]; - static $pc2mapc3 = [ - 0x00000000, 0x00000004, 0x00001000, 0x00001004, - 0x00000000, 0x00000004, 0x00001000, 0x00001004, - 0x10000000, 0x10000004, 0x10001000, 0x10001004, - 0x10000000, 0x10000004, 0x10001000, 0x10001004, - 0x00000020, 0x00000024, 0x00001020, 0x00001024, - 0x00000020, 0x00000024, 0x00001020, 0x00001024, - 0x10000020, 0x10000024, 0x10001020, 0x10001024, - 0x10000020, 0x10000024, 0x10001020, 0x10001024, - 0x00080000, 0x00080004, 0x00081000, 0x00081004, - 0x00080000, 0x00080004, 0x00081000, 0x00081004, - 0x10080000, 0x10080004, 0x10081000, 0x10081004, - 0x10080000, 0x10080004, 0x10081000, 0x10081004, - 0x00080020, 0x00080024, 0x00081020, 0x00081024, - 0x00080020, 0x00080024, 0x00081020, 0x00081024, - 0x10080020, 0x10080024, 0x10081020, 0x10081024, - 0x10080020, 0x10080024, 0x10081020, 0x10081024, - 0x20000000, 0x20000004, 0x20001000, 0x20001004, - 0x20000000, 0x20000004, 0x20001000, 0x20001004, - 0x30000000, 0x30000004, 0x30001000, 0x30001004, - 0x30000000, 0x30000004, 0x30001000, 0x30001004, - 0x20000020, 0x20000024, 0x20001020, 0x20001024, - 0x20000020, 0x20000024, 0x20001020, 0x20001024, - 0x30000020, 0x30000024, 0x30001020, 0x30001024, - 0x30000020, 0x30000024, 0x30001020, 0x30001024, - 0x20080000, 0x20080004, 0x20081000, 0x20081004, - 0x20080000, 0x20080004, 0x20081000, 0x20081004, - 0x30080000, 0x30080004, 0x30081000, 0x30081004, - 0x30080000, 0x30080004, 0x30081000, 0x30081004, - 0x20080020, 0x20080024, 0x20081020, 0x20081024, - 0x20080020, 0x20080024, 0x20081020, 0x20081024, - 0x30080020, 0x30080024, 0x30081020, 0x30081024, - 0x30080020, 0x30080024, 0x30081020, 0x30081024, - 0x00000002, 0x00000006, 0x00001002, 0x00001006, - 0x00000002, 0x00000006, 0x00001002, 0x00001006, - 0x10000002, 0x10000006, 0x10001002, 0x10001006, - 0x10000002, 0x10000006, 0x10001002, 0x10001006, - 0x00000022, 0x00000026, 0x00001022, 0x00001026, - 0x00000022, 0x00000026, 0x00001022, 0x00001026, - 0x10000022, 0x10000026, 0x10001022, 0x10001026, - 0x10000022, 0x10000026, 0x10001022, 0x10001026, - 0x00080002, 0x00080006, 0x00081002, 0x00081006, - 0x00080002, 0x00080006, 0x00081002, 0x00081006, - 0x10080002, 0x10080006, 0x10081002, 0x10081006, - 0x10080002, 0x10080006, 0x10081002, 0x10081006, - 0x00080022, 0x00080026, 0x00081022, 0x00081026, - 0x00080022, 0x00080026, 0x00081022, 0x00081026, - 0x10080022, 0x10080026, 0x10081022, 0x10081026, - 0x10080022, 0x10080026, 0x10081022, 0x10081026, - 0x20000002, 0x20000006, 0x20001002, 0x20001006, - 0x20000002, 0x20000006, 0x20001002, 0x20001006, - 0x30000002, 0x30000006, 0x30001002, 0x30001006, - 0x30000002, 0x30000006, 0x30001002, 0x30001006, - 0x20000022, 0x20000026, 0x20001022, 0x20001026, - 0x20000022, 0x20000026, 0x20001022, 0x20001026, - 0x30000022, 0x30000026, 0x30001022, 0x30001026, - 0x30000022, 0x30000026, 0x30001022, 0x30001026, - 0x20080002, 0x20080006, 0x20081002, 0x20081006, - 0x20080002, 0x20080006, 0x20081002, 0x20081006, - 0x30080002, 0x30080006, 0x30081002, 0x30081006, - 0x30080002, 0x30080006, 0x30081002, 0x30081006, - 0x20080022, 0x20080026, 0x20081022, 0x20081026, - 0x20080022, 0x20080026, 0x20081022, 0x20081026, - 0x30080022, 0x30080026, 0x30081022, 0x30081026, - 0x30080022, 0x30080026, 0x30081022, 0x30081026 - ]; - static $pc2mapc4 = [ - 0x00000000, 0x00100000, 0x00000008, 0x00100008, - 0x00000200, 0x00100200, 0x00000208, 0x00100208, - 0x00000000, 0x00100000, 0x00000008, 0x00100008, - 0x00000200, 0x00100200, 0x00000208, 0x00100208, - 0x04000000, 0x04100000, 0x04000008, 0x04100008, - 0x04000200, 0x04100200, 0x04000208, 0x04100208, - 0x04000000, 0x04100000, 0x04000008, 0x04100008, - 0x04000200, 0x04100200, 0x04000208, 0x04100208, - 0x00002000, 0x00102000, 0x00002008, 0x00102008, - 0x00002200, 0x00102200, 0x00002208, 0x00102208, - 0x00002000, 0x00102000, 0x00002008, 0x00102008, - 0x00002200, 0x00102200, 0x00002208, 0x00102208, - 0x04002000, 0x04102000, 0x04002008, 0x04102008, - 0x04002200, 0x04102200, 0x04002208, 0x04102208, - 0x04002000, 0x04102000, 0x04002008, 0x04102008, - 0x04002200, 0x04102200, 0x04002208, 0x04102208, - 0x00000000, 0x00100000, 0x00000008, 0x00100008, - 0x00000200, 0x00100200, 0x00000208, 0x00100208, - 0x00000000, 0x00100000, 0x00000008, 0x00100008, - 0x00000200, 0x00100200, 0x00000208, 0x00100208, - 0x04000000, 0x04100000, 0x04000008, 0x04100008, - 0x04000200, 0x04100200, 0x04000208, 0x04100208, - 0x04000000, 0x04100000, 0x04000008, 0x04100008, - 0x04000200, 0x04100200, 0x04000208, 0x04100208, - 0x00002000, 0x00102000, 0x00002008, 0x00102008, - 0x00002200, 0x00102200, 0x00002208, 0x00102208, - 0x00002000, 0x00102000, 0x00002008, 0x00102008, - 0x00002200, 0x00102200, 0x00002208, 0x00102208, - 0x04002000, 0x04102000, 0x04002008, 0x04102008, - 0x04002200, 0x04102200, 0x04002208, 0x04102208, - 0x04002000, 0x04102000, 0x04002008, 0x04102008, - 0x04002200, 0x04102200, 0x04002208, 0x04102208, - 0x00020000, 0x00120000, 0x00020008, 0x00120008, - 0x00020200, 0x00120200, 0x00020208, 0x00120208, - 0x00020000, 0x00120000, 0x00020008, 0x00120008, - 0x00020200, 0x00120200, 0x00020208, 0x00120208, - 0x04020000, 0x04120000, 0x04020008, 0x04120008, - 0x04020200, 0x04120200, 0x04020208, 0x04120208, - 0x04020000, 0x04120000, 0x04020008, 0x04120008, - 0x04020200, 0x04120200, 0x04020208, 0x04120208, - 0x00022000, 0x00122000, 0x00022008, 0x00122008, - 0x00022200, 0x00122200, 0x00022208, 0x00122208, - 0x00022000, 0x00122000, 0x00022008, 0x00122008, - 0x00022200, 0x00122200, 0x00022208, 0x00122208, - 0x04022000, 0x04122000, 0x04022008, 0x04122008, - 0x04022200, 0x04122200, 0x04022208, 0x04122208, - 0x04022000, 0x04122000, 0x04022008, 0x04122008, - 0x04022200, 0x04122200, 0x04022208, 0x04122208, - 0x00020000, 0x00120000, 0x00020008, 0x00120008, - 0x00020200, 0x00120200, 0x00020208, 0x00120208, - 0x00020000, 0x00120000, 0x00020008, 0x00120008, - 0x00020200, 0x00120200, 0x00020208, 0x00120208, - 0x04020000, 0x04120000, 0x04020008, 0x04120008, - 0x04020200, 0x04120200, 0x04020208, 0x04120208, - 0x04020000, 0x04120000, 0x04020008, 0x04120008, - 0x04020200, 0x04120200, 0x04020208, 0x04120208, - 0x00022000, 0x00122000, 0x00022008, 0x00122008, - 0x00022200, 0x00122200, 0x00022208, 0x00122208, - 0x00022000, 0x00122000, 0x00022008, 0x00122008, - 0x00022200, 0x00122200, 0x00022208, 0x00122208, - 0x04022000, 0x04122000, 0x04022008, 0x04122008, - 0x04022200, 0x04122200, 0x04022208, 0x04122208, - 0x04022000, 0x04122000, 0x04022008, 0x04122008, - 0x04022200, 0x04122200, 0x04022208, 0x04122208 - ]; - static $pc2mapd1 = [ - 0x00000000, 0x00000001, 0x08000000, 0x08000001, - 0x00200000, 0x00200001, 0x08200000, 0x08200001, - 0x00000002, 0x00000003, 0x08000002, 0x08000003, - 0x00200002, 0x00200003, 0x08200002, 0x08200003 - ]; - static $pc2mapd2 = [ - 0x00000000, 0x00100000, 0x00000800, 0x00100800, - 0x00000000, 0x00100000, 0x00000800, 0x00100800, - 0x04000000, 0x04100000, 0x04000800, 0x04100800, - 0x04000000, 0x04100000, 0x04000800, 0x04100800, - 0x00000004, 0x00100004, 0x00000804, 0x00100804, - 0x00000004, 0x00100004, 0x00000804, 0x00100804, - 0x04000004, 0x04100004, 0x04000804, 0x04100804, - 0x04000004, 0x04100004, 0x04000804, 0x04100804, - 0x00000000, 0x00100000, 0x00000800, 0x00100800, - 0x00000000, 0x00100000, 0x00000800, 0x00100800, - 0x04000000, 0x04100000, 0x04000800, 0x04100800, - 0x04000000, 0x04100000, 0x04000800, 0x04100800, - 0x00000004, 0x00100004, 0x00000804, 0x00100804, - 0x00000004, 0x00100004, 0x00000804, 0x00100804, - 0x04000004, 0x04100004, 0x04000804, 0x04100804, - 0x04000004, 0x04100004, 0x04000804, 0x04100804, - 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, - 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, - 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, - 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, - 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, - 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, - 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, - 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, - 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, - 0x00000200, 0x00100200, 0x00000A00, 0x00100A00, - 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, - 0x04000200, 0x04100200, 0x04000A00, 0x04100A00, - 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, - 0x00000204, 0x00100204, 0x00000A04, 0x00100A04, - 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, - 0x04000204, 0x04100204, 0x04000A04, 0x04100A04, - 0x00020000, 0x00120000, 0x00020800, 0x00120800, - 0x00020000, 0x00120000, 0x00020800, 0x00120800, - 0x04020000, 0x04120000, 0x04020800, 0x04120800, - 0x04020000, 0x04120000, 0x04020800, 0x04120800, - 0x00020004, 0x00120004, 0x00020804, 0x00120804, - 0x00020004, 0x00120004, 0x00020804, 0x00120804, - 0x04020004, 0x04120004, 0x04020804, 0x04120804, - 0x04020004, 0x04120004, 0x04020804, 0x04120804, - 0x00020000, 0x00120000, 0x00020800, 0x00120800, - 0x00020000, 0x00120000, 0x00020800, 0x00120800, - 0x04020000, 0x04120000, 0x04020800, 0x04120800, - 0x04020000, 0x04120000, 0x04020800, 0x04120800, - 0x00020004, 0x00120004, 0x00020804, 0x00120804, - 0x00020004, 0x00120004, 0x00020804, 0x00120804, - 0x04020004, 0x04120004, 0x04020804, 0x04120804, - 0x04020004, 0x04120004, 0x04020804, 0x04120804, - 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, - 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, - 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, - 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, - 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, - 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, - 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, - 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, - 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, - 0x00020200, 0x00120200, 0x00020A00, 0x00120A00, - 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, - 0x04020200, 0x04120200, 0x04020A00, 0x04120A00, - 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, - 0x00020204, 0x00120204, 0x00020A04, 0x00120A04, - 0x04020204, 0x04120204, 0x04020A04, 0x04120A04, - 0x04020204, 0x04120204, 0x04020A04, 0x04120A04 - ]; - static $pc2mapd3 = [ - 0x00000000, 0x00010000, 0x02000000, 0x02010000, - 0x00000020, 0x00010020, 0x02000020, 0x02010020, - 0x00040000, 0x00050000, 0x02040000, 0x02050000, - 0x00040020, 0x00050020, 0x02040020, 0x02050020, - 0x00002000, 0x00012000, 0x02002000, 0x02012000, - 0x00002020, 0x00012020, 0x02002020, 0x02012020, - 0x00042000, 0x00052000, 0x02042000, 0x02052000, - 0x00042020, 0x00052020, 0x02042020, 0x02052020, - 0x00000000, 0x00010000, 0x02000000, 0x02010000, - 0x00000020, 0x00010020, 0x02000020, 0x02010020, - 0x00040000, 0x00050000, 0x02040000, 0x02050000, - 0x00040020, 0x00050020, 0x02040020, 0x02050020, - 0x00002000, 0x00012000, 0x02002000, 0x02012000, - 0x00002020, 0x00012020, 0x02002020, 0x02012020, - 0x00042000, 0x00052000, 0x02042000, 0x02052000, - 0x00042020, 0x00052020, 0x02042020, 0x02052020, - 0x00000010, 0x00010010, 0x02000010, 0x02010010, - 0x00000030, 0x00010030, 0x02000030, 0x02010030, - 0x00040010, 0x00050010, 0x02040010, 0x02050010, - 0x00040030, 0x00050030, 0x02040030, 0x02050030, - 0x00002010, 0x00012010, 0x02002010, 0x02012010, - 0x00002030, 0x00012030, 0x02002030, 0x02012030, - 0x00042010, 0x00052010, 0x02042010, 0x02052010, - 0x00042030, 0x00052030, 0x02042030, 0x02052030, - 0x00000010, 0x00010010, 0x02000010, 0x02010010, - 0x00000030, 0x00010030, 0x02000030, 0x02010030, - 0x00040010, 0x00050010, 0x02040010, 0x02050010, - 0x00040030, 0x00050030, 0x02040030, 0x02050030, - 0x00002010, 0x00012010, 0x02002010, 0x02012010, - 0x00002030, 0x00012030, 0x02002030, 0x02012030, - 0x00042010, 0x00052010, 0x02042010, 0x02052010, - 0x00042030, 0x00052030, 0x02042030, 0x02052030, - 0x20000000, 0x20010000, 0x22000000, 0x22010000, - 0x20000020, 0x20010020, 0x22000020, 0x22010020, - 0x20040000, 0x20050000, 0x22040000, 0x22050000, - 0x20040020, 0x20050020, 0x22040020, 0x22050020, - 0x20002000, 0x20012000, 0x22002000, 0x22012000, - 0x20002020, 0x20012020, 0x22002020, 0x22012020, - 0x20042000, 0x20052000, 0x22042000, 0x22052000, - 0x20042020, 0x20052020, 0x22042020, 0x22052020, - 0x20000000, 0x20010000, 0x22000000, 0x22010000, - 0x20000020, 0x20010020, 0x22000020, 0x22010020, - 0x20040000, 0x20050000, 0x22040000, 0x22050000, - 0x20040020, 0x20050020, 0x22040020, 0x22050020, - 0x20002000, 0x20012000, 0x22002000, 0x22012000, - 0x20002020, 0x20012020, 0x22002020, 0x22012020, - 0x20042000, 0x20052000, 0x22042000, 0x22052000, - 0x20042020, 0x20052020, 0x22042020, 0x22052020, - 0x20000010, 0x20010010, 0x22000010, 0x22010010, - 0x20000030, 0x20010030, 0x22000030, 0x22010030, - 0x20040010, 0x20050010, 0x22040010, 0x22050010, - 0x20040030, 0x20050030, 0x22040030, 0x22050030, - 0x20002010, 0x20012010, 0x22002010, 0x22012010, - 0x20002030, 0x20012030, 0x22002030, 0x22012030, - 0x20042010, 0x20052010, 0x22042010, 0x22052010, - 0x20042030, 0x20052030, 0x22042030, 0x22052030, - 0x20000010, 0x20010010, 0x22000010, 0x22010010, - 0x20000030, 0x20010030, 0x22000030, 0x22010030, - 0x20040010, 0x20050010, 0x22040010, 0x22050010, - 0x20040030, 0x20050030, 0x22040030, 0x22050030, - 0x20002010, 0x20012010, 0x22002010, 0x22012010, - 0x20002030, 0x20012030, 0x22002030, 0x22012030, - 0x20042010, 0x20052010, 0x22042010, 0x22052010, - 0x20042030, 0x20052030, 0x22042030, 0x22052030 - ]; - static $pc2mapd4 = [ - 0x00000000, 0x00000400, 0x01000000, 0x01000400, - 0x00000000, 0x00000400, 0x01000000, 0x01000400, - 0x00000100, 0x00000500, 0x01000100, 0x01000500, - 0x00000100, 0x00000500, 0x01000100, 0x01000500, - 0x10000000, 0x10000400, 0x11000000, 0x11000400, - 0x10000000, 0x10000400, 0x11000000, 0x11000400, - 0x10000100, 0x10000500, 0x11000100, 0x11000500, - 0x10000100, 0x10000500, 0x11000100, 0x11000500, - 0x00080000, 0x00080400, 0x01080000, 0x01080400, - 0x00080000, 0x00080400, 0x01080000, 0x01080400, - 0x00080100, 0x00080500, 0x01080100, 0x01080500, - 0x00080100, 0x00080500, 0x01080100, 0x01080500, - 0x10080000, 0x10080400, 0x11080000, 0x11080400, - 0x10080000, 0x10080400, 0x11080000, 0x11080400, - 0x10080100, 0x10080500, 0x11080100, 0x11080500, - 0x10080100, 0x10080500, 0x11080100, 0x11080500, - 0x00000008, 0x00000408, 0x01000008, 0x01000408, - 0x00000008, 0x00000408, 0x01000008, 0x01000408, - 0x00000108, 0x00000508, 0x01000108, 0x01000508, - 0x00000108, 0x00000508, 0x01000108, 0x01000508, - 0x10000008, 0x10000408, 0x11000008, 0x11000408, - 0x10000008, 0x10000408, 0x11000008, 0x11000408, - 0x10000108, 0x10000508, 0x11000108, 0x11000508, - 0x10000108, 0x10000508, 0x11000108, 0x11000508, - 0x00080008, 0x00080408, 0x01080008, 0x01080408, - 0x00080008, 0x00080408, 0x01080008, 0x01080408, - 0x00080108, 0x00080508, 0x01080108, 0x01080508, - 0x00080108, 0x00080508, 0x01080108, 0x01080508, - 0x10080008, 0x10080408, 0x11080008, 0x11080408, - 0x10080008, 0x10080408, 0x11080008, 0x11080408, - 0x10080108, 0x10080508, 0x11080108, 0x11080508, - 0x10080108, 0x10080508, 0x11080108, 0x11080508, - 0x00001000, 0x00001400, 0x01001000, 0x01001400, - 0x00001000, 0x00001400, 0x01001000, 0x01001400, - 0x00001100, 0x00001500, 0x01001100, 0x01001500, - 0x00001100, 0x00001500, 0x01001100, 0x01001500, - 0x10001000, 0x10001400, 0x11001000, 0x11001400, - 0x10001000, 0x10001400, 0x11001000, 0x11001400, - 0x10001100, 0x10001500, 0x11001100, 0x11001500, - 0x10001100, 0x10001500, 0x11001100, 0x11001500, - 0x00081000, 0x00081400, 0x01081000, 0x01081400, - 0x00081000, 0x00081400, 0x01081000, 0x01081400, - 0x00081100, 0x00081500, 0x01081100, 0x01081500, - 0x00081100, 0x00081500, 0x01081100, 0x01081500, - 0x10081000, 0x10081400, 0x11081000, 0x11081400, - 0x10081000, 0x10081400, 0x11081000, 0x11081400, - 0x10081100, 0x10081500, 0x11081100, 0x11081500, - 0x10081100, 0x10081500, 0x11081100, 0x11081500, - 0x00001008, 0x00001408, 0x01001008, 0x01001408, - 0x00001008, 0x00001408, 0x01001008, 0x01001408, - 0x00001108, 0x00001508, 0x01001108, 0x01001508, - 0x00001108, 0x00001508, 0x01001108, 0x01001508, - 0x10001008, 0x10001408, 0x11001008, 0x11001408, - 0x10001008, 0x10001408, 0x11001008, 0x11001408, - 0x10001108, 0x10001508, 0x11001108, 0x11001508, - 0x10001108, 0x10001508, 0x11001108, 0x11001508, - 0x00081008, 0x00081408, 0x01081008, 0x01081408, - 0x00081008, 0x00081408, 0x01081008, 0x01081408, - 0x00081108, 0x00081508, 0x01081108, 0x01081508, - 0x00081108, 0x00081508, 0x01081108, 0x01081508, - 0x10081008, 0x10081408, 0x11081008, 0x11081408, - 0x10081008, 0x10081408, 0x11081008, 0x11081408, - 0x10081108, 0x10081508, 0x11081108, 0x11081508, - 0x10081108, 0x10081508, 0x11081108, 0x11081508 - ]; - - $keys = []; - for ($des_round = 0; $des_round < $this->des_rounds; ++$des_round) { - // pad the key and remove extra characters as appropriate. - $key = str_pad(substr($this->key, $des_round * 8, 8), 8, "\0"); - - // Perform the PC/1 transformation and compute C and D. - $t = unpack('Nl/Nr', $key); - list($l, $r) = [$t['l'], $t['r']]; - $key = (self::$shuffle[$pc1map[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") | - (self::$shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") | - (self::$shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") | - (self::$shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") | - (self::$shuffle[$pc1map[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") | - (self::$shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") | - (self::$shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") | - (self::$shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00"); - $key = unpack('Nc/Nd', $key); - $c = ( $key['c'] >> 4) & 0x0FFFFFFF; - $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F); - - $keys[$des_round] = [ - self::ENCRYPT => [], - self::DECRYPT => array_fill(0, 32, 0) - ]; - for ($i = 0, $ki = 31; $i < 16; ++$i, $ki -= 2) { - $c <<= $shifts[$i]; - $c = ($c | ($c >> 28)) & 0x0FFFFFFF; - $d <<= $shifts[$i]; - $d = ($d | ($d >> 28)) & 0x0FFFFFFF; - - // Perform the PC-2 transformation. - $cp = $pc2mapc1[ $c >> 24 ] | $pc2mapc2[($c >> 16) & 0xFF] | - $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[ $c & 0xFF]; - $dp = $pc2mapd1[ $d >> 24 ] | $pc2mapd2[($d >> 16) & 0xFF] | - $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[ $d & 0xFF]; - - // Reorder: odd bytes/even bytes. Push the result in key schedule. - $val1 = ( $cp & intval(0xFF000000)) | (($cp << 8) & 0x00FF0000) | - (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF); - $val2 = (($cp << 8) & intval(0xFF000000)) | (($cp << 16) & 0x00FF0000) | - (($dp >> 8) & 0x0000FF00) | ( $dp & 0x000000FF); - $keys[$des_round][self::ENCRYPT][ ] = $val1; - $keys[$des_round][self::DECRYPT][$ki - 1] = $val1; - $keys[$des_round][self::ENCRYPT][ ] = $val2; - $keys[$des_round][self::DECRYPT][$ki ] = $val2; - } - } - - switch ($this->des_rounds) { - case 3: // 3DES keys - $this->keys = [ - self::ENCRYPT => array_merge( - $keys[0][self::ENCRYPT], - $keys[1][self::DECRYPT], - $keys[2][self::ENCRYPT] - ), - self::DECRYPT => array_merge( - $keys[2][self::DECRYPT], - $keys[1][self::ENCRYPT], - $keys[0][self::DECRYPT] - ) - ]; - break; - // case 1: // DES keys - default: - $this->keys = [ - self::ENCRYPT => $keys[0][self::ENCRYPT], - self::DECRYPT => $keys[0][self::DECRYPT] - ]; - } - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() - */ - protected function setupInlineCrypt() - { - // Engine configuration for: - // - DES ($des_rounds == 1) or - // - 3DES ($des_rounds == 3) - $des_rounds = $this->des_rounds; - - $init_crypt = 'static $sbox1, $sbox2, $sbox3, $sbox4, $sbox5, $sbox6, $sbox7, $sbox8, $shuffleip, $shuffleinvip; - if (!$sbox1) { - $sbox1 = array_map("intval", self::$sbox1); - $sbox2 = array_map("intval", self::$sbox2); - $sbox3 = array_map("intval", self::$sbox3); - $sbox4 = array_map("intval", self::$sbox4); - $sbox5 = array_map("intval", self::$sbox5); - $sbox6 = array_map("intval", self::$sbox6); - $sbox7 = array_map("intval", self::$sbox7); - $sbox8 = array_map("intval", self::$sbox8);' - /* Merge $shuffle with $[inv]ipmap */ . ' - for ($i = 0; $i < 256; ++$i) { - $shuffleip[] = self::$shuffle[self::$ipmap[$i]]; - $shuffleinvip[] = self::$shuffle[self::$invipmap[$i]]; - } - } - '; - - $k = [ - self::ENCRYPT => $this->keys[self::ENCRYPT], - self::DECRYPT => $this->keys[self::DECRYPT] - ]; - $init_encrypt = ''; - $init_decrypt = ''; - - // Creating code for en- and decryption. - $crypt_block = []; - foreach ([self::ENCRYPT, self::DECRYPT] as $c) { - /* Do the initial IP permutation. */ - $crypt_block[$c] = ' - $in = unpack("N*", $in); - $l = $in[1]; - $r = $in[2]; - $in = unpack("N*", - ($shuffleip[ $r & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleip[($r >> 8) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleip[($r >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleip[($r >> 24) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleip[ $l & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleip[($l >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleip[($l >> 16) & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleip[($l >> 24) & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01") - ); - ' . /* Extract L0 and R0 */ ' - $l = $in[1]; - $r = $in[2]; - '; - - $l = '$l'; - $r = '$r'; - - // Perform DES or 3DES. - for ($ki = -1, $des_round = 0; $des_round < $des_rounds; ++$des_round) { - // Perform the 16 steps. - for ($i = 0; $i < 16; ++$i) { - // start of "the Feistel (F) function" - see the following URL: - // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png - // Merge key schedule. - $crypt_block[$c] .= ' - $b1 = ((' . $r . ' >> 3) & 0x1FFFFFFF) ^ (' . $r . ' << 29) ^ ' . $k[$c][++$ki] . '; - $b2 = ((' . $r . ' >> 31) & 0x00000001) ^ (' . $r . ' << 1) ^ ' . $k[$c][++$ki] . ';' . - /* S-box indexing. */ - $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^ - $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^ - $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^ - $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ ' . $l . '; - '; - // end of "the Feistel (F) function" - - // swap L & R - list($l, $r) = [$r, $l]; - } - list($l, $r) = [$r, $l]; - } - - // Perform the inverse IP permutation. - $crypt_block[$c] .= '$in = - ($shuffleinvip[($l >> 24) & 0xFF] & "\x80\x80\x80\x80\x80\x80\x80\x80") | - ($shuffleinvip[($r >> 24) & 0xFF] & "\x40\x40\x40\x40\x40\x40\x40\x40") | - ($shuffleinvip[($l >> 16) & 0xFF] & "\x20\x20\x20\x20\x20\x20\x20\x20") | - ($shuffleinvip[($r >> 16) & 0xFF] & "\x10\x10\x10\x10\x10\x10\x10\x10") | - ($shuffleinvip[($l >> 8) & 0xFF] & "\x08\x08\x08\x08\x08\x08\x08\x08") | - ($shuffleinvip[($r >> 8) & 0xFF] & "\x04\x04\x04\x04\x04\x04\x04\x04") | - ($shuffleinvip[ $l & 0xFF] & "\x02\x02\x02\x02\x02\x02\x02\x02") | - ($shuffleinvip[ $r & 0xFF] & "\x01\x01\x01\x01\x01\x01\x01\x01"); - '; - } - - // Creates the inline-crypt function - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'init_encrypt' => $init_encrypt, - 'init_decrypt' => $init_decrypt, - 'encrypt_block' => $crypt_block[self::ENCRYPT], - 'decrypt_block' => $crypt_block[self::DECRYPT] - ] - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php deleted file mode 100644 index e1deaf0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH.php +++ /dev/null @@ -1,405 +0,0 @@ - - * - * - * - * @author Jim Wigginton - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\DH\Parameters; -use phpseclib3\Crypt\DH\PrivateKey; -use phpseclib3\Crypt\DH\PublicKey; -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP (EC)DH implementation - * - * @author Jim Wigginton - */ -abstract class DH extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - */ - const ALGORITHM = 'DH'; - - /** - * DH prime - * - * @var \phpseclib3\Math\BigInteger - */ - protected $prime; - - /** - * DH Base - * - * Prime divisor of p-1 - * - * @var \phpseclib3\Math\BigInteger - */ - protected $base; - - /** - * Public Key - * - * @var \phpseclib3\Math\BigInteger - */ - protected $publicKey; - - /** - * Create DH parameters - * - * This method is a bit polymorphic. It can take any of the following: - * - two BigInteger's (prime and base) - * - an integer representing the size of the prime in bits (the base is assumed to be 2) - * - a string (eg. diffie-hellman-group14-sha1) - * - * @return Parameters - */ - public static function createParameters(...$args) - { - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); - } - - $params = new Parameters(); - if (count($args) == 2 && $args[0] instanceof BigInteger && $args[1] instanceof BigInteger) { - //if (!$args[0]->isPrime()) { - // throw new \InvalidArgumentException('The first parameter should be a prime number'); - //} - $params->prime = $args[0]; - $params->base = $args[1]; - return $params; - } elseif (count($args) == 1 && is_numeric($args[0])) { - $params->prime = BigInteger::randomPrime($args[0]); - $params->base = new BigInteger(2); - return $params; - } elseif (count($args) != 1 || !is_string($args[0])) { - throw new \InvalidArgumentException('Valid parameters are either: two BigInteger\'s (prime and base), a single integer (the length of the prime; base is assumed to be 2) or a string'); - } - switch ($args[0]) { - // see http://tools.ietf.org/html/rfc2409#section-6.2 and - // http://tools.ietf.org/html/rfc2412, appendex E - case 'diffie-hellman-group1-sha1': - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF'; - break; - // see http://tools.ietf.org/html/rfc3526#section-3 - case 'diffie-hellman-group14-sha1': // 2048-bit MODP Group - case 'diffie-hellman-group14-sha256': - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-4 - case 'diffie-hellman-group15-sha512': // 3072-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-5 - case 'diffie-hellman-group16-sha512': // 4096-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . - '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . - 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . - '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . - '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-6 - case 'diffie-hellman-group17-sha512': // 6144-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . - '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . - 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . - '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . - '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . - 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . - 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . - 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . - 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . - '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . - 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . - 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . - '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF'; - break; - // see https://tools.ietf.org/html/rfc3526#section-7 - case 'diffie-hellman-group18-sha512': // 8192-bit MODP Group - $prime = 'FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74' . - '020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437' . - '4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED' . - 'EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05' . - '98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB' . - '9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B' . - 'E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF695581718' . - '3995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33' . - 'A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7' . - 'ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864' . - 'D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E2' . - '08E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7' . - '88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8' . - 'DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2' . - '233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9' . - '93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C93402849236C3FAB4D27C7026' . - 'C1D4DCB2602646DEC9751E763DBA37BDF8FF9406AD9E530EE5DB382F413001AE' . - 'B06A53ED9027D831179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B' . - 'DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF5983CA01C64B92EC' . - 'F032EA15D1721D03F482D7CE6E74FEF6D55E702F46980C82B5A84031900B1C9E' . - '59E7C97FBEC7E8F323A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA' . - 'CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE32806A1D58BB7C5DA76' . - 'F550AA3D8A1FBFF0EB19CCB1A313D55CDA56C9EC2EF29632387FE8D76E3C0468' . - '043E8F663F4860EE12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4' . - '38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300741FA7BF8AFC47ED' . - '2576F6936BA424663AAB639C5AE4F5683423B4742BF1C978238F16CBE39D652D' . - 'E3FDB8BEFC848AD922222E04A4037C0713EB57A81A23F0C73473FC646CEA306B' . - '4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A062B3CF5B3A278A6' . - '6D2A13F83F44F82DDF310EE074AB6A364597E899A0255DC164F31CC50846851D' . - 'F9AB48195DED7EA1B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92' . - '4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E479558E4475677E9AA' . - '9E3050E2765694DFC81F56E880B96E7160C980DD98EDD3DFFFFFFFFFFFFFFFFF'; - break; - default: - throw new \InvalidArgumentException('Invalid named prime provided'); - } - - $params->prime = new BigInteger($prime, 16); - $params->base = new BigInteger(2); - - return $params; - } - - /** - * Create public / private key pair. - * - * The rationale for the second parameter is described in http://tools.ietf.org/html/rfc4419#section-6.2 : - * - * "To increase the speed of the key exchange, both client and server may - * reduce the size of their private exponents. It should be at least - * twice as long as the key material that is generated from the shared - * secret. For more details, see the paper by van Oorschot and Wiener - * [VAN-OORSCHOT]." - * - * $length is in bits - * - * @param Parameters $params - * @param int $length optional - * @return DH\PrivateKey - */ - public static function createKey(Parameters $params, $length = 0) - { - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); - } - - $one = new BigInteger(1); - if ($length) { - $max = $one->bitwise_leftShift($length); - $max = $max->subtract($one); - } else { - $max = $params->prime->subtract($one); - } - - $key = new PrivateKey(); - $key->prime = $params->prime; - $key->base = $params->base; - $key->privateKey = BigInteger::randomRange($one, $max); - $key->publicKey = $key->base->powMod($key->privateKey, $key->prime); - return $key; - } - - /** - * Compute Shared Secret - * - * @param PrivateKey|EC $private - * @param PublicKey|BigInteger|string $public - * @return mixed - */ - public static function computeSecret($private, $public) - { - if ($private instanceof PrivateKey) { // DH\PrivateKey - switch (true) { - case $public instanceof PublicKey: - if (!$private->prime->equals($public->prime) || !$private->base->equals($public->base)) { - throw new \InvalidArgumentException('The public and private key do not share the same prime and / or base numbers'); - } - return $public->publicKey->powMod($private->privateKey, $private->prime)->toBytes(true); - case is_string($public): - $public = new BigInteger($public, -256); - // fall-through - case $public instanceof BigInteger: - return $public->powMod($private->privateKey, $private->prime)->toBytes(true); - default: - throw new \InvalidArgumentException('$public needs to be an instance of DH\PublicKey, a BigInteger or a string'); - } - } - - if ($private instanceof EC\PrivateKey) { - switch (true) { - case $public instanceof EC\PublicKey: - $public = $public->getEncodedCoordinates(); - // fall-through - case is_string($public): - $point = $private->multiply($public); - switch ($private->getCurve()) { - case 'Curve25519': - case 'Curve448': - $secret = $point; - break; - default: - // according to https://www.secg.org/sec1-v2.pdf#page=33 only X is returned - $secret = substr($point, 1, (strlen($point) - 1) >> 1); - } - /* - if (($secret[0] & "\x80") === "\x80") { - $secret = "\0$secret"; - } - */ - return $secret; - default: - throw new \InvalidArgumentException('$public needs to be an instance of EC\PublicKey or a string (an encoded coordinate)'); - } - } - } - - /** - * Load the key - * - * @param string $key - * @param string $password optional - * @return AsymmetricKey - */ - public static function load($key, $password = false) - { - try { - return EC::load($key, $password); - } catch (NoKeyLoadedException $e) { - } - - return parent::load($key, $password); - } - - /** - * OnLoad Handler - * - * @return bool - */ - protected static function onLoad(array $components) - { - if (!isset($components['privateKey']) && !isset($components['publicKey'])) { - $new = new Parameters(); - } else { - $new = isset($components['privateKey']) ? - new PrivateKey() : - new PublicKey(); - } - - $new->prime = $components['prime']; - $new->base = $components['base']; - - if (isset($components['privateKey'])) { - $new->privateKey = $components['privateKey']; - } - if (isset($components['publicKey'])) { - $new->publicKey = $components['publicKey']; - } - - return $new; - } - - /** - * Determines which hashing function should be used - * - * @param string $hash - */ - public function withHash($hash) - { - throw new UnsupportedOperationException('DH does not use a hash algorithm'); - } - - /** - * Returns the hash algorithm currently being used - * - */ - public function getHash() - { - throw new UnsupportedOperationException('DH does not use a hash algorithm'); - } - - /** - * Returns the parameters - * - * A public / private key is only returned if the currently loaded "key" contains an x or y - * value. - * - * @see self::getPublicKey() - * @return mixed - */ - public function getParameters() - { - $type = DH::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - $key = $type::saveParameters($this->prime, $this->base); - return DH::load($key, 'PKCS1'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php deleted file mode 100644 index 65a0a5d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,77 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH\Formats\Keys; - -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * "PKCS1" Formatted DH Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS1 extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - - $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); - if (!is_array($components)) { - throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); - } - - return $components; - } - - /** - * Convert EC parameters to the appropriate format - * - * @return string - */ - public static function saveParameters(BigInteger $prime, BigInteger $base, array $options = []) - { - $params = [ - 'prime' => $prime, - 'base' => $base - ]; - $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); - - return "-----BEGIN DH PARAMETERS-----\r\n" . - chunk_split(base64_encode($params), 64) . - "-----END DH PARAMETERS-----\r\n"; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php deleted file mode 100644 index c330a3c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH\Formats\Keys; - -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#8 Formatted DH Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS8 extends Progenitor -{ - /** - * OID Name - * - * @var string - */ - const OID_NAME = 'dhKeyAgreement'; - - /** - * OID Value - * - * @var string - */ - const OID_VALUE = '1.2.840.113549.1.3.1'; - - /** - * Child OIDs loaded - * - * @var bool - */ - protected static $childOIDsLoaded = false; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; - - $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER of parameters'); - } - $components = ASN1::asn1map($decoded[0], Maps\DHParameter::MAP); - if (!is_array($components)) { - throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); - } - - $decoded = ASN1::decodeBER($key[$type]); - switch (true) { - case !isset($decoded): - case !isset($decoded[0]['content']): - case !$decoded[0]['content'] instanceof BigInteger: - throw new \RuntimeException('Unable to decode BER of parameters'); - } - $components[$type] = $decoded[0]['content']; - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $prime - * @param \phpseclib3\Math\BigInteger $base - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Math\BigInteger $publicKey - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $prime, BigInteger $base, BigInteger $privateKey, BigInteger $publicKey, $password = '', array $options = []) - { - $params = [ - 'prime' => $prime, - 'base' => $base - ]; - $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($privateKey, ['type' => ASN1::TYPE_INTEGER]); - return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $prime - * @param \phpseclib3\Math\BigInteger $base - * @param \phpseclib3\Math\BigInteger $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $prime, BigInteger $base, BigInteger $publicKey, array $options = []) - { - $params = [ - 'prime' => $prime, - 'base' => $base - ]; - $params = ASN1::encodeDER($params, Maps\DHParameter::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($publicKey, ['type' => ASN1::TYPE_INTEGER]); - return self::wrapPublicKey($key, $params); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php deleted file mode 100644 index c0ded84..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/Parameters.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH; - -use phpseclib3\Crypt\DH; - -/** - * DH Parameters - * - * @author Jim Wigginton - */ -final class Parameters extends DH -{ - /** - * Returns the parameters - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type = 'PKCS1', array $options = []) - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - return $type::saveParameters($this->prime, $this->base, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php deleted file mode 100644 index 737781f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PrivateKey.php +++ /dev/null @@ -1,75 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH; - -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\DH; - -/** - * DH Private Key - * - * @author Jim Wigginton - */ -final class PrivateKey extends DH -{ - use Common\Traits\PasswordProtected; - - /** - * Private Key - * - * @var \phpseclib3\Math\BigInteger - */ - protected $privateKey; - - /** - * Public Key - * - * @var \phpseclib3\Math\BigInteger - */ - protected $publicKey; - - /** - * Returns the public key - * - * @return DH\PublicKey - */ - public function getPublicKey() - { - $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); - - if (!isset($this->publicKey)) { - $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); - } - - $key = $type::savePublicKey($this->prime, $this->base, $this->publicKey); - - return DH::loadFormat('PKCS8', $key); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); - - if (!isset($this->publicKey)) { - $this->publicKey = $this->base->powMod($this->privateKey, $this->prime); - } - - return $type::savePrivateKey($this->prime, $this->base, $this->privateKey, $this->publicKey, $this->password, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php deleted file mode 100644 index 87726a5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DH/PublicKey.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DH; - -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\DH; - -/** - * DH Public Key - * - * @author Jim Wigginton - */ -final class PublicKey extends DH -{ - use Common\Traits\Fingerprint; - - /** - * Returns the public key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - return $type::savePublicKey($this->prime, $this->base, $this->publicKey, $options); - } - - /** - * Returns the public key as a BigInteger - * - * @return \phpseclib3\Math\BigInteger - */ - public function toBigInteger() - { - return $this->publicKey; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php deleted file mode 100644 index 0123c66..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA.php +++ /dev/null @@ -1,337 +0,0 @@ - - * getPublicKey(); - * - * $plaintext = 'terrafrost'; - * - * $signature = $private->sign($plaintext); - * - * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; - * ?> - * - * - * @author Jim Wigginton - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\DSA\Parameters; -use phpseclib3\Crypt\DSA\PrivateKey; -use phpseclib3\Crypt\DSA\PublicKey; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP FIPS 186-4 compliant implementation of DSA. - * - * @author Jim Wigginton - */ -abstract class DSA extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - */ - const ALGORITHM = 'DSA'; - - /** - * DSA Prime P - * - * @var \phpseclib3\Math\BigInteger - */ - protected $p; - - /** - * DSA Group Order q - * - * Prime divisor of p-1 - * - * @var \phpseclib3\Math\BigInteger - */ - protected $q; - - /** - * DSA Group Generator G - * - * @var \phpseclib3\Math\BigInteger - */ - protected $g; - - /** - * DSA public key value y - * - * @var \phpseclib3\Math\BigInteger - */ - protected $y; - - /** - * Signature Format - * - * @var string - */ - protected $sigFormat; - - /** - * Signature Format (Short) - * - * @var string - */ - protected $shortFormat; - - /** - * Create DSA parameters - * - * @param int $L - * @param int $N - * @return \phpseclib3\Crypt\DSA|bool - */ - public static function createParameters($L = 2048, $N = 224) - { - self::initialize_static_variables(); - - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('createParameters() should not be called from final classes (' . static::class . ')'); - } - - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - switch (true) { - case $N == 160: - /* - in FIPS 186-1 and 186-2 N was fixed at 160 whereas K had an upper bound of 1024. - RFC 4253 (SSH Transport Layer Protocol) references FIPS 186-2 and as such most - SSH DSA implementations only support keys with an N of 160. - puttygen let's you set the size of L (but not the size of N) and uses 2048 as the - default L value. that's not really compliant with any of the FIPS standards, however, - for the purposes of maintaining compatibility with puttygen, we'll support it - */ - //case ($L >= 512 || $L <= 1024) && (($L & 0x3F) == 0) && $N == 160: - // FIPS 186-3 changed this as follows: - //case $L == 1024 && $N == 160: - case $L == 2048 && $N == 224: - case $L == 2048 && $N == 256: - case $L == 3072 && $N == 256: - break; - default: - throw new \InvalidArgumentException('Invalid values for N and L'); - } - - $two = new BigInteger(2); - - $q = BigInteger::randomPrime($N); - $divisor = $q->multiply($two); - - do { - $x = BigInteger::random($L); - list(, $c) = $x->divide($divisor); - $p = $x->subtract($c->subtract(self::$one)); - } while ($p->getLength() != $L || !$p->isPrime()); - - $p_1 = $p->subtract(self::$one); - list($e) = $p_1->divide($q); - - // quoting http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf#page=50 , - // "h could be obtained from a random number generator or from a counter that - // changes after each use". PuTTY (sshdssg.c) starts h off at 1 and increments - // it on each loop. wikipedia says "commonly h = 2 is used" so we'll just do that - $h = clone $two; - while (true) { - $g = $h->powMod($e, $p); - if (!$g->equals(self::$one)) { - break; - } - $h = $h->add(self::$one); - } - - $dsa = new Parameters(); - $dsa->p = $p; - $dsa->q = $q; - $dsa->g = $g; - - return $dsa; - } - - /** - * Create public / private key pair. - * - * This method is a bit polymorphic. It can take a DSA/Parameters object, L / N as two distinct parameters or - * no parameters (at which point L and N will be generated with this method) - * - * Returns the private key, from which the publickey can be extracted - * - * @param int[] ...$args - * @return DSA\PrivateKey - */ - public static function createKey(...$args) - { - self::initialize_static_variables(); - - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); - } - - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - if (count($args) == 2 && is_int($args[0]) && is_int($args[1])) { - $params = self::createParameters($args[0], $args[1]); - } elseif (count($args) == 1 && $args[0] instanceof Parameters) { - $params = $args[0]; - } elseif (!count($args)) { - $params = self::createParameters(); - } else { - throw new InsufficientSetupException('Valid parameters are either two integers (L and N), a single DSA object or no parameters at all.'); - } - - $private = new PrivateKey(); - $private->p = $params->p; - $private->q = $params->q; - $private->g = $params->g; - - $private->x = BigInteger::randomRange(self::$one, $private->q->subtract(self::$one)); - $private->y = $private->g->powMod($private->x, $private->p); - - //$public = clone $private; - //unset($public->x); - - return $private - ->withHash($params->hash->getHash()) - ->withSignatureFormat($params->shortFormat); - } - - /** - * OnLoad Handler - * - * @return bool - */ - protected static function onLoad(array $components) - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - if (!isset($components['x']) && !isset($components['y'])) { - $new = new Parameters(); - } elseif (isset($components['x'])) { - $new = new PrivateKey(); - $new->x = $components['x']; - } else { - $new = new PublicKey(); - } - - $new->p = $components['p']; - $new->q = $components['q']; - $new->g = $components['g']; - - if (isset($components['y'])) { - $new->y = $components['y']; - } - - return $new; - } - - /** - * Constructor - * - * PublicKey and PrivateKey objects can only be created from abstract RSA class - */ - protected function __construct() - { - $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); - $this->shortFormat = 'ASN1'; - - parent::__construct(); - } - - /** - * Returns the key size - * - * More specifically, this L (the length of DSA Prime P) and N (the length of DSA Group Order q) - * - * @return array - */ - public function getLength() - { - return ['L' => $this->p->getLength(), 'N' => $this->q->getLength()]; - } - - /** - * Returns the current engine being used - * - * @see self::useInternalEngine() - * @see self::useBestEngine() - * @return string - */ - public function getEngine() - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? - 'OpenSSL' : 'PHP'; - } - - /** - * Returns the parameters - * - * A public / private key is only returned if the currently loaded "key" contains an x or y - * value. - * - * @see self::getPublicKey() - * @return mixed - */ - public function getParameters() - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - $key = $type::saveParameters($this->p, $this->q, $this->g); - return DSA::load($key, 'PKCS1') - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - } - - /** - * Determines the signature padding mode - * - * Valid values are: ASN1, SSH2, Raw - * - * @param string $format - */ - public function withSignatureFormat($format) - { - $new = clone $this; - $new->shortFormat = $format; - $new->sigFormat = self::validatePlugin('Signature', $format); - return $new; - } - - /** - * Returns the signature format currently being used - * - */ - public function getSignatureFormat() - { - return $this->shortFormat; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php deleted file mode 100644 index cc204fa..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; -use phpseclib3\Math\BigInteger; - -/** - * OpenSSH Formatted DSA Key Handler - * - * @author Jim Wigginton - */ -abstract class OpenSSH extends Progenitor -{ - /** - * Supported Key Types - * - * @var array - */ - protected static $types = ['ssh-dss']; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $parsed = parent::load($key, $password); - - if (isset($parsed['paddedKey'])) { - list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); - if ($type != $parsed['type']) { - throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); - } - - list($p, $q, $g, $y, $x, $comment) = Strings::unpackSSH2('i5s', $parsed['paddedKey']); - - return compact('p', 'q', 'g', 'y', 'x', 'comment'); - } - - list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $parsed['publicKey']); - - $comment = $parsed['comment']; - - return compact('p', 'q', 'g', 'y', 'comment'); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) - { - if ($q->getLength() != 160) { - throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); - } - - // from : - // string "ssh-dss" - // mpint p - // mpint q - // mpint g - // mpint y - $DSAPublicKey = Strings::packSSH2('siiii', 'ssh-dss', $p, $q, $g, $y); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $DSAPublicKey; - } - - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $DSAPublicKey = 'ssh-dss ' . base64_encode($DSAPublicKey) . ' ' . $comment; - - return $DSAPublicKey; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) - { - $publicKey = self::savePublicKey($p, $q, $g, $y, ['binary' => true]); - $privateKey = Strings::packSSH2('si5', 'ssh-dss', $p, $q, $g, $y, $x); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php deleted file mode 100644 index 52a0499..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#1 Formatted DSA Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS1 extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - - $key = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); - if (is_array($key)) { - return $key; - } - - $key = ASN1::asn1map($decoded[0], Maps\DSAPrivateKey::MAP); - if (is_array($key)) { - return $key; - } - - $key = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); - if (is_array($key)) { - return $key; - } - - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - /** - * Convert DSA parameters to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @return string - */ - public static function saveParameters(BigInteger $p, BigInteger $q, BigInteger $g) - { - $key = [ - 'p' => $p, - 'q' => $q, - 'g' => $g - ]; - - $key = ASN1::encodeDER($key, Maps\DSAParams::MAP); - - return "-----BEGIN DSA PARAMETERS-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END DSA PARAMETERS-----\r\n"; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) - { - $key = [ - 'version' => 0, - 'p' => $p, - 'q' => $q, - 'g' => $g, - 'y' => $y, - 'x' => $x - ]; - - $key = ASN1::encodeDER($key, Maps\DSAPrivateKey::MAP); - - return self::wrapPrivateKey($key, 'DSA', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); - - return self::wrapPublicKey($key, 'DSA'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php deleted file mode 100644 index 004881e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,146 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#8 Formatted DSA Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS8 extends Progenitor -{ - /** - * OID Name - * - * @var string - */ - const OID_NAME = 'id-dsa'; - - /** - * OID Value - * - * @var string - */ - const OID_VALUE = '1.2.840.10040.4.1'; - - /** - * Child OIDs loaded - * - * @var bool - */ - protected static $childOIDsLoaded = false; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; - - $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER of parameters'); - } - $components = ASN1::asn1map($decoded[0], Maps\DSAParams::MAP); - if (!is_array($components)) { - throw new \RuntimeException('Unable to perform ASN1 mapping on parameters'); - } - - $decoded = ASN1::decodeBER($key[$type]); - if (empty($decoded)) { - throw new \RuntimeException('Unable to decode BER'); - } - - $var = $type == 'privateKey' ? 'x' : 'y'; - $components[$var] = ASN1::asn1map($decoded[0], Maps\DSAPublicKey::MAP); - if (!$components[$var] instanceof BigInteger) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - if (isset($key['meta'])) { - $components['meta'] = $key['meta']; - } - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '', array $options = []) - { - $params = [ - 'p' => $p, - 'q' => $q, - 'g' => $g - ]; - $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($x, Maps\DSAPublicKey::MAP); - return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, array $options = []) - { - $params = [ - 'p' => $p, - 'q' => $q, - 'g' => $g - ]; - $params = ASN1::encodeDER($params, Maps\DSAParams::MAP); - $params = new ASN1\Element($params); - $key = ASN1::encodeDER($y, Maps\DSAPublicKey::MAP); - return self::wrapPublicKey($key, $params); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php deleted file mode 100644 index 177bfdd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,109 +0,0 @@ - 160 kinda useless, hence this handlers not supporting such keys. - * - * PHP version 5 - * - * @author Jim Wigginton - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; -use phpseclib3\Math\BigInteger; - -/** - * PuTTY Formatted DSA Key Handler - * - * @author Jim Wigginton - */ -abstract class PuTTY extends Progenitor -{ - /** - * Public Handler - * - * @var string - */ - const PUBLIC_HANDLER = 'phpseclib3\Crypt\DSA\Formats\Keys\OpenSSH'; - - /** - * Algorithm Identifier - * - * @var array - */ - protected static $types = ['ssh-dss']; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $components = parent::load($key, $password); - if (!isset($components['private'])) { - return $components; - } - extract($components); - unset($components['public'], $components['private']); - - list($p, $q, $g, $y) = Strings::unpackSSH2('iiii', $public); - list($x) = Strings::unpackSSH2('i', $private); - - return compact('p', 'q', 'g', 'y', 'x', 'comment'); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = false, array $options = []) - { - if ($q->getLength() != 160) { - throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); - } - - $public = Strings::packSSH2('iiii', $p, $q, $g, $y); - $private = Strings::packSSH2('i', $x); - - return self::wrapPrivateKey($public, $private, 'ssh-dss', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - if ($q->getLength() != 160) { - throw new \InvalidArgumentException('SSH only supports keys with an N (length of Group Order q) of 160'); - } - - return self::wrapPublicKey(Strings::packSSH2('iiii', $p, $q, $g, $y), 'ssh-dss'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php deleted file mode 100644 index 201aa6f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/Raw.php +++ /dev/null @@ -1,85 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; - -/** - * Raw DSA Key Handler - * - * @author Jim Wigginton - */ -abstract class Raw -{ - /** - * Break a public or private key down into its constituent components - * - * @param array $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!is_array($key)) { - throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); - } - - switch (true) { - case !isset($key['p']) || !isset($key['q']) || !isset($key['g']): - case !$key['p'] instanceof BigInteger: - case !$key['q'] instanceof BigInteger: - case !$key['g'] instanceof BigInteger: - case !isset($key['x']) && !isset($key['y']): - case isset($key['x']) && !$key['x'] instanceof BigInteger: - case isset($key['y']) && !$key['y'] instanceof BigInteger: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $options = ['p' => 1, 'q' => 1, 'g' => 1, 'x' => 1, 'y' => 1]; - - return array_intersect_key($key, $options); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @param \phpseclib3\Math\BigInteger $x - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y, BigInteger $x, $password = '') - { - return compact('p', 'q', 'g', 'y', 'x'); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - return compact('p', 'q', 'g', 'y'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php deleted file mode 100644 index fc36367..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Keys/XML.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Math\BigInteger; - -/** - * XML Formatted DSA Key Handler - * - * @author Jim Wigginton - */ -abstract class XML -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (!class_exists('DOMDocument')) { - throw new BadConfigurationException('The dom extension is not setup correctly on this system'); - } - - $use_errors = libxml_use_internal_errors(true); - - $dom = new \DOMDocument(); - if (substr($key, 0, 5) != '' . $key . ''; - } - if (!$dom->loadXML($key)) { - libxml_use_internal_errors($use_errors); - throw new \UnexpectedValueException('Key does not appear to contain XML'); - } - $xpath = new \DOMXPath($dom); - $keys = ['p', 'q', 'g', 'y', 'j', 'seed', 'pgencounter']; - foreach ($keys as $key) { - // $dom->getElementsByTagName($key) is case-sensitive - $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); - if (!$temp->length) { - continue; - } - $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); - switch ($key) { - case 'p': // a prime modulus meeting the [DSS] requirements - // Parameters P, Q, and G can be public and common to a group of users. They might be known - // from application context. As such, they are optional but P and Q must either both appear - // or both be absent - $components['p'] = $value; - break; - case 'q': // an integer in the range 2**159 < Q < 2**160 which is a prime divisor of P-1 - $components['q'] = $value; - break; - case 'g': // an integer with certain properties with respect to P and Q - $components['g'] = $value; - break; - case 'y': // G**X mod P (where X is part of the private key and not made public) - $components['y'] = $value; - // the remaining options do not do anything - case 'j': // (P - 1) / Q - // Parameter J is available for inclusion solely for efficiency as it is calculatable from - // P and Q - case 'seed': // a DSA prime generation seed - // Parameters seed and pgenCounter are used in the DSA prime number generation algorithm - // specified in [DSS]. As such, they are optional but must either both be present or both - // be absent - case 'pgencounter': // a DSA prime generation counter - } - } - - libxml_use_internal_errors($use_errors); - - if (!isset($components['y'])) { - throw new \UnexpectedValueException('Key is missing y component'); - } - - switch (true) { - case !isset($components['p']): - case !isset($components['q']): - case !isset($components['g']): - return ['y' => $components['y']]; - } - - return $components; - } - - /** - * Convert a public key to the appropriate format - * - * See https://www.w3.org/TR/xmldsig-core/#sec-DSAKeyValue - * - * @param \phpseclib3\Math\BigInteger $p - * @param \phpseclib3\Math\BigInteger $q - * @param \phpseclib3\Math\BigInteger $g - * @param \phpseclib3\Math\BigInteger $y - * @return string - */ - public static function savePublicKey(BigInteger $p, BigInteger $q, BigInteger $g, BigInteger $y) - { - return "\r\n" . - '

          ' . Strings::base64_encode($p->toBytes()) . "

          \r\n" . - ' ' . Strings::base64_encode($q->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($g->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($y->toBytes()) . "\r\n" . - '
          '; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php deleted file mode 100644 index df52bee..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/ASN1.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Signature; - -use phpseclib3\File\ASN1 as Encoder; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * ASN1 Signature Handler - * - * @author Jim Wigginton - */ -abstract class ASN1 -{ - /** - * Loads a signature - * - * @param string $sig - * @return array|bool - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $decoded = Encoder::decodeBER($sig); - if (empty($decoded)) { - return false; - } - $components = Encoder::asn1map($decoded[0], Maps\DssSigValue::MAP); - - return $components; - } - - /** - * Returns a signature in the appropriate format - * - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - return Encoder::encodeDER(compact('r', 's'), Maps\DssSigValue::MAP); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php deleted file mode 100644 index 2657a2a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/Raw.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Signature; - -use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; - -/** - * Raw DSA Signature Handler - * - * @author Jim Wigginton - */ -abstract class Raw extends Progenitor -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php deleted file mode 100644 index dbfceab..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Formats/Signature/SSH2.php +++ /dev/null @@ -1,74 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA\Formats\Signature; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; - -/** - * SSH2 Signature Handler - * - * @author Jim Wigginton - */ -abstract class SSH2 -{ - /** - * Loads a signature - * - * @param string $sig - * @return mixed - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $result = Strings::unpackSSH2('ss', $sig); - if ($result === false) { - return false; - } - list($type, $blob) = $result; - if ($type != 'ssh-dss' || strlen($blob) != 40) { - return false; - } - - return [ - 'r' => new BigInteger(substr($blob, 0, 20), 256), - 's' => new BigInteger(substr($blob, 20), 256) - ]; - } - - /** - * Returns a signature in the appropriate format - * - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - if ($r->getLength() > 160 || $s->getLength() > 160) { - return false; - } - return Strings::packSSH2( - 'ss', - 'ssh-dss', - str_pad($r->toBytes(), 20, "\0", STR_PAD_LEFT) . - str_pad($s->toBytes(), 20, "\0", STR_PAD_LEFT) - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php deleted file mode 100644 index 84d16ba..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/Parameters.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA; - -use phpseclib3\Crypt\DSA; - -/** - * DSA Parameters - * - * @author Jim Wigginton - */ -final class Parameters extends DSA -{ - /** - * Returns the parameters - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type = 'PKCS1', array $options = []) - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - return $type::saveParameters($this->p, $this->q, $this->g, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php deleted file mode 100644 index 74d3e69..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PrivateKey.php +++ /dev/null @@ -1,152 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA; - -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Math\BigInteger; - -/** - * DSA Private Key - * - * @author Jim Wigginton - */ -final class PrivateKey extends DSA implements Common\PrivateKey -{ - use Common\Traits\PasswordProtected; - - /** - * DSA secret exponent x - * - * @var \phpseclib3\Math\BigInteger - */ - protected $x; - - /** - * Returns the public key - * - * If you do "openssl rsa -in private.rsa -pubout -outform PEM" you get a PKCS8 formatted key - * that contains a publicKeyAlgorithm AlgorithmIdentifier and a publicKey BIT STRING. - * An AlgorithmIdentifier contains an OID and a parameters field. With RSA public keys this - * parameters field is NULL. With DSA PKCS8 public keys it is not - it contains the p, q and g - * variables. The publicKey BIT STRING contains, simply, the y variable. This can be verified - * by getting a DSA PKCS8 public key: - * - * "openssl dsa -in private.dsa -pubout -outform PEM" - * - * ie. just swap out rsa with dsa in the rsa command above. - * - * A PKCS1 public key corresponds to the publicKey portion of the PKCS8 key. In the case of RSA - * the publicKey portion /is/ the key. In the case of DSA it is not. You cannot verify a signature - * without the parameters and the PKCS1 DSA public key format does not include the parameters. - * - * @see self::getPrivateKey() - * @return mixed - */ - public function getPublicKey() - { - $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); - - if (!isset($this->y)) { - $this->y = $this->g->powMod($this->x, $this->p); - } - - $key = $type::savePublicKey($this->p, $this->q, $this->g, $this->y); - - return DSA::loadFormat('PKCS8', $key) - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - } - - /** - * Create a signature - * - * @see self::verify() - * @param string $message - * @return mixed - */ - public function sign($message) - { - $format = $this->sigFormat; - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $signature = ''; - $result = openssl_sign($message, $signature, $this->toString('PKCS8'), $this->hash->getHash()); - - if ($result) { - if ($this->shortFormat == 'ASN1') { - return $signature; - } - - extract(ASN1Signature::load($signature)); - - return $format::save($r, $s); - } - } - - $h = $this->hash->hash($message); - $h = $this->bits2int($h); - - while (true) { - $k = BigInteger::randomRange(self::$one, $this->q->subtract(self::$one)); - $r = $this->g->powMod($k, $this->p); - list(, $r) = $r->divide($this->q); - if ($r->equals(self::$zero)) { - continue; - } - $kinv = $k->modInverse($this->q); - $temp = $h->add($this->x->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($this->q); - if (!$s->equals(self::$zero)) { - break; - } - } - - // the following is an RFC6979 compliant implementation of deterministic DSA - // it's unused because it's mainly intended for use when a good CSPRNG isn't - // available. if phpseclib's CSPRNG isn't good then even key generation is - // suspect - /* - $h1 = $this->hash->hash($message); - $k = $this->computek($h1); - $r = $this->g->powMod($k, $this->p); - list(, $r) = $r->divide($this->q); - $kinv = $k->modInverse($this->q); - $h1 = $this->bits2int($h1); - $temp = $h1->add($this->x->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($this->q); - */ - - return $format::save($r, $s); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); - - if (!isset($this->y)) { - $this->y = $this->g->powMod($this->x, $this->p); - } - - return $type::savePrivateKey($this->p, $this->q, $this->g, $this->y, $this->x, $this->password, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php deleted file mode 100644 index c14ffbd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/DSA/PublicKey.php +++ /dev/null @@ -1,86 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\DSA; - -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\DSA\Formats\Signature\ASN1 as ASN1Signature; - -/** - * DSA Public Key - * - * @author Jim Wigginton - */ -final class PublicKey extends DSA implements Common\PublicKey -{ - use Common\Traits\Fingerprint; - - /** - * Verify a signature - * - * @see self::verify() - * @param string $message - * @param string $signature - * @return mixed - */ - public function verify($message, $signature) - { - $format = $this->sigFormat; - - $params = $format::load($signature); - if ($params === false || count($params) != 2) { - return false; - } - extract($params); - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; - - $result = openssl_verify($message, $sig, $this->toString('PKCS8'), $this->hash->getHash()); - - if ($result != -1) { - return (bool) $result; - } - } - - $q_1 = $this->q->subtract(self::$one); - if (!$r->between(self::$one, $q_1) || !$s->between(self::$one, $q_1)) { - return false; - } - - $w = $s->modInverse($this->q); - $h = $this->hash->hash($message); - $h = $this->bits2int($h); - list(, $u1) = $h->multiply($w)->divide($this->q); - list(, $u2) = $r->multiply($w)->divide($this->q); - $v1 = $this->g->powMod($u1, $this->p); - $v2 = $this->y->powMod($u2, $this->p); - list(, $v) = $v1->multiply($v2)->divide($this->p); - list(, $v) = $v->divide($this->q); - - return $v->equals($r); - } - - /** - * Returns the public key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - return $type::savePublicKey($this->p, $this->q, $this->g, $this->y, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php deleted file mode 100644 index 10b3825..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC.php +++ /dev/null @@ -1,480 +0,0 @@ - - * getPublicKey(); - * - * $plaintext = 'terrafrost'; - * - * $signature = $private->sign($plaintext); - * - * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; - * ?> - * - * - * @author Jim Wigginton - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Curves\Ed448; -use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; -use phpseclib3\Crypt\EC\Parameters; -use phpseclib3\Crypt\EC\PrivateKey; -use phpseclib3\Crypt\EC\PublicKey; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps\ECParameters; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP implementation of EC. - * - * @author Jim Wigginton - */ -abstract class EC extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - */ - const ALGORITHM = 'EC'; - - /** - * Public Key QA - * - * @var object[] - */ - protected $QA; - - /** - * Curve - * - * @var \phpseclib3\Crypt\EC\BaseCurves\Base - */ - protected $curve; - - /** - * Signature Format - * - * @var string - */ - protected $format; - - /** - * Signature Format (Short) - * - * @var string - */ - protected $shortFormat; - - /** - * Curve Name - * - * @var string - */ - private $curveName; - - /** - * Curve Order - * - * Used for deterministic ECDSA - * - * @var \phpseclib3\Math\BigInteger - */ - protected $q; - - /** - * Alias for the private key - * - * Used for deterministic ECDSA. AsymmetricKey expects $x. I don't like x because - * with x you have x * the base point yielding an (x, y)-coordinate that is the - * public key. But the x is different depending on which side of the equal sign - * you're on. It's less ambiguous if you do dA * base point = (x, y)-coordinate. - * - * @var \phpseclib3\Math\BigInteger - */ - protected $x; - - /** - * Context - * - * @var string - */ - protected $context; - - /** - * Signature Format - * - * @var string - */ - protected $sigFormat; - - /** - * Create public / private key pair. - * - * @param string $curve - * @return \phpseclib3\Crypt\EC\PrivateKey - */ - public static function createKey($curve) - { - self::initialize_static_variables(); - - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); - } - - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - $curve = strtolower($curve); - if (self::$engines['libsodium'] && $curve == 'ed25519' && function_exists('sodium_crypto_sign_keypair')) { - $kp = sodium_crypto_sign_keypair(); - - $privatekey = EC::loadFormat('libsodium', sodium_crypto_sign_secretkey($kp)); - //$publickey = EC::loadFormat('libsodium', sodium_crypto_sign_publickey($kp)); - - $privatekey->curveName = 'Ed25519'; - //$publickey->curveName = $curve; - - return $privatekey; - } - - $privatekey = new PrivateKey(); - - $curveName = $curve; - if (preg_match('#(?:^curve|^ed)\d+$#', $curveName)) { - $curveName = ucfirst($curveName); - } elseif (substr($curveName, 0, 10) == 'brainpoolp') { - $curveName = 'brainpoolP' . substr($curveName, 10); - } - $curve = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; - - if (!class_exists($curve)) { - throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported'); - } - - $reflect = new \ReflectionClass($curve); - $curveName = $reflect->isFinal() ? - $reflect->getParentClass()->getShortName() : - $reflect->getShortName(); - - $curve = new $curve(); - if ($curve instanceof TwistedEdwardsCurve) { - $arr = $curve->extractSecret(Random::string($curve instanceof Ed448 ? 57 : 32)); - $privatekey->dA = $dA = $arr['dA']; - $privatekey->secret = $arr['secret']; - } else { - $privatekey->dA = $dA = $curve->createRandomMultiplier(); - } - if ($curve instanceof Curve25519 && self::$engines['libsodium']) { - //$r = pack('H*', '0900000000000000000000000000000000000000000000000000000000000000'); - //$QA = sodium_crypto_scalarmult($dA->toBytes(), $r); - $QA = sodium_crypto_box_publickey_from_secretkey($dA->toBytes()); - $privatekey->QA = [$curve->convertInteger(new BigInteger(strrev($QA), 256))]; - } else { - $privatekey->QA = $curve->multiplyPoint($curve->getBasePoint(), $dA); - } - $privatekey->curve = $curve; - - //$publickey = clone $privatekey; - //unset($publickey->dA); - //unset($publickey->x); - - $privatekey->curveName = $curveName; - //$publickey->curveName = $curveName; - - if ($privatekey->curve instanceof TwistedEdwardsCurve) { - return $privatekey->withHash($curve::HASH); - } - - return $privatekey; - } - - /** - * OnLoad Handler - * - * @return bool - */ - protected static function onLoad(array $components) - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - if (!isset($components['dA']) && !isset($components['QA'])) { - $new = new Parameters(); - $new->curve = $components['curve']; - return $new; - } - - $new = isset($components['dA']) ? - new PrivateKey() : - new PublicKey(); - $new->curve = $components['curve']; - $new->QA = $components['QA']; - - if (isset($components['dA'])) { - $new->dA = $components['dA']; - $new->secret = $components['secret']; - } - - if ($new->curve instanceof TwistedEdwardsCurve) { - return $new->withHash($components['curve']::HASH); - } - - return $new; - } - - /** - * Constructor - * - * PublicKey and PrivateKey objects can only be created from abstract RSA class - */ - protected function __construct() - { - $this->sigFormat = self::validatePlugin('Signature', 'ASN1'); - $this->shortFormat = 'ASN1'; - - parent::__construct(); - } - - /** - * Returns the curve - * - * Returns a string if it's a named curve, an array if not - * - * @return string|array - */ - public function getCurve() - { - if ($this->curveName) { - return $this->curveName; - } - - if ($this->curve instanceof MontgomeryCurve) { - $this->curveName = $this->curve instanceof Curve25519 ? 'Curve25519' : 'Curve448'; - return $this->curveName; - } - - if ($this->curve instanceof TwistedEdwardsCurve) { - $this->curveName = $this->curve instanceof Ed25519 ? 'Ed25519' : 'Ed448'; - return $this->curveName; - } - - $params = $this->getParameters()->toString('PKCS8', ['namedCurve' => true]); - $decoded = ASN1::extractBER($params); - $decoded = ASN1::decodeBER($decoded); - $decoded = ASN1::asn1map($decoded[0], ECParameters::MAP); - if (isset($decoded['namedCurve'])) { - $this->curveName = $decoded['namedCurve']; - return $decoded['namedCurve']; - } - - if (!$namedCurves) { - PKCS1::useSpecifiedCurve(); - } - - return $decoded; - } - - /** - * Returns the key size - * - * Quoting https://tools.ietf.org/html/rfc5656#section-2, - * - * "The size of a set of elliptic curve domain parameters on a prime - * curve is defined as the number of bits in the binary representation - * of the field order, commonly denoted by p. Size on a - * characteristic-2 curve is defined as the number of bits in the binary - * representation of the field, commonly denoted by m. A set of - * elliptic curve domain parameters defines a group of order n generated - * by a base point P" - * - * @return int - */ - public function getLength() - { - return $this->curve->getLength(); - } - - /** - * Returns the current engine being used - * - * @see self::useInternalEngine() - * @see self::useBestEngine() - * @return string - */ - public function getEngine() - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - if ($this->curve instanceof TwistedEdwardsCurve) { - return $this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context) ? - 'libsodium' : 'PHP'; - } - - return self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods()) ? - 'OpenSSL' : 'PHP'; - } - - /** - * Returns the public key coordinates as a string - * - * Used by ECDH - * - * @return string - */ - public function getEncodedCoordinates() - { - if ($this->curve instanceof MontgomeryCurve) { - return strrev($this->QA[0]->toBytes(true)); - } - if ($this->curve instanceof TwistedEdwardsCurve) { - return $this->curve->encodePoint($this->QA); - } - return "\4" . $this->QA[0]->toBytes(true) . $this->QA[1]->toBytes(true); - } - - /** - * Returns the parameters - * - * @see self::getPublicKey() - * @param string $type optional - * @return mixed - */ - public function getParameters($type = 'PKCS1') - { - $type = self::validatePlugin('Keys', $type, 'saveParameters'); - - $key = $type::saveParameters($this->curve); - - return EC::load($key, 'PKCS1') - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - } - - /** - * Determines the signature padding mode - * - * Valid values are: ASN1, SSH2, Raw - * - * @param string $format - */ - public function withSignatureFormat($format) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - - $new = clone $this; - $new->shortFormat = $format; - $new->sigFormat = self::validatePlugin('Signature', $format); - return $new; - } - - /** - * Returns the signature format currently being used - * - */ - public function getSignatureFormat() - { - return $this->shortFormat; - } - - /** - * Sets the context - * - * Used by Ed25519 / Ed448. - * - * @see self::sign() - * @see self::verify() - * @param string $context optional - */ - public function withContext($context = null) - { - if (!$this->curve instanceof TwistedEdwardsCurve) { - throw new UnsupportedCurveException('Only Ed25519 and Ed448 support contexts'); - } - - $new = clone $this; - if (!isset($context)) { - $new->context = null; - return $new; - } - if (!is_string($context)) { - throw new \InvalidArgumentException('setContext expects a string'); - } - if (strlen($context) > 255) { - throw new \LengthException('The context is supposed to be, at most, 255 bytes long'); - } - $new->context = $context; - return $new; - } - - /** - * Returns the signature format currently being used - * - */ - public function getContext() - { - return $this->context; - } - - /** - * Determines which hashing function should be used - * - * @param string $hash - */ - public function withHash($hash) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - if ($this->curve instanceof Ed25519 && $hash != 'sha512') { - throw new UnsupportedAlgorithmException('Ed25519 only supports sha512 as a hash'); - } - if ($this->curve instanceof Ed448 && $hash != 'shake256-912') { - throw new UnsupportedAlgorithmException('Ed448 only supports shake256 with a length of 114 bytes'); - } - - return parent::withHash($hash); - } - - /** - * __toString() magic method - * - * @return string - */ - public function __toString() - { - if ($this->curve instanceof MontgomeryCurve) { - return ''; - } - - return parent::__toString(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php deleted file mode 100644 index dbc914b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Base.php +++ /dev/null @@ -1,218 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\BigInteger; - -/** - * Base - * - * @author Jim Wigginton - */ -abstract class Base -{ - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Finite Field Integer factory - * - * @var \phpseclib3\Math\FiniteField\Integer - */ - protected $factory; - - /** - * Returns a random integer - * - * @return object - */ - public function randomInteger() - { - return $this->factory->randomInteger(); - } - - /** - * Converts a BigInteger to a \phpseclib3\Math\FiniteField\Integer integer - * - * @return object - */ - public function convertInteger(BigInteger $x) - { - return $this->factory->newInteger($x); - } - - /** - * Returns the length, in bytes, of the modulo - * - * @return integer - */ - public function getLengthInBytes() - { - return $this->factory->getLengthInBytes(); - } - - /** - * Returns the length, in bits, of the modulo - * - * @return integer - */ - public function getLength() - { - return $this->factory->getLength(); - } - - /** - * Multiply a point on the curve by a scalar - * - * Uses the montgomery ladder technique as described here: - * - * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder - * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 - * - * @return array - */ - public function multiplyPoint(array $p, BigInteger $d) - { - $alreadyInternal = isset($p[2]); - $r = $alreadyInternal ? - [[], $p] : - [[], $this->convertToInternal($p)]; - - $d = $d->toBits(); - for ($i = 0; $i < strlen($d); $i++) { - $d_i = (int) $d[$i]; - $r[1 - $d_i] = $this->addPoint($r[0], $r[1]); - $r[$d_i] = $this->doublePoint($r[$d_i]); - } - - return $alreadyInternal ? $r[0] : $this->convertToAffine($r[0]); - } - - /** - * Creates a random scalar multiplier - * - * @return BigInteger - */ - public function createRandomMultiplier() - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - return BigInteger::randomRange($one, $this->order->subtract($one)); - } - - /** - * Performs range check - */ - public function rangeCheck(BigInteger $x) - { - static $zero; - if (!isset($zero)) { - $zero = new BigInteger(); - } - - if (!isset($this->order)) { - throw new \RuntimeException('setOrder needs to be called before this method'); - } - if ($x->compare($this->order) > 0 || $x->compare($zero) <= 0) { - throw new \RangeException('x must be between 1 and the order of the curve'); - } - } - - /** - * Sets the Order - */ - public function setOrder(BigInteger $order) - { - $this->order = $order; - } - - /** - * Returns the Order - * - * @return \phpseclib3\Math\BigInteger - */ - public function getOrder() - { - return $this->order; - } - - /** - * Use a custom defined modular reduction function - * - * @return object - */ - public function setReduction(callable $func) - { - $this->factory->setReduction($func); - } - - /** - * Returns the affine point - * - * @return object[] - */ - public function convertToAffine(array $p) - { - return $p; - } - - /** - * Converts an affine point to a jacobian coordinate - * - * @return object[] - */ - public function convertToInternal(array $p) - { - return $p; - } - - /** - * Negates a point - * - * @return object[] - */ - public function negatePoint(array $p) - { - $temp = [ - $p[0], - $p[1]->negate() - ]; - if (isset($p[2])) { - $temp[] = $p[2]; - } - return $temp; - } - - /** - * Multiply and Add Points - * - * @return int[] - */ - public function multiplyAddPoints(array $points, array $scalars) - { - $p1 = $this->convertToInternal($points[0]); - $p2 = $this->convertToInternal($points[1]); - $p1 = $this->multiplyPoint($p1, $scalars[0]); - $p2 = $this->multiplyPoint($p2, $scalars[1]); - $r = $this->addPoint($p1, $p2); - return $this->convertToAffine($r); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php deleted file mode 100644 index 4fc6c70..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Binary.php +++ /dev/null @@ -1,373 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\BinaryField; -use phpseclib3\Math\BinaryField\Integer as BinaryInteger; - -/** - * Curves over y^2 + x*y = x^3 + a*x^2 + b - * - * @author Jim Wigginton - */ -class Binary extends Base -{ - /** - * Binary Field Integer factory - * - * @var \phpseclib3\Math\BinaryField - */ - protected $factory; - - /** - * Cofficient for x^1 - * - * @var object - */ - protected $a; - - /** - * Cofficient for x^0 - * - * @var object - */ - protected $b; - - /** - * Base Point - * - * @var object - */ - protected $p; - - /** - * The number one over the specified finite field - * - * @var object - */ - protected $one; - - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Sets the modulo - */ - public function setModulo(...$modulo) - { - $this->modulo = $modulo; - $this->factory = new BinaryField(...$modulo); - - $this->one = $this->factory->newInteger("\1"); - } - - /** - * Set coefficients a and b - * - * @param string $a - * @param string $b - */ - public function setCoefficients($a, $b) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger(pack('H*', $a)); - $this->b = $this->factory->newInteger(pack('H*', $b)); - } - - /** - * Set x and y coordinates for the base point - * - * @param string|BinaryInteger $x - * @param string|BinaryInteger $y - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !is_string($x) && !$x instanceof BinaryInteger: - throw new \UnexpectedValueException('Argument 1 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); - case !is_string($y) && !$y instanceof BinaryInteger: - throw new \UnexpectedValueException('Argument 2 passed to Binary::setBasePoint() must be a string or an instance of BinaryField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - is_string($x) ? $this->factory->newInteger(pack('H*', $x)) : $x, - is_string($y) ? $this->factory->newInteger(pack('H*', $y)) : $y - ]; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - if (!isset($p[2]) || !isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); - } - - // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html - - list($x1, $y1, $z1) = $p; - list($x2, $y2, $z2) = $q; - - $o1 = $z1->multiply($z1); - $b = $x2->multiply($o1); - - if ($z2->equals($this->one)) { - $d = $y2->multiply($o1)->multiply($z1); - $e = $x1->add($b); - $f = $y1->add($d); - $z3 = $e->multiply($z1); - $h = $f->multiply($x2)->add($z3->multiply($y2)); - $i = $f->add($z3); - $g = $z3->multiply($z3); - $p1 = $this->a->multiply($g); - $p2 = $f->multiply($i); - $p3 = $e->multiply($e)->multiply($e); - $x3 = $p1->add($p2)->add($p3); - $y3 = $i->multiply($x3)->add($g->multiply($h)); - - return [$x3, $y3, $z3]; - } - - $o2 = $z2->multiply($z2); - $a = $x1->multiply($o2); - $c = $y1->multiply($o2)->multiply($z2); - $d = $y2->multiply($o1)->multiply($z1); - $e = $a->add($b); - $f = $c->add($d); - $g = $e->multiply($z1); - $h = $f->multiply($x2)->add($g->multiply($y2)); - $z3 = $g->multiply($z2); - $i = $f->add($z3); - $p1 = $this->a->multiply($z3->multiply($z3)); - $p2 = $f->multiply($i); - $p3 = $e->multiply($e)->multiply($e); - $x3 = $p1->add($p2)->add($p3); - $y3 = $i->multiply($x3)->add($g->multiply($g)->multiply($h)); - - return [$x3, $y3, $z3]; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - if (!isset($p[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - // formulas from http://hyperelliptic.org/EFD/g12o/auto-shortw-jacobian.html - - list($x1, $y1, $z1) = $p; - - $a = $x1->multiply($x1); - $b = $a->multiply($a); - - if ($z1->equals($this->one)) { - $x3 = $b->add($this->b); - $z3 = clone $x1; - $p1 = $a->add($y1)->add($z3)->multiply($this->b); - $p2 = $a->add($y1)->multiply($b); - $y3 = $p1->add($p2); - - return [$x3, $y3, $z3]; - } - - $c = $z1->multiply($z1); - $d = $c->multiply($c); - $x3 = $b->add($this->b->multiply($d->multiply($d))); - $z3 = $x1->multiply($c); - $p1 = $b->multiply($z3); - $p2 = $a->add($y1->multiply($z1))->add($z3)->multiply($x3); - $y3 = $p1->add($p2); - - return [$x3, $y3, $z3]; - } - - /** - * Returns the X coordinate and the derived Y coordinate - * - * Not supported because it is covered by patents. - * Quoting https://www.openssl.org/docs/man1.1.0/apps/ecparam.html , - * - * "Due to patent issues the compressed option is disabled by default for binary curves - * and can be enabled by defining the preprocessor macro OPENSSL_EC_BIN_PT_COMP at - * compile time." - * - * @return array - */ - public function derivePoint($m) - { - throw new \RuntimeException('Point compression on binary finite field elliptic curves is not supported'); - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $lhs = $y->multiply($y); - $lhs = $lhs->add($x->multiply($y)); - $x2 = $x->multiply($x); - $x3 = $x2->multiply($x); - $rhs = $x3->add($this->a->multiply($x2))->add($this->b); - - return $lhs->equals($rhs); - } - - /** - * Returns the modulo - * - * @return \phpseclib3\Math\BigInteger - */ - public function getModulo() - { - return $this->modulo; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getA() - { - return $this->a; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getB() - { - return $this->b; - } - - /** - * Returns the affine point - * - * A Jacobian Coordinate is of the form (x, y, z). - * To convert a Jacobian Coordinate to an Affine Point - * you do (x / z^2, y / z^3) - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[2])) { - return $p; - } - list($x, $y, $z) = $p; - $z = $this->one->divide($z); - $z2 = $z->multiply($z); - return [ - $x->multiply($z2), - $y->multiply($z2)->multiply($z) - ]; - } - - /** - * Converts an affine point to a jacobian coordinate - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - $p['fresh'] = true; - return $p; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php deleted file mode 100644 index d8492eb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/KoblitzPrime.php +++ /dev/null @@ -1,335 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField; - -/** - * Curves over y^2 = x^3 + b - * - * @author Jim Wigginton - */ -class KoblitzPrime extends Prime -{ - /** - * Basis - * - * @var list - */ - protected $basis; - - /** - * Beta - * - * @var PrimeField\Integer - */ - protected $beta; - - // don't overwrite setCoefficients() with one that only accepts one parameter so that - // one might be able to switch between KoblitzPrime and Prime more easily (for benchmarking - // purposes). - - /** - * Multiply and Add Points - * - * Uses a efficiently computable endomorphism to achieve a slight speedup - * - * Adapted from: - * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/short.js#L219 - * - * @return int[] - */ - public function multiplyAddPoints(array $points, array $scalars) - { - static $zero, $one, $two; - if (!isset($two)) { - $two = new BigInteger(2); - $one = new BigInteger(1); - } - - if (!isset($this->beta)) { - // get roots - $inv = $this->one->divide($this->two)->negate(); - $s = $this->three->negate()->squareRoot()->multiply($inv); - $betas = [ - $inv->add($s), - $inv->subtract($s) - ]; - $this->beta = $betas[0]->compare($betas[1]) < 0 ? $betas[0] : $betas[1]; - //echo strtoupper($this->beta->toHex(true)) . "\n"; exit; - } - - if (!isset($this->basis)) { - $factory = new PrimeField($this->order); - $tempOne = $factory->newInteger($one); - $tempTwo = $factory->newInteger($two); - $tempThree = $factory->newInteger(new BigInteger(3)); - - $inv = $tempOne->divide($tempTwo)->negate(); - $s = $tempThree->negate()->squareRoot()->multiply($inv); - - $lambdas = [ - $inv->add($s), - $inv->subtract($s) - ]; - - $lhs = $this->multiplyPoint($this->p, $lambdas[0])[0]; - $rhs = $this->p[0]->multiply($this->beta); - $lambda = $lhs->equals($rhs) ? $lambdas[0] : $lambdas[1]; - - $this->basis = static::extendedGCD($lambda->toBigInteger(), $this->order); - ///* - foreach ($this->basis as $basis) { - echo strtoupper($basis['a']->toHex(true)) . "\n"; - echo strtoupper($basis['b']->toHex(true)) . "\n\n"; - } - exit; - //*/ - } - - $npoints = $nscalars = []; - for ($i = 0; $i < count($points); $i++) { - $p = $points[$i]; - $k = $scalars[$i]->toBigInteger(); - - // begin split - list($v1, $v2) = $this->basis; - - $c1 = $v2['b']->multiply($k); - list($c1, $r) = $c1->divide($this->order); - if ($this->order->compare($r->multiply($two)) <= 0) { - $c1 = $c1->add($one); - } - - $c2 = $v1['b']->negate()->multiply($k); - list($c2, $r) = $c2->divide($this->order); - if ($this->order->compare($r->multiply($two)) <= 0) { - $c2 = $c2->add($one); - } - - $p1 = $c1->multiply($v1['a']); - $p2 = $c2->multiply($v2['a']); - $q1 = $c1->multiply($v1['b']); - $q2 = $c2->multiply($v2['b']); - - $k1 = $k->subtract($p1)->subtract($p2); - $k2 = $q1->add($q2)->negate(); - // end split - - $beta = [ - $p[0]->multiply($this->beta), - $p[1], - clone $this->one - ]; - - if (isset($p['naf'])) { - $beta['naf'] = array_map(function ($p) { - return [ - $p[0]->multiply($this->beta), - $p[1], - clone $this->one - ]; - }, $p['naf']); - $beta['nafwidth'] = $p['nafwidth']; - } - - if ($k1->isNegative()) { - $k1 = $k1->negate(); - $p = $this->negatePoint($p); - } - - if ($k2->isNegative()) { - $k2 = $k2->negate(); - $beta = $this->negatePoint($beta); - } - - $pos = 2 * $i; - $npoints[$pos] = $p; - $nscalars[$pos] = $this->factory->newInteger($k1); - - $pos++; - $npoints[$pos] = $beta; - $nscalars[$pos] = $this->factory->newInteger($k2); - } - - return parent::multiplyAddPoints($npoints, $nscalars); - } - - /** - * Returns the numerator and denominator of the slope - * - * @return FiniteField[] - */ - protected function doublePointHelper(array $p) - { - $numerator = $this->three->multiply($p[0])->multiply($p[0]); - $denominator = $this->two->multiply($p[1]); - return [$numerator, $denominator]; - } - - /** - * Doubles a jacobian coordinate on the curve - * - * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l - * - * @return FiniteField[] - */ - protected function jacobianDoublePoint(array $p) - { - list($x1, $y1, $z1) = $p; - $a = $x1->multiply($x1); - $b = $y1->multiply($y1); - $c = $b->multiply($b); - $d = $x1->add($b); - $d = $d->multiply($d)->subtract($a)->subtract($c)->multiply($this->two); - $e = $this->three->multiply($a); - $f = $e->multiply($e); - $x3 = $f->subtract($this->two->multiply($d)); - $y3 = $e->multiply($d->subtract($x3))->subtract( - $this->eight->multiply($c) - ); - $z3 = $this->two->multiply($y1)->multiply($z1); - return [$x3, $y3, $z3]; - } - - /** - * Doubles a "fresh" jacobian coordinate on the curve - * - * See http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-mdbl-2007-bl - * - * @return FiniteField[] - */ - protected function jacobianDoublePointMixed(array $p) - { - list($x1, $y1) = $p; - $xx = $x1->multiply($x1); - $yy = $y1->multiply($y1); - $yyyy = $yy->multiply($yy); - $s = $x1->add($yy); - $s = $s->multiply($s)->subtract($xx)->subtract($yyyy)->multiply($this->two); - $m = $this->three->multiply($xx); - $t = $m->multiply($m)->subtract($this->two->multiply($s)); - $x3 = $t; - $y3 = $s->subtract($t); - $y3 = $m->multiply($y3)->subtract($this->eight->multiply($yyyy)); - $z3 = $this->two->multiply($y1); - return [$x3, $y3, $z3]; - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $lhs = $y->multiply($y); - $temp = $x->multiply($x)->multiply($x); - $rhs = $temp->add($this->b); - - return $lhs->equals($rhs); - } - - /** - * Calculates the parameters needed from the Euclidean algorithm as discussed at - * http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=148 - * - * @param BigInteger $u - * @param BigInteger $v - * @return BigInteger[] - */ - protected static function extendedGCD(BigInteger $u, BigInteger $v) - { - $one = new BigInteger(1); - $zero = new BigInteger(); - - $a = clone $one; - $b = clone $zero; - $c = clone $zero; - $d = clone $one; - - $stop = $v->bitwise_rightShift($v->getLength() >> 1); - - $a1 = clone $zero; - $b1 = clone $zero; - $a2 = clone $zero; - $b2 = clone $zero; - - $postGreatestIndex = 0; - - while (!$v->equals($zero)) { - list($q) = $u->divide($v); - - $temp = $u; - $u = $v; - $v = $temp->subtract($v->multiply($q)); - - $temp = $a; - $a = $c; - $c = $temp->subtract($a->multiply($q)); - - $temp = $b; - $b = $d; - $d = $temp->subtract($b->multiply($q)); - - if ($v->compare($stop) > 0) { - $a0 = $v; - $b0 = $c; - } else { - $postGreatestIndex++; - } - - if ($postGreatestIndex == 1) { - $a1 = $v; - $b1 = $c->negate(); - } - - if ($postGreatestIndex == 2) { - $rhs = $a0->multiply($a0)->add($b0->multiply($b0)); - $lhs = $v->multiply($v)->add($b->multiply($b)); - if ($lhs->compare($rhs) <= 0) { - $a2 = $a0; - $b2 = $b0->negate(); - } else { - $a2 = $v; - $b2 = $c->negate(); - } - - break; - } - } - - return [ - ['a' => $a1, 'b' => $b1], - ['a' => $a2, 'b' => $b2] - ]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php deleted file mode 100644 index e3fa50b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Montgomery.php +++ /dev/null @@ -1,279 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over y^2 = x^3 + a*x + x - * - * @author Jim Wigginton - */ -class Montgomery extends Base -{ - /** - * Prime Field Integer factory - * - * @var \phpseclib3\Math\PrimeField - */ - protected $factory; - - /** - * Cofficient for x - * - * @var object - */ - protected $a; - - /** - * Constant used for point doubling - * - * @var object - */ - protected $a24; - - /** - * The Number Zero - * - * @var object - */ - protected $zero; - - /** - * The Number One - * - * @var object - */ - protected $one; - - /** - * Base Point - * - * @var object - */ - protected $p; - - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Sets the modulo - */ - public function setModulo(BigInteger $modulo) - { - $this->modulo = $modulo; - $this->factory = new PrimeField($modulo); - $this->zero = $this->factory->newInteger(new BigInteger()); - $this->one = $this->factory->newInteger(new BigInteger(1)); - } - - /** - * Set coefficients a - */ - public function setCoefficients(BigInteger $a) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger($a); - $two = $this->factory->newInteger(new BigInteger(2)); - $four = $this->factory->newInteger(new BigInteger(4)); - $this->a24 = $this->a->subtract($two)->divide($four); - } - - /** - * Set x and y coordinates for the base point - * - * @param BigInteger|PrimeInteger $x - * @param BigInteger|PrimeInteger $y - * @return PrimeInteger[] - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !$x instanceof BigInteger && !$x instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - case !$y instanceof BigInteger && !$y instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, - $y instanceof BigInteger ? $this->factory->newInteger($y) : $y - ]; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Doubles and adds a point on a curve - * - * See https://tools.ietf.org/html/draft-ietf-tls-curve25519-01#appendix-A.1.3 - * - * @return FiniteField[][] - */ - private function doubleAndAddPoint(array $p, array $q, PrimeInteger $x1) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - return []; - } - - if (!isset($p[1])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to XZ coordinates'); - } - - list($x2, $z2) = $p; - list($x3, $z3) = $q; - - $a = $x2->add($z2); - $aa = $a->multiply($a); - $b = $x2->subtract($z2); - $bb = $b->multiply($b); - $e = $aa->subtract($bb); - $c = $x3->add($z3); - $d = $x3->subtract($z3); - $da = $d->multiply($a); - $cb = $c->multiply($b); - $temp = $da->add($cb); - $x5 = $temp->multiply($temp); - $temp = $da->subtract($cb); - $z5 = $x1->multiply($temp->multiply($temp)); - $x4 = $aa->multiply($bb); - $temp = static::class == Curve25519::class ? $bb : $aa; - $z4 = $e->multiply($temp->add($this->a24->multiply($e))); - - return [ - [$x4, $z4], - [$x5, $z5] - ]; - } - - /** - * Multiply a point on the curve by a scalar - * - * Uses the montgomery ladder technique as described here: - * - * https://en.wikipedia.org/wiki/Elliptic_curve_point_multiplication#Montgomery_ladder - * https://github.com/phpecc/phpecc/issues/16#issuecomment-59176772 - * - * @return array - */ - public function multiplyPoint(array $p, BigInteger $d) - { - $p1 = [$this->one, $this->zero]; - $alreadyInternal = isset($x[1]); - $p2 = $this->convertToInternal($p); - $x = $p[0]; - - $b = $d->toBits(); - $b = str_pad($b, 256, '0', STR_PAD_LEFT); - for ($i = 0; $i < strlen($b); $i++) { - $b_i = (int) $b[$i]; - if ($b_i) { - list($p2, $p1) = $this->doubleAndAddPoint($p2, $p1, $x); - } else { - list($p1, $p2) = $this->doubleAndAddPoint($p1, $p2, $x); - } - } - - return $alreadyInternal ? $p1 : $this->convertToAffine($p1); - } - - /** - * Converts an affine point to an XZ coordinate - * - * From https://hyperelliptic.org/EFD/g1p/auto-montgom-xz.html - * - * XZ coordinates represent x y as X Z satsfying the following equations: - * - * x=X/Z - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (empty($p)) { - return [clone $this->zero, clone $this->one]; - } - - if (isset($p[1])) { - return $p; - } - - $p[1] = clone $this->one; - - return $p; - } - - /** - * Returns the affine point - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[1])) { - return $p; - } - list($x, $z) = $p; - return [$x->divide($z)]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php deleted file mode 100644 index 6250dfb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/Prime.php +++ /dev/null @@ -1,785 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\Common\FiniteField\Integer; -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over y^2 = x^3 + a*x + b - * - * @author Jim Wigginton - */ -class Prime extends Base -{ - /** - * Prime Field Integer factory - * - * @var \phpseclib3\Math\PrimeFields - */ - protected $factory; - - /** - * Cofficient for x^1 - * - * @var object - */ - protected $a; - - /** - * Cofficient for x^0 - * - * @var object - */ - protected $b; - - /** - * Base Point - * - * @var object - */ - protected $p; - - /** - * The number one over the specified finite field - * - * @var object - */ - protected $one; - - /** - * The number two over the specified finite field - * - * @var object - */ - protected $two; - - /** - * The number three over the specified finite field - * - * @var object - */ - protected $three; - - /** - * The number four over the specified finite field - * - * @var object - */ - protected $four; - - /** - * The number eight over the specified finite field - * - * @var object - */ - protected $eight; - - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * The Order - * - * @var BigInteger - */ - protected $order; - - /** - * Sets the modulo - */ - public function setModulo(BigInteger $modulo) - { - $this->modulo = $modulo; - $this->factory = new PrimeField($modulo); - $this->two = $this->factory->newInteger(new BigInteger(2)); - $this->three = $this->factory->newInteger(new BigInteger(3)); - // used by jacobian coordinates - $this->one = $this->factory->newInteger(new BigInteger(1)); - $this->four = $this->factory->newInteger(new BigInteger(4)); - $this->eight = $this->factory->newInteger(new BigInteger(8)); - } - - /** - * Set coefficients a and b - */ - public function setCoefficients(BigInteger $a, BigInteger $b) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger($a); - $this->b = $this->factory->newInteger($b); - } - - /** - * Set x and y coordinates for the base point - * - * @param BigInteger|PrimeInteger $x - * @param BigInteger|PrimeInteger $y - * @return PrimeInteger[] - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !$x instanceof BigInteger && !$x instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - case !$y instanceof BigInteger && !$y instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, - $y instanceof BigInteger ? $this->factory->newInteger($y) : $y - ]; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Adds two "fresh" jacobian form on the curve - * - * @return FiniteField[] - */ - protected function jacobianAddPointMixedXY(array $p, array $q) - { - list($u1, $s1) = $p; - list($u2, $s2) = $q; - if ($u1->equals($u2)) { - if (!$s1->equals($s2)) { - return []; - } else { - return $this->doublePoint($p); - } - } - $h = $u2->subtract($u1); - $r = $s2->subtract($s1); - $h2 = $h->multiply($h); - $h3 = $h2->multiply($h); - $v = $u1->multiply($h2); - $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); - $y3 = $r->multiply( - $v->subtract($x3) - )->subtract( - $s1->multiply($h3) - ); - return [$x3, $y3, $h]; - } - - /** - * Adds one "fresh" jacobian form on the curve - * - * The second parameter should be the "fresh" one - * - * @return FiniteField[] - */ - protected function jacobianAddPointMixedX(array $p, array $q) - { - list($u1, $s1, $z1) = $p; - list($x2, $y2) = $q; - - $z12 = $z1->multiply($z1); - - $u2 = $x2->multiply($z12); - $s2 = $y2->multiply($z12->multiply($z1)); - if ($u1->equals($u2)) { - if (!$s1->equals($s2)) { - return []; - } else { - return $this->doublePoint($p); - } - } - $h = $u2->subtract($u1); - $r = $s2->subtract($s1); - $h2 = $h->multiply($h); - $h3 = $h2->multiply($h); - $v = $u1->multiply($h2); - $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); - $y3 = $r->multiply( - $v->subtract($x3) - )->subtract( - $s1->multiply($h3) - ); - $z3 = $h->multiply($z1); - return [$x3, $y3, $z3]; - } - - /** - * Adds two jacobian coordinates on the curve - * - * @return FiniteField[] - */ - protected function jacobianAddPoint(array $p, array $q) - { - list($x1, $y1, $z1) = $p; - list($x2, $y2, $z2) = $q; - - $z12 = $z1->multiply($z1); - $z22 = $z2->multiply($z2); - - $u1 = $x1->multiply($z22); - $u2 = $x2->multiply($z12); - $s1 = $y1->multiply($z22->multiply($z2)); - $s2 = $y2->multiply($z12->multiply($z1)); - if ($u1->equals($u2)) { - if (!$s1->equals($s2)) { - return []; - } else { - return $this->doublePoint($p); - } - } - $h = $u2->subtract($u1); - $r = $s2->subtract($s1); - $h2 = $h->multiply($h); - $h3 = $h2->multiply($h); - $v = $u1->multiply($h2); - $x3 = $r->multiply($r)->subtract($h3)->subtract($v->multiply($this->two)); - $y3 = $r->multiply( - $v->subtract($x3) - )->subtract( - $s1->multiply($h3) - ); - $z3 = $h->multiply($z1)->multiply($z2); - return [$x3, $y3, $z3]; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - // use jacobian coordinates - if (isset($p[2]) && isset($q[2])) { - if (isset($p['fresh']) && isset($q['fresh'])) { - return $this->jacobianAddPointMixedXY($p, $q); - } - if (isset($p['fresh'])) { - return $this->jacobianAddPointMixedX($q, $p); - } - if (isset($q['fresh'])) { - return $this->jacobianAddPointMixedX($p, $q); - } - return $this->jacobianAddPoint($p, $q); - } - - if (isset($p[2]) || isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to Jacobi coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - if (!$p[1]->equals($q[1])) { - return []; - } else { // eg. doublePoint - list($numerator, $denominator) = $this->doublePointHelper($p); - } - } else { - $numerator = $q[1]->subtract($p[1]); - $denominator = $q[0]->subtract($p[0]); - } - $slope = $numerator->divide($denominator); - $x = $slope->multiply($slope)->subtract($p[0])->subtract($q[0]); - $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); - - return [$x, $y]; - } - - /** - * Returns the numerator and denominator of the slope - * - * @return FiniteField[] - */ - protected function doublePointHelper(array $p) - { - $numerator = $this->three->multiply($p[0])->multiply($p[0])->add($this->a); - $denominator = $this->two->multiply($p[1]); - return [$numerator, $denominator]; - } - - /** - * Doubles a jacobian coordinate on the curve - * - * @return FiniteField[] - */ - protected function jacobianDoublePoint(array $p) - { - list($x, $y, $z) = $p; - $x2 = $x->multiply($x); - $y2 = $y->multiply($y); - $z2 = $z->multiply($z); - $s = $this->four->multiply($x)->multiply($y2); - $m1 = $this->three->multiply($x2); - $m2 = $this->a->multiply($z2->multiply($z2)); - $m = $m1->add($m2); - $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); - $y1 = $m->multiply($s->subtract($x1))->subtract( - $this->eight->multiply($y2->multiply($y2)) - ); - $z1 = $this->two->multiply($y)->multiply($z); - return [$x1, $y1, $z1]; - } - - /** - * Doubles a "fresh" jacobian coordinate on the curve - * - * @return FiniteField[] - */ - protected function jacobianDoublePointMixed(array $p) - { - list($x, $y) = $p; - $x2 = $x->multiply($x); - $y2 = $y->multiply($y); - $s = $this->four->multiply($x)->multiply($y2); - $m1 = $this->three->multiply($x2); - $m = $m1->add($this->a); - $x1 = $m->multiply($m)->subtract($this->two->multiply($s)); - $y1 = $m->multiply($s->subtract($x1))->subtract( - $this->eight->multiply($y2->multiply($y2)) - ); - $z1 = $this->two->multiply($y); - return [$x1, $y1, $z1]; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - // use jacobian coordinates - if (isset($p[2])) { - if (isset($p['fresh'])) { - return $this->jacobianDoublePointMixed($p); - } - return $this->jacobianDoublePoint($p); - } - - list($numerator, $denominator) = $this->doublePointHelper($p); - - $slope = $numerator->divide($denominator); - - $x = $slope->multiply($slope)->subtract($p[0])->subtract($p[0]); - $y = $slope->multiply($p[0]->subtract($x))->subtract($p[1]); - - return [$x, $y]; - } - - /** - * Returns the X coordinate and the derived Y coordinate - * - * @return array - */ - public function derivePoint($m) - { - $y = ord(Strings::shift($m)); - $x = new BigInteger($m, 256); - $xp = $this->convertInteger($x); - switch ($y) { - case 2: - $ypn = false; - break; - case 3: - $ypn = true; - break; - default: - throw new \RuntimeException('Coordinate not in recognized format'); - } - $temp = $xp->multiply($this->a); - $temp = $xp->multiply($xp)->multiply($xp)->add($temp); - $temp = $temp->add($this->b); - $b = $temp->squareRoot(); - if (!$b) { - throw new \RuntimeException('Unable to derive Y coordinate'); - } - $bn = $b->isOdd(); - $yp = $ypn == $bn ? $b : $b->negate(); - return [$xp, $yp]; - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $lhs = $y->multiply($y); - $temp = $x->multiply($this->a); - $temp = $x->multiply($x)->multiply($x)->add($temp); - $rhs = $temp->add($this->b); - - return $lhs->equals($rhs); - } - - /** - * Returns the modulo - * - * @return \phpseclib3\Math\BigInteger - */ - public function getModulo() - { - return $this->modulo; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getA() - { - return $this->a; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getB() - { - return $this->b; - } - - /** - * Multiply and Add Points - * - * Adapted from: - * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L125 - * - * @return int[] - */ - public function multiplyAddPoints(array $points, array $scalars) - { - $length = count($points); - - foreach ($points as &$point) { - $point = $this->convertToInternal($point); - } - - $wnd = [$this->getNAFPoints($points[0], 7)]; - $wndWidth = [isset($points[0]['nafwidth']) ? $points[0]['nafwidth'] : 7]; - for ($i = 1; $i < $length; $i++) { - $wnd[] = $this->getNAFPoints($points[$i], 1); - $wndWidth[] = isset($points[$i]['nafwidth']) ? $points[$i]['nafwidth'] : 1; - } - - $naf = []; - - // comb all window NAFs - - $max = 0; - for ($i = $length - 1; $i >= 1; $i -= 2) { - $a = $i - 1; - $b = $i; - if ($wndWidth[$a] != 1 || $wndWidth[$b] != 1) { - $naf[$a] = $scalars[$a]->getNAF($wndWidth[$a]); - $naf[$b] = $scalars[$b]->getNAF($wndWidth[$b]); - $max = max(count($naf[$a]), count($naf[$b]), $max); - continue; - } - - $comb = [ - $points[$a], // 1 - null, // 3 - null, // 5 - $points[$b] // 7 - ]; - - $comb[1] = $this->addPoint($points[$a], $points[$b]); - $comb[2] = $this->addPoint($points[$a], $this->negatePoint($points[$b])); - - $index = [ - -3, /* -1 -1 */ - -1, /* -1 0 */ - -5, /* -1 1 */ - -7, /* 0 -1 */ - 0, /* 0 -1 */ - 7, /* 0 1 */ - 5, /* 1 -1 */ - 1, /* 1 0 */ - 3 /* 1 1 */ - ]; - - $jsf = self::getJSFPoints($scalars[$a], $scalars[$b]); - - $max = max(count($jsf[0]), $max); - if ($max > 0) { - $naf[$a] = array_fill(0, $max, 0); - $naf[$b] = array_fill(0, $max, 0); - } else { - $naf[$a] = []; - $naf[$b] = []; - } - - for ($j = 0; $j < $max; $j++) { - $ja = isset($jsf[0][$j]) ? $jsf[0][$j] : 0; - $jb = isset($jsf[1][$j]) ? $jsf[1][$j] : 0; - - $naf[$a][$j] = $index[3 * ($ja + 1) + $jb + 1]; - $naf[$b][$j] = 0; - $wnd[$a] = $comb; - } - } - - $acc = []; - $temp = [0, 0, 0, 0]; - for ($i = $max; $i >= 0; $i--) { - $k = 0; - while ($i >= 0) { - $zero = true; - for ($j = 0; $j < $length; $j++) { - $temp[$j] = isset($naf[$j][$i]) ? $naf[$j][$i] : 0; - if ($temp[$j] != 0) { - $zero = false; - } - } - if (!$zero) { - break; - } - $k++; - $i--; - } - - if ($i >= 0) { - $k++; - } - while ($k--) { - $acc = $this->doublePoint($acc); - } - - if ($i < 0) { - break; - } - - for ($j = 0; $j < $length; $j++) { - $z = $temp[$j]; - $p = null; - if ($z == 0) { - continue; - } - $p = $z > 0 ? - $wnd[$j][($z - 1) >> 1] : - $this->negatePoint($wnd[$j][(-$z - 1) >> 1]); - $acc = $this->addPoint($acc, $p); - } - } - - return $this->convertToAffine($acc); - } - - /** - * Precomputes NAF points - * - * Adapted from: - * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/curve/base.js#L351 - * - * @return int[] - */ - private function getNAFPoints(array $point, $wnd) - { - if (isset($point['naf'])) { - return $point['naf']; - } - - $res = [$point]; - $max = (1 << $wnd) - 1; - $dbl = $max == 1 ? null : $this->doublePoint($point); - for ($i = 1; $i < $max; $i++) { - $res[] = $this->addPoint($res[$i - 1], $dbl); - } - - $point['naf'] = $res; - - /* - $str = ''; - foreach ($res as $re) { - $re[0] = bin2hex($re[0]->toBytes()); - $re[1] = bin2hex($re[1]->toBytes()); - $str.= " ['$re[0]', '$re[1]'],\r\n"; - } - file_put_contents('temp.txt', $str); - exit; - */ - - return $res; - } - - /** - * Precomputes points in Joint Sparse Form - * - * Adapted from: - * https://github.com/indutny/elliptic/blob/725bd91/lib/elliptic/utils.js#L96 - * - * @return int[] - */ - private static function getJSFPoints(Integer $k1, Integer $k2) - { - static $three; - if (!isset($three)) { - $three = new BigInteger(3); - } - - $jsf = [[], []]; - $k1 = $k1->toBigInteger(); - $k2 = $k2->toBigInteger(); - $d1 = 0; - $d2 = 0; - - while ($k1->compare(new BigInteger(-$d1)) > 0 || $k2->compare(new BigInteger(-$d2)) > 0) { - // first phase - $m14 = $k1->testBit(0) + 2 * $k1->testBit(1); - $m14 += $d1; - $m14 &= 3; - - $m24 = $k2->testBit(0) + 2 * $k2->testBit(1); - $m24 += $d2; - $m24 &= 3; - - if ($m14 == 3) { - $m14 = -1; - } - if ($m24 == 3) { - $m24 = -1; - } - - $u1 = 0; - if ($m14 & 1) { // if $m14 is odd - $m8 = $k1->testBit(0) + 2 * $k1->testBit(1) + 4 * $k1->testBit(2); - $m8 += $d1; - $m8 &= 7; - $u1 = ($m8 == 3 || $m8 == 5) && $m24 == 2 ? -$m14 : $m14; - } - $jsf[0][] = $u1; - - $u2 = 0; - if ($m24 & 1) { // if $m24 is odd - $m8 = $k2->testBit(0) + 2 * $k2->testBit(1) + 4 * $k2->testBit(2); - $m8 += $d2; - $m8 &= 7; - $u2 = ($m8 == 3 || $m8 == 5) && $m14 == 2 ? -$m24 : $m24; - } - $jsf[1][] = $u2; - - // second phase - if (2 * $d1 == $u1 + 1) { - $d1 = 1 - $d1; - } - if (2 * $d2 == $u2 + 1) { - $d2 = 1 - $d2; - } - $k1 = $k1->bitwise_rightShift(1); - $k2 = $k2->bitwise_rightShift(1); - } - - return $jsf; - } - - /** - * Returns the affine point - * - * A Jacobian Coordinate is of the form (x, y, z). - * To convert a Jacobian Coordinate to an Affine Point - * you do (x / z^2, y / z^3) - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[2])) { - return $p; - } - list($x, $y, $z) = $p; - $z = $this->one->divide($z); - $z2 = $z->multiply($z); - return [ - $x->multiply($z2), - $y->multiply($z2)->multiply($z) - ]; - } - - /** - * Converts an affine point to a jacobian coordinate - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - $p['fresh'] = true; - return $p; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php deleted file mode 100644 index 2521a4c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/BaseCurves/TwistedEdwards.php +++ /dev/null @@ -1,215 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\BaseCurves; - -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField; -use phpseclib3\Math\PrimeField\Integer as PrimeInteger; - -/** - * Curves over a*x^2 + y^2 = 1 + d*x^2*y^2 - * - * @author Jim Wigginton - */ -class TwistedEdwards extends Base -{ - /** - * The modulo - * - * @var BigInteger - */ - protected $modulo; - - /** - * Cofficient for x^2 - * - * @var object - */ - protected $a; - - /** - * Cofficient for x^2*y^2 - * - * @var object - */ - protected $d; - - /** - * Base Point - * - * @var object[] - */ - protected $p; - - /** - * The number zero over the specified finite field - * - * @var object - */ - protected $zero; - - /** - * The number one over the specified finite field - * - * @var object - */ - protected $one; - - /** - * The number two over the specified finite field - * - * @var object - */ - protected $two; - - /** - * Sets the modulo - */ - public function setModulo(BigInteger $modulo) - { - $this->modulo = $modulo; - $this->factory = new PrimeField($modulo); - $this->zero = $this->factory->newInteger(new BigInteger(0)); - $this->one = $this->factory->newInteger(new BigInteger(1)); - $this->two = $this->factory->newInteger(new BigInteger(2)); - } - - /** - * Set coefficients a and b - */ - public function setCoefficients(BigInteger $a, BigInteger $d) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->a = $this->factory->newInteger($a); - $this->d = $this->factory->newInteger($d); - } - - /** - * Set x and y coordinates for the base point - */ - public function setBasePoint($x, $y) - { - switch (true) { - case !$x instanceof BigInteger && !$x instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 1 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - case !$y instanceof BigInteger && !$y instanceof PrimeInteger: - throw new \UnexpectedValueException('Argument 2 passed to Prime::setBasePoint() must be an instance of either BigInteger or PrimeField\Integer'); - } - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - $this->p = [ - $x instanceof BigInteger ? $this->factory->newInteger($x) : $x, - $y instanceof BigInteger ? $this->factory->newInteger($y) : $y - ]; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getA() - { - return $this->a; - } - - /** - * Returns the a coefficient - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function getD() - { - return $this->d; - } - - /** - * Retrieve the base point as an array - * - * @return array - */ - public function getBasePoint() - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - /* - if (!isset($this->p)) { - throw new \RuntimeException('setBasePoint needs to be called before this method'); - } - */ - return $this->p; - } - - /** - * Returns the affine point - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToAffine(array $p) - { - if (!isset($p[2])) { - return $p; - } - list($x, $y, $z) = $p; - $z = $this->one->divide($z); - return [ - $x->multiply($z), - $y->multiply($z) - ]; - } - - /** - * Returns the modulo - * - * @return \phpseclib3\Math\BigInteger - */ - public function getModulo() - { - return $this->modulo; - } - - /** - * Tests whether or not the x / y values satisfy the equation - * - * @return boolean - */ - public function verifyPoint(array $p) - { - list($x, $y) = $p; - $x2 = $x->multiply($x); - $y2 = $y->multiply($y); - - $lhs = $this->a->multiply($x2)->add($y2); - $rhs = $this->d->multiply($x2)->multiply($y2)->add($this->one); - - return $lhs->equals($rhs); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php deleted file mode 100644 index 0f3f4d8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve25519.php +++ /dev/null @@ -1,81 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Montgomery; -use phpseclib3\Math\BigInteger; - -class Curve25519 extends Montgomery -{ - public function __construct() - { - // 2^255 - 19 - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); - $this->a24 = $this->factory->newInteger(new BigInteger('121666')); - $this->p = [$this->factory->newInteger(new BigInteger(9))]; - // 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed - $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); - - /* - $this->setCoefficients( - new BigInteger('486662'), // a - ); - $this->setBasePoint( - new BigInteger(9), - new BigInteger('14781619447589544791020593568409986887264606134616475288964881837755586237401') - ); - */ - } - - /** - * Multiply a point on the curve by a scalar - * - * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 - * - * @return array - */ - public function multiplyPoint(array $p, BigInteger $d) - { - //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); - //return [$this->factory->newInteger(new BigInteger($r, 256))]; - - $d = $d->toBytes(); - $d &= "\xF8" . str_repeat("\xFF", 30) . "\x7F"; - $d = strrev($d); - $d |= "\x40"; - $d = new BigInteger($d, -256); - - return parent::multiplyPoint($p, $d); - } - - /** - * Creates a random scalar multiplier - * - * @return BigInteger - */ - public function createRandomMultiplier() - { - return BigInteger::random(256); - } - - /** - * Performs range check - */ - public function rangeCheck(BigInteger $x) - { - if ($x->getLength() > 256 || $x->isNegative()) { - throw new \RangeException('x must be a positive integer less than 256 bytes in length'); - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php deleted file mode 100644 index f4a4423..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Curve448.php +++ /dev/null @@ -1,92 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Montgomery; -use phpseclib3\Math\BigInteger; - -class Curve448 extends Montgomery -{ - public function __construct() - { - // 2^448 - 2^224 - 1 - $this->setModulo(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', - 16 - )); - $this->a24 = $this->factory->newInteger(new BigInteger('39081')); - $this->p = [$this->factory->newInteger(new BigInteger(5))]; - // 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d - $this->setOrder(new BigInteger( - '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', - 16 - )); - - /* - $this->setCoefficients( - new BigInteger('156326'), // a - ); - $this->setBasePoint( - new BigInteger(5), - new BigInteger( - '355293926785568175264127502063783334808976399387714271831880898' . - '435169088786967410002932673765864550910142774147268105838985595290' . - '606362') - ); - */ - } - - /** - * Multiply a point on the curve by a scalar - * - * Modifies the scalar as described at https://tools.ietf.org/html/rfc7748#page-8 - * - * @return array - */ - public function multiplyPoint(array $p, BigInteger $d) - { - //$r = strrev(sodium_crypto_scalarmult($d->toBytes(), strrev($p[0]->toBytes()))); - //return [$this->factory->newInteger(new BigInteger($r, 256))]; - - $d = $d->toBytes(); - $d[0] = $d[0] & "\xFC"; - $d = strrev($d); - $d |= "\x80"; - $d = new BigInteger($d, 256); - - return parent::multiplyPoint($p, $d); - } - - /** - * Creates a random scalar multiplier - * - * @return BigInteger - */ - public function createRandomMultiplier() - { - return BigInteger::random(446); - } - - /** - * Performs range check - */ - public function rangeCheck(BigInteger $x) - { - if ($x->getLength() > 448 || $x->isNegative()) { - throw new \RangeException('x must be a positive integer less than 446 bytes in length'); - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php deleted file mode 100644 index 9d3de68..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed25519.php +++ /dev/null @@ -1,333 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Math\BigInteger; - -class Ed25519 extends TwistedEdwards -{ - const HASH = 'sha512'; - /* - Per https://tools.ietf.org/html/rfc8032#page-6 EdDSA has several parameters, one of which is b: - - 2. An integer b with 2^(b-1) > p. EdDSA public keys have exactly b - bits, and EdDSA signatures have exactly 2*b bits. b is - recommended to be a multiple of 8, so public key and signature - lengths are an integral number of octets. - - SIZE corresponds to b - */ - const SIZE = 32; - - public function __construct() - { - // 2^255 - 19 - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED', 16)); - $this->setCoefficients( - // -1 - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC', 16), // a - // -121665/121666 - new BigInteger('52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3', 16) // d - ); - $this->setBasePoint( - new BigInteger('216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A', 16), - new BigInteger('6666666666666666666666666666666666666666666666666666666666666658', 16) - ); - $this->setOrder(new BigInteger('1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED', 16)); - // algorithm 14.47 from http://cacr.uwaterloo.ca/hac/about/chap14.pdf#page=16 - /* - $this->setReduction(function($x) { - $parts = $x->bitwise_split(255); - $className = $this->className; - - if (count($parts) > 2) { - list(, $r) = $x->divide($className::$modulo); - return $r; - } - - $zero = new BigInteger(); - $c = new BigInteger(19); - - switch (count($parts)) { - case 2: - list($qi, $ri) = $parts; - break; - case 1: - $qi = $zero; - list($ri) = $parts; - break; - case 0: - return $zero; - } - $r = $ri; - - while ($qi->compare($zero) > 0) { - $temp = $qi->multiply($c)->bitwise_split(255); - if (count($temp) == 2) { - list($qi, $ri) = $temp; - } else { - $qi = $zero; - list($ri) = $temp; - } - $r = $r->add($ri); - } - - while ($r->compare($className::$modulo) > 0) { - $r = $r->subtract($className::$modulo); - } - return $r; - }); - */ - } - - /** - * Recover X from Y - * - * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.1.3 - * - * Used by EC\Keys\Common.php - * - * @param BigInteger $y - * @param boolean $sign - * @return object[] - */ - public function recoverX(BigInteger $y, $sign) - { - $y = $this->factory->newInteger($y); - - $y2 = $y->multiply($y); - $u = $y2->subtract($this->one); - $v = $this->d->multiply($y2)->add($this->one); - $x2 = $u->divide($v); - if ($x2->equals($this->zero)) { - if ($sign) { - throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); - } - return clone $this->zero; - } - // find the square root - /* we don't do $x2->squareRoot() because, quoting from - https://tools.ietf.org/html/rfc8032#section-5.1.1: - - "For point decoding or "decompression", square roots modulo p are - needed. They can be computed using the Tonelli-Shanks algorithm or - the special case for p = 5 (mod 8). To find a square root of a, - first compute the candidate root x = a^((p+3)/8) (mod p)." - */ - $exp = $this->getModulo()->add(new BigInteger(3)); - $exp = $exp->bitwise_rightShift(3); - $x = $x2->pow($exp); - - // If v x^2 = -u (mod p), set x <-- x * 2^((p-1)/4), which is a square root. - if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { - $temp = $this->getModulo()->subtract(new BigInteger(1)); - $temp = $temp->bitwise_rightShift(2); - $temp = $this->two->pow($temp); - $x = $x->multiply($temp); - if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { - throw new \RuntimeException('Unable to recover X coordinate'); - } - } - if ($x->isOdd() != $sign) { - $x = $x->negate(); - } - - return [$x, $y]; - } - - /** - * Extract Secret Scalar - * - * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.1.5 - * - * Used by the various key handlers - * - * @param string $str - * @return array - */ - public function extractSecret($str) - { - if (strlen($str) != 32) { - throw new \LengthException('Private Key should be 32-bytes long'); - } - // 1. Hash the 32-byte private key using SHA-512, storing the digest in - // a 64-octet large buffer, denoted h. Only the lower 32 bytes are - // used for generating the public key. - $hash = new Hash('sha512'); - $h = $hash->hash($str); - $h = substr($h, 0, 32); - // 2. Prune the buffer: The lowest three bits of the first octet are - // cleared, the highest bit of the last octet is cleared, and the - // second highest bit of the last octet is set. - $h[0] = $h[0] & chr(0xF8); - $h = strrev($h); - $h[0] = ($h[0] & chr(0x3F)) | chr(0x40); - // 3. Interpret the buffer as the little-endian integer, forming a - // secret scalar s. - $dA = new BigInteger($h, 256); - - return [ - 'dA' => $dA, - 'secret' => $str - ]; - } - - /** - * Encode a point as a string - * - * @param array $point - * @return string - */ - public function encodePoint($point) - { - list($x, $y) = $point; - $y = $y->toBytes(); - $y[0] = $y[0] & chr(0x7F); - if ($x->isOdd()) { - $y[0] = $y[0] | chr(0x80); - } - $y = strrev($y); - - return $y; - } - - /** - * Creates a random scalar multiplier - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function createRandomMultiplier() - { - return $this->extractSecret(Random::string(32))['dA']; - } - - /** - * Converts an affine point to an extended homogeneous coordinate - * - * From https://tools.ietf.org/html/rfc8032#section-5.1.4 : - * - * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), - * with x = X/Z, y = Y/Z, x * y = T/Z. - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (empty($p)) { - return [clone $this->zero, clone $this->one, clone $this->one, clone $this->zero]; - } - - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - $p[3] = $p[0]->multiply($p[1]); - - return $p; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - if (!isset($p[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - // from https://tools.ietf.org/html/rfc8032#page-12 - - list($x1, $y1, $z1, $t1) = $p; - - $a = $x1->multiply($x1); - $b = $y1->multiply($y1); - $c = $this->two->multiply($z1)->multiply($z1); - $h = $a->add($b); - $temp = $x1->add($y1); - $e = $h->subtract($temp->multiply($temp)); - $g = $a->subtract($b); - $f = $c->add($g); - - $x3 = $e->multiply($f); - $y3 = $g->multiply($h); - $t3 = $e->multiply($h); - $z3 = $f->multiply($g); - - return [$x3, $y3, $z3, $t3]; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - if (!isset($p[2]) || !isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); - } - - // from https://tools.ietf.org/html/rfc8032#page-12 - - list($x1, $y1, $z1, $t1) = $p; - list($x2, $y2, $z2, $t2) = $q; - - $a = $y1->subtract($x1)->multiply($y2->subtract($x2)); - $b = $y1->add($x1)->multiply($y2->add($x2)); - $c = $t1->multiply($this->two)->multiply($this->d)->multiply($t2); - $d = $z1->multiply($this->two)->multiply($z2); - $e = $b->subtract($a); - $f = $d->subtract($c); - $g = $d->add($c); - $h = $b->add($a); - - $x3 = $e->multiply($f); - $y3 = $g->multiply($h); - $t3 = $e->multiply($h); - $z3 = $f->multiply($g); - - return [$x3, $y3, $z3, $t3]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php deleted file mode 100644 index 5451f90..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/Ed448.php +++ /dev/null @@ -1,273 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Math\BigInteger; - -class Ed448 extends TwistedEdwards -{ - const HASH = 'shake256-912'; - const SIZE = 57; - - public function __construct() - { - // 2^448 - 2^224 - 1 - $this->setModulo(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF', - 16 - )); - $this->setCoefficients( - new BigInteger(1), - // -39081 - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756', 16) - ); - $this->setBasePoint( - new BigInteger('4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324' . - 'A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E', 16), - new BigInteger('693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E' . - '05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14', 16) - ); - $this->setOrder(new BigInteger( - '3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - '7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3', - 16 - )); - } - - /** - * Recover X from Y - * - * Implements steps 2-4 at https://tools.ietf.org/html/rfc8032#section-5.2.3 - * - * Used by EC\Keys\Common.php - * - * @param BigInteger $y - * @param boolean $sign - * @return object[] - */ - public function recoverX(BigInteger $y, $sign) - { - $y = $this->factory->newInteger($y); - - $y2 = $y->multiply($y); - $u = $y2->subtract($this->one); - $v = $this->d->multiply($y2)->subtract($this->one); - $x2 = $u->divide($v); - if ($x2->equals($this->zero)) { - if ($sign) { - throw new \RuntimeException('Unable to recover X coordinate (x2 = 0)'); - } - return clone $this->zero; - } - // find the square root - $exp = $this->getModulo()->add(new BigInteger(1)); - $exp = $exp->bitwise_rightShift(2); - $x = $x2->pow($exp); - - if (!$x->multiply($x)->subtract($x2)->equals($this->zero)) { - throw new \RuntimeException('Unable to recover X coordinate'); - } - if ($x->isOdd() != $sign) { - $x = $x->negate(); - } - - return [$x, $y]; - } - - /** - * Extract Secret Scalar - * - * Implements steps 1-3 at https://tools.ietf.org/html/rfc8032#section-5.2.5 - * - * Used by the various key handlers - * - * @param string $str - * @return array - */ - public function extractSecret($str) - { - if (strlen($str) != 57) { - throw new \LengthException('Private Key should be 57-bytes long'); - } - // 1. Hash the 57-byte private key using SHAKE256(x, 114), storing the - // digest in a 114-octet large buffer, denoted h. Only the lower 57 - // bytes are used for generating the public key. - $hash = new Hash('shake256-912'); - $h = $hash->hash($str); - $h = substr($h, 0, 57); - // 2. Prune the buffer: The two least significant bits of the first - // octet are cleared, all eight bits the last octet are cleared, and - // the highest bit of the second to last octet is set. - $h[0] = $h[0] & chr(0xFC); - $h = strrev($h); - $h[0] = "\0"; - $h[1] = $h[1] | chr(0x80); - // 3. Interpret the buffer as the little-endian integer, forming a - // secret scalar s. - $dA = new BigInteger($h, 256); - - return [ - 'dA' => $dA, - 'secret' => $str - ]; - - $dA->secret = $str; - return $dA; - } - - /** - * Encode a point as a string - * - * @param array $point - * @return string - */ - public function encodePoint($point) - { - list($x, $y) = $point; - $y = "\0" . $y->toBytes(); - if ($x->isOdd()) { - $y[0] = $y[0] | chr(0x80); - } - $y = strrev($y); - - return $y; - } - - /** - * Creates a random scalar multiplier - * - * @return \phpseclib3\Math\PrimeField\Integer - */ - public function createRandomMultiplier() - { - return $this->extractSecret(Random::string(57))['dA']; - } - - /** - * Converts an affine point to an extended homogeneous coordinate - * - * From https://tools.ietf.org/html/rfc8032#section-5.2.4 : - * - * A point (x,y) is represented in extended homogeneous coordinates (X, Y, Z, T), - * with x = X/Z, y = Y/Z, x * y = T/Z. - * - * @return \phpseclib3\Math\PrimeField\Integer[] - */ - public function convertToInternal(array $p) - { - if (empty($p)) { - return [clone $this->zero, clone $this->one, clone $this->one]; - } - - if (isset($p[2])) { - return $p; - } - - $p[2] = clone $this->one; - - return $p; - } - - /** - * Doubles a point on a curve - * - * @return FiniteField[] - */ - public function doublePoint(array $p) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p)) { - return []; - } - - if (!isset($p[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - // from https://tools.ietf.org/html/rfc8032#page-18 - - list($x1, $y1, $z1) = $p; - - $b = $x1->add($y1); - $b = $b->multiply($b); - $c = $x1->multiply($x1); - $d = $y1->multiply($y1); - $e = $c->add($d); - $h = $z1->multiply($z1); - $j = $e->subtract($this->two->multiply($h)); - - $x3 = $b->subtract($e)->multiply($j); - $y3 = $c->subtract($d)->multiply($e); - $z3 = $e->multiply($j); - - return [$x3, $y3, $z3]; - } - - /** - * Adds two points on the curve - * - * @return FiniteField[] - */ - public function addPoint(array $p, array $q) - { - if (!isset($this->factory)) { - throw new \RuntimeException('setModulo needs to be called before this method'); - } - - if (!count($p) || !count($q)) { - if (count($q)) { - return $q; - } - if (count($p)) { - return $p; - } - return []; - } - - if (!isset($p[2]) || !isset($q[2])) { - throw new \RuntimeException('Affine coordinates need to be manually converted to "Jacobi" coordinates or vice versa'); - } - - if ($p[0]->equals($q[0])) { - return !$p[1]->equals($q[1]) ? [] : $this->doublePoint($p); - } - - // from https://tools.ietf.org/html/rfc8032#page-17 - - list($x1, $y1, $z1) = $p; - list($x2, $y2, $z2) = $q; - - $a = $z1->multiply($z2); - $b = $a->multiply($a); - $c = $x1->multiply($x2); - $d = $y1->multiply($y2); - $e = $this->d->multiply($c)->multiply($d); - $f = $b->subtract($e); - $g = $b->add($e); - $h = $x1->add($y1)->multiply($x2->add($y2)); - - $x3 = $a->multiply($f)->multiply($h->subtract($c)->subtract($d)); - $y3 = $a->multiply($g)->multiply($d->subtract($c)); - $z3 = $f->multiply($g); - - return [$x3, $y3, $z3]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php deleted file mode 100644 index 7bc2272..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP160r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); - $this->setCoefficients( - new BigInteger('340E7BE2A280EB74E2BE61BADA745D97E8F7C300', 16), - new BigInteger('1E589A8595423412134FAA2DBDEC95C8D8675E58', 16) - ); - $this->setBasePoint( - new BigInteger('BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3', 16), - new BigInteger('1667CB477A1A8EC338F94741669C976316DA6321', 16) - ); - $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php deleted file mode 100644 index ebfb29a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP160t1.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP160t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620F', 16)); - $this->setCoefficients( - new BigInteger('E95E4A5F737059DC60DFC7AD95B3D8139515620C', 16), // eg. -3 - new BigInteger('7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380', 16) - ); - $this->setBasePoint( - new BigInteger('B199B13B9B34EFC1397E64BAEB05ACC265FF2378', 16), - new BigInteger('ADD6718B7C7C1961F0991B842443772152C9E0AD', 16) - ); - $this->setOrder(new BigInteger('E95E4A5F737059DC60DF5991D45029409E60FC09', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php deleted file mode 100644 index 6ec848b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP192r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); - $this->setCoefficients( - new BigInteger('6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF', 16), - new BigInteger('469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9', 16) - ); - $this->setBasePoint( - new BigInteger('C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6', 16), - new BigInteger('14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F', 16) - ); - $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php deleted file mode 100644 index e6a86bb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP192t1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP192t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297', 16)); - $this->setCoefficients( - new BigInteger('C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294', 16), // eg. -3 - new BigInteger('13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79', 16) - ); - $this->setBasePoint( - new BigInteger('3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129', 16), - new BigInteger('097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9', 16) - ); - $this->setOrder(new BigInteger('C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php deleted file mode 100644 index 3d7d872..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP224r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); - $this->setCoefficients( - new BigInteger('68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43', 16), - new BigInteger('2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B', 16) - ); - $this->setBasePoint( - new BigInteger('0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D', 16), - new BigInteger('58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD', 16) - ); - $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php deleted file mode 100644 index 3d4f928..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP224t1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP224t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF', 16)); - $this->setCoefficients( - new BigInteger('D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC', 16), // eg. -3 - new BigInteger('4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D', 16) - ); - $this->setBasePoint( - new BigInteger('6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580', 16), - new BigInteger('0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C', 16) - ); - $this->setOrder(new BigInteger('D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php deleted file mode 100644 index 5780da7..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP256r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); - $this->setCoefficients( - new BigInteger('7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9', 16), - new BigInteger('26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6', 16) - ); - $this->setBasePoint( - new BigInteger('8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262', 16), - new BigInteger('547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997', 16) - ); - $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php deleted file mode 100644 index 724d8b8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP256t1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP256t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377', 16)); - $this->setCoefficients( - new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374', 16), // eg. -3 - new BigInteger('662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04', 16) - ); - $this->setBasePoint( - new BigInteger('A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4', 16), - new BigInteger('2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE', 16) - ); - $this->setOrder(new BigInteger('A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php deleted file mode 100644 index 182e622..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320r1.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP320r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . - '2B9EC7893EC28FCD412B1F1B32E27', 16)); - $this->setCoefficients( - new BigInteger('3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F4' . - '92F375A97D860EB4', 16), - new BigInteger('520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD88453981' . - '6F5EB4AC8FB1F1A6', 16) - ); - $this->setBasePoint( - new BigInteger('43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C7' . - '10AF8D0D39E20611', 16), - new BigInteger('14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7' . - 'D35245D1692E8EE1', 16) - ); - $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . - '82EC7EE8658E98691555B44C59311', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php deleted file mode 100644 index d5a620d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP320t1.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP320t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F9' . - '2B9EC7893EC28FCD412B1F1B32E27', 16)); - $this->setCoefficients( - new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28' . - 'FCD412B1F1B32E24', 16), // eg. -3 - new BigInteger('A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CE' . - 'B5B4FEF422340353', 16) - ); - $this->setBasePoint( - new BigInteger('925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF' . - '3357F624A21BED52', 16), - new BigInteger('63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B' . - '1B9BC0455FB0D2C3', 16) - ); - $this->setOrder(new BigInteger('D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D4' . - '82EC7EE8658E98691555B44C59311', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php deleted file mode 100644 index a20b4b4..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384r1.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP384r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . - '1874700133107EC53', - 16 - )); - $this->setCoefficients( - new BigInteger( - '7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503' . - 'AD4EB04A8C7DD22CE2826', - 16 - ), - new BigInteger( - '4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DB' . - 'C9943AB78696FA504C11', - 16 - ) - ); - $this->setBasePoint( - new BigInteger( - '1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D' . - '646AAEF87B2E247D4AF1E', - 16 - ), - new BigInteger( - '8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E464621779' . - '1811142820341263C5315', - 16 - ) - ); - $this->setOrder(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . - '03B883202E9046565', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php deleted file mode 100644 index 366660e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP384t1.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP384t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A7' . - '1874700133107EC53', - 16 - )); - $this->setCoefficients( - new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901' . - 'D1A71874700133107EC50', - 16 - ), // eg. -3 - new BigInteger( - '7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B8' . - '8805CED70355A33B471EE', - 16 - ) - ); - $this->setBasePoint( - new BigInteger( - '18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946' . - 'A5F54D8D0AA2F418808CC', - 16 - ), - new BigInteger( - '25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC' . - '2B2912675BF5B9E582928', - 16 - ) - ); - $this->setOrder(new BigInteger( - '8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC31' . - '03B883202E9046565', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php deleted file mode 100644 index 5efe5e1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512r1.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP512r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . - '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', - 16 - )); - $this->setCoefficients( - new BigInteger( - '7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA82' . - '53AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA', - 16 - ), - new BigInteger( - '3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C' . - '1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723', - 16 - ) - ); - $this->setBasePoint( - new BigInteger( - '81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D' . - '0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822', - 16 - ), - new BigInteger( - '7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5' . - 'F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892', - 16 - ) - ); - $this->setOrder(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . - '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php deleted file mode 100644 index 745863a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/brainpoolP512t1.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class brainpoolP512t1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . - '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3', - 16 - )); - $this->setCoefficients( - new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC' . - '66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0', - 16 - ), // eg. -3 - new BigInteger( - '7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA23049' . - '76540F6450085F2DAE145C22553B465763689180EA2571867423E', - 16 - ) - ); - $this->setBasePoint( - new BigInteger( - '640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CD' . - 'B3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA', - 16 - ), - new BigInteger( - '5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEE' . - 'F216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332', - 16 - ) - ); - $this->setOrder(new BigInteger( - 'AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA' . - '92619418661197FAC10471DB1D381085DDADDB58796829CA90069', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php deleted file mode 100644 index bae12b0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb233.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistb233 extends sect233r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php deleted file mode 100644 index a46153d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistb409.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistb409 extends sect409r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php deleted file mode 100644 index 8b26376..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk163.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk163 extends sect163k1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php deleted file mode 100644 index 69e1413..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk233.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk233 extends sect233k1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php deleted file mode 100644 index 9e95f10..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk283.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk283 extends sect283k1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php deleted file mode 100644 index 06bd9af..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistk409.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistk409 extends sect409k1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php deleted file mode 100644 index ddead3c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp192.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp192 extends secp192r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php deleted file mode 100644 index 746571b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp224.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp224 extends secp224r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php deleted file mode 100644 index a26c0f9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp256.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp256 extends secp256r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php deleted file mode 100644 index 1f20c02..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp384.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp384 extends secp384r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php deleted file mode 100644 index 86fa050..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistp521.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistp521 extends secp521r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php deleted file mode 100644 index 7908b38..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/nistt571.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class nistt571 extends sect571k1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php deleted file mode 100644 index e9c13cd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v1.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class prime192v1 extends secp192r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php deleted file mode 100644 index e3e341f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v2.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime192v2 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), - new BigInteger('CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953', 16) - ); - $this->setBasePoint( - new BigInteger('EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A', 16), - new BigInteger('6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php deleted file mode 100644 index 1e97992..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime192v3.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime192v3 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), - new BigInteger('22123DC2395A05CAA7423DAECCC94760A7D462256BD56916', 16) - ); - $this->setBasePoint( - new BigInteger('7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896', 16), - new BigInteger('38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php deleted file mode 100644 index 084be9d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime239v1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), - new BigInteger('6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A', 16) - ); - $this->setBasePoint( - new BigInteger('0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF', 16), - new BigInteger('7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE', 16) - ); - $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php deleted file mode 100644 index 21941b8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v2.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime239v2 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), - new BigInteger('617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C', 16) - ); - $this->setBasePoint( - new BigInteger('38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7', 16), - new BigInteger('5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA', 16) - ); - $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php deleted file mode 100644 index 78c50f0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime239v3.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class prime239v3 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC', 16), - new BigInteger('255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E', 16) - ); - $this->setBasePoint( - new BigInteger('6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A', 16), - new BigInteger('1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3', 16) - ); - $this->setOrder(new BigInteger('7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php deleted file mode 100644 index c72b22e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/prime256v1.php +++ /dev/null @@ -1,18 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -final class prime256v1 extends secp256r1 -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php deleted file mode 100644 index d1d3194..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp112r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); - $this->setCoefficients( - new BigInteger('DB7C2ABF62E35E668076BEAD2088', 16), - new BigInteger('659EF8BA043916EEDE8911702B22', 16) - ); - $this->setBasePoint( - new BigInteger('09487239995A5EE76B55F9C2F098', 16), - new BigInteger('A89CE5AF8724C0A23E0E0FF77500', 16) - ); - $this->setOrder(new BigInteger('DB7C2ABF62E35E7628DFAC6561C5', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php deleted file mode 100644 index da44e7f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp112r2.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp112r2 extends Prime -{ - public function __construct() - { - // same modulo as secp112r1 - $this->setModulo(new BigInteger('DB7C2ABF62E35E668076BEAD208B', 16)); - $this->setCoefficients( - new BigInteger('6127C24C05F38A0AAAF65C0EF02C', 16), - new BigInteger('51DEF1815DB5ED74FCC34C85D709', 16) - ); - $this->setBasePoint( - new BigInteger('4BA30AB5E892B4E1649DD0928643', 16), - new BigInteger('ADCD46F5882E3747DEF36E956E97', 16) - ); - $this->setOrder(new BigInteger('36DF0AAFD8B8D7597CA10520D04B', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php deleted file mode 100644 index 34456bc..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp128r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC', 16), - new BigInteger('E87579C11079F43DD824993C2CEE5ED3', 16) - ); - $this->setBasePoint( - new BigInteger('161FF7528B899B2D0C28607CA52C5B86', 16), - new BigInteger('CF5AC8395BAFEB13C02DA292DDED7A83', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFE0000000075A30D1B9038A115', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php deleted file mode 100644 index e102c34..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp128r2.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp128r2 extends Prime -{ - public function __construct() - { - // same as secp128r1 - $this->setModulo(new BigInteger('FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('D6031998D1B3BBFEBF59CC9BBFF9AEE1', 16), - new BigInteger('5EEEFCA380D02919DC2C6558BB6D8A5D', 16) - ); - $this->setBasePoint( - new BigInteger('7B6AA5D85E572983E6FB32A7CDEBC140', 16), - new BigInteger('27B6916A894D3AEE7106FE805FC34B44', 16) - ); - $this->setOrder(new BigInteger('3FFFFFFF7FFFFFFFBE0024720613B5A3', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php deleted file mode 100644 index c6a3334..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160k1.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -class secp160k1 extends KoblitzPrime -{ - public function __construct() - { - // same as secp160r2 - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); - $this->setCoefficients( - new BigInteger('0000000000000000000000000000000000000000', 16), - new BigInteger('0000000000000000000000000000000000000007', 16) - ); - $this->setBasePoint( - new BigInteger('3B4C382CE37AA192A4019E763036F4F5DD4D7EBB', 16), - new BigInteger('938CF935318FDCED6BC28286531733C3F03C4FEE', 16) - ); - $this->setOrder(new BigInteger('0100000000000000000001B8FA16DFAB9ACA16B6B3', 16)); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('0096341F1138933BC2F505', -16), - 'b' => new BigInteger('FF6E9D0418C67BB8D5F562', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('01BDCB3A09AAAABEAFF4A8', -16), - 'b' => new BigInteger('04D12329FF0EF498EA67', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('645B7345A143464942CC46D7CF4D5D1E1E6CBB68', -16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php deleted file mode 100644 index af46877..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp160r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC', 16), - new BigInteger('1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45', 16) - ); - $this->setBasePoint( - new BigInteger('4A96B5688EF573284664698968C38BB913CBFC82', 16), - new BigInteger('23A628553168947D59DCC912042351377AC5FB32', 16) - ); - $this->setOrder(new BigInteger('0100000000000000000001F4C8F927AED3CA752257', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php deleted file mode 100644 index 9bd23d2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp160r2.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp160r2 extends Prime -{ - public function __construct() - { - // same as secp160k1 - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70', 16), - new BigInteger('B4E134D3FB59EB8BAB57274904664D5AF50388BA', 16) - ); - $this->setBasePoint( - new BigInteger('52DCB034293A117E1F4FF11B30F7199D3144CE6D', 16), - new BigInteger('FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E', 16) - ); - $this->setOrder(new BigInteger('0100000000000000000000351EE786A818F3A1A16B', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php deleted file mode 100644 index 79ff2e0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192k1.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -class secp192k1 extends KoblitzPrime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37', 16)); - $this->setCoefficients( - new BigInteger('000000000000000000000000000000000000000000000000', 16), - new BigInteger('000000000000000000000000000000000000000000000003', 16) - ); - $this->setBasePoint( - new BigInteger('DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D', 16), - new BigInteger('9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D', 16)); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('00B3FB3400DEC5C4ADCEB8655C', -16), - 'b' => new BigInteger('8EE96418CCF4CFC7124FDA0F', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('01D90D03E8F096B9948B20F0A9', -16), - 'b' => new BigInteger('42E49819ABBA9474E1083F6B', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('447A96E6C647963E2F7809FEAAB46947F34B0AA3CA0BBA74', -16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php deleted file mode 100644 index 83ab1c7..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp192r1.php +++ /dev/null @@ -1,78 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp192r1 extends Prime -{ - public function __construct() - { - $modulo = new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF', 16); - $this->setModulo($modulo); - - // algorithm 2.27 from http://diamond.boisestate.edu/~liljanab/MATH308/GuideToECC.pdf#page=66 - /* in theory this should be faster than regular modular reductions save for one small issue. - to convert to / from base-2**8 with BCMath you have to call bcmul() and bcdiv() a lot. - to convert to / from base-2**8 with PHP64 you have to call base256_rshift() a lot. - in short, converting to / from base-2**8 is pretty expensive and that expense is - enough to offset whatever else might be gained by a simplified reduction algorithm. - now, if PHP supported unsigned integers things might be different. no bit-shifting - would be required for the PHP engine and it'd be a lot faster. but as is, BigInteger - uses base-2**31 or base-2**26 depending on whether or not the system is has a 32-bit - or a 64-bit OS. - */ - /* - $m_length = $this->getLengthInBytes(); - $this->setReduction(function($c) use ($m_length) { - $cBytes = $c->toBytes(); - $className = $this->className; - - if (strlen($cBytes) > 2 * $m_length) { - list(, $r) = $c->divide($className::$modulo); - return $r; - } - - $c = str_pad($cBytes, 48, "\0", STR_PAD_LEFT); - $c = array_reverse(str_split($c, 8)); - - $null = "\0\0\0\0\0\0\0\0"; - $s1 = new BigInteger($c[2] . $c[1] . $c[0], 256); - $s2 = new BigInteger($null . $c[3] . $c[3], 256); - $s3 = new BigInteger($c[4] . $c[4] . $null, 256); - $s4 = new BigInteger($c[5] . $c[5] . $c[5], 256); - - $r = $s1->add($s2)->add($s3)->add($s4); - while ($r->compare($className::$modulo) >= 0) { - $r = $r->subtract($className::$modulo); - } - - return $r; - }); - */ - - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC', 16), - new BigInteger('64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1', 16) - ); - $this->setBasePoint( - new BigInteger('188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012', 16), - new BigInteger('07192B95FFC8DA78631011ED6B24CDD573F977A11E794811', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php deleted file mode 100644 index 79a5c54..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224k1.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -class secp224k1 extends KoblitzPrime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D', 16)); - $this->setCoefficients( - new BigInteger('00000000000000000000000000000000000000000000000000000000', 16), - new BigInteger('00000000000000000000000000000000000000000000000000000005', 16) - ); - $this->setBasePoint( - new BigInteger('A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C', 16), - new BigInteger('7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5', 16) - ); - $this->setOrder(new BigInteger('010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7', 16)); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('00B8ADF1378A6EB73409FA6C9C637D', -16), - 'b' => new BigInteger('94730F82B358A3776A826298FA6F', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('01DCE8D2EC6184CAF0A972769FCC8B', -16), - 'b' => new BigInteger('4D2100BA3DC75AAB747CCF355DEC', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('01F178FFA4B17C89E6F73AECE2AAD57AF4C0A748B63C830947B27E04', -16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php deleted file mode 100644 index a9e474a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp224r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp224r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE', 16), - new BigInteger('B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4', 16) - ); - $this->setBasePoint( - new BigInteger('B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21', 16), - new BigInteger('BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php deleted file mode 100644 index 462e7a1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256k1.php +++ /dev/null @@ -1,49 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -//use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Crypt\EC\BaseCurves\KoblitzPrime; -use phpseclib3\Math\BigInteger; - -//class secp256k1 extends Prime -class secp256k1 extends KoblitzPrime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F', 16)); - $this->setCoefficients( - new BigInteger('0000000000000000000000000000000000000000000000000000000000000000', 16), - new BigInteger('0000000000000000000000000000000000000000000000000000000000000007', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16)); - $this->setBasePoint( - new BigInteger('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16), - new BigInteger('483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8', 16) - ); - - $this->basis = []; - $this->basis[] = [ - 'a' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16), - 'b' => new BigInteger('FF1BBC8129FEF177D790AB8056F5401B3D', -16) - ]; - $this->basis[] = [ - 'a' => new BigInteger('114CA50F7A8E2F3F657C1108D9D44CFD8', -16), - 'b' => new BigInteger('3086D221A7D46BCDE86C90E49284EB15', -16) - ]; - $this->beta = $this->factory->newInteger(new BigInteger('7AE96A2B657C07106E64479EAC3434E99CF0497512F58995C1396C28719501EE', -16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php deleted file mode 100644 index 9003373..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp256r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp256r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)); - $this->setCoefficients( - new BigInteger('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16), - new BigInteger('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16) - ); - $this->setBasePoint( - new BigInteger('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296', 16), - new BigInteger('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5', 16) - ); - $this->setOrder(new BigInteger('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php deleted file mode 100644 index 98764a3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp384r1.php +++ /dev/null @@ -1,52 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp384r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF', - 16 - )); - $this->setCoefficients( - new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC', - 16 - ), - new BigInteger( - 'B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF', - 16 - ) - ); - $this->setBasePoint( - new BigInteger( - 'AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7', - 16 - ), - new BigInteger( - '3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F', - 16 - ) - ); - $this->setOrder(new BigInteger( - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php deleted file mode 100644 index b89a4ea..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/secp521r1.php +++ /dev/null @@ -1,46 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Prime; -use phpseclib3\Math\BigInteger; - -class secp521r1 extends Prime -{ - public function __construct() - { - $this->setModulo(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFF', 16)); - $this->setCoefficients( - new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFC', 16), - new BigInteger('0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF1' . - '09E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B50' . - '3F00', 16) - ); - $this->setBasePoint( - new BigInteger('00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D' . - '3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5' . - 'BD66', 16), - new BigInteger('011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E' . - '662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD1' . - '6650', 16) - ); - $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'FFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E9138' . - '6409', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php deleted file mode 100644 index 77ec760..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect113r1 extends Binary -{ - public function __construct() - { - $this->setModulo(113, 9, 0); - $this->setCoefficients( - '003088250CA6E7C7FE649CE85820F7', - '00E8BEE4D3E2260744188BE0E9C723' - ); - $this->setBasePoint( - '009D73616F35F4AB1407D73562C10F', - '00A52830277958EE84D1315ED31886' - ); - $this->setOrder(new BigInteger('0100000000000000D9CCEC8A39E56F', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php deleted file mode 100644 index 2185d60..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect113r2.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect113r2 extends Binary -{ - public function __construct() - { - $this->setModulo(113, 9, 0); - $this->setCoefficients( - '00689918DBEC7E5A0DD6DFC0AA55C7', - '0095E9A9EC9B297BD4BF36E059184F' - ); - $this->setBasePoint( - '01A57A6A7B26CA5EF52FCDB8164797', - '00B3ADC94ED1FE674C06E695BABA1D' - ); - $this->setOrder(new BigInteger('010000000000000108789B2496AF93', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php deleted file mode 100644 index 1365cb6..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect131r1 extends Binary -{ - public function __construct() - { - $this->setModulo(131, 8, 3, 2, 0); - $this->setCoefficients( - '07A11B09A76B562144418FF3FF8C2570B8', - '0217C05610884B63B9C6C7291678F9D341' - ); - $this->setBasePoint( - '0081BAF91FDF9833C40F9C181343638399', - '078C6E7EA38C001F73C8134B1B4EF9E150' - ); - $this->setOrder(new BigInteger('0400000000000000023123953A9464B54D', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php deleted file mode 100644 index 93c11b2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect131r2.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect131r2 extends Binary -{ - public function __construct() - { - $this->setModulo(131, 8, 3, 2, 0); - $this->setCoefficients( - '03E5A88919D7CAFCBF415F07C2176573B2', - '04B8266A46C55657AC734CE38F018F2192' - ); - $this->setBasePoint( - '0356DCD8F2F95031AD652D23951BB366A8', - '0648F06D867940A5366D9E265DE9EB240F' - ); - $this->setOrder(new BigInteger('0400000000000000016954A233049BA98F', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php deleted file mode 100644 index 3c8574b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163k1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect163k1 extends Binary -{ - public function __construct() - { - $this->setModulo(163, 7, 6, 3, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000001', - '000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8', - '0289070FB05D38FF58321F2E800536D538CCDAA3D9' - ); - $this->setOrder(new BigInteger('04000000000000000000020108A2E0CC0D99F8A5EF', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php deleted file mode 100644 index 26afd87..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect163r1 extends Binary -{ - public function __construct() - { - $this->setModulo(163, 7, 6, 3, 0); - $this->setCoefficients( - '07B6882CAAEFA84F9554FF8428BD88E246D2782AE2', - '0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9' - ); - $this->setBasePoint( - '0369979697AB43897789566789567F787A7876A654', - '00435EDB42EFAFB2989D51FEFCE3C80988F41FF883' - ); - $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php deleted file mode 100644 index 38f9466..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect163r2.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect163r2 extends Binary -{ - public function __construct() - { - $this->setModulo(163, 7, 6, 3, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000001', - '020A601907B8C953CA1481EB10512F78744A3205FD' - ); - $this->setBasePoint( - '03F0EBA16286A2D57EA0991168D4994637E8343E36', - '00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1' - ); - $this->setOrder(new BigInteger('040000000000000000000292FE77E70C12A4234C33', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php deleted file mode 100644 index 951f261..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect193r1 extends Binary -{ - public function __construct() - { - $this->setModulo(193, 15, 0); - $this->setCoefficients( - '0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01', - '00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814' - ); - $this->setBasePoint( - '01F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E1', - '0025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05' - ); - $this->setOrder(new BigInteger('01000000000000000000000000C7F34A778F443ACC920EBA49', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php deleted file mode 100644 index e3ff47a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect193r2.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect193r2 extends Binary -{ - public function __construct() - { - $this->setModulo(193, 15, 0); - $this->setCoefficients( - '0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B', - '00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE' - ); - $this->setBasePoint( - '00D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F', - '01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C' - ); - $this->setOrder(new BigInteger('010000000000000000000000015AAB561B005413CCD4EE99D5', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php deleted file mode 100644 index eea3f7a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233k1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect233k1 extends Binary -{ - public function __construct() - { - $this->setModulo(233, 74, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126', - '01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3' - ); - $this->setOrder(new BigInteger('8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php deleted file mode 100644 index 68219f0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect233r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect233r1 extends Binary -{ - public function __construct() - { - $this->setModulo(233, 74, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000001', - '0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD' - ); - $this->setBasePoint( - '00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B', - '01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052' - ); - $this->setOrder(new BigInteger('01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php deleted file mode 100644 index 0e6994b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect239k1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect239k1 extends Binary -{ - public function __construct() - { - $this->setModulo(239, 158, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '29A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC', - '76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA' - ); - $this->setOrder(new BigInteger('2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php deleted file mode 100644 index 279c24a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283k1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect283k1 extends Binary -{ - public function __construct() - { - $this->setModulo(283, 12, 7, 5, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836', - '01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259' - ); - $this->setOrder(new BigInteger('01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php deleted file mode 100644 index e44a607..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect283r1.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect283r1 extends Binary -{ - public function __construct() - { - $this->setModulo(283, 12, 7, 5, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000001', - '027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5' - ); - $this->setBasePoint( - '05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053', - '03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4' - ); - $this->setOrder(new BigInteger('03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307', 16)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php deleted file mode 100644 index 1fe329d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409k1.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect409k1 extends Binary -{ - public function __construct() - { - $this->setModulo(409, 87, 0); - $this->setCoefficients( - '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746', - '01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B' - ); - $this->setOrder(new BigInteger( - '7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F' . - '83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php deleted file mode 100644 index 3e209ef..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect409r1.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect409r1 extends Binary -{ - public function __construct() - { - $this->setModulo(409, 87, 0); - $this->setCoefficients( - '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001', - '0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F' - ); - $this->setBasePoint( - '015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7', - '0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706' - ); - $this->setOrder(new BigInteger( - '010000000000000000000000000000000000000000000000000001E2' . - 'AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php deleted file mode 100644 index 3c54eab..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571k1.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect571k1 extends Binary -{ - public function __construct() - { - $this->setModulo(571, 10, 5, 2, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000000' . - '000000000000000000000000000000000000000000000000000000000000000000000000', - '000000000000000000000000000000000000000000000000000000000000000000000000' . - '000000000000000000000000000000000000000000000000000000000000000000000001' - ); - $this->setBasePoint( - '026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA443709584' . - '93B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972', - '0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0' . - 'AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3' - ); - $this->setOrder(new BigInteger( - '020000000000000000000000000000000000000000000000000000000000000000000000' . - '131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php deleted file mode 100644 index 172c1af..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Curves/sect571r1.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Crypt\EC\Curves; - -use phpseclib3\Crypt\EC\BaseCurves\Binary; -use phpseclib3\Math\BigInteger; - -class sect571r1 extends Binary -{ - public function __construct() - { - $this->setModulo(571, 10, 5, 2, 0); - $this->setCoefficients( - '000000000000000000000000000000000000000000000000000000000000000000000000' . - '000000000000000000000000000000000000000000000000000000000000000000000001', - '02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD' . - '8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A' - ); - $this->setBasePoint( - '0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950' . - 'F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19', - '037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43' . - 'BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B' - ); - $this->setOrder(new BigInteger( - '03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' . - 'E661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47', - 16 - )); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php deleted file mode 100644 index 63402b4..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/Common.php +++ /dev/null @@ -1,549 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\Binary as BinaryCurve; -use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * Generic EC Key Parsing Helper functions - * - * @author Jim Wigginton - */ -trait Common -{ - /** - * Curve OIDs - * - * @var array - */ - private static $curveOIDs = []; - - /** - * Child OIDs loaded - * - * @var bool - */ - protected static $childOIDsLoaded = false; - - /** - * Use Named Curves - * - * @var bool - */ - private static $useNamedCurves = true; - - /** - * Initialize static variables - */ - private static function initialize_static_variables() - { - if (empty(self::$curveOIDs)) { - // the sec* curves are from the standards for efficient cryptography group - // sect* curves are curves over binary finite fields - // secp* curves are curves over prime finite fields - // sec*r* curves are regular curves; sec*k* curves are koblitz curves - // brainpool*r* curves are regular prime finite field curves - // brainpool*t* curves are twisted versions of the brainpool*r* curves - self::$curveOIDs = [ - 'prime192v1' => '1.2.840.10045.3.1.1', // J.5.1, example 1 (aka secp192r1) - 'prime192v2' => '1.2.840.10045.3.1.2', // J.5.1, example 2 - 'prime192v3' => '1.2.840.10045.3.1.3', // J.5.1, example 3 - 'prime239v1' => '1.2.840.10045.3.1.4', // J.5.2, example 1 - 'prime239v2' => '1.2.840.10045.3.1.5', // J.5.2, example 2 - 'prime239v3' => '1.2.840.10045.3.1.6', // J.5.2, example 3 - 'prime256v1' => '1.2.840.10045.3.1.7', // J.5.3, example 1 (aka secp256r1) - - // https://tools.ietf.org/html/rfc5656#section-10 - 'nistp256' => '1.2.840.10045.3.1.7', // aka secp256r1 - 'nistp384' => '1.3.132.0.34', // aka secp384r1 - 'nistp521' => '1.3.132.0.35', // aka secp521r1 - - 'nistk163' => '1.3.132.0.1', // aka sect163k1 - 'nistp192' => '1.2.840.10045.3.1.1', // aka secp192r1 - 'nistp224' => '1.3.132.0.33', // aka secp224r1 - 'nistk233' => '1.3.132.0.26', // aka sect233k1 - 'nistb233' => '1.3.132.0.27', // aka sect233r1 - 'nistk283' => '1.3.132.0.16', // aka sect283k1 - 'nistk409' => '1.3.132.0.36', // aka sect409k1 - 'nistb409' => '1.3.132.0.37', // aka sect409r1 - 'nistt571' => '1.3.132.0.38', // aka sect571k1 - - // from https://tools.ietf.org/html/rfc5915 - 'secp192r1' => '1.2.840.10045.3.1.1', // aka prime192v1 - 'sect163k1' => '1.3.132.0.1', - 'sect163r2' => '1.3.132.0.15', - 'secp224r1' => '1.3.132.0.33', - 'sect233k1' => '1.3.132.0.26', - 'sect233r1' => '1.3.132.0.27', - 'secp256r1' => '1.2.840.10045.3.1.7', // aka prime256v1 - 'sect283k1' => '1.3.132.0.16', - 'sect283r1' => '1.3.132.0.17', - 'secp384r1' => '1.3.132.0.34', - 'sect409k1' => '1.3.132.0.36', - 'sect409r1' => '1.3.132.0.37', - 'secp521r1' => '1.3.132.0.35', - 'sect571k1' => '1.3.132.0.38', - 'sect571r1' => '1.3.132.0.39', - // from http://www.secg.org/SEC2-Ver-1.0.pdf - 'secp112r1' => '1.3.132.0.6', - 'secp112r2' => '1.3.132.0.7', - 'secp128r1' => '1.3.132.0.28', - 'secp128r2' => '1.3.132.0.29', - 'secp160k1' => '1.3.132.0.9', - 'secp160r1' => '1.3.132.0.8', - 'secp160r2' => '1.3.132.0.30', - 'secp192k1' => '1.3.132.0.31', - 'secp224k1' => '1.3.132.0.32', - 'secp256k1' => '1.3.132.0.10', - - 'sect113r1' => '1.3.132.0.4', - 'sect113r2' => '1.3.132.0.5', - 'sect131r1' => '1.3.132.0.22', - 'sect131r2' => '1.3.132.0.23', - 'sect163r1' => '1.3.132.0.2', - 'sect193r1' => '1.3.132.0.24', - 'sect193r2' => '1.3.132.0.25', - 'sect239k1' => '1.3.132.0.3', - - // from http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.202.2977&rep=rep1&type=pdf#page=36 - /* - 'c2pnb163v1' => '1.2.840.10045.3.0.1', // J.4.1, example 1 - 'c2pnb163v2' => '1.2.840.10045.3.0.2', // J.4.1, example 2 - 'c2pnb163v3' => '1.2.840.10045.3.0.3', // J.4.1, example 3 - 'c2pnb172w1' => '1.2.840.10045.3.0.4', // J.4.2, example 1 - 'c2tnb191v1' => '1.2.840.10045.3.0.5', // J.4.3, example 1 - 'c2tnb191v2' => '1.2.840.10045.3.0.6', // J.4.3, example 2 - 'c2tnb191v3' => '1.2.840.10045.3.0.7', // J.4.3, example 3 - 'c2onb191v4' => '1.2.840.10045.3.0.8', // J.4.3, example 4 - 'c2onb191v5' => '1.2.840.10045.3.0.9', // J.4.3, example 5 - 'c2pnb208w1' => '1.2.840.10045.3.0.10', // J.4.4, example 1 - 'c2tnb239v1' => '1.2.840.10045.3.0.11', // J.4.5, example 1 - 'c2tnb239v2' => '1.2.840.10045.3.0.12', // J.4.5, example 2 - 'c2tnb239v3' => '1.2.840.10045.3.0.13', // J.4.5, example 3 - 'c2onb239v4' => '1.2.840.10045.3.0.14', // J.4.5, example 4 - 'c2onb239v5' => '1.2.840.10045.3.0.15', // J.4.5, example 5 - 'c2pnb272w1' => '1.2.840.10045.3.0.16', // J.4.6, example 1 - 'c2pnb304w1' => '1.2.840.10045.3.0.17', // J.4.7, example 1 - 'c2tnb359v1' => '1.2.840.10045.3.0.18', // J.4.8, example 1 - 'c2pnb368w1' => '1.2.840.10045.3.0.19', // J.4.9, example 1 - 'c2tnb431r1' => '1.2.840.10045.3.0.20', // J.4.10, example 1 - */ - - // http://www.ecc-brainpool.org/download/Domain-parameters.pdf - // https://tools.ietf.org/html/rfc5639 - 'brainpoolP160r1' => '1.3.36.3.3.2.8.1.1.1', - 'brainpoolP160t1' => '1.3.36.3.3.2.8.1.1.2', - 'brainpoolP192r1' => '1.3.36.3.3.2.8.1.1.3', - 'brainpoolP192t1' => '1.3.36.3.3.2.8.1.1.4', - 'brainpoolP224r1' => '1.3.36.3.3.2.8.1.1.5', - 'brainpoolP224t1' => '1.3.36.3.3.2.8.1.1.6', - 'brainpoolP256r1' => '1.3.36.3.3.2.8.1.1.7', - 'brainpoolP256t1' => '1.3.36.3.3.2.8.1.1.8', - 'brainpoolP320r1' => '1.3.36.3.3.2.8.1.1.9', - 'brainpoolP320t1' => '1.3.36.3.3.2.8.1.1.10', - 'brainpoolP384r1' => '1.3.36.3.3.2.8.1.1.11', - 'brainpoolP384t1' => '1.3.36.3.3.2.8.1.1.12', - 'brainpoolP512r1' => '1.3.36.3.3.2.8.1.1.13', - 'brainpoolP512t1' => '1.3.36.3.3.2.8.1.1.14' - ]; - ASN1::loadOIDs([ - 'prime-field' => '1.2.840.10045.1.1', - 'characteristic-two-field' => '1.2.840.10045.1.2', - 'characteristic-two-basis' => '1.2.840.10045.1.2.3', - // per http://www.secg.org/SEC1-Ver-1.0.pdf#page=84, gnBasis "not used here" - 'gnBasis' => '1.2.840.10045.1.2.3.1', // NULL - 'tpBasis' => '1.2.840.10045.1.2.3.2', // Trinomial - 'ppBasis' => '1.2.840.10045.1.2.3.3' // Pentanomial - ] + self::$curveOIDs); - } - } - - /** - * Explicitly set the curve - * - * If the key contains an implicit curve phpseclib needs the curve - * to be explicitly provided - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - */ - public static function setImplicitCurve(BaseCurve $curve) - { - self::$implicitCurve = $curve; - } - - /** - * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based - * on the curve parameters - * - * @param array $params - * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false - */ - protected static function loadCurveByParam(array $params) - { - if (count($params) > 1) { - throw new \RuntimeException('No parameters are present'); - } - if (isset($params['namedCurve'])) { - $curve = '\phpseclib3\Crypt\EC\Curves\\' . $params['namedCurve']; - if (!class_exists($curve)) { - throw new UnsupportedCurveException('Named Curve of ' . $params['namedCurve'] . ' is not supported'); - } - return new $curve(); - } - if (isset($params['implicitCurve'])) { - if (!isset(self::$implicitCurve)) { - throw new \RuntimeException('Implicit curves can be provided by calling setImplicitCurve'); - } - return self::$implicitCurve; - } - if (isset($params['specifiedCurve'])) { - $data = $params['specifiedCurve']; - switch ($data['fieldID']['fieldType']) { - case 'prime-field': - $curve = new PrimeCurve(); - $curve->setModulo($data['fieldID']['parameters']); - $curve->setCoefficients( - new BigInteger($data['curve']['a'], 256), - new BigInteger($data['curve']['b'], 256) - ); - $point = self::extractPoint("\0" . $data['base'], $curve); - $curve->setBasePoint(...$point); - $curve->setOrder($data['order']); - return $curve; - case 'characteristic-two-field': - $curve = new BinaryCurve(); - $params = ASN1::decodeBER($data['fieldID']['parameters']); - $params = ASN1::asn1map($params[0], Maps\Characteristic_two::MAP); - $modulo = [(int) $params['m']->toString()]; - switch ($params['basis']) { - case 'tpBasis': - $modulo[] = (int) $params['parameters']->toString(); - break; - case 'ppBasis': - $temp = ASN1::decodeBER($params['parameters']); - $temp = ASN1::asn1map($temp[0], Maps\Pentanomial::MAP); - $modulo[] = (int) $temp['k3']->toString(); - $modulo[] = (int) $temp['k2']->toString(); - $modulo[] = (int) $temp['k1']->toString(); - } - $modulo[] = 0; - $curve->setModulo(...$modulo); - $len = ceil($modulo[0] / 8); - $curve->setCoefficients( - Strings::bin2hex($data['curve']['a']), - Strings::bin2hex($data['curve']['b']) - ); - $point = self::extractPoint("\0" . $data['base'], $curve); - $curve->setBasePoint(...$point); - $curve->setOrder($data['order']); - return $curve; - default: - throw new UnsupportedCurveException('Field Type of ' . $data['fieldID']['fieldType'] . ' is not supported'); - } - } - throw new \RuntimeException('No valid parameters are present'); - } - - /** - * Extract points from a string - * - * Supports both compressed and uncompressed points - * - * @param string $str - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @return object[] - */ - public static function extractPoint($str, BaseCurve $curve) - { - if ($curve instanceof TwistedEdwardsCurve) { - // first step of point deciding as discussed at the following URL's: - // https://tools.ietf.org/html/rfc8032#section-5.1.3 - // https://tools.ietf.org/html/rfc8032#section-5.2.3 - $y = $str; - $y = strrev($y); - $sign = (bool) (ord($y[0]) & 0x80); - $y[0] = $y[0] & chr(0x7F); - $y = new BigInteger($y, 256); - if ($y->compare($curve->getModulo()) >= 0) { - throw new \RuntimeException('The Y coordinate should not be >= the modulo'); - } - $point = $curve->recoverX($y, $sign); - if (!$curve->verifyPoint($point)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - return $point; - } - - // the first byte of a bit string represents the number of bits in the last byte that are to be ignored but, - // currently, bit strings wanting a non-zero amount of bits trimmed are not supported - if (($val = Strings::shift($str)) != "\0") { - throw new \UnexpectedValueException('extractPoint expects the first byte to be null - not ' . Strings::bin2hex($val)); - } - if ($str == "\0") { - return []; - } - - $keylen = strlen($str); - $order = $curve->getLengthInBytes(); - // point compression is being used - if ($keylen == $order + 1) { - return $curve->derivePoint($str); - } - - // point compression is not being used - if ($keylen == 2 * $order + 1) { - preg_match("#(.)(.{{$order}})(.{{$order}})#s", $str, $matches); - list(, $w, $x, $y) = $matches; - if ($w != "\4") { - throw new \UnexpectedValueException('The first byte of an uncompressed point should be 04 - not ' . Strings::bin2hex($val)); - } - $point = [ - $curve->convertInteger(new BigInteger($x, 256)), - $curve->convertInteger(new BigInteger($y, 256)) - ]; - - if (!$curve->verifyPoint($point)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - - return $point; - } - - throw new \UnexpectedValueException('The string representation of the points is not of an appropriate length'); - } - - /** - * Encode Parameters - * - * @todo Maybe at some point this could be moved to __toString() for each of the curves? - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param bool $returnArray optional - * @param array $options optional - * @return string|false - */ - private static function encodeParameters(BaseCurve $curve, $returnArray = false, array $options = []) - { - $useNamedCurves = isset($options['namedCurve']) ? $options['namedCurve'] : self::$useNamedCurves; - - $reflect = new \ReflectionClass($curve); - $name = $reflect->getShortName(); - if ($useNamedCurves) { - if (isset(self::$curveOIDs[$name])) { - if ($reflect->isFinal()) { - $reflect = $reflect->getParentClass(); - $name = $reflect->getShortName(); - } - return $returnArray ? - ['namedCurve' => $name] : - ASN1::encodeDER(['namedCurve' => $name], Maps\ECParameters::MAP); - } - foreach (new \DirectoryIterator(__DIR__ . '/../../Curves/') as $file) { - if ($file->getExtension() != 'php') { - continue; - } - $testName = $file->getBasename('.php'); - $class = 'phpseclib3\Crypt\EC\Curves\\' . $testName; - $reflect = new \ReflectionClass($class); - if ($reflect->isFinal()) { - continue; - } - $candidate = new $class(); - switch ($name) { - case 'Prime': - if (!$candidate instanceof PrimeCurve) { - break; - } - if (!$candidate->getModulo()->equals($curve->getModulo())) { - break; - } - if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { - break; - } - if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { - break; - } - - list($candidateX, $candidateY) = $candidate->getBasePoint(); - list($curveX, $curveY) = $curve->getBasePoint(); - if ($candidateX->toBytes() != $curveX->toBytes()) { - break; - } - if ($candidateY->toBytes() != $curveY->toBytes()) { - break; - } - - return $returnArray ? - ['namedCurve' => $testName] : - ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); - case 'Binary': - if (!$candidate instanceof BinaryCurve) { - break; - } - if ($candidate->getModulo() != $curve->getModulo()) { - break; - } - if ($candidate->getA()->toBytes() != $curve->getA()->toBytes()) { - break; - } - if ($candidate->getB()->toBytes() != $curve->getB()->toBytes()) { - break; - } - - list($candidateX, $candidateY) = $candidate->getBasePoint(); - list($curveX, $curveY) = $curve->getBasePoint(); - if ($candidateX->toBytes() != $curveX->toBytes()) { - break; - } - if ($candidateY->toBytes() != $curveY->toBytes()) { - break; - } - - return $returnArray ? - ['namedCurve' => $testName] : - ASN1::encodeDER(['namedCurve' => $testName], Maps\ECParameters::MAP); - } - } - } - - $order = $curve->getOrder(); - // we could try to calculate the order thusly: - // https://crypto.stackexchange.com/a/27914/4520 - // https://en.wikipedia.org/wiki/Schoof%E2%80%93Elkies%E2%80%93Atkin_algorithm - if (!$order) { - throw new \RuntimeException('Specified Curves need the order to be specified'); - } - $point = $curve->getBasePoint(); - $x = $point[0]->toBytes(); - $y = $point[1]->toBytes(); - - if ($curve instanceof PrimeCurve) { - /* - * valid versions are: - * - * ecdpVer1: - * - neither the curve or the base point are generated verifiably randomly. - * ecdpVer2: - * - curve and base point are generated verifiably at random and curve.seed is present - * ecdpVer3: - * - base point is generated verifiably at random but curve is not. curve.seed is present - */ - // other (optional) parameters can be calculated using the methods discused at - // https://crypto.stackexchange.com/q/28947/4520 - $data = [ - 'version' => 'ecdpVer1', - 'fieldID' => [ - 'fieldType' => 'prime-field', - 'parameters' => $curve->getModulo() - ], - 'curve' => [ - 'a' => $curve->getA()->toBytes(), - 'b' => $curve->getB()->toBytes() - ], - 'base' => "\4" . $x . $y, - 'order' => $order - ]; - - return $returnArray ? - ['specifiedCurve' => $data] : - ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); - } - if ($curve instanceof BinaryCurve) { - $modulo = $curve->getModulo(); - $basis = count($modulo); - $m = array_shift($modulo); - array_pop($modulo); // the last parameter should always be 0 - //rsort($modulo); - switch ($basis) { - case 3: - $basis = 'tpBasis'; - $modulo = new BigInteger($modulo[0]); - break; - case 5: - $basis = 'ppBasis'; - // these should be in strictly ascending order (hence the commented out rsort above) - $modulo = [ - 'k1' => new BigInteger($modulo[2]), - 'k2' => new BigInteger($modulo[1]), - 'k3' => new BigInteger($modulo[0]) - ]; - $modulo = ASN1::encodeDER($modulo, Maps\Pentanomial::MAP); - $modulo = new ASN1\Element($modulo); - } - $params = ASN1::encodeDER([ - 'm' => new BigInteger($m), - 'basis' => $basis, - 'parameters' => $modulo - ], Maps\Characteristic_two::MAP); - $params = new ASN1\Element($params); - $a = ltrim($curve->getA()->toBytes(), "\0"); - if (!strlen($a)) { - $a = "\0"; - } - $b = ltrim($curve->getB()->toBytes(), "\0"); - if (!strlen($b)) { - $b = "\0"; - } - $data = [ - 'version' => 'ecdpVer1', - 'fieldID' => [ - 'fieldType' => 'characteristic-two-field', - 'parameters' => $params - ], - 'curve' => [ - 'a' => $a, - 'b' => $b - ], - 'base' => "\4" . $x . $y, - 'order' => $order - ]; - - return $returnArray ? - ['specifiedCurve' => $data] : - ASN1::encodeDER(['specifiedCurve' => $data], Maps\ECParameters::MAP); - } - - throw new UnsupportedCurveException('Curve cannot be serialized'); - } - - /** - * Use Specified Curve - * - * A specified curve has all the coefficients, the base points, etc, explicitely included. - * A specified curve is a more verbose way of representing a curve - */ - public static function useSpecifiedCurve() - { - self::$useNamedCurves = false; - } - - /** - * Use Named Curve - * - * A named curve does not include any parameters. It is up to the EC parameters to - * know what the coefficients, the base points, etc, are from the name of the curve. - * A named curve is a more concise way of representing a curve - */ - public static function useNamedCurve() - { - self::$useNamedCurves = true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php deleted file mode 100644 index fd18a98..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/JWK.php +++ /dev/null @@ -1,189 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Curves\secp256k1; -use phpseclib3\Crypt\EC\Curves\secp256r1; -use phpseclib3\Crypt\EC\Curves\secp384r1; -use phpseclib3\Crypt\EC\Curves\secp521r1; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Math\BigInteger; - -/** - * JWK Formatted EC Handler - * - * @author Jim Wigginton - */ -abstract class JWK extends Progenitor -{ - use Common; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - switch ($key->kty) { - case 'EC': - switch ($key->crv) { - case 'P-256': - case 'P-384': - case 'P-521': - case 'secp256k1': - break; - default: - throw new UnsupportedCurveException('Only P-256, P-384, P-521 and secp256k1 curves are accepted (' . $key->crv . ' provided)'); - } - break; - case 'OKP': - switch ($key->crv) { - case 'Ed25519': - case 'Ed448': - break; - default: - throw new UnsupportedCurveException('Only Ed25519 and Ed448 curves are accepted (' . $key->crv . ' provided)'); - } - break; - default: - throw new \Exception('Only EC and OKP JWK keys are supported'); - } - - $curve = '\phpseclib3\Crypt\EC\Curves\\' . str_replace('P-', 'nistp', $key->crv); - $curve = new $curve(); - - if ($curve instanceof TwistedEdwardsCurve) { - $QA = self::extractPoint(Strings::base64url_decode($key->x), $curve); - if (!isset($key->d)) { - return compact('curve', 'QA'); - } - $arr = $curve->extractSecret(Strings::base64url_decode($key->d)); - return compact('curve', 'QA') + $arr; - } - - $QA = [ - $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->x), 256)), - $curve->convertInteger(new BigInteger(Strings::base64url_decode($key->y), 256)) - ]; - - if (!$curve->verifyPoint($QA)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - - if (!isset($key->d)) { - return compact('curve', 'QA'); - } - - $dA = new BigInteger(Strings::base64url_decode($key->d), 256); - - $curve->rangeCheck($dA); - - return compact('curve', 'dA', 'QA'); - } - - /** - * Returns the alias that corresponds to a curve - * - * @return string - */ - private static function getAlias(BaseCurve $curve) - { - switch (true) { - case $curve instanceof secp256r1: - return 'P-256'; - case $curve instanceof secp384r1: - return 'P-384'; - case $curve instanceof secp521r1: - return 'P-521'; - case $curve instanceof secp256k1: - return 'secp256k1'; - } - - $reflect = new \ReflectionClass($curve); - $curveName = $reflect->isFinal() ? - $reflect->getParentClass()->getShortName() : - $reflect->getShortName(); - throw new UnsupportedCurveException("$curveName is not a supported curve"); - } - - /** - * Return the array superstructure for an EC public key - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return array - */ - private static function savePublicKeyHelper(BaseCurve $curve, array $publicKey) - { - if ($curve instanceof TwistedEdwardsCurve) { - return [ - 'kty' => 'OKP', - 'crv' => $curve instanceof Ed25519 ? 'Ed25519' : 'Ed448', - 'x' => Strings::base64url_encode($curve->encodePoint($publicKey)) - ]; - } - - return [ - 'kty' => 'EC', - 'crv' => self::getAlias($curve), - 'x' => Strings::base64url_encode($publicKey[0]->toBytes()), - 'y' => Strings::base64url_encode($publicKey[1]->toBytes()) - ]; - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - $key = self::savePublicKeyHelper($curve, $publicKey); - - return self::wrapKey($key, $options); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) - { - $key = self::savePublicKeyHelper($curve, $publicKey); - $key['d'] = $curve instanceof TwistedEdwardsCurve ? $secret : $privateKey->toBytes(); - $key['d'] = Strings::base64url_encode($key['d']); - - return self::wrapKey($key, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php deleted file mode 100644 index 5741b05..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPrivate.php +++ /dev/null @@ -1,101 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Curve448; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Math\BigInteger; - -/** - * Montgomery Curve Private Key Handler - * - * @author Jim Wigginton - */ -abstract class MontgomeryPrivate -{ - /** - * Is invisible flag - * - */ - const IS_INVISIBLE = true; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - switch (strlen($key)) { - case 32: - $curve = new Curve25519(); - break; - case 56: - $curve = new Curve448(); - break; - default: - throw new \LengthException('The only supported lengths are 32 and 56'); - } - - $components = ['curve' => $curve]; - $components['dA'] = new BigInteger($key, 256); - $curve->rangeCheck($components['dA']); - // note that EC::getEncodedCoordinates does some additional "magic" (it does strrev on the result) - $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return string - */ - public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) - { - return strrev($publicKey[0]->toBytes()); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, MontgomeryCurve $curve, array $publicKey, $secret = null, $password = '') - { - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('MontgomeryPrivate private keys do not support encryption'); - } - - return $privateKey->toBytes(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php deleted file mode 100644 index d1ad48a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/MontgomeryPublic.php +++ /dev/null @@ -1,71 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Curve448; -use phpseclib3\Math\BigInteger; - -/** - * Montgomery Public Key Handler - * - * @author Jim Wigginton - */ -abstract class MontgomeryPublic -{ - /** - * Is invisible flag - * - */ - const IS_INVISIBLE = true; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - switch (strlen($key)) { - case 32: - $curve = new Curve25519(); - break; - case 56: - $curve = new Curve448(); - break; - default: - throw new \LengthException('The only supported lengths are 32 and 56'); - } - - $components = ['curve' => $curve]; - $components['QA'] = [$components['curve']->convertInteger(new BigInteger(strrev($key), 256))]; - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Montgomery $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return string - */ - public static function savePublicKey(MontgomeryCurve $curve, array $publicKey) - { - return strrev($publicKey[0]->toBytes()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php deleted file mode 100644 index 2cd3e19..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,209 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Math\BigInteger; - -/** - * OpenSSH Formatted EC Key Handler - * - * @author Jim Wigginton - */ -abstract class OpenSSH extends Progenitor -{ - use Common; - - /** - * Supported Key Types - * - * @var array - */ - protected static $types = [ - 'ecdsa-sha2-nistp256', - 'ecdsa-sha2-nistp384', - 'ecdsa-sha2-nistp521', - 'ssh-ed25519' - ]; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $parsed = parent::load($key, $password); - - if (isset($parsed['paddedKey'])) { - $paddedKey = $parsed['paddedKey']; - list($type) = Strings::unpackSSH2('s', $paddedKey); - if ($type != $parsed['type']) { - throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); - } - if ($type == 'ssh-ed25519') { - list(, $key, $comment) = Strings::unpackSSH2('sss', $paddedKey); - $key = libsodium::load($key); - $key['comment'] = $comment; - return $key; - } - list($curveName, $publicKey, $privateKey, $comment) = Strings::unpackSSH2('ssis', $paddedKey); - $curve = self::loadCurveByParam(['namedCurve' => $curveName]); - $curve->rangeCheck($privateKey); - return [ - 'curve' => $curve, - 'dA' => $privateKey, - 'QA' => self::extractPoint("\0$publicKey", $curve), - 'comment' => $comment - ]; - } - - if ($parsed['type'] == 'ssh-ed25519') { - if (Strings::shift($parsed['publicKey'], 4) != "\0\0\0\x20") { - throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); - } - - $curve = new Ed25519(); - $qa = self::extractPoint($parsed['publicKey'], $curve); - } else { - list($curveName, $publicKey) = Strings::unpackSSH2('ss', $parsed['publicKey']); - $curveName = '\phpseclib3\Crypt\EC\Curves\\' . $curveName; - $curve = new $curveName(); - - $qa = self::extractPoint("\0" . $publicKey, $curve); - } - - return [ - 'curve' => $curve, - 'QA' => $qa, - 'comment' => $parsed['comment'] - ]; - } - - /** - * Returns the alias that corresponds to a curve - * - * @return string - */ - private static function getAlias(BaseCurve $curve) - { - self::initialize_static_variables(); - - $reflect = new \ReflectionClass($curve); - $name = $reflect->getShortName(); - - $oid = self::$curveOIDs[$name]; - $aliases = array_filter(self::$curveOIDs, function ($v) use ($oid) { - return $v == $oid; - }); - $aliases = array_keys($aliases); - - for ($i = 0; $i < count($aliases); $i++) { - if (in_array('ecdsa-sha2-' . $aliases[$i], self::$types)) { - $alias = $aliases[$i]; - break; - } - } - - if (!isset($alias)) { - throw new UnsupportedCurveException($name . ' is not a curve that the OpenSSH plugin supports'); - } - - return $alias; - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - - if ($curve instanceof Ed25519) { - $key = Strings::packSSH2('ss', 'ssh-ed25519', $curve->encodePoint($publicKey)); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $key; - } - - $key = 'ssh-ed25519 ' . base64_encode($key) . ' ' . $comment; - return $key; - } - - $alias = self::getAlias($curve); - - $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - $key = Strings::packSSH2('sss', 'ecdsa-sha2-' . $alias, $alias, $points); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $key; - } - - $key = 'ecdsa-sha2-' . $alias . ' ' . base64_encode($key) . ' ' . $comment; - - return $key; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) - { - if ($curve instanceof Ed25519) { - if (!isset($secret)) { - throw new \RuntimeException('Private Key does not have a secret set'); - } - if (strlen($secret) != 32) { - throw new \RuntimeException('Private Key secret is not of the correct length'); - } - - $pubKey = $curve->encodePoint($publicKey); - - $publicKey = Strings::packSSH2('ss', 'ssh-ed25519', $pubKey); - $privateKey = Strings::packSSH2('sss', 'ssh-ed25519', $pubKey, $secret . $pubKey); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } - - $alias = self::getAlias($curve); - - $points = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - $publicKey = self::savePublicKey($curve, $publicKey, ['binary' => true]); - - $privateKey = Strings::packSSH2('sssi', 'ecdsa-sha2-' . $alias, $alias, $points, $privateKey); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php deleted file mode 100644 index 9f4b330..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,194 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * "PKCS1" (RFC5915) Formatted EC Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS1 extends Progenitor -{ - use Common; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'BEGIN EC PARAMETERS') && strpos($key, 'BEGIN EC PRIVATE KEY')) { - $components = []; - - preg_match('#-*BEGIN EC PRIVATE KEY-*[^-]*-*END EC PRIVATE KEY-*#s', $key, $matches); - $decoded = parent::load($matches[0], $password); - $decoded = ASN1::decodeBER($decoded); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - - $ecPrivate = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); - if (!is_array($ecPrivate)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - if (isset($ecPrivate['parameters'])) { - $components['curve'] = self::loadCurveByParam($ecPrivate['parameters']); - } - - preg_match('#-*BEGIN EC PARAMETERS-*[^-]*-*END EC PARAMETERS-*#s', $key, $matches); - $decoded = parent::load($matches[0], ''); - $decoded = ASN1::decodeBER($decoded); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - $ecParams = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); - if (!is_array($ecParams)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - $ecParams = self::loadCurveByParam($ecParams); - - // comparing $ecParams and $components['curve'] directly won't work because they'll have different Math\Common\FiniteField classes - // even if the modulo is the same - if (isset($components['curve']) && self::encodeParameters($ecParams, false, []) != self::encodeParameters($components['curve'], false, [])) { - throw new \RuntimeException('EC PARAMETERS does not correspond to EC PRIVATE KEY'); - } - - if (!isset($components['curve'])) { - $components['curve'] = $ecParams; - } - - $components['dA'] = new BigInteger($ecPrivate['privateKey'], 256); - $components['curve']->rangeCheck($components['dA']); - $components['QA'] = isset($ecPrivate['publicKey']) ? - self::extractPoint($ecPrivate['publicKey'], $components['curve']) : - $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - - $key = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); - if (is_array($key)) { - return ['curve' => self::loadCurveByParam($key)]; - } - - $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); - if (!is_array($key)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - if (!isset($key['parameters'])) { - throw new \RuntimeException('Key cannot be loaded without parameters'); - } - - $components = []; - $components['curve'] = self::loadCurveByParam($key['parameters']); - $components['dA'] = new BigInteger($key['privateKey'], 256); - $components['QA'] = isset($ecPrivate['publicKey']) ? - self::extractPoint($ecPrivate['publicKey'], $components['curve']) : - $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - /** - * Convert EC parameters to the appropriate format - * - * @return string - */ - public static function saveParameters(BaseCurve $curve, array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); - } - - $key = self::encodeParameters($curve, false, $options); - - return "-----BEGIN EC PARAMETERS-----\r\n" . - chunk_split(Strings::base64_encode($key), 64) . - "-----END EC PARAMETERS-----\r\n"; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('TwistedEdwards Curves are not supported'); - } - - $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - $key = [ - 'version' => 'ecPrivkeyVer1', - 'privateKey' => $privateKey->toBytes(), - 'parameters' => new ASN1\Element(self::encodeParameters($curve)), - 'publicKey' => "\0" . $publicKey - ]; - - $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); - - return self::wrapPrivateKey($key, 'EC', $password, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php deleted file mode 100644 index 0ec7742..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,234 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Curves\Ed448; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#8 Formatted EC Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS8 extends Progenitor -{ - use Common; - - /** - * OID Name - * - * @var array - */ - const OID_NAME = ['id-ecPublicKey', 'id-Ed25519', 'id-Ed448']; - - /** - * OID Value - * - * @var string - */ - const OID_VALUE = ['1.2.840.10045.2.1', '1.3.101.112', '1.3.101.113']; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - // initialize_static_variables() is defined in both the trait and the parent class - // when it's defined in two places it's the traits one that's called - // the parent one is needed, as well, but the parent one is called by other methods - // in the parent class as needed and in the context of the parent it's the parent - // one that's called - self::initialize_static_variables(); - - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'privateKey' : 'publicKey'; - - switch ($key[$type . 'Algorithm']['algorithm']) { - case 'id-Ed25519': - case 'id-Ed448': - return self::loadEdDSA($key); - } - - $decoded = ASN1::decodeBER($key[$type . 'Algorithm']['parameters']->element); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - $params = ASN1::asn1map($decoded[0], Maps\ECParameters::MAP); - if (!$params) { - throw new \RuntimeException('Unable to decode the parameters using Maps\ECParameters'); - } - - $components = []; - $components['curve'] = self::loadCurveByParam($params); - - if ($type == 'publicKey') { - $components['QA'] = self::extractPoint("\0" . $key['publicKey'], $components['curve']); - - return $components; - } - - $decoded = ASN1::decodeBER($key['privateKey']); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - $key = ASN1::asn1map($decoded[0], Maps\ECPrivateKey::MAP); - if (isset($key['parameters']) && $params != $key['parameters']) { - throw new \RuntimeException('The PKCS8 parameter field does not match the private key parameter field'); - } - - $components['dA'] = new BigInteger($key['privateKey'], 256); - $components['curve']->rangeCheck($components['dA']); - $components['QA'] = isset($key['publicKey']) ? - self::extractPoint($key['publicKey'], $components['curve']) : - $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - - return $components; - } - - /** - * Break a public or private EdDSA key down into its constituent components - * - * @return array - */ - private static function loadEdDSA(array $key) - { - $components = []; - - if (isset($key['privateKey'])) { - $components['curve'] = $key['privateKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); - - // 0x04 == octet string - // 0x20 == length (32 bytes) - if (substr($key['privateKey'], 0, 2) != "\x04\x20") { - throw new \RuntimeException('The first two bytes of the private key field should be 0x0420'); - } - $arr = $components['curve']->extractSecret(substr($key['privateKey'], 2)); - $components['dA'] = $arr['dA']; - $components['secret'] = $arr['secret']; - } - - if (isset($key['publicKey'])) { - if (!isset($components['curve'])) { - $components['curve'] = $key['publicKeyAlgorithm']['algorithm'] == 'id-Ed25519' ? new Ed25519() : new Ed448(); - } - - $components['QA'] = self::extractPoint($key['publicKey'], $components['curve']); - } - - if (isset($key['privateKey']) && !isset($components['QA'])) { - $components['QA'] = $components['curve']->multiplyPoint($components['curve']->getBasePoint(), $components['dA']); - } - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('Montgomery Curves are not supported'); - } - - if ($curve instanceof TwistedEdwardsCurve) { - return self::wrapPublicKey( - $curve->encodePoint($publicKey), - null, - $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' - ); - } - - $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); - - $key = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - return self::wrapPublicKey($key, $params, 'id-ecPublicKey'); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = '', array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('Montgomery Curves are not supported'); - } - - if ($curve instanceof TwistedEdwardsCurve) { - return self::wrapPrivateKey( - "\x04\x20" . $secret, - [], - null, - $password, - $curve instanceof Ed25519 ? 'id-Ed25519' : 'id-Ed448' - ); - } - - $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - $params = new ASN1\Element(self::encodeParameters($curve, false, $options)); - - $key = [ - 'version' => 'ecPrivkeyVer1', - 'privateKey' => $privateKey->toBytes(), - //'parameters' => $params, - 'publicKey' => "\0" . $publicKey - ]; - - $key = ASN1::encodeDER($key, Maps\ECPrivateKey::MAP); - - return self::wrapPrivateKey($key, [], $params, $password, 'id-ecPublicKey', '', $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php deleted file mode 100644 index 866c883..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,138 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Math\BigInteger; - -/** - * PuTTY Formatted EC Key Handler - * - * @author Jim Wigginton - */ -abstract class PuTTY extends Progenitor -{ - use Common; - - /** - * Public Handler - * - * @var string - */ - const PUBLIC_HANDLER = 'phpseclib3\Crypt\EC\Formats\Keys\OpenSSH'; - - /** - * Supported Key Types - * - * @var array - */ - protected static $types = [ - 'ecdsa-sha2-nistp256', - 'ecdsa-sha2-nistp384', - 'ecdsa-sha2-nistp521', - 'ssh-ed25519' - ]; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $components = parent::load($key, $password); - if (!isset($components['private'])) { - return $components; - } - - $private = $components['private']; - - $temp = Strings::base64_encode(Strings::packSSH2('s', $components['type']) . $components['public']); - $components = OpenSSH::load($components['type'] . ' ' . $temp . ' ' . $components['comment']); - - if ($components['curve'] instanceof TwistedEdwardsCurve) { - if (Strings::shift($private, 4) != "\0\0\0\x20") { - throw new \RuntimeException('Length of ssh-ed25519 key should be 32'); - } - $arr = $components['curve']->extractSecret($private); - $components['dA'] = $arr['dA']; - $components['secret'] = $arr['secret']; - } else { - list($components['dA']) = Strings::unpackSSH2('i', $private); - $components['curve']->rangeCheck($components['dA']); - } - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, BaseCurve $curve, array $publicKey, $secret = null, $password = false, array $options = []) - { - self::initialize_static_variables(); - - $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); - $name = $public[0]; - $public = Strings::base64_decode($public[1]); - list(, $length) = unpack('N', Strings::shift($public, 4)); - Strings::shift($public, $length); - - // PuTTY pads private keys with a null byte per the following: - // https://github.com/github/putty/blob/a3d14d77f566a41fc61dfdc5c2e0e384c9e6ae8b/sshecc.c#L1926 - if (!$curve instanceof TwistedEdwardsCurve) { - $private = $privateKey->toBytes(); - if (!(strlen($privateKey->toBits()) & 7)) { - $private = "\0$private"; - } - } - - $private = $curve instanceof TwistedEdwardsCurve ? - Strings::packSSH2('s', $secret) : - Strings::packSSH2('s', $private); - - return self::wrapPrivateKey($public, $private, $name, $password, $options); - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField[] $publicKey - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey) - { - $public = explode(' ', OpenSSH::savePublicKey($curve, $publicKey)); - $type = $public[0]; - $public = Strings::base64_decode($public[1]); - list(, $length) = unpack('N', Strings::shift($public, 4)); - Strings::shift($public, $length); - - return self::wrapPublicKey($public, $type); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php deleted file mode 100644 index 27d9218..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/XML.php +++ /dev/null @@ -1,485 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\EC\BaseCurves\Base as BaseCurve; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\BaseCurves\Prime as PrimeCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Math\BigInteger; - -/** - * XML Formatted EC Key Handler - * - * @author Jim Wigginton - */ -abstract class XML -{ - use Common; - - /** - * Default namespace - * - * @var string - */ - private static $namespace; - - /** - * Flag for using RFC4050 syntax - * - * @var bool - */ - private static $rfc4050 = false; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (!class_exists('DOMDocument')) { - throw new BadConfigurationException('The dom extension is not setup correctly on this system'); - } - - $use_errors = libxml_use_internal_errors(true); - - $temp = self::isolateNamespace($key, 'http://www.w3.org/2009/xmldsig11#'); - if ($temp) { - $key = $temp; - } - - $temp = self::isolateNamespace($key, 'http://www.w3.org/2001/04/xmldsig-more#'); - if ($temp) { - $key = $temp; - } - - $dom = new \DOMDocument(); - if (substr($key, 0, 5) != '' . $key . ''; - } - - if (!$dom->loadXML($key)) { - libxml_use_internal_errors($use_errors); - throw new \UnexpectedValueException('Key does not appear to contain XML'); - } - $xpath = new \DOMXPath($dom); - libxml_use_internal_errors($use_errors); - $curve = self::loadCurveByParam($xpath); - - $pubkey = self::query($xpath, 'publickey', 'Public Key is not present'); - - $QA = self::query($xpath, 'ecdsakeyvalue')->length ? - self::extractPointRFC4050($xpath, $curve) : - self::extractPoint("\0" . $pubkey, $curve); - - libxml_use_internal_errors($use_errors); - - return compact('curve', 'QA'); - } - - /** - * Case-insensitive xpath query - * - * @param \DOMXPath $xpath - * @param string $name - * @param string $error optional - * @param bool $decode optional - * @return \DOMNodeList - */ - private static function query(\DOMXPath $xpath, $name, $error = null, $decode = true) - { - $query = '/'; - $names = explode('/', $name); - foreach ($names as $name) { - $query .= "/*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$name']"; - } - $result = $xpath->query($query); - if (!isset($error)) { - return $result; - } - - if (!$result->length) { - throw new \RuntimeException($error); - } - return $decode ? self::decodeValue($result->item(0)->textContent) : $result->item(0)->textContent; - } - - /** - * Finds the first element in the relevant namespace, strips the namespacing and returns the XML for that element. - * - * @param string $xml - * @param string $ns - */ - private static function isolateNamespace($xml, $ns) - { - $dom = new \DOMDocument(); - if (!$dom->loadXML($xml)) { - return false; - } - $xpath = new \DOMXPath($dom); - $nodes = $xpath->query("//*[namespace::*[.='$ns'] and not(../namespace::*[.='$ns'])]"); - if (!$nodes->length) { - return false; - } - $node = $nodes->item(0); - $ns_name = $node->lookupPrefix($ns); - if ($ns_name) { - $node->removeAttributeNS($ns, $ns_name); - } - return $dom->saveXML($node); - } - - /** - * Decodes the value - * - * @param string $value - */ - private static function decodeValue($value) - { - return Strings::base64_decode(str_replace(["\r", "\n", ' ', "\t"], '', $value)); - } - - /** - * Extract points from an XML document - * - * @param \DOMXPath $xpath - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @return object[] - */ - private static function extractPointRFC4050(\DOMXPath $xpath, BaseCurve $curve) - { - $x = self::query($xpath, 'publickey/x'); - $y = self::query($xpath, 'publickey/y'); - if (!$x->length || !$x->item(0)->hasAttribute('Value')) { - throw new \RuntimeException('Public Key / X coordinate not found'); - } - if (!$y->length || !$y->item(0)->hasAttribute('Value')) { - throw new \RuntimeException('Public Key / Y coordinate not found'); - } - $point = [ - $curve->convertInteger(new BigInteger($x->item(0)->getAttribute('Value'))), - $curve->convertInteger(new BigInteger($y->item(0)->getAttribute('Value'))) - ]; - if (!$curve->verifyPoint($point)) { - throw new \RuntimeException('Unable to verify that point exists on curve'); - } - return $point; - } - - /** - * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based - * on the curve parameters - * - * @param \DomXPath $xpath - * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false - */ - private static function loadCurveByParam(\DOMXPath $xpath) - { - $namedCurve = self::query($xpath, 'namedcurve'); - if ($namedCurve->length == 1) { - $oid = $namedCurve->item(0)->getAttribute('URN'); - $oid = preg_replace('#[^\d.]#', '', $oid); - $name = array_search($oid, self::$curveOIDs); - if ($name === false) { - throw new UnsupportedCurveException('Curve with OID of ' . $oid . ' is not supported'); - } - - $curve = '\phpseclib3\Crypt\EC\Curves\\' . $name; - if (!class_exists($curve)) { - throw new UnsupportedCurveException('Named Curve of ' . $name . ' is not supported'); - } - return new $curve(); - } - - $params = self::query($xpath, 'explicitparams'); - if ($params->length) { - return self::loadCurveByParamRFC4050($xpath); - } - - $params = self::query($xpath, 'ecparameters'); - if (!$params->length) { - throw new \RuntimeException('No parameters are present'); - } - - $fieldTypes = [ - 'prime-field' => ['fieldid/prime/p'], - 'gnb' => ['fieldid/gnb/m'], - 'tnb' => ['fieldid/tnb/k'], - 'pnb' => ['fieldid/pnb/k1', 'fieldid/pnb/k2', 'fieldid/pnb/k3'], - 'unknown' => [] - ]; - - foreach ($fieldTypes as $type => $queries) { - foreach ($queries as $query) { - $result = self::query($xpath, $query); - if (!$result->length) { - continue 2; - } - $param = preg_replace('#.*/#', '', $query); - $$param = self::decodeValue($result->item(0)->textContent); - } - break; - } - - $a = self::query($xpath, 'curve/a', 'A coefficient is not present'); - $b = self::query($xpath, 'curve/b', 'B coefficient is not present'); - $base = self::query($xpath, 'base', 'Base point is not present'); - $order = self::query($xpath, 'order', 'Order is not present'); - - switch ($type) { - case 'prime-field': - $curve = new PrimeCurve(); - $curve->setModulo(new BigInteger($p, 256)); - $curve->setCoefficients( - new BigInteger($a, 256), - new BigInteger($b, 256) - ); - $point = self::extractPoint("\0" . $base, $curve); - $curve->setBasePoint(...$point); - $curve->setOrder(new BigInteger($order, 256)); - return $curve; - case 'gnb': - case 'tnb': - case 'pnb': - default: - throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); - } - } - - /** - * Returns an instance of \phpseclib3\Crypt\EC\BaseCurves\Base based - * on the curve parameters - * - * @param \DomXPath $xpath - * @return \phpseclib3\Crypt\EC\BaseCurves\Base|false - */ - private static function loadCurveByParamRFC4050(\DOMXPath $xpath) - { - $fieldTypes = [ - 'prime-field' => ['primefieldparamstype/p'], - 'unknown' => [] - ]; - - foreach ($fieldTypes as $type => $queries) { - foreach ($queries as $query) { - $result = self::query($xpath, $query); - if (!$result->length) { - continue 2; - } - $param = preg_replace('#.*/#', '', $query); - $$param = $result->item(0)->textContent; - } - break; - } - - $a = self::query($xpath, 'curveparamstype/a', 'A coefficient is not present', false); - $b = self::query($xpath, 'curveparamstype/b', 'B coefficient is not present', false); - $x = self::query($xpath, 'basepointparams/basepoint/ecpointtype/x', 'Base Point X is not present', false); - $y = self::query($xpath, 'basepointparams/basepoint/ecpointtype/y', 'Base Point Y is not present', false); - $order = self::query($xpath, 'order', 'Order is not present', false); - - switch ($type) { - case 'prime-field': - $curve = new PrimeCurve(); - - $p = str_replace(["\r", "\n", ' ', "\t"], '', $p); - $curve->setModulo(new BigInteger($p)); - - $a = str_replace(["\r", "\n", ' ', "\t"], '', $a); - $b = str_replace(["\r", "\n", ' ', "\t"], '', $b); - $curve->setCoefficients( - new BigInteger($a), - new BigInteger($b) - ); - - $x = str_replace(["\r", "\n", ' ', "\t"], '', $x); - $y = str_replace(["\r", "\n", ' ', "\t"], '', $y); - $curve->setBasePoint( - new BigInteger($x), - new BigInteger($y) - ); - - $order = str_replace(["\r", "\n", ' ', "\t"], '', $order); - $curve->setOrder(new BigInteger($order)); - return $curve; - default: - throw new UnsupportedCurveException('Field Type of ' . $type . ' is not supported'); - } - } - - /** - * Sets the namespace. dsig11 is the most common one. - * - * Set to null to unset. Used only for creating public keys. - * - * @param string $namespace - */ - public static function setNamespace($namespace) - { - self::$namespace = $namespace; - } - - /** - * Uses the XML syntax specified in https://tools.ietf.org/html/rfc4050 - */ - public static function enableRFC4050Syntax() - { - self::$rfc4050 = true; - } - - /** - * Uses the XML syntax specified in https://www.w3.org/TR/xmldsig-core/#sec-ECParameters - */ - public static function disableRFC4050Syntax() - { - self::$rfc4050 = false; - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param array $options optional - * @return string - */ - public static function savePublicKey(BaseCurve $curve, array $publicKey, array $options = []) - { - self::initialize_static_variables(); - - if ($curve instanceof TwistedEdwardsCurve || $curve instanceof MontgomeryCurve) { - throw new UnsupportedCurveException('TwistedEdwards and Montgomery Curves are not supported'); - } - - if (empty(static::$namespace)) { - $pre = $post = ''; - } else { - $pre = static::$namespace . ':'; - $post = ':' . static::$namespace; - } - - if (self::$rfc4050) { - return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2001/04/xmldsig-more#">' . "\r\n" . - self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . - '<' . $pre . 'PublicKey>' . "\r\n" . - '<' . $pre . 'X Value="' . $publicKey[0] . '" />' . "\r\n" . - '<' . $pre . 'Y Value="' . $publicKey[1] . '" />' . "\r\n" . - '' . "\r\n" . - ''; - } - - $publicKey = "\4" . $publicKey[0]->toBytes() . $publicKey[1]->toBytes(); - - return '<' . $pre . 'ECDSAKeyValue xmlns' . $post . '="http://www.w3.org/2009/xmldsig11#">' . "\r\n" . - self::encodeXMLParameters($curve, $pre, $options) . "\r\n" . - '<' . $pre . 'PublicKey>' . Strings::base64_encode($publicKey) . '' . "\r\n" . - ''; - } - - /** - * Encode Parameters - * - * @param \phpseclib3\Crypt\EC\BaseCurves\Base $curve - * @param string $pre - * @param array $options optional - * @return string|false - */ - private static function encodeXMLParameters(BaseCurve $curve, $pre, array $options = []) - { - $result = self::encodeParameters($curve, true, $options); - - if (isset($result['namedCurve'])) { - $namedCurve = '<' . $pre . 'NamedCurve URI="urn:oid:' . self::$curveOIDs[$result['namedCurve']] . '" />'; - return self::$rfc4050 ? - '' . str_replace('URI', 'URN', $namedCurve) . '' : - $namedCurve; - } - - if (self::$rfc4050) { - $xml = '<' . $pre . 'ExplicitParams>' . "\r\n" . - '<' . $pre . 'FieldParams>' . "\r\n"; - $temp = $result['specifiedCurve']; - switch ($temp['fieldID']['fieldType']) { - case 'prime-field': - $xml .= '<' . $pre . 'PrimeFieldParamsType>' . "\r\n" . - '<' . $pre . 'P>' . $temp['fieldID']['parameters'] . '' . "\r\n" . - '' . "\r\n"; - $a = $curve->getA(); - $b = $curve->getB(); - list($x, $y) = $curve->getBasePoint(); - break; - default: - throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); - } - $xml .= '' . "\r\n" . - '<' . $pre . 'CurveParamsType>' . "\r\n" . - '<' . $pre . 'A>' . $a . '' . "\r\n" . - '<' . $pre . 'B>' . $b . '' . "\r\n" . - '' . "\r\n" . - '<' . $pre . 'BasePointParams>' . "\r\n" . - '<' . $pre . 'BasePoint>' . "\r\n" . - '<' . $pre . 'ECPointType>' . "\r\n" . - '<' . $pre . 'X>' . $x . '' . "\r\n" . - '<' . $pre . 'Y>' . $y . '' . "\r\n" . - '' . "\r\n" . - '' . "\r\n" . - '<' . $pre . 'Order>' . $curve->getOrder() . '' . "\r\n" . - '' . "\r\n" . - '' . "\r\n"; - - return $xml; - } - - if (isset($result['specifiedCurve'])) { - $xml = '<' . $pre . 'ECParameters>' . "\r\n" . - '<' . $pre . 'FieldID>' . "\r\n"; - $temp = $result['specifiedCurve']; - switch ($temp['fieldID']['fieldType']) { - case 'prime-field': - $xml .= '<' . $pre . 'Prime>' . "\r\n" . - '<' . $pre . 'P>' . Strings::base64_encode($temp['fieldID']['parameters']->toBytes()) . '' . "\r\n" . - '' . "\r\n" ; - break; - default: - throw new UnsupportedCurveException('Field Type of ' . $temp['fieldID']['fieldType'] . ' is not supported'); - } - $xml .= '' . "\r\n" . - '<' . $pre . 'Curve>' . "\r\n" . - '<' . $pre . 'A>' . Strings::base64_encode($temp['curve']['a']) . '' . "\r\n" . - '<' . $pre . 'B>' . Strings::base64_encode($temp['curve']['b']) . '' . "\r\n" . - '' . "\r\n" . - '<' . $pre . 'Base>' . Strings::base64_encode($temp['base']) . '' . "\r\n" . - '<' . $pre . 'Order>' . Strings::base64_encode($temp['order']) . '' . "\r\n" . - ''; - return $xml; - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php deleted file mode 100644 index 2be6ba5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Keys/libsodium.php +++ /dev/null @@ -1,116 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Keys; - -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Math\BigInteger; - -/** - * libsodium Key Handler - * - * @author Jim Wigginton - */ -abstract class libsodium -{ - use Common; - - /** - * Is invisible flag - * - */ - const IS_INVISIBLE = true; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - switch (strlen($key)) { - case 32: - $public = $key; - break; - case 64: - $private = substr($key, 0, 32); - $public = substr($key, -32); - break; - case 96: - $public = substr($key, -32); - if (substr($key, 32, 32) != $public) { - throw new \RuntimeException('Keys with 96 bytes should have the 2nd and 3rd set of 32 bytes match'); - } - $private = substr($key, 0, 32); - break; - default: - throw new \RuntimeException('libsodium keys need to either be 32 bytes long, 64 bytes long or 96 bytes long'); - } - - $curve = new Ed25519(); - $components = ['curve' => $curve]; - if (isset($private)) { - $arr = $curve->extractSecret($private); - $components['dA'] = $arr['dA']; - $components['secret'] = $arr['secret']; - } - $components['QA'] = isset($public) ? - self::extractPoint($public, $curve) : - $curve->multiplyPoint($curve->getBasePoint(), $components['dA']); - - return $components; - } - - /** - * Convert an EC public key to the appropriate format - * - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @return string - */ - public static function savePublicKey(Ed25519 $curve, array $publicKey) - { - return $curve->encodePoint($publicKey); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $privateKey - * @param \phpseclib3\Crypt\EC\Curves\Ed25519 $curve - * @param \phpseclib3\Math\Common\FiniteField\Integer[] $publicKey - * @param string $secret optional - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $privateKey, Ed25519 $curve, array $publicKey, $secret = null, $password = '') - { - if (!isset($secret)) { - throw new \RuntimeException('Private Key does not have a secret set'); - } - if (strlen($secret) != 32) { - throw new \RuntimeException('Private Key secret is not of the correct length'); - } - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('libsodium private keys do not support encryption'); - } - return $secret . $curve->encodePoint($publicKey); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php deleted file mode 100644 index d2a80a1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/ASN1.php +++ /dev/null @@ -1,62 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\File\ASN1 as Encoder; -use phpseclib3\File\ASN1\Maps\EcdsaSigValue; -use phpseclib3\Math\BigInteger; - -/** - * ASN1 Signature Handler - * - * @author Jim Wigginton - */ -abstract class ASN1 -{ - /** - * Loads a signature - * - * @param string $sig - * @return array - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $decoded = Encoder::decodeBER($sig); - if (empty($decoded)) { - return false; - } - $components = Encoder::asn1map($decoded[0], EcdsaSigValue::MAP); - - return $components; - } - - /** - * Returns a signature in the appropriate format - * - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - return Encoder::encodeDER(compact('r', 's'), EcdsaSigValue::MAP); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php deleted file mode 100644 index 69139da..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/IEEE.php +++ /dev/null @@ -1,66 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\Math\BigInteger; - -/** - * ASN1 Signature Handler - * - * @author Jim Wigginton - */ -abstract class IEEE -{ - /** - * Loads a signature - * - * @param string $sig - * @return array - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $len = strlen($sig); - if ($len & 1) { - return false; - } - - $r = new BigInteger(substr($sig, 0, $len >> 1), 256); - $s = new BigInteger(substr($sig, $len >> 1), 256); - - return compact('r', 's'); - } - - /** - * Returns a signature in the appropriate format - * - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @return string - */ - public static function save(BigInteger $r, BigInteger $s) - { - $r = $r->toBytes(); - $s = $s->toBytes(); - $len = max(strlen($r), strlen($s)); - return str_pad($r, $len, "\0", STR_PAD_LEFT) . str_pad($s, $len, "\0", STR_PAD_LEFT); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php deleted file mode 100644 index 7e4b47f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/Raw.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\Crypt\Common\Formats\Signature\Raw as Progenitor; - -/** - * Raw DSA Signature Handler - * - * @author Jim Wigginton - */ -abstract class Raw extends Progenitor -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php deleted file mode 100644 index e064442..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Formats/Signature/SSH2.php +++ /dev/null @@ -1,94 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC\Formats\Signature; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; - -/** - * SSH2 Signature Handler - * - * @author Jim Wigginton - */ -abstract class SSH2 -{ - /** - * Loads a signature - * - * @param string $sig - * @return mixed - */ - public static function load($sig) - { - if (!is_string($sig)) { - return false; - } - - $result = Strings::unpackSSH2('ss', $sig); - if ($result === false) { - return false; - } - list($type, $blob) = $result; - switch ($type) { - // see https://tools.ietf.org/html/rfc5656#section-3.1.2 - case 'ecdsa-sha2-nistp256': - case 'ecdsa-sha2-nistp384': - case 'ecdsa-sha2-nistp521': - break; - default: - return false; - } - - $result = Strings::unpackSSH2('ii', $blob); - if ($result === false) { - return false; - } - - return [ - 'r' => $result[0], - 's' => $result[1] - ]; - } - - /** - * Returns a signature in the appropriate format - * - * @param \phpseclib3\Math\BigInteger $r - * @param \phpseclib3\Math\BigInteger $s - * @param string $curve - * @return string - */ - public static function save(BigInteger $r, BigInteger $s, $curve) - { - switch ($curve) { - case 'secp256r1': - $curve = 'nistp256'; - break; - case 'secp384r1': - $curve = 'nistp384'; - break; - case 'secp521r1': - $curve = 'nistp521'; - break; - default: - return false; - } - - $blob = Strings::packSSH2('ii', $r, $s); - - return Strings::packSSH2('ss', 'ecdsa-sha2-' . $curve, $blob); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php deleted file mode 100644 index c0ed64a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/Parameters.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC; - -use phpseclib3\Crypt\EC; - -/** - * EC Parameters - * - * @author Jim Wigginton - */ -final class Parameters extends EC -{ - /** - * Returns the parameters - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type = 'PKCS1', array $options = []) - { - $type = self::validatePlugin('Keys', 'PKCS1', 'saveParameters'); - - return $type::saveParameters($this->curve, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php deleted file mode 100644 index 462ea1a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PrivateKey.php +++ /dev/null @@ -1,256 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\Curves\Curve25519; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; -use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Crypt\Hash; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\Math\BigInteger; - -/** - * EC Private Key - * - * @author Jim Wigginton - */ -final class PrivateKey extends EC implements Common\PrivateKey -{ - use Common\Traits\PasswordProtected; - - /** - * Private Key dA - * - * sign() converts this to a BigInteger so one might wonder why this is a FiniteFieldInteger instead of - * a BigInteger. That's because a FiniteFieldInteger, when converted to a byte string, is null padded by - * a certain amount whereas a BigInteger isn't. - * - * @var object - */ - protected $dA; - - /** - * @var string - */ - protected $secret; - - /** - * Multiplies an encoded point by the private key - * - * Used by ECDH - * - * @param string $coordinates - * @return string - */ - public function multiply($coordinates) - { - if ($this->curve instanceof MontgomeryCurve) { - if ($this->curve instanceof Curve25519 && self::$engines['libsodium']) { - return sodium_crypto_scalarmult($this->dA->toBytes(), $coordinates); - } - - $point = [$this->curve->convertInteger(new BigInteger(strrev($coordinates), 256))]; - $point = $this->curve->multiplyPoint($point, $this->dA); - return strrev($point[0]->toBytes(true)); - } - if (!$this->curve instanceof TwistedEdwardsCurve) { - $coordinates = "\0$coordinates"; - } - $point = PKCS1::extractPoint($coordinates, $this->curve); - $point = $this->curve->multiplyPoint($point, $this->dA); - if ($this->curve instanceof TwistedEdwardsCurve) { - return $this->curve->encodePoint($point); - } - if (empty($point)) { - throw new \RuntimeException('The infinity point is invalid'); - } - return "\4" . $point[0]->toBytes(true) . $point[1]->toBytes(true); - } - - /** - * Create a signature - * - * @see self::verify() - * @param string $message - * @return mixed - */ - public function sign($message) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - - $dA = $this->dA; - $order = $this->curve->getOrder(); - - $shortFormat = $this->shortFormat; - $format = $this->sigFormat; - if ($format === false) { - return false; - } - - if ($this->curve instanceof TwistedEdwardsCurve) { - if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { - $result = sodium_crypto_sign_detached($message, $this->withPassword()->toString('libsodium')); - return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $result) : $result; - } - - // contexts (Ed25519ctx) are supported but prehashing (Ed25519ph) is not. - // quoting https://tools.ietf.org/html/rfc8032#section-8.5 , - // "The Ed25519ph and Ed448ph variants ... SHOULD NOT be used" - $A = $this->curve->encodePoint($this->QA); - $curve = $this->curve; - $hash = new Hash($curve::HASH); - - $secret = substr($hash->hash($this->secret), $curve::SIZE); - - if ($curve instanceof Ed25519) { - $dom = !isset($this->context) ? '' : - 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; - } else { - $context = isset($this->context) ? $this->context : ''; - $dom = 'SigEd448' . "\0" . chr(strlen($context)) . $context; - } - // SHA-512(dom2(F, C) || prefix || PH(M)) - $r = $hash->hash($dom . $secret . $message); - $r = strrev($r); - $r = new BigInteger($r, 256); - list(, $r) = $r->divide($order); - $R = $curve->multiplyPoint($curve->getBasePoint(), $r); - $R = $curve->encodePoint($R); - $k = $hash->hash($dom . $R . $A . $message); - $k = strrev($k); - $k = new BigInteger($k, 256); - list(, $k) = $k->divide($order); - $S = $k->multiply($dA)->add($r); - list(, $S) = $S->divide($order); - $S = str_pad(strrev($S->toBytes()), $curve::SIZE, "\0"); - return $shortFormat == 'SSH2' ? Strings::packSSH2('ss', 'ssh-' . strtolower($this->getCurve()), $R . $S) : $R . $S; - } - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $signature = ''; - // altho PHP's OpenSSL bindings only supported EC key creation in PHP 7.1 they've long - // supported signing / verification - // we use specified curves to avoid issues with OpenSSL possibly not supporting a given named curve; - // doing this may mean some curve-specific optimizations can't be used but idk if OpenSSL even - // has curve-specific optimizations - $result = openssl_sign($message, $signature, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); - - if ($result) { - if ($shortFormat == 'ASN1') { - return $signature; - } - - extract(ASN1Signature::load($signature)); - - return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); - } - } - - $e = $this->hash->hash($message); - $e = new BigInteger($e, 256); - - $Ln = $this->hash->getLength() - $order->getLength(); - $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; - - while (true) { - $k = BigInteger::randomRange(self::$one, $order->subtract(self::$one)); - list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); - $x = $x->toBigInteger(); - list(, $r) = $x->divide($order); - if ($r->equals(self::$zero)) { - continue; - } - $kinv = $k->modInverse($order); - $temp = $z->add($dA->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($order); - if (!$s->equals(self::$zero)) { - break; - } - } - - // the following is an RFC6979 compliant implementation of deterministic ECDSA - // it's unused because it's mainly intended for use when a good CSPRNG isn't - // available. if phpseclib's CSPRNG isn't good then even key generation is - // suspect - /* - // if this were actually being used it'd probably be better if this lived in load() and createKey() - $this->q = $this->curve->getOrder(); - $dA = $this->dA->toBigInteger(); - $this->x = $dA; - - $h1 = $this->hash->hash($message); - $k = $this->computek($h1); - list($x, $y) = $this->curve->multiplyPoint($this->curve->getBasePoint(), $k); - $x = $x->toBigInteger(); - list(, $r) = $x->divide($this->q); - $kinv = $k->modInverse($this->q); - $h1 = $this->bits2int($h1); - $temp = $h1->add($dA->multiply($r)); - $temp = $kinv->multiply($temp); - list(, $s) = $temp->divide($this->q); - */ - - return $shortFormat == 'SSH2' ? $format::save($r, $s, $this->getCurve()) : $format::save($r, $s); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePrivateKey'); - - return $type::savePrivateKey($this->dA, $this->curve, $this->QA, $this->secret, $this->password, $options); - } - - /** - * Returns the public key - * - * @see self::getPrivateKey() - * @return mixed - */ - public function getPublicKey() - { - $format = 'PKCS8'; - if ($this->curve instanceof MontgomeryCurve) { - $format = 'MontgomeryPublic'; - } - - $type = self::validatePlugin('Keys', $format, 'savePublicKey'); - - $key = $type::savePublicKey($this->curve, $this->QA); - $key = EC::loadFormat($format, $key); - if ($this->curve instanceof MontgomeryCurve) { - return $key; - } - $key = $key - ->withHash($this->hash->getHash()) - ->withSignatureFormat($this->shortFormat); - if ($this->curve instanceof TwistedEdwardsCurve) { - $key = $key->withContext($this->context); - } - return $key; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php deleted file mode 100644 index 4558ce3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/EC/PublicKey.php +++ /dev/null @@ -1,172 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\EC; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\EC\BaseCurves\Montgomery as MontgomeryCurve; -use phpseclib3\Crypt\EC\BaseCurves\TwistedEdwards as TwistedEdwardsCurve; -use phpseclib3\Crypt\EC\Curves\Ed25519; -use phpseclib3\Crypt\EC\Formats\Keys\PKCS1; -use phpseclib3\Crypt\EC\Formats\Signature\ASN1 as ASN1Signature; -use phpseclib3\Crypt\Hash; -use phpseclib3\Exception\UnsupportedOperationException; -use phpseclib3\Math\BigInteger; - -/** - * EC Public Key - * - * @author Jim Wigginton - */ -final class PublicKey extends EC implements Common\PublicKey -{ - use Common\Traits\Fingerprint; - - /** - * Verify a signature - * - * @see self::verify() - * @param string $message - * @param string $signature - * @return mixed - */ - public function verify($message, $signature) - { - if ($this->curve instanceof MontgomeryCurve) { - throw new UnsupportedOperationException('Montgomery Curves cannot be used to create signatures'); - } - - $shortFormat = $this->shortFormat; - $format = $this->sigFormat; - if ($format === false) { - return false; - } - - $order = $this->curve->getOrder(); - - if ($this->curve instanceof TwistedEdwardsCurve) { - if ($shortFormat == 'SSH2') { - list(, $signature) = Strings::unpackSSH2('ss', $signature); - } - - if ($this->curve instanceof Ed25519 && self::$engines['libsodium'] && !isset($this->context)) { - return sodium_crypto_sign_verify_detached($signature, $message, $this->toString('libsodium')); - } - - $curve = $this->curve; - if (strlen($signature) != 2 * $curve::SIZE) { - return false; - } - - $R = substr($signature, 0, $curve::SIZE); - $S = substr($signature, $curve::SIZE); - - try { - $R = PKCS1::extractPoint($R, $curve); - $R = $this->curve->convertToInternal($R); - } catch (\Exception $e) { - return false; - } - - $S = strrev($S); - $S = new BigInteger($S, 256); - - if ($S->compare($order) >= 0) { - return false; - } - - $A = $curve->encodePoint($this->QA); - - if ($curve instanceof Ed25519) { - $dom2 = !isset($this->context) ? '' : - 'SigEd25519 no Ed25519 collisions' . "\0" . chr(strlen($this->context)) . $this->context; - } else { - $context = isset($this->context) ? $this->context : ''; - $dom2 = 'SigEd448' . "\0" . chr(strlen($context)) . $context; - } - - $hash = new Hash($curve::HASH); - $k = $hash->hash($dom2 . substr($signature, 0, $curve::SIZE) . $A . $message); - $k = strrev($k); - $k = new BigInteger($k, 256); - list(, $k) = $k->divide($order); - - $qa = $curve->convertToInternal($this->QA); - - $lhs = $curve->multiplyPoint($curve->getBasePoint(), $S); - $rhs = $curve->multiplyPoint($qa, $k); - $rhs = $curve->addPoint($rhs, $R); - $rhs = $curve->convertToAffine($rhs); - - return $lhs[0]->equals($rhs[0]) && $lhs[1]->equals($rhs[1]); - } - - $params = $format::load($signature); - if ($params === false || count($params) != 2) { - return false; - } - extract($params); - - if (self::$engines['OpenSSL'] && in_array($this->hash->getHash(), openssl_get_md_methods())) { - $sig = $format != 'ASN1' ? ASN1Signature::save($r, $s) : $signature; - - $result = openssl_verify($message, $sig, $this->toString('PKCS8', ['namedCurve' => false]), $this->hash->getHash()); - - if ($result != -1) { - return (bool) $result; - } - } - - $n_1 = $order->subtract(self::$one); - if (!$r->between(self::$one, $n_1) || !$s->between(self::$one, $n_1)) { - return false; - } - - $e = $this->hash->hash($message); - $e = new BigInteger($e, 256); - - $Ln = $this->hash->getLength() - $order->getLength(); - $z = $Ln > 0 ? $e->bitwise_rightShift($Ln) : $e; - - $w = $s->modInverse($order); - list(, $u1) = $z->multiply($w)->divide($order); - list(, $u2) = $r->multiply($w)->divide($order); - - $u1 = $this->curve->convertInteger($u1); - $u2 = $this->curve->convertInteger($u2); - - list($x1, $y1) = $this->curve->multiplyAddPoints( - [$this->curve->getBasePoint(), $this->QA], - [$u1, $u2] - ); - - $x1 = $x1->toBigInteger(); - list(, $x1) = $x1->divide($order); - - return $x1->equals($r); - } - - /** - * Returns the public key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - return $type::savePublicKey($this->curve, $this->QA, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php deleted file mode 100644 index 0e02544..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Hash.php +++ /dev/null @@ -1,1455 +0,0 @@ - - * setKey('abcdefg'); - * - * echo base64_encode($hash->hash('abcdefg')); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2015 Jim Wigginton - * @author Andreas Fischer - * @copyright 2015 Andreas Fischer - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\PrimeField; - -/** - * @author Jim Wigginton - * @author Andreas Fischer - */ -class Hash -{ - /** - * Padding Types - * - */ - const PADDING_KECCAK = 1; - - /** - * Padding Types - * - */ - const PADDING_SHA3 = 2; - - /** - * Padding Types - * - */ - const PADDING_SHAKE = 3; - - /** - * Padding Type - * - * Only used by SHA3 - * - * @var int - */ - private $paddingType = 0; - - /** - * Hash Parameter - * - * @see self::setHash() - * @var int - */ - private $hashParam; - - /** - * Byte-length of hash output (Internal HMAC) - * - * @see self::setHash() - * @var int - */ - private $length; - - /** - * Hash Algorithm - * - * @see self::setHash() - * @var string - */ - private $algo; - - /** - * Key - * - * @see self::setKey() - * @var string - */ - private $key = false; - - /** - * Nonce - * - * @see self::setNonce() - * @var string - */ - private $nonce = false; - - /** - * Hash Parameters - * - * @var array - */ - private $parameters = []; - - /** - * Computed Key - * - * @see self::_computeKey() - * @var string - */ - private $computedKey = false; - - /** - * Outer XOR (Internal HMAC) - * - * Used only for sha512/* - * - * @see self::hash() - * @var string - */ - private $opad; - - /** - * Inner XOR (Internal HMAC) - * - * Used only for sha512/* - * - * @see self::hash() - * @var string - */ - private $ipad; - - /** - * Recompute AES Key - * - * Used only for umac - * - * @see self::hash() - * @var boolean - */ - private $recomputeAESKey; - - /** - * umac cipher object - * - * @see self::hash() - * @var \phpseclib3\Crypt\AES - */ - private $c; - - /** - * umac pad - * - * @see self::hash() - * @var string - */ - private $pad; - - /** - * Block Size - * - * @var int - */ - private $blockSize; - - /**#@+ - * UMAC variables - * - * @var PrimeField - */ - private static $factory36; - private static $factory64; - private static $factory128; - private static $offset64; - private static $offset128; - private static $marker64; - private static $marker128; - private static $maxwordrange64; - private static $maxwordrange128; - /**#@-*/ - - /** - * Default Constructor. - * - * @param string $hash - */ - public function __construct($hash = 'sha256') - { - $this->setHash($hash); - } - - /** - * Sets the key for HMACs - * - * Keys can be of any length. - * - * @param string $key - */ - public function setKey($key = false) - { - $this->key = $key; - $this->computeKey(); - $this->recomputeAESKey = true; - } - - /** - * Sets the nonce for UMACs - * - * Keys can be of any length. - * - * @param string $nonce - */ - public function setNonce($nonce = false) - { - switch (true) { - case !is_string($nonce): - case strlen($nonce) > 0 && strlen($nonce) <= 16: - $this->recomputeAESKey = true; - $this->nonce = $nonce; - return; - } - - throw new \LengthException('The nonce length must be between 1 and 16 bytes, inclusive'); - } - - /** - * Pre-compute the key used by the HMAC - * - * Quoting http://tools.ietf.org/html/rfc2104#section-2, "Applications that use keys longer than B bytes - * will first hash the key using H and then use the resultant L byte string as the actual key to HMAC." - * - * As documented in https://www.reddit.com/r/PHP/comments/9nct2l/symfonypolyfill_hash_pbkdf2_correct_fix_for/ - * when doing an HMAC multiple times it's faster to compute the hash once instead of computing it during - * every call - * - */ - private function computeKey() - { - if ($this->key === false) { - $this->computedKey = false; - return; - } - - if (strlen($this->key) <= $this->getBlockLengthInBytes()) { - $this->computedKey = $this->key; - return; - } - - $this->computedKey = is_array($this->algo) ? - call_user_func($this->algo, $this->key) : - hash($this->algo, $this->key, true); - } - - /** - * Gets the hash function. - * - * As set by the constructor or by the setHash() method. - * - * @return string - */ - public function getHash() - { - return $this->hashParam; - } - - /** - * Sets the hash function. - * - * @param string $hash - */ - public function setHash($hash) - { - $this->hashParam = $hash = strtolower($hash); - switch ($hash) { - case 'umac-32': - case 'umac-64': - case 'umac-96': - case 'umac-128': - $this->blockSize = 128; - $this->length = abs(substr($hash, -3)) >> 3; - $this->algo = 'umac'; - return; - case 'md2-96': - case 'md5-96': - case 'sha1-96': - case 'sha224-96': - case 'sha256-96': - case 'sha384-96': - case 'sha512-96': - case 'sha512/224-96': - case 'sha512/256-96': - $hash = substr($hash, 0, -3); - $this->length = 12; // 96 / 8 = 12 - break; - case 'md2': - case 'md5': - $this->length = 16; - break; - case 'sha1': - $this->length = 20; - break; - case 'sha224': - case 'sha512/224': - case 'sha3-224': - $this->length = 28; - break; - case 'keccak256': - $this->paddingType = self::PADDING_KECCAK; - // fall-through - case 'sha256': - case 'sha512/256': - case 'sha3-256': - $this->length = 32; - break; - case 'sha384': - case 'sha3-384': - $this->length = 48; - break; - case 'sha512': - case 'sha3-512': - $this->length = 64; - break; - default: - if (preg_match('#^(shake(?:128|256))-(\d+)$#', $hash, $matches)) { - $this->paddingType = self::PADDING_SHAKE; - $hash = $matches[1]; - $this->length = $matches[2] >> 3; - } else { - throw new UnsupportedAlgorithmException( - "$hash is not a supported algorithm" - ); - } - } - - switch ($hash) { - case 'md2': - case 'md2-96': - $this->blockSize = 128; - break; - case 'md5-96': - case 'sha1-96': - case 'sha224-96': - case 'sha256-96': - case 'md5': - case 'sha1': - case 'sha224': - case 'sha256': - $this->blockSize = 512; - break; - case 'sha3-224': - $this->blockSize = 1152; // 1600 - 2*224 - break; - case 'sha3-256': - case 'shake256': - case 'keccak256': - $this->blockSize = 1088; // 1600 - 2*256 - break; - case 'sha3-384': - $this->blockSize = 832; // 1600 - 2*384 - break; - case 'sha3-512': - $this->blockSize = 576; // 1600 - 2*512 - break; - case 'shake128': - $this->blockSize = 1344; // 1600 - 2*128 - break; - default: - $this->blockSize = 1024; - } - - if (in_array(substr($hash, 0, 5), ['sha3-', 'shake', 'kecca'])) { - // PHP 7.1.0 introduced support for "SHA3 fixed mode algorithms": - // http://php.net/ChangeLog-7.php#7.1.0 - if (version_compare(PHP_VERSION, '7.1.0') < 0 || substr($hash, 0, 5) != 'sha3-') { - //preg_match('#(\d+)$#', $hash, $matches); - //$this->parameters['capacity'] = 2 * $matches[1]; // 1600 - $this->blockSize - //$this->parameters['rate'] = 1600 - $this->parameters['capacity']; // == $this->blockSize - if (!$this->paddingType) { - $this->paddingType = self::PADDING_SHA3; - } - $this->parameters = [ - 'capacity' => 1600 - $this->blockSize, - 'rate' => $this->blockSize, - 'length' => $this->length, - 'padding' => $this->paddingType - ]; - $hash = ['phpseclib3\Crypt\Hash', PHP_INT_SIZE == 8 ? 'sha3_64' : 'sha3_32']; - } - } - - if ($hash == 'sha512/224' || $hash == 'sha512/256') { - // PHP 7.1.0 introduced sha512/224 and sha512/256 support: - // http://php.net/ChangeLog-7.php#7.1.0 - if (version_compare(PHP_VERSION, '7.1.0') < 0) { - // from http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf#page=24 - $initial = $hash == 'sha512/256' ? - [ - '22312194FC2BF72C', '9F555FA3C84C64C2', '2393B86B6F53B151', '963877195940EABD', - '96283EE2A88EFFE3', 'BE5E1E2553863992', '2B0199FC2C85B8AA', '0EB72DDC81C52CA2' - ] : - [ - '8C3D37C819544DA2', '73E1996689DCD4D6', '1DFAB7AE32FF9C82', '679DD514582F9FCF', - '0F6D2B697BD44DA8', '77E36F7304C48942', '3F9D85A86A1D36C8', '1112E6AD91D692A1' - ]; - for ($i = 0; $i < 8; $i++) { - $initial[$i] = new BigInteger($initial[$i], 16); - $initial[$i]->setPrecision(64); - } - - $this->parameters = compact('initial'); - - $hash = ['phpseclib3\Crypt\Hash', 'sha512']; - } - } - - if (is_array($hash)) { - $b = $this->blockSize >> 3; - $this->ipad = str_repeat(chr(0x36), $b); - $this->opad = str_repeat(chr(0x5C), $b); - } - - $this->algo = $hash; - - $this->computeKey(); - } - - /** - * KDF: Key-Derivation Function - * - * The key-derivation function generates pseudorandom bits used to key the hash functions. - * - * @param int $index a non-negative integer less than 2^64 - * @param int $numbytes a non-negative integer less than 2^64 - * @return string string of length numbytes bytes - */ - private function kdf($index, $numbytes) - { - $this->c->setIV(pack('N4', 0, $index, 0, 1)); - - return $this->c->encrypt(str_repeat("\0", $numbytes)); - } - - /** - * PDF Algorithm - * - * @return string string of length taglen bytes. - */ - private function pdf() - { - $k = $this->key; - $nonce = $this->nonce; - $taglen = $this->length; - - // - // Extract and zero low bit(s) of Nonce if needed - // - if ($taglen <= 8) { - $last = strlen($nonce) - 1; - $mask = $taglen == 4 ? "\3" : "\1"; - $index = $nonce[$last] & $mask; - $nonce[$last] = $nonce[$last] ^ $index; - } - - // - // Make Nonce BLOCKLEN bytes by appending zeroes if needed - // - $nonce = str_pad($nonce, 16, "\0"); - - // - // Generate subkey, encipher and extract indexed substring - // - $kp = $this->kdf(0, 16); - $c = new AES('ctr'); - $c->disablePadding(); - $c->setKey($kp); - $c->setIV($nonce); - $t = $c->encrypt("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"); - - // we could use ord() but per https://paragonie.com/blog/2016/06/constant-time-encoding-boring-cryptography-rfc-4648-and-you - // unpack() doesn't leak timing info - return $taglen <= 8 ? - substr($t, unpack('C', $index)[1] * $taglen, $taglen) : - substr($t, 0, $taglen); - } - - /** - * UHASH Algorithm - * - * @param string $m string of length less than 2^67 bits. - * @param int $taglen the integer 4, 8, 12 or 16. - * @return string string of length taglen bytes. - */ - private function uhash($m, $taglen) - { - // - // One internal iteration per 4 bytes of output - // - $iters = $taglen >> 2; - - // - // Define total key needed for all iterations using KDF. - // L1Key reuses most key material between iterations. - // - //$L1Key = $this->kdf(1, 1024 + ($iters - 1) * 16); - $L1Key = $this->kdf(1, (1024 + ($iters - 1)) * 16); - $L2Key = $this->kdf(2, $iters * 24); - $L3Key1 = $this->kdf(3, $iters * 64); - $L3Key2 = $this->kdf(4, $iters * 4); - - // - // For each iteration, extract key and do three-layer hash. - // If bytelength(M) <= 1024, then skip L2-HASH. - // - $y = ''; - for ($i = 0; $i < $iters; $i++) { - $L1Key_i = substr($L1Key, $i * 16, 1024); - $L2Key_i = substr($L2Key, $i * 24, 24); - $L3Key1_i = substr($L3Key1, $i * 64, 64); - $L3Key2_i = substr($L3Key2, $i * 4, 4); - - $a = self::L1Hash($L1Key_i, $m); - $b = strlen($m) <= 1024 ? "\0\0\0\0\0\0\0\0$a" : self::L2Hash($L2Key_i, $a); - $c = self::L3Hash($L3Key1_i, $L3Key2_i, $b); - $y .= $c; - } - - return $y; - } - - /** - * L1-HASH Algorithm - * - * The first-layer hash breaks the message into 1024-byte chunks and - * hashes each with a function called NH. Concatenating the results - * forms a string, which is up to 128 times shorter than the original. - * - * @param string $k string of length 1024 bytes. - * @param string $m string of length less than 2^67 bits. - * @return string string of length (8 * ceil(bitlength(M)/8192)) bytes. - */ - private static function L1Hash($k, $m) - { - // - // Break M into 1024 byte chunks (final chunk may be shorter) - // - $m = str_split($m, 1024); - - // - // For each chunk, except the last: endian-adjust, NH hash - // and add bit-length. Use results to build Y. - // - $length = new BigInteger(1024 * 8); - $y = ''; - for ($i = 0; $i < count($m) - 1; $i++) { - $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP - $y .= static::nh($k, $m[$i], $length); - } - - // - // For the last chunk: pad to 32-byte boundary, endian-adjust, - // NH hash and add bit-length. Concatenate the result to Y. - // - $length = count($m) ? strlen($m[$i]) : 0; - $pad = 32 - ($length % 32); - $pad = max(32, $length + $pad % 32); - $m[$i] = str_pad(isset($m[$i]) ? $m[$i] : '', $pad, "\0"); // zeropad - $m[$i] = pack('N*', ...unpack('V*', $m[$i])); // ENDIAN-SWAP - - $y .= static::nh($k, $m[$i], new BigInteger($length * 8)); - - return $y; - } - - /** - * NH Algorithm - * - * @param string $k string of length 1024 bytes. - * @param string $m string with length divisible by 32 bytes. - * @return string string of length 8 bytes. - */ - private static function nh($k, $m, $length) - { - $toUInt32 = function ($x) { - $x = new BigInteger($x, 256); - $x->setPrecision(32); - return $x; - }; - - // - // Break M and K into 4-byte chunks - // - //$t = strlen($m) >> 2; - $m = str_split($m, 4); - $t = count($m); - $k = str_split($k, 4); - $k = array_pad(array_slice($k, 0, $t), $t, 0); - - $m = array_map($toUInt32, $m); - $k = array_map($toUInt32, $k); - - // - // Perform NH hash on the chunks, pairing words for multiplication - // which are 4 apart to accommodate vector-parallelism. - // - $y = new BigInteger(); - $y->setPrecision(64); - $i = 0; - while ($i < $t) { - $temp = $m[$i]->add($k[$i]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 4]->add($k[$i + 4])); - $y = $y->add($temp); - - $temp = $m[$i + 1]->add($k[$i + 1]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 5]->add($k[$i + 5])); - $y = $y->add($temp); - - $temp = $m[$i + 2]->add($k[$i + 2]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 6]->add($k[$i + 6])); - $y = $y->add($temp); - - $temp = $m[$i + 3]->add($k[$i + 3]); - $temp->setPrecision(64); - $temp = $temp->multiply($m[$i + 7]->add($k[$i + 7])); - $y = $y->add($temp); - - $i += 8; - } - - return $y->add($length)->toBytes(); - } - - /** - * L2-HASH: Second-Layer Hash - * - * The second-layer rehashes the L1-HASH output using a polynomial hash - * called POLY. If the L1-HASH output is long, then POLY is called once - * on a prefix of the L1-HASH output and called using different settings - * on the remainder. (This two-step hashing of the L1-HASH output is - * needed only if the message length is greater than 16 megabytes.) - * Careful implementation of POLY is necessary to avoid a possible - * timing attack (see Section 6.6 for more information). - * - * @param string $k string of length 24 bytes. - * @param string $m string of length less than 2^64 bytes. - * @return string string of length 16 bytes. - */ - private static function L2Hash($k, $m) - { - // - // Extract keys and restrict to special key-sets - // - $k64 = $k & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; - $k64 = new BigInteger($k64, 256); - $k128 = substr($k, 8) & "\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF\x01\xFF\xFF\xFF"; - $k128 = new BigInteger($k128, 256); - - // - // If M is no more than 2^17 bytes, hash under 64-bit prime, - // otherwise, hash first 2^17 bytes under 64-bit prime and - // remainder under 128-bit prime. - // - if (strlen($m) <= 0x20000) { // 2^14 64-bit words - $y = self::poly(64, self::$maxwordrange64, $k64, $m); - } else { - $m_1 = substr($m, 0, 0x20000); // 1 << 17 - $m_2 = substr($m, 0x20000) . "\x80"; - $length = strlen($m_2); - $pad = 16 - ($length % 16); - $pad %= 16; - $m_2 = str_pad($m_2, $length + $pad, "\0"); // zeropad - $y = self::poly(64, self::$maxwordrange64, $k64, $m_1); - $y = str_pad($y, 16, "\0", STR_PAD_LEFT); - $y = self::poly(128, self::$maxwordrange128, $k128, $y . $m_2); - } - - return str_pad($y, 16, "\0", STR_PAD_LEFT); - } - - /** - * POLY Algorithm - * - * @param int $wordbits the integer 64 or 128. - * @param BigInteger $maxwordrange positive integer less than 2^wordbits. - * @param BigInteger $k integer in the range 0 ... prime(wordbits) - 1. - * @param string $m string with length divisible by (wordbits / 8) bytes. - * @return integer in the range 0 ... prime(wordbits) - 1. - */ - private static function poly($wordbits, $maxwordrange, $k, $m) - { - // - // Define constants used for fixing out-of-range words - // - $wordbytes = $wordbits >> 3; - if ($wordbits == 128) { - $factory = self::$factory128; - $offset = self::$offset128; - $marker = self::$marker128; - } else { - $factory = self::$factory64; - $offset = self::$offset64; - $marker = self::$marker64; - } - - $k = $factory->newInteger($k); - - // - // Break M into chunks of length wordbytes bytes - // - $m_i = str_split($m, $wordbytes); - - // - // Each input word m is compared with maxwordrange. If not smaller - // then 'marker' and (m - offset), both in range, are hashed. - // - $y = $factory->newInteger(new BigInteger(1)); - foreach ($m_i as $m) { - $m = $factory->newInteger(new BigInteger($m, 256)); - if ($m->compare($maxwordrange) >= 0) { - $y = $k->multiply($y)->add($marker); - $y = $k->multiply($y)->add($m->subtract($offset)); - } else { - $y = $k->multiply($y)->add($m); - } - } - - return $y->toBytes(); - } - - /** - * L3-HASH: Third-Layer Hash - * - * The output from L2-HASH is 16 bytes long. This final hash function - * hashes the 16-byte string to a fixed length of 4 bytes. - * - * @param string $k1 string of length 64 bytes. - * @param string $k2 string of length 4 bytes. - * @param string $m string of length 16 bytes. - * @return string string of length 4 bytes. - */ - private static function L3Hash($k1, $k2, $m) - { - $factory = self::$factory36; - - $y = $factory->newInteger(new BigInteger()); - for ($i = 0; $i < 8; $i++) { - $m_i = $factory->newInteger(new BigInteger(substr($m, 2 * $i, 2), 256)); - $k_i = $factory->newInteger(new BigInteger(substr($k1, 8 * $i, 8), 256)); - $y = $y->add($m_i->multiply($k_i)); - } - $y = str_pad(substr($y->toBytes(), -4), 4, "\0", STR_PAD_LEFT); - $y = $y ^ $k2; - - return $y; - } - - /** - * Compute the Hash / HMAC / UMAC. - * - * @param string $text - * @return string - */ - public function hash($text) - { - $algo = $this->algo; - if ($algo == 'umac') { - if ($this->recomputeAESKey) { - if (!is_string($this->nonce)) { - throw new InsufficientSetupException('No nonce has been set'); - } - if (!is_string($this->key)) { - throw new InsufficientSetupException('No key has been set'); - } - if (strlen($this->key) != 16) { - throw new \LengthException('Key must be 16 bytes long'); - } - - if (!isset(self::$maxwordrange64)) { - $one = new BigInteger(1); - - $prime36 = new BigInteger("\x00\x00\x00\x0F\xFF\xFF\xFF\xFB", 256); - self::$factory36 = new PrimeField($prime36); - - $prime64 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xC5", 256); - self::$factory64 = new PrimeField($prime64); - - $prime128 = new BigInteger("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x61", 256); - self::$factory128 = new PrimeField($prime128); - - self::$offset64 = new BigInteger("\1\0\0\0\0\0\0\0\0", 256); - self::$offset64 = self::$factory64->newInteger(self::$offset64->subtract($prime64)); - self::$offset128 = new BigInteger("\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 256); - self::$offset128 = self::$factory128->newInteger(self::$offset128->subtract($prime128)); - - self::$marker64 = self::$factory64->newInteger($prime64->subtract($one)); - self::$marker128 = self::$factory128->newInteger($prime128->subtract($one)); - - $maxwordrange64 = $one->bitwise_leftShift(64)->subtract($one->bitwise_leftShift(32)); - self::$maxwordrange64 = self::$factory64->newInteger($maxwordrange64); - - $maxwordrange128 = $one->bitwise_leftShift(128)->subtract($one->bitwise_leftShift(96)); - self::$maxwordrange128 = self::$factory128->newInteger($maxwordrange128); - } - - $this->c = new AES('ctr'); - $this->c->disablePadding(); - $this->c->setKey($this->key); - - $this->pad = $this->pdf(); - - $this->recomputeAESKey = false; - } - - $hashedmessage = $this->uhash($text, $this->length); - return $hashedmessage ^ $this->pad; - } - - if (is_array($algo)) { - if (empty($this->key) || !is_string($this->key)) { - return substr($algo($text, ...array_values($this->parameters)), 0, $this->length); - } - - // SHA3 HMACs are discussed at https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=30 - - $key = str_pad($this->computedKey, $b, chr(0)); - $temp = $this->ipad ^ $key; - $temp .= $text; - $temp = substr($algo($temp, ...array_values($this->parameters)), 0, $this->length); - $output = $this->opad ^ $key; - $output .= $temp; - $output = $algo($output, ...array_values($this->parameters)); - - return substr($output, 0, $this->length); - } - - $output = !empty($this->key) || is_string($this->key) ? - hash_hmac($algo, $text, $this->computedKey, true) : - hash($algo, $text, true); - - return strlen($output) > $this->length - ? substr($output, 0, $this->length) - : $output; - } - - /** - * Returns the hash length (in bits) - * - * @return int - */ - public function getLength() - { - return $this->length << 3; - } - - /** - * Returns the hash length (in bytes) - * - * @return int - */ - public function getLengthInBytes() - { - return $this->length; - } - - /** - * Returns the block length (in bits) - * - * @return int - */ - public function getBlockLength() - { - return $this->blockSize; - } - - /** - * Returns the block length (in bytes) - * - * @return int - */ - public function getBlockLengthInBytes() - { - return $this->blockSize >> 3; - } - - /** - * Pads SHA3 based on the mode - * - * @param int $padLength - * @param int $padType - * @return string - */ - private static function sha3_pad($padLength, $padType) - { - switch ($padType) { - case self::PADDING_KECCAK: - $temp = chr(0x01) . str_repeat("\0", $padLength - 1); - $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); - return $temp; - case self::PADDING_SHAKE: - $temp = chr(0x1F) . str_repeat("\0", $padLength - 1); - $temp[$padLength - 1] = $temp[$padLength - 1] | chr(0x80); - return $temp; - //case self::PADDING_SHA3: - default: - // from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf#page=36 - return $padLength == 1 ? chr(0x86) : chr(0x06) . str_repeat("\0", $padLength - 2) . chr(0x80); - } - } - - /** - * Pure-PHP 32-bit implementation of SHA3 - * - * Whereas BigInteger.php's 32-bit engine works on PHP 64-bit this 32-bit implementation - * of SHA3 will *not* work on PHP 64-bit. This is because this implementation - * employees bitwise NOTs and bitwise left shifts. And the round constants only work - * on 32-bit PHP. eg. dechex(-2147483648) returns 80000000 on 32-bit PHP and - * FFFFFFFF80000000 on 64-bit PHP. Sure, we could do bitwise ANDs but that would slow - * things down. - * - * SHA512 requires BigInteger to simulate 64-bit unsigned integers because SHA2 employees - * addition whereas SHA3 just employees bitwise operators. PHP64 only supports signed - * 64-bit integers, which complicates addition, whereas that limitation isn't an issue - * for SHA3. - * - * In https://ws680.nist.gov/publication/get_pdf.cfm?pub_id=919061#page=16 KECCAK[C] is - * defined as "the KECCAK instance with KECCAK-f[1600] as the underlying permutation and - * capacity c". This is relevant because, altho the KECCAK standard defines a mode - * (KECCAK-f[800]) designed for 32-bit machines that mode is incompatible with SHA3 - * - * @param string $p - * @param int $c - * @param int $r - * @param int $d - * @param int $padType - */ - private static function sha3_32($p, $c, $r, $d, $padType) - { - $block_size = $r >> 3; - $padLength = $block_size - (strlen($p) % $block_size); - $num_ints = $block_size >> 2; - - $p .= static::sha3_pad($padLength, $padType); - - $n = strlen($p) / $r; // number of blocks - - $s = [ - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]], - [[0, 0], [0, 0], [0, 0], [0, 0], [0, 0]] - ]; - - $p = str_split($p, $block_size); - - foreach ($p as $pi) { - $pi = unpack('V*', $pi); - $x = $y = 0; - for ($i = 1; $i <= $num_ints; $i += 2) { - $s[$x][$y][0] ^= $pi[$i + 1]; - $s[$x][$y][1] ^= $pi[$i]; - if (++$y == 5) { - $y = 0; - $x++; - } - } - static::processSHA3Block32($s); - } - - $z = ''; - $i = $j = 0; - while (strlen($z) < $d) { - $z .= pack('V2', $s[$i][$j][1], $s[$i][$j++][0]); - if ($j == 5) { - $j = 0; - $i++; - if ($i == 5) { - $i = 0; - static::processSHA3Block32($s); - } - } - } - - return $z; - } - - /** - * 32-bit block processing method for SHA3 - * - * @param array $s - */ - private static function processSHA3Block32(&$s) - { - static $rotationOffsets = [ - [ 0, 1, 62, 28, 27], - [36, 44, 6, 55, 20], - [ 3, 10, 43, 25, 39], - [41, 45, 15, 21, 8], - [18, 2, 61, 56, 14] - ]; - - // the standards give these constants in hexadecimal notation. it's tempting to want to use - // that same notation, here, however, we can't, because 0x80000000, on PHP32, is a positive - // float - not the negative int that we need to be in PHP32. so we use -2147483648 instead - static $roundConstants = [ - [0, 1], - [0, 32898], - [-2147483648, 32906], - [-2147483648, -2147450880], - [0, 32907], - [0, -2147483647], - [-2147483648, -2147450751], - [-2147483648, 32777], - [0, 138], - [0, 136], - [0, -2147450871], - [0, -2147483638], - [0, -2147450741], - [-2147483648, 139], - [-2147483648, 32905], - [-2147483648, 32771], - [-2147483648, 32770], - [-2147483648, 128], - [0, 32778], - [-2147483648, -2147483638], - [-2147483648, -2147450751], - [-2147483648, 32896], - [0, -2147483647], - [-2147483648, -2147450872] - ]; - - for ($round = 0; $round < 24; $round++) { - // theta step - $parity = $rotated = []; - for ($i = 0; $i < 5; $i++) { - $parity[] = [ - $s[0][$i][0] ^ $s[1][$i][0] ^ $s[2][$i][0] ^ $s[3][$i][0] ^ $s[4][$i][0], - $s[0][$i][1] ^ $s[1][$i][1] ^ $s[2][$i][1] ^ $s[3][$i][1] ^ $s[4][$i][1] - ]; - $rotated[] = static::rotateLeft32($parity[$i], 1); - } - - $temp = [ - [$parity[4][0] ^ $rotated[1][0], $parity[4][1] ^ $rotated[1][1]], - [$parity[0][0] ^ $rotated[2][0], $parity[0][1] ^ $rotated[2][1]], - [$parity[1][0] ^ $rotated[3][0], $parity[1][1] ^ $rotated[3][1]], - [$parity[2][0] ^ $rotated[4][0], $parity[2][1] ^ $rotated[4][1]], - [$parity[3][0] ^ $rotated[0][0], $parity[3][1] ^ $rotated[0][1]] - ]; - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $s[$i][$j][0] ^= $temp[$j][0]; - $s[$i][$j][1] ^= $temp[$j][1]; - } - } - - $st = $s; - - // rho and pi steps - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft32($s[$j][$i], $rotationOffsets[$j][$i]); - } - } - - // chi step - for ($i = 0; $i < 5; $i++) { - $s[$i][0] = [ - $st[$i][0][0] ^ (~$st[$i][1][0] & $st[$i][2][0]), - $st[$i][0][1] ^ (~$st[$i][1][1] & $st[$i][2][1]) - ]; - $s[$i][1] = [ - $st[$i][1][0] ^ (~$st[$i][2][0] & $st[$i][3][0]), - $st[$i][1][1] ^ (~$st[$i][2][1] & $st[$i][3][1]) - ]; - $s[$i][2] = [ - $st[$i][2][0] ^ (~$st[$i][3][0] & $st[$i][4][0]), - $st[$i][2][1] ^ (~$st[$i][3][1] & $st[$i][4][1]) - ]; - $s[$i][3] = [ - $st[$i][3][0] ^ (~$st[$i][4][0] & $st[$i][0][0]), - $st[$i][3][1] ^ (~$st[$i][4][1] & $st[$i][0][1]) - ]; - $s[$i][4] = [ - $st[$i][4][0] ^ (~$st[$i][0][0] & $st[$i][1][0]), - $st[$i][4][1] ^ (~$st[$i][0][1] & $st[$i][1][1]) - ]; - } - - // iota step - $s[0][0][0] ^= $roundConstants[$round][0]; - $s[0][0][1] ^= $roundConstants[$round][1]; - } - } - - /** - * Rotate 32-bit int - * - * @param array $x - * @param int $shift - */ - private static function rotateLeft32($x, $shift) - { - if ($shift < 32) { - list($hi, $lo) = $x; - } else { - $shift -= 32; - list($lo, $hi) = $x; - } - - return [ - ($hi << $shift) | (($lo >> (32 - $shift)) & (1 << $shift) - 1), - ($lo << $shift) | (($hi >> (32 - $shift)) & (1 << $shift) - 1) - ]; - } - - /** - * Pure-PHP 64-bit implementation of SHA3 - * - * @param string $p - * @param int $c - * @param int $r - * @param int $d - * @param int $padType - */ - private static function sha3_64($p, $c, $r, $d, $padType) - { - $block_size = $r >> 3; - $padLength = $block_size - (strlen($p) % $block_size); - $num_ints = $block_size >> 2; - - $p .= static::sha3_pad($padLength, $padType); - - $n = strlen($p) / $r; // number of blocks - - $s = [ - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0], - [0, 0, 0, 0, 0] - ]; - - $p = str_split($p, $block_size); - - foreach ($p as $pi) { - $pi = unpack('P*', $pi); - $x = $y = 0; - foreach ($pi as $subpi) { - $s[$x][$y++] ^= $subpi; - if ($y == 5) { - $y = 0; - $x++; - } - } - static::processSHA3Block64($s); - } - - $z = ''; - $i = $j = 0; - while (strlen($z) < $d) { - $z .= pack('P', $s[$i][$j++]); - if ($j == 5) { - $j = 0; - $i++; - if ($i == 5) { - $i = 0; - static::processSHA3Block64($s); - } - } - } - - return $z; - } - - /** - * 64-bit block processing method for SHA3 - * - * @param array $s - */ - private static function processSHA3Block64(&$s) - { - static $rotationOffsets = [ - [ 0, 1, 62, 28, 27], - [36, 44, 6, 55, 20], - [ 3, 10, 43, 25, 39], - [41, 45, 15, 21, 8], - [18, 2, 61, 56, 14] - ]; - - static $roundConstants = [ - 1, - 32898, - -9223372036854742902, - -9223372034707259392, - 32907, - 2147483649, - -9223372034707259263, - -9223372036854743031, - 138, - 136, - 2147516425, - 2147483658, - 2147516555, - -9223372036854775669, - -9223372036854742903, - -9223372036854743037, - -9223372036854743038, - -9223372036854775680, - 32778, - -9223372034707292150, - -9223372034707259263, - -9223372036854742912, - 2147483649, - -9223372034707259384 - ]; - - for ($round = 0; $round < 24; $round++) { - // theta step - $parity = []; - for ($i = 0; $i < 5; $i++) { - $parity[] = $s[0][$i] ^ $s[1][$i] ^ $s[2][$i] ^ $s[3][$i] ^ $s[4][$i]; - } - $temp = [ - $parity[4] ^ static::rotateLeft64($parity[1], 1), - $parity[0] ^ static::rotateLeft64($parity[2], 1), - $parity[1] ^ static::rotateLeft64($parity[3], 1), - $parity[2] ^ static::rotateLeft64($parity[4], 1), - $parity[3] ^ static::rotateLeft64($parity[0], 1) - ]; - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $s[$i][$j] ^= $temp[$j]; - } - } - - $st = $s; - - // rho and pi steps - for ($i = 0; $i < 5; $i++) { - for ($j = 0; $j < 5; $j++) { - $st[(2 * $i + 3 * $j) % 5][$j] = static::rotateLeft64($s[$j][$i], $rotationOffsets[$j][$i]); - } - } - - // chi step - for ($i = 0; $i < 5; $i++) { - $s[$i] = [ - $st[$i][0] ^ (~$st[$i][1] & $st[$i][2]), - $st[$i][1] ^ (~$st[$i][2] & $st[$i][3]), - $st[$i][2] ^ (~$st[$i][3] & $st[$i][4]), - $st[$i][3] ^ (~$st[$i][4] & $st[$i][0]), - $st[$i][4] ^ (~$st[$i][0] & $st[$i][1]) - ]; - } - - // iota step - $s[0][0] ^= $roundConstants[$round]; - } - } - - /** - * Rotate 64-bit int - * - * @param int $x - * @param int $shift - */ - private static function rotateLeft64($x, $shift) - { - return ($x << $shift) | (($x >> (64 - $shift)) & ((1 << $shift) - 1)); - } - - /** - * Pure-PHP implementation of SHA512 - * - * @param string $m - * @param array $hash - * @return string - */ - private static function sha512($m, $hash) - { - static $k; - - if (!isset($k)) { - // Initialize table of round constants - // (first 64 bits of the fractional parts of the cube roots of the first 80 primes 2..409) - $k = [ - '428a2f98d728ae22', '7137449123ef65cd', 'b5c0fbcfec4d3b2f', 'e9b5dba58189dbbc', - '3956c25bf348b538', '59f111f1b605d019', '923f82a4af194f9b', 'ab1c5ed5da6d8118', - 'd807aa98a3030242', '12835b0145706fbe', '243185be4ee4b28c', '550c7dc3d5ffb4e2', - '72be5d74f27b896f', '80deb1fe3b1696b1', '9bdc06a725c71235', 'c19bf174cf692694', - 'e49b69c19ef14ad2', 'efbe4786384f25e3', '0fc19dc68b8cd5b5', '240ca1cc77ac9c65', - '2de92c6f592b0275', '4a7484aa6ea6e483', '5cb0a9dcbd41fbd4', '76f988da831153b5', - '983e5152ee66dfab', 'a831c66d2db43210', 'b00327c898fb213f', 'bf597fc7beef0ee4', - 'c6e00bf33da88fc2', 'd5a79147930aa725', '06ca6351e003826f', '142929670a0e6e70', - '27b70a8546d22ffc', '2e1b21385c26c926', '4d2c6dfc5ac42aed', '53380d139d95b3df', - '650a73548baf63de', '766a0abb3c77b2a8', '81c2c92e47edaee6', '92722c851482353b', - 'a2bfe8a14cf10364', 'a81a664bbc423001', 'c24b8b70d0f89791', 'c76c51a30654be30', - 'd192e819d6ef5218', 'd69906245565a910', 'f40e35855771202a', '106aa07032bbd1b8', - '19a4c116b8d2d0c8', '1e376c085141ab53', '2748774cdf8eeb99', '34b0bcb5e19b48a8', - '391c0cb3c5c95a63', '4ed8aa4ae3418acb', '5b9cca4f7763e373', '682e6ff3d6b2b8a3', - '748f82ee5defb2fc', '78a5636f43172f60', '84c87814a1f0ab72', '8cc702081a6439ec', - '90befffa23631e28', 'a4506cebde82bde9', 'bef9a3f7b2c67915', 'c67178f2e372532b', - 'ca273eceea26619c', 'd186b8c721c0c207', 'eada7dd6cde0eb1e', 'f57d4f7fee6ed178', - '06f067aa72176fba', '0a637dc5a2c898a6', '113f9804bef90dae', '1b710b35131c471b', - '28db77f523047d84', '32caab7b40c72493', '3c9ebe0a15c9bebc', '431d67c49c100d4c', - '4cc5d4becb3e42b6', '597f299cfc657e2a', '5fcb6fab3ad6faec', '6c44198c4a475817' - ]; - - for ($i = 0; $i < 80; $i++) { - $k[$i] = new BigInteger($k[$i], 16); - } - } - - // Pre-processing - $length = strlen($m); - // to round to nearest 112 mod 128, we'll add 128 - (length + (128 - 112)) % 128 - $m .= str_repeat(chr(0), 128 - (($length + 16) & 0x7F)); - $m[$length] = chr(0x80); - // we don't support hashing strings 512MB long - $m .= pack('N4', 0, 0, 0, $length << 3); - - // Process the message in successive 1024-bit chunks - $chunks = str_split($m, 128); - foreach ($chunks as $chunk) { - $w = []; - for ($i = 0; $i < 16; $i++) { - $temp = new BigInteger(Strings::shift($chunk, 8), 256); - $temp->setPrecision(64); - $w[] = $temp; - } - - // Extend the sixteen 32-bit words into eighty 32-bit words - for ($i = 16; $i < 80; $i++) { - $temp = [ - $w[$i - 15]->bitwise_rightRotate(1), - $w[$i - 15]->bitwise_rightRotate(8), - $w[$i - 15]->bitwise_rightShift(7) - ]; - $s0 = $temp[0]->bitwise_xor($temp[1]); - $s0 = $s0->bitwise_xor($temp[2]); - $temp = [ - $w[$i - 2]->bitwise_rightRotate(19), - $w[$i - 2]->bitwise_rightRotate(61), - $w[$i - 2]->bitwise_rightShift(6) - ]; - $s1 = $temp[0]->bitwise_xor($temp[1]); - $s1 = $s1->bitwise_xor($temp[2]); - $w[$i] = clone $w[$i - 16]; - $w[$i] = $w[$i]->add($s0); - $w[$i] = $w[$i]->add($w[$i - 7]); - $w[$i] = $w[$i]->add($s1); - } - - // Initialize hash value for this chunk - $a = clone $hash[0]; - $b = clone $hash[1]; - $c = clone $hash[2]; - $d = clone $hash[3]; - $e = clone $hash[4]; - $f = clone $hash[5]; - $g = clone $hash[6]; - $h = clone $hash[7]; - - // Main loop - for ($i = 0; $i < 80; $i++) { - $temp = [ - $a->bitwise_rightRotate(28), - $a->bitwise_rightRotate(34), - $a->bitwise_rightRotate(39) - ]; - $s0 = $temp[0]->bitwise_xor($temp[1]); - $s0 = $s0->bitwise_xor($temp[2]); - $temp = [ - $a->bitwise_and($b), - $a->bitwise_and($c), - $b->bitwise_and($c) - ]; - $maj = $temp[0]->bitwise_xor($temp[1]); - $maj = $maj->bitwise_xor($temp[2]); - $t2 = $s0->add($maj); - - $temp = [ - $e->bitwise_rightRotate(14), - $e->bitwise_rightRotate(18), - $e->bitwise_rightRotate(41) - ]; - $s1 = $temp[0]->bitwise_xor($temp[1]); - $s1 = $s1->bitwise_xor($temp[2]); - $temp = [ - $e->bitwise_and($f), - $g->bitwise_and($e->bitwise_not()) - ]; - $ch = $temp[0]->bitwise_xor($temp[1]); - $t1 = $h->add($s1); - $t1 = $t1->add($ch); - $t1 = $t1->add($k[$i]); - $t1 = $t1->add($w[$i]); - - $h = clone $g; - $g = clone $f; - $f = clone $e; - $e = $d->add($t1); - $d = clone $c; - $c = clone $b; - $b = clone $a; - $a = $t1->add($t2); - } - - // Add this chunk's hash to result so far - $hash = [ - $hash[0]->add($a), - $hash[1]->add($b), - $hash[2]->add($c), - $hash[3]->add($d), - $hash[4]->add($e), - $hash[5]->add($f), - $hash[6]->add($g), - $hash[7]->add($h) - ]; - } - - // Produce the final hash value (big-endian) - // (\phpseclib3\Crypt\Hash::hash() trims the output for hashes but not for HMACs. as such, we trim the output here) - $temp = $hash[0]->toBytes() . $hash[1]->toBytes() . $hash[2]->toBytes() . $hash[3]->toBytes() . - $hash[4]->toBytes() . $hash[5]->toBytes() . $hash[6]->toBytes() . $hash[7]->toBytes(); - - return $temp; - } - - /** - * __toString() magic method - */ - public function __toString() - { - return $this->getHash(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php deleted file mode 100644 index 61afbae..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/PublicKeyLoader.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Crypt\Common\PublicKey; -use phpseclib3\Exception\NoKeyLoadedException; -use phpseclib3\File\X509; - -/** - * PublicKeyLoader - * - * @author Jim Wigginton - */ -abstract class PublicKeyLoader -{ - /** - * Loads a public or private key - * - * @return AsymmetricKey - * @param string|array $key - * @param string $password optional - */ - public static function load($key, $password = false) - { - try { - return EC::load($key, $password); - } catch (NoKeyLoadedException $e) { - } - - try { - return RSA::load($key, $password); - } catch (NoKeyLoadedException $e) { - } - - try { - return DSA::load($key, $password); - } catch (NoKeyLoadedException $e) { - } - - try { - $x509 = new X509(); - $x509->loadX509($key); - $key = $x509->getPublicKey(); - if ($key) { - return $key; - } - } catch (\Exception $e) { - } - - throw new NoKeyLoadedException('Unable to read key'); - } - - /** - * Loads a private key - * - * @return PrivateKey - * @param string|array $key - * @param string $password optional - */ - public static function loadPrivateKey($key, $password = false) - { - $key = self::load($key, $password); - if (!$key instanceof PrivateKey) { - throw new NoKeyLoadedException('The key that was loaded was not a private key'); - } - return $key; - } - - /** - * Loads a public key - * - * @return PublicKey - * @param string|array $key - */ - public static function loadPublicKey($key) - { - $key = self::load($key); - if (!$key instanceof PublicKey) { - throw new NoKeyLoadedException('The key that was loaded was not a public key'); - } - return $key; - } - - /** - * Loads parameters - * - * @return AsymmetricKey - * @param string|array $key - */ - public static function loadParameters($key) - { - $key = self::load($key); - if (!$key instanceof PrivateKey && !$key instanceof PublicKey) { - throw new NoKeyLoadedException('The key that was loaded was not a parameter'); - } - return $key; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php deleted file mode 100644 index 654c906..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC2.php +++ /dev/null @@ -1,640 +0,0 @@ - - * setKey('abcdefgh'); - * - * $plaintext = str_repeat('a', 1024); - * - * echo $rc2->decrypt($rc2->encrypt($plaintext)); - * ?> - * - * - * @author Patrick Monnerat - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadModeException; - -/** - * Pure-PHP implementation of RC2. - * - */ -class RC2 extends BlockCipher -{ - /** - * Block Length of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::block_size - * @var int - */ - protected $block_size = 8; - - /** - * The Key - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::key - * @see self::setKey() - * @var string - */ - protected $key; - - /** - * The Original (unpadded) Key - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::key - * @see self::setKey() - * @see self::encrypt() - * @see self::decrypt() - * @var string - */ - private $orig_key; - - /** - * Key Length (in bytes) - * - * @see \phpseclib3\Crypt\RC2::setKeyLength() - * @var int - */ - protected $key_length = 16; // = 128 bits - - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @var string - */ - protected $cipher_name_mcrypt = 'rc2'; - - /** - * Optimizing value while CFB-encrypting - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len - * @var int - */ - protected $cfb_init_len = 500; - - /** - * The key length in bits. - * - * {@internal Should be in range [1..1024].} - * - * {@internal Changing this value after setting the key has no effect.} - * - * @see self::setKeyLength() - * @see self::setKey() - * @var int - */ - private $default_key_length = 1024; - - /** - * The key length in bits. - * - * {@internal Should be in range [1..1024].} - * - * @see self::isValidEnine() - * @see self::setKey() - * @var int - */ - private $current_key_length; - - /** - * The Key Schedule - * - * @see self::setupKey() - * @var array - */ - private $keys; - - /** - * Key expansion randomization table. - * Twice the same 256-value sequence to save a modulus in key expansion. - * - * @see self::setKey() - * @var array - */ - private static $pitable = [ - 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, - 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, - 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, - 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, - 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, - 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, - 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, - 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, - 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, - 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, - 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, - 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, - 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, - 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, - 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, - 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, - 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, - 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, - 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, - 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, - 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, - 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, - 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, - 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, - 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, - 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, - 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, - 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, - 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, - 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, - 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, - 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD, - 0xD9, 0x78, 0xF9, 0xC4, 0x19, 0xDD, 0xB5, 0xED, - 0x28, 0xE9, 0xFD, 0x79, 0x4A, 0xA0, 0xD8, 0x9D, - 0xC6, 0x7E, 0x37, 0x83, 0x2B, 0x76, 0x53, 0x8E, - 0x62, 0x4C, 0x64, 0x88, 0x44, 0x8B, 0xFB, 0xA2, - 0x17, 0x9A, 0x59, 0xF5, 0x87, 0xB3, 0x4F, 0x13, - 0x61, 0x45, 0x6D, 0x8D, 0x09, 0x81, 0x7D, 0x32, - 0xBD, 0x8F, 0x40, 0xEB, 0x86, 0xB7, 0x7B, 0x0B, - 0xF0, 0x95, 0x21, 0x22, 0x5C, 0x6B, 0x4E, 0x82, - 0x54, 0xD6, 0x65, 0x93, 0xCE, 0x60, 0xB2, 0x1C, - 0x73, 0x56, 0xC0, 0x14, 0xA7, 0x8C, 0xF1, 0xDC, - 0x12, 0x75, 0xCA, 0x1F, 0x3B, 0xBE, 0xE4, 0xD1, - 0x42, 0x3D, 0xD4, 0x30, 0xA3, 0x3C, 0xB6, 0x26, - 0x6F, 0xBF, 0x0E, 0xDA, 0x46, 0x69, 0x07, 0x57, - 0x27, 0xF2, 0x1D, 0x9B, 0xBC, 0x94, 0x43, 0x03, - 0xF8, 0x11, 0xC7, 0xF6, 0x90, 0xEF, 0x3E, 0xE7, - 0x06, 0xC3, 0xD5, 0x2F, 0xC8, 0x66, 0x1E, 0xD7, - 0x08, 0xE8, 0xEA, 0xDE, 0x80, 0x52, 0xEE, 0xF7, - 0x84, 0xAA, 0x72, 0xAC, 0x35, 0x4D, 0x6A, 0x2A, - 0x96, 0x1A, 0xD2, 0x71, 0x5A, 0x15, 0x49, 0x74, - 0x4B, 0x9F, 0xD0, 0x5E, 0x04, 0x18, 0xA4, 0xEC, - 0xC2, 0xE0, 0x41, 0x6E, 0x0F, 0x51, 0xCB, 0xCC, - 0x24, 0x91, 0xAF, 0x50, 0xA1, 0xF4, 0x70, 0x39, - 0x99, 0x7C, 0x3A, 0x85, 0x23, 0xB8, 0xB4, 0x7A, - 0xFC, 0x02, 0x36, 0x5B, 0x25, 0x55, 0x97, 0x31, - 0x2D, 0x5D, 0xFA, 0x98, 0xE3, 0x8A, 0x92, 0xAE, - 0x05, 0xDF, 0x29, 0x10, 0x67, 0x6C, 0xBA, 0xC9, - 0xD3, 0x00, 0xE6, 0xCF, 0xE1, 0x9E, 0xA8, 0x2C, - 0x63, 0x16, 0x01, 0x3F, 0x58, 0xE2, 0x89, 0xA9, - 0x0D, 0x38, 0x34, 0x1B, 0xAB, 0x33, 0xFF, 0xB0, - 0xBB, 0x48, 0x0C, 0x5F, 0xB9, 0xB1, 0xCD, 0x2E, - 0xC5, 0xF3, 0xDB, 0x47, 0xE5, 0xA5, 0x9C, 0x77, - 0x0A, 0xA6, 0x20, 0x68, 0xFE, 0x7F, 0xC1, 0xAD - ]; - - /** - * Inverse key expansion randomization table. - * - * @see self::setKey() - * @var array - */ - private static $invpitable = [ - 0xD1, 0xDA, 0xB9, 0x6F, 0x9C, 0xC8, 0x78, 0x66, - 0x80, 0x2C, 0xF8, 0x37, 0xEA, 0xE0, 0x62, 0xA4, - 0xCB, 0x71, 0x50, 0x27, 0x4B, 0x95, 0xD9, 0x20, - 0x9D, 0x04, 0x91, 0xE3, 0x47, 0x6A, 0x7E, 0x53, - 0xFA, 0x3A, 0x3B, 0xB4, 0xA8, 0xBC, 0x5F, 0x68, - 0x08, 0xCA, 0x8F, 0x14, 0xD7, 0xC0, 0xEF, 0x7B, - 0x5B, 0xBF, 0x2F, 0xE5, 0xE2, 0x8C, 0xBA, 0x12, - 0xE1, 0xAF, 0xB2, 0x54, 0x5D, 0x59, 0x76, 0xDB, - 0x32, 0xA2, 0x58, 0x6E, 0x1C, 0x29, 0x64, 0xF3, - 0xE9, 0x96, 0x0C, 0x98, 0x19, 0x8D, 0x3E, 0x26, - 0xAB, 0xA5, 0x85, 0x16, 0x40, 0xBD, 0x49, 0x67, - 0xDC, 0x22, 0x94, 0xBB, 0x3C, 0xC1, 0x9B, 0xEB, - 0x45, 0x28, 0x18, 0xD8, 0x1A, 0x42, 0x7D, 0xCC, - 0xFB, 0x65, 0x8E, 0x3D, 0xCD, 0x2A, 0xA3, 0x60, - 0xAE, 0x93, 0x8A, 0x48, 0x97, 0x51, 0x15, 0xF7, - 0x01, 0x0B, 0xB7, 0x36, 0xB1, 0x2E, 0x11, 0xFD, - 0x84, 0x2D, 0x3F, 0x13, 0x88, 0xB3, 0x34, 0x24, - 0x1B, 0xDE, 0xC5, 0x1D, 0x4D, 0x2B, 0x17, 0x31, - 0x74, 0xA9, 0xC6, 0x43, 0x6D, 0x39, 0x90, 0xBE, - 0xC3, 0xB0, 0x21, 0x6B, 0xF6, 0x0F, 0xD5, 0x99, - 0x0D, 0xAC, 0x1F, 0x5C, 0x9E, 0xF5, 0xF9, 0x4C, - 0xD6, 0xDF, 0x89, 0xE4, 0x8B, 0xFF, 0xC7, 0xAA, - 0xE7, 0xED, 0x46, 0x25, 0xB6, 0x06, 0x5E, 0x35, - 0xB5, 0xEC, 0xCE, 0xE8, 0x6C, 0x30, 0x55, 0x61, - 0x4A, 0xFE, 0xA0, 0x79, 0x03, 0xF0, 0x10, 0x72, - 0x7C, 0xCF, 0x52, 0xA6, 0xA7, 0xEE, 0x44, 0xD3, - 0x9A, 0x57, 0x92, 0xD0, 0x5A, 0x7A, 0x41, 0x7F, - 0x0E, 0x00, 0x63, 0xF2, 0x4F, 0x05, 0x83, 0xC9, - 0xA1, 0xD4, 0xDD, 0xC4, 0x56, 0xF4, 0xD2, 0x77, - 0x81, 0x09, 0x82, 0x33, 0x9F, 0x07, 0x86, 0x75, - 0x38, 0x4E, 0x69, 0xF1, 0xAD, 0x23, 0x73, 0x87, - 0x70, 0x02, 0xC2, 0x1E, 0xB8, 0x0A, 0xFC, 0xE6 - ]; - - /** - * Default Constructor. - * - * @param string $mode - * @throws \InvalidArgumentException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - switch ($engine) { - case self::ENGINE_OPENSSL: - if ($this->current_key_length != 128 || strlen($this->orig_key) < 16) { - return false; - } - // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 - // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" - // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { - return false; - } - $this->cipher_name_openssl_ecb = 'rc2-ecb'; - $this->cipher_name_openssl = 'rc2-' . $this->openssl_translate_mode(); - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Sets the key length. - * - * Valid key lengths are 8 to 1024. - * Calling this function after setting the key has no effect until the next - * \phpseclib3\Crypt\RC2::setKey() call. - * - * @param int $length in bits - * @throws \LengthException if the key length isn't supported - */ - public function setKeyLength($length) - { - if ($length < 8 || $length > 1024) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); - } - - $this->default_key_length = $this->current_key_length = $length; - $this->explicit_key_length = $length >> 3; - } - - /** - * Returns the current key length - * - * @return int - */ - public function getKeyLength() - { - return $this->current_key_length; - } - - /** - * Sets the key. - * - * Keys can be of any length. RC2, itself, uses 8 to 1024 bit keys (eg. - * strlen($key) <= 128), however, we only use the first 128 bytes if $key - * has more then 128 bytes in it, and set $key to a single null byte if - * it is empty. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() - * @param string $key - * @param int|boolean $t1 optional Effective key length in bits. - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key, $t1 = false) - { - $this->orig_key = $key; - - if ($t1 === false) { - $t1 = $this->default_key_length; - } - - if ($t1 < 1 || $t1 > 1024) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 1024 bits, inclusive, are supported'); - } - - $this->current_key_length = $t1; - if (strlen($key) < 1 || strlen($key) > 128) { - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes between 8 and 1024 bits, inclusive, are supported'); - } - - $t = strlen($key); - - // The mcrypt RC2 implementation only supports effective key length - // of 1024 bits. It is however possible to handle effective key - // lengths in range 1..1024 by expanding the key and applying - // inverse pitable mapping to the first byte before submitting it - // to mcrypt. - - // Key expansion. - $l = array_values(unpack('C*', $key)); - $t8 = ($t1 + 7) >> 3; - $tm = 0xFF >> (8 * $t8 - $t1); - - // Expand key. - $pitable = self::$pitable; - for ($i = $t; $i < 128; $i++) { - $l[$i] = $pitable[$l[$i - 1] + $l[$i - $t]]; - } - $i = 128 - $t8; - $l[$i] = $pitable[$l[$i] & $tm]; - while ($i--) { - $l[$i] = $pitable[$l[$i + 1] ^ $l[$i + $t8]]; - } - - // Prepare the key for mcrypt. - $l[0] = self::$invpitable[$l[0]]; - array_unshift($l, 'C*'); - - $this->key = pack(...$l); - $this->key_length = strlen($this->key); - $this->changed = $this->nonIVChanged = true; - $this->setEngine(); - } - - /** - * Encrypts a message. - * - * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::encrypt, with some additional OpenSSL handling code - * - * @see self::decrypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - if ($this->engine == self::ENGINE_OPENSSL) { - $temp = $this->key; - $this->key = $this->orig_key; - $result = parent::encrypt($plaintext); - $this->key = $temp; - return $result; - } - - return parent::encrypt($plaintext); - } - - /** - * Decrypts a message. - * - * Mostly a wrapper for \phpseclib3\Crypt\Common\SymmetricKey::decrypt, with some additional OpenSSL handling code - * - * @see self::encrypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - if ($this->engine == self::ENGINE_OPENSSL) { - $temp = $this->key; - $this->key = $this->orig_key; - $result = parent::decrypt($ciphertext); - $this->key = $temp; - return $result; - } - - return parent::decrypt($ciphertext); - } - - /** - * Encrypts a block - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @param string $in - * @return string - */ - protected function encryptBlock($in) - { - list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); - $keys = $this->keys; - $limit = 20; - $actions = [$limit => 44, 44 => 64]; - $j = 0; - - for (;;) { - // Mixing round. - $r0 = (($r0 + $keys[$j++] + ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; - $r0 |= $r0 >> 16; - $r1 = (($r1 + $keys[$j++] + ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; - $r1 |= $r1 >> 16; - $r2 = (($r2 + $keys[$j++] + ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; - $r2 |= $r2 >> 16; - $r3 = (($r3 + $keys[$j++] + ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; - $r3 |= $r3 >> 16; - - if ($j === $limit) { - if ($limit === 64) { - break; - } - - // Mashing round. - $r0 += $keys[$r3 & 0x3F]; - $r1 += $keys[$r0 & 0x3F]; - $r2 += $keys[$r1 & 0x3F]; - $r3 += $keys[$r2 & 0x3F]; - $limit = $actions[$limit]; - } - } - - return pack('vvvv', $r0, $r1, $r2, $r3); - } - - /** - * Decrypts a block - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decryptBlock() - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @param string $in - * @return string - */ - protected function decryptBlock($in) - { - list($r0, $r1, $r2, $r3) = array_values(unpack('v*', $in)); - $keys = $this->keys; - $limit = 44; - $actions = [$limit => 20, 20 => 0]; - $j = 64; - - for (;;) { - // R-mixing round. - $r3 = ($r3 | ($r3 << 16)) >> 5; - $r3 = ($r3 - $keys[--$j] - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; - $r2 = ($r2 | ($r2 << 16)) >> 3; - $r2 = ($r2 - $keys[--$j] - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; - $r1 = ($r1 | ($r1 << 16)) >> 2; - $r1 = ($r1 - $keys[--$j] - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; - $r0 = ($r0 | ($r0 << 16)) >> 1; - $r0 = ($r0 - $keys[--$j] - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF; - - if ($j === $limit) { - if ($limit === 0) { - break; - } - - // R-mashing round. - $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; - $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; - $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; - $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF; - $limit = $actions[$limit]; - } - } - - return pack('vvvv', $r0, $r1, $r2, $r3); - } - - /** - * Creates the key schedule - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() - */ - protected function setupKey() - { - if (!isset($this->key)) { - $this->setKey(''); - } - - // Key has already been expanded in \phpseclib3\Crypt\RC2::setKey(): - // Only the first value must be altered. - $l = unpack('Ca/Cb/v*', $this->key); - array_unshift($l, self::$pitable[$l['a']] | ($l['b'] << 8)); - unset($l['a']); - unset($l['b']); - $this->keys = $l; - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() - */ - protected function setupInlineCrypt() - { - // Init code for both, encrypt and decrypt. - $init_crypt = '$keys = $this->keys;'; - - $keys = $this->keys; - - // $in is the current 8 bytes block which has to be en/decrypt - $encrypt_block = $decrypt_block = ' - $in = unpack("v4", $in); - $r0 = $in[1]; - $r1 = $in[2]; - $r2 = $in[3]; - $r3 = $in[4]; - '; - - // Create code for encryption. - $limit = 20; - $actions = [$limit => 44, 44 => 64]; - $j = 0; - - for (;;) { - // Mixing round. - $encrypt_block .= ' - $r0 = (($r0 + ' . $keys[$j++] . ' + - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF) << 1; - $r0 |= $r0 >> 16; - $r1 = (($r1 + ' . $keys[$j++] . ' + - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF) << 2; - $r1 |= $r1 >> 16; - $r2 = (($r2 + ' . $keys[$j++] . ' + - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF) << 3; - $r2 |= $r2 >> 16; - $r3 = (($r3 + ' . $keys[$j++] . ' + - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF) << 5; - $r3 |= $r3 >> 16;'; - - if ($j === $limit) { - if ($limit === 64) { - break; - } - - // Mashing round. - $encrypt_block .= ' - $r0 += $keys[$r3 & 0x3F]; - $r1 += $keys[$r0 & 0x3F]; - $r2 += $keys[$r1 & 0x3F]; - $r3 += $keys[$r2 & 0x3F];'; - $limit = $actions[$limit]; - } - } - - $encrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; - - // Create code for decryption. - $limit = 44; - $actions = [$limit => 20, 20 => 0]; - $j = 64; - - for (;;) { - // R-mixing round. - $decrypt_block .= ' - $r3 = ($r3 | ($r3 << 16)) >> 5; - $r3 = ($r3 - ' . $keys[--$j] . ' - - ((($r0 ^ $r1) & $r2) ^ $r0)) & 0xFFFF; - $r2 = ($r2 | ($r2 << 16)) >> 3; - $r2 = ($r2 - ' . $keys[--$j] . ' - - ((($r3 ^ $r0) & $r1) ^ $r3)) & 0xFFFF; - $r1 = ($r1 | ($r1 << 16)) >> 2; - $r1 = ($r1 - ' . $keys[--$j] . ' - - ((($r2 ^ $r3) & $r0) ^ $r2)) & 0xFFFF; - $r0 = ($r0 | ($r0 << 16)) >> 1; - $r0 = ($r0 - ' . $keys[--$j] . ' - - ((($r1 ^ $r2) & $r3) ^ $r1)) & 0xFFFF;'; - - if ($j === $limit) { - if ($limit === 0) { - break; - } - - // R-mashing round. - $decrypt_block .= ' - $r3 = ($r3 - $keys[$r2 & 0x3F]) & 0xFFFF; - $r2 = ($r2 - $keys[$r1 & 0x3F]) & 0xFFFF; - $r1 = ($r1 - $keys[$r0 & 0x3F]) & 0xFFFF; - $r0 = ($r0 - $keys[$r3 & 0x3F]) & 0xFFFF;'; - $limit = $actions[$limit]; - } - } - - $decrypt_block .= '$in = pack("v4", $r0, $r1, $r2, $r3);'; - - // Creates the inline-crypt function - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php deleted file mode 100644 index 5f3bff2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RC4.php +++ /dev/null @@ -1,280 +0,0 @@ - - * setKey('abcdefgh'); - * - * $size = 10 * 1024; - * $plaintext = ''; - * for ($i = 0; $i < $size; $i++) { - * $plaintext.= 'a'; - * } - * - * echo $rc4->decrypt($rc4->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\StreamCipher; - -/** - * Pure-PHP implementation of RC4. - * - * @author Jim Wigginton - */ -class RC4 extends StreamCipher -{ - /** - * @see \phpseclib3\Crypt\RC4::_crypt() - */ - const ENCRYPT = 0; - - /** - * @see \phpseclib3\Crypt\RC4::_crypt() - */ - const DECRYPT = 1; - - /** - * Key Length (in bytes) - * - * @see \phpseclib3\Crypt\RC4::setKeyLength() - * @var int - */ - protected $key_length = 128; // = 1024 bits - - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @var string - */ - protected $cipher_name_mcrypt = 'arcfour'; - - /** - * The Key - * - * @see self::setKey() - * @var string - */ - protected $key; - - /** - * The Key Stream for decryption and encryption - * - * @see self::setKey() - * @var array - */ - private $stream; - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - if ($engine == self::ENGINE_OPENSSL) { - if ($this->continuousBuffer) { - return false; - } - // quoting https://www.openssl.org/news/openssl-3.0-notes.html, OpenSSL 3.0.1 - // "Moved all variations of the EVP ciphers CAST5, BF, IDEA, SEED, RC2, RC4, RC5, and DES to the legacy provider" - // in theory openssl_get_cipher_methods() should catch this but, on GitHub Actions, at least, it does not - if (defined('OPENSSL_VERSION_TEXT') && version_compare(preg_replace('#OpenSSL (\d+\.\d+\.\d+) .*#', '$1', OPENSSL_VERSION_TEXT), '3.0.1', '>=')) { - return false; - } - $this->cipher_name_openssl = 'rc4-40'; - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Sets the key length - * - * Keys can be between 1 and 256 bytes long. - * - * @param int $length - * @throws \LengthException if the key length is invalid - */ - public function setKeyLength($length) - { - if ($length < 8 || $length > 2048) { - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys between 1 and 256 bytes are supported'); - } - - $this->key_length = $length >> 3; - - parent::setKeyLength($length); - } - - /** - * Sets the key length - * - * Keys can be between 1 and 256 bytes long. - * - * @param string $key - */ - public function setKey($key) - { - $length = strlen($key); - if ($length < 1 || $length > 256) { - throw new \LengthException('Key size of ' . $length . ' bytes is not supported by RC4. Keys must be between 1 and 256 bytes long'); - } - - parent::setKey($key); - } - - /** - * Encrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::crypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - if ($this->engine != self::ENGINE_INTERNAL) { - return parent::encrypt($plaintext); - } - return $this->crypt($plaintext, self::ENCRYPT); - } - - /** - * Decrypts a message. - * - * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). - * At least if the continuous buffer is disabled. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::crypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - if ($this->engine != self::ENGINE_INTERNAL) { - return parent::decrypt($ciphertext); - } - return $this->crypt($ciphertext, self::DECRYPT); - } - - /** - * Encrypts a block - * - * @param string $in - */ - protected function encryptBlock($in) - { - // RC4 does not utilize this method - } - - /** - * Decrypts a block - * - * @param string $in - */ - protected function decryptBlock($in) - { - // RC4 does not utilize this method - } - - /** - * Setup the key (expansion) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() - */ - protected function setupKey() - { - $key = $this->key; - $keyLength = strlen($key); - $keyStream = range(0, 255); - $j = 0; - for ($i = 0; $i < 256; $i++) { - $j = ($j + $keyStream[$i] + ord($key[$i % $keyLength])) & 255; - $temp = $keyStream[$i]; - $keyStream[$i] = $keyStream[$j]; - $keyStream[$j] = $temp; - } - - $this->stream = []; - $this->stream[self::DECRYPT] = $this->stream[self::ENCRYPT] = [ - 0, // index $i - 0, // index $j - $keyStream - ]; - } - - /** - * Encrypts or decrypts a message. - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $text - * @param int $mode - * @return string $text - */ - private function crypt($text, $mode) - { - if ($this->changed) { - $this->setup(); - } - - $stream = &$this->stream[$mode]; - if ($this->continuousBuffer) { - $i = &$stream[0]; - $j = &$stream[1]; - $keyStream = &$stream[2]; - } else { - $i = $stream[0]; - $j = $stream[1]; - $keyStream = $stream[2]; - } - - $len = strlen($text); - for ($k = 0; $k < $len; ++$k) { - $i = ($i + 1) & 255; - $ksi = $keyStream[$i]; - $j = ($j + $ksi) & 255; - $ksj = $keyStream[$j]; - - $keyStream[$i] = $ksj; - $keyStream[$j] = $ksi; - $text[$k] = $text[$k] ^ chr($keyStream[($ksj + $ksi) & 255]); - } - - return $text; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php deleted file mode 100644 index 19dcfea..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA.php +++ /dev/null @@ -1,934 +0,0 @@ - - * getPublicKey(); - * - * $plaintext = 'terrafrost'; - * - * $ciphertext = $public->encrypt($plaintext); - * - * echo $private->decrypt($ciphertext); - * ?> - * - * - * Here's an example of how to create signatures and verify signatures with this library: - * - * getPublicKey(); - * - * $plaintext = 'terrafrost'; - * - * $signature = $private->sign($plaintext); - * - * echo $public->verify($plaintext, $signature) ? 'verified' : 'unverified'; - * ?> - * - * - * One thing to consider when using this: so phpseclib uses PSS mode by default. - * Technically, id-RSASSA-PSS has a different key format than rsaEncryption. So - * should phpseclib save to the id-RSASSA-PSS format by default or the - * rsaEncryption format? For stand-alone keys I figure rsaEncryption is better - * because SSH doesn't use PSS and idk how many SSH servers would be able to - * decode an id-RSASSA-PSS key. For X.509 certificates the id-RSASSA-PSS - * format is used by default (unless you change it up to use PKCS1 instead) - * - * @author Jim Wigginton - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; -use phpseclib3\Crypt\RSA\PrivateKey; -use phpseclib3\Crypt\RSA\PublicKey; -use phpseclib3\Exception\InconsistentSetupException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP PKCS#1 compliant implementation of RSA. - * - * @author Jim Wigginton - */ -abstract class RSA extends AsymmetricKey -{ - /** - * Algorithm Name - * - * @var string - */ - const ALGORITHM = 'RSA'; - - /** - * Use {@link http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding Optimal Asymmetric Encryption Padding} - * (OAEP) for encryption / decryption. - * - * Uses sha256 by default - * - * @see self::setHash() - * @see self::setMGFHash() - * @see self::encrypt() - * @see self::decrypt() - */ - const ENCRYPTION_OAEP = 1; - - /** - * Use PKCS#1 padding. - * - * Although self::PADDING_OAEP / self::PADDING_PSS offers more security, including PKCS#1 padding is necessary for purposes of backwards - * compatibility with protocols (like SSH-1) written before OAEP's introduction. - * - * @see self::encrypt() - * @see self::decrypt() - */ - const ENCRYPTION_PKCS1 = 2; - - /** - * Do not use any padding - * - * Although this method is not recommended it can none-the-less sometimes be useful if you're trying to decrypt some legacy - * stuff, if you're trying to diagnose why an encrypted message isn't decrypting, etc. - * - * @see self::encrypt() - * @see self::decrypt() - */ - const ENCRYPTION_NONE = 4; - - /** - * Use the Probabilistic Signature Scheme for signing - * - * Uses sha256 and 0 as the salt length - * - * @see self::setSaltLength() - * @see self::setMGFHash() - * @see self::setHash() - * @see self::sign() - * @see self::verify() - * @see self::setHash() - */ - const SIGNATURE_PSS = 16; - - /** - * Use a relaxed version of PKCS#1 padding for signature verification - * - * @see self::sign() - * @see self::verify() - * @see self::setHash() - */ - const SIGNATURE_RELAXED_PKCS1 = 32; - - /** - * Use PKCS#1 padding for signature verification - * - * @see self::sign() - * @see self::verify() - * @see self::setHash() - */ - const SIGNATURE_PKCS1 = 64; - - /** - * Encryption padding mode - * - * @var int - */ - protected $encryptionPadding = self::ENCRYPTION_OAEP; - - /** - * Signature padding mode - * - * @var int - */ - protected $signaturePadding = self::SIGNATURE_PSS; - - /** - * Length of hash function output - * - * @var int - */ - protected $hLen; - - /** - * Length of salt - * - * @var int - */ - protected $sLen; - - /** - * Label - * - * @var string - */ - protected $label = ''; - - /** - * Hash function for the Mask Generation Function - * - * @var \phpseclib3\Crypt\Hash - */ - protected $mgfHash; - - /** - * Length of MGF hash function output - * - * @var int - */ - protected $mgfHLen; - - /** - * Modulus (ie. n) - * - * @var \phpseclib3\Math\BigInteger - */ - protected $modulus; - - /** - * Modulus length - * - * @var \phpseclib3\Math\BigInteger - */ - protected $k; - - /** - * Exponent (ie. e or d) - * - * @var \phpseclib3\Math\BigInteger - */ - protected $exponent; - - /** - * Default public exponent - * - * @var int - * @link http://en.wikipedia.org/wiki/65537_%28number%29 - */ - private static $defaultExponent = 65537; - - /** - * Enable Blinding? - * - * @var bool - */ - protected static $enableBlinding = true; - - /** - * OpenSSL configuration file name. - * - * @see self::createKey() - * @var ?string - */ - protected static $configFile; - - /** - * Smallest Prime - * - * Per , this number ought not result in primes smaller - * than 256 bits. As a consequence if the key you're trying to create is 1024 bits and you've set smallestPrime - * to 384 bits then you're going to get a 384 bit prime and a 640 bit prime (384 + 1024 % 384). At least if - * engine is set to self::ENGINE_INTERNAL. If Engine is set to self::ENGINE_OPENSSL then smallest Prime is - * ignored (ie. multi-prime RSA support is more intended as a way to speed up RSA key generation when there's - * a chance neither gmp nor OpenSSL are installed) - * - * @var int - */ - private static $smallestPrime = 4096; - - /** - * Public Exponent - * - * @var \phpseclib3\Math\BigInteger - */ - protected $publicExponent; - - /** - * Sets the public exponent for key generation - * - * This will be 65537 unless changed. - * - * @param int $val - */ - public static function setExponent($val) - { - self::$defaultExponent = $val; - } - - /** - * Sets the smallest prime number in bits. Used for key generation - * - * This will be 4096 unless changed. - * - * @param int $val - */ - public static function setSmallestPrime($val) - { - self::$smallestPrime = $val; - } - - /** - * Sets the OpenSSL config file path - * - * Set to the empty string to use the default config file - * - * @param string $val - */ - public static function setOpenSSLConfigPath($val) - { - self::$configFile = $val; - } - - /** - * Create a private key - * - * The public key can be extracted from the private key - * - * @return RSA\PrivateKey - * @param int $bits - */ - public static function createKey($bits = 2048) - { - self::initialize_static_variables(); - - $class = new \ReflectionClass(static::class); - if ($class->isFinal()) { - throw new \RuntimeException('createKey() should not be called from final classes (' . static::class . ')'); - } - - $regSize = $bits >> 1; // divide by two to see how many bits P and Q would be - if ($regSize > self::$smallestPrime) { - $num_primes = floor($bits / self::$smallestPrime); - $regSize = self::$smallestPrime; - } else { - $num_primes = 2; - } - - if ($num_primes == 2 && $bits >= 384 && self::$defaultExponent == 65537) { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - - // OpenSSL uses 65537 as the exponent and requires RSA keys be 384 bits minimum - if (self::$engines['OpenSSL']) { - $config = []; - if (self::$configFile) { - $config['config'] = self::$configFile; - } - $rsa = openssl_pkey_new(['private_key_bits' => $bits] + $config); - openssl_pkey_export($rsa, $privatekeystr, null, $config); - - // clear the buffer of error strings stemming from a minimalistic openssl.cnf - // https://github.com/php/php-src/issues/11054 talks about other errors this'll pick up - while (openssl_error_string() !== false) { - } - - return RSA::load($privatekeystr); - } - } - - static $e; - if (!isset($e)) { - $e = new BigInteger(self::$defaultExponent); - } - - $n = clone self::$one; - $exponents = $coefficients = $primes = []; - $lcm = [ - 'top' => clone self::$one, - 'bottom' => false - ]; - - do { - for ($i = 1; $i <= $num_primes; $i++) { - if ($i != $num_primes) { - $primes[$i] = BigInteger::randomPrime($regSize); - } else { - extract(BigInteger::minMaxBits($bits)); - /** @var BigInteger $min - * @var BigInteger $max - */ - list($min) = $min->divide($n); - $min = $min->add(self::$one); - list($max) = $max->divide($n); - $primes[$i] = BigInteger::randomRangePrime($min, $max); - } - - // the first coefficient is calculated differently from the rest - // ie. instead of being $primes[1]->modInverse($primes[2]), it's $primes[2]->modInverse($primes[1]) - if ($i > 2) { - $coefficients[$i] = $n->modInverse($primes[$i]); - } - - $n = $n->multiply($primes[$i]); - - $temp = $primes[$i]->subtract(self::$one); - - // textbook RSA implementations use Euler's totient function instead of the least common multiple. - // see http://en.wikipedia.org/wiki/Euler%27s_totient_function - $lcm['top'] = $lcm['top']->multiply($temp); - $lcm['bottom'] = $lcm['bottom'] === false ? $temp : $lcm['bottom']->gcd($temp); - } - - list($temp) = $lcm['top']->divide($lcm['bottom']); - $gcd = $temp->gcd($e); - $i0 = 1; - } while (!$gcd->equals(self::$one)); - - $coefficients[2] = $primes[2]->modInverse($primes[1]); - - $d = $e->modInverse($temp); - - foreach ($primes as $i => $prime) { - $temp = $prime->subtract(self::$one); - $exponents[$i] = $e->modInverse($temp); - } - - // from : - // RSAPrivateKey ::= SEQUENCE { - // version Version, - // modulus INTEGER, -- n - // publicExponent INTEGER, -- e - // privateExponent INTEGER, -- d - // prime1 INTEGER, -- p - // prime2 INTEGER, -- q - // exponent1 INTEGER, -- d mod (p-1) - // exponent2 INTEGER, -- d mod (q-1) - // coefficient INTEGER, -- (inverse of q) mod p - // otherPrimeInfos OtherPrimeInfos OPTIONAL - // } - $privatekey = new PrivateKey(); - $privatekey->modulus = $n; - $privatekey->k = $bits >> 3; - $privatekey->publicExponent = $e; - $privatekey->exponent = $d; - $privatekey->primes = $primes; - $privatekey->exponents = $exponents; - $privatekey->coefficients = $coefficients; - - /* - $publickey = new PublicKey; - $publickey->modulus = $n; - $publickey->k = $bits >> 3; - $publickey->exponent = $e; - $publickey->publicExponent = $e; - $publickey->isPublic = true; - */ - - return $privatekey; - } - - /** - * OnLoad Handler - * - * @return bool - */ - protected static function onLoad(array $components) - { - $key = $components['isPublicKey'] ? - new PublicKey() : - new PrivateKey(); - - $key->modulus = $components['modulus']; - $key->publicExponent = $components['publicExponent']; - $key->k = $key->modulus->getLengthInBytes(); - - if ($components['isPublicKey'] || !isset($components['privateExponent'])) { - $key->exponent = $key->publicExponent; - } else { - $key->privateExponent = $components['privateExponent']; - $key->exponent = $key->privateExponent; - $key->primes = $components['primes']; - $key->exponents = $components['exponents']; - $key->coefficients = $components['coefficients']; - } - - if ($components['format'] == PSS::class) { - // in the X509 world RSA keys are assumed to use PKCS1 padding by default. only if the key is - // explicitly a PSS key is the use of PSS assumed. phpseclib does not work like this. phpseclib - // uses PSS padding by default. it assumes the more secure method by default and altho it provides - // for the less secure PKCS1 method you have to go out of your way to use it. this is consistent - // with the latest trends in crypto. libsodium (NaCl) is actually a little more extreme in that - // not only does it defaults to the most secure methods - it doesn't even let you choose less - // secure methods - //$key = $key->withPadding(self::SIGNATURE_PSS); - if (isset($components['hash'])) { - $key = $key->withHash($components['hash']); - } - if (isset($components['MGFHash'])) { - $key = $key->withMGFHash($components['MGFHash']); - } - if (isset($components['saltLength'])) { - $key = $key->withSaltLength($components['saltLength']); - } - } - - return $key; - } - - /** - * Initialize static variables - */ - protected static function initialize_static_variables() - { - if (!isset(self::$configFile)) { - self::$configFile = dirname(__FILE__) . '/../openssl.cnf'; - } - - parent::initialize_static_variables(); - } - - /** - * Constructor - * - * PublicKey and PrivateKey objects can only be created from abstract RSA class - */ - protected function __construct() - { - parent::__construct(); - - $this->hLen = $this->hash->getLengthInBytes(); - $this->mgfHash = new Hash('sha256'); - $this->mgfHLen = $this->mgfHash->getLengthInBytes(); - } - - /** - * Integer-to-Octet-String primitive - * - * See {@link http://tools.ietf.org/html/rfc3447#section-4.1 RFC3447#section-4.1}. - * - * @param bool|\phpseclib3\Math\BigInteger $x - * @param int $xLen - * @return bool|string - */ - protected function i2osp($x, $xLen) - { - if ($x === false) { - return false; - } - $x = $x->toBytes(); - if (strlen($x) > $xLen) { - throw new \OutOfRangeException('Resultant string length out of range'); - } - return str_pad($x, $xLen, chr(0), STR_PAD_LEFT); - } - - /** - * Octet-String-to-Integer primitive - * - * See {@link http://tools.ietf.org/html/rfc3447#section-4.2 RFC3447#section-4.2}. - * - * @param string $x - * @return \phpseclib3\Math\BigInteger - */ - protected function os2ip($x) - { - return new BigInteger($x, 256); - } - - /** - * EMSA-PKCS1-V1_5-ENCODE - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.2 RFC3447#section-9.2}. - * - * @param string $m - * @param int $emLen - * @throws \LengthException if the intended encoded message length is too short - * @return string - */ - protected function emsa_pkcs1_v1_5_encode($m, $emLen) - { - $h = $this->hash->hash($m); - - // see http://tools.ietf.org/html/rfc3447#page-43 - switch ($this->hash->getHash()) { - case 'md2': - $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02\x05\x00\x04\x10"; - break; - case 'md5': - $t = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"; - break; - case 'sha1': - $t = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"; - break; - case 'sha256': - $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"; - break; - case 'sha384': - $t = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"; - break; - case 'sha512': - $t = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"; - break; - // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 - case 'sha224': - $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"; - break; - case 'sha512/224': - $t = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x05\x00\x04\x1c"; - break; - case 'sha512/256': - $t = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x05\x00\x04\x20"; - } - $t .= $h; - $tLen = strlen($t); - - if ($emLen < $tLen + 11) { - throw new \LengthException('Intended encoded message length too short'); - } - - $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); - - $em = "\0\1$ps\0$t"; - - return $em; - } - - /** - * EMSA-PKCS1-V1_5-ENCODE (without NULL) - * - * Quoting https://tools.ietf.org/html/rfc8017#page-65, - * - * "The parameters field associated with id-sha1, id-sha224, id-sha256, - * id-sha384, id-sha512, id-sha512/224, and id-sha512/256 should - * generally be omitted, but if present, it shall have a value of type - * NULL" - * - * @param string $m - * @param int $emLen - * @return string - */ - protected function emsa_pkcs1_v1_5_encode_without_null($m, $emLen) - { - $h = $this->hash->hash($m); - - // see http://tools.ietf.org/html/rfc3447#page-43 - switch ($this->hash->getHash()) { - case 'sha1': - $t = "\x30\x1f\x30\x07\x06\x05\x2b\x0e\x03\x02\x1a\x04\x14"; - break; - case 'sha256': - $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x04\x20"; - break; - case 'sha384': - $t = "\x30\x3f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x04\x30"; - break; - case 'sha512': - $t = "\x30\x4f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x04\x40"; - break; - // from https://www.emc.com/collateral/white-papers/h11300-pkcs-1v2-2-rsa-cryptography-standard-wp.pdf#page=40 - case 'sha224': - $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x04\x1c"; - break; - case 'sha512/224': - $t = "\x30\x2b\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x05\x04\x1c"; - break; - case 'sha512/256': - $t = "\x30\x2f\x30\x0b\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x06\x04\x20"; - break; - default: - throw new UnsupportedAlgorithmException('md2 and md5 require NULLs'); - } - $t .= $h; - $tLen = strlen($t); - - if ($emLen < $tLen + 11) { - throw new \LengthException('Intended encoded message length too short'); - } - - $ps = str_repeat(chr(0xFF), $emLen - $tLen - 3); - - $em = "\0\1$ps\0$t"; - - return $em; - } - - /** - * MGF1 - * - * See {@link http://tools.ietf.org/html/rfc3447#appendix-B.2.1 RFC3447#appendix-B.2.1}. - * - * @param string $mgfSeed - * @param int $maskLen - * @return string - */ - protected function mgf1($mgfSeed, $maskLen) - { - // if $maskLen would yield strings larger than 4GB, PKCS#1 suggests a "Mask too long" error be output. - - $t = ''; - $count = ceil($maskLen / $this->mgfHLen); - for ($i = 0; $i < $count; $i++) { - $c = pack('N', $i); - $t .= $this->mgfHash->hash($mgfSeed . $c); - } - - return substr($t, 0, $maskLen); - } - - /** - * Returns the key size - * - * More specifically, this returns the size of the modulo in bits. - * - * @return int - */ - public function getLength() - { - return !isset($this->modulus) ? 0 : $this->modulus->getLength(); - } - - /** - * Determines which hashing function should be used - * - * Used with signature production / verification and (if the encryption mode is self::PADDING_OAEP) encryption and - * decryption. - * - * @param string $hash - */ - public function withHash($hash) - { - $new = clone $this; - - // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. - switch (strtolower($hash)) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha256': - case 'sha384': - case 'sha512': - case 'sha224': - case 'sha512/224': - case 'sha512/256': - $new->hash = new Hash($hash); - break; - default: - throw new UnsupportedAlgorithmException( - 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' - ); - } - $new->hLen = $new->hash->getLengthInBytes(); - - return $new; - } - - /** - * Determines which hashing function should be used for the mask generation function - * - * The mask generation function is used by self::PADDING_OAEP and self::PADDING_PSS and although it's - * best if Hash and MGFHash are set to the same thing this is not a requirement. - * - * @param string $hash - */ - public function withMGFHash($hash) - { - $new = clone $this; - - // \phpseclib3\Crypt\Hash supports algorithms that PKCS#1 doesn't support. md5-96 and sha1-96, for example. - switch (strtolower($hash)) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha256': - case 'sha384': - case 'sha512': - case 'sha224': - case 'sha512/224': - case 'sha512/256': - $new->mgfHash = new Hash($hash); - break; - default: - throw new UnsupportedAlgorithmException( - 'The only supported hash algorithms are: md2, md5, sha1, sha256, sha384, sha512, sha224, sha512/224, sha512/256' - ); - } - $new->mgfHLen = $new->mgfHash->getLengthInBytes(); - - return $new; - } - - /** - * Returns the MGF hash algorithm currently being used - * - */ - public function getMGFHash() - { - return clone $this->mgfHash; - } - - /** - * Determines the salt length - * - * Used by RSA::PADDING_PSS - * - * To quote from {@link http://tools.ietf.org/html/rfc3447#page-38 RFC3447#page-38}: - * - * Typical salt lengths in octets are hLen (the length of the output - * of the hash function Hash) and 0. - * - * @param int $sLen - */ - public function withSaltLength($sLen) - { - $new = clone $this; - $new->sLen = $sLen; - return $new; - } - - /** - * Returns the salt length currently being used - * - */ - public function getSaltLength() - { - return $this->sLen !== null ? $this->sLen : $this->hLen; - } - - /** - * Determines the label - * - * Used by RSA::PADDING_OAEP - * - * To quote from {@link http://tools.ietf.org/html/rfc3447#page-17 RFC3447#page-17}: - * - * Both the encryption and the decryption operations of RSAES-OAEP take - * the value of a label L as input. In this version of PKCS #1, L is - * the empty string; other uses of the label are outside the scope of - * this document. - * - * @param string $label - */ - public function withLabel($label) - { - $new = clone $this; - $new->label = $label; - return $new; - } - - /** - * Returns the label currently being used - * - */ - public function getLabel() - { - return $this->label; - } - - /** - * Determines the padding modes - * - * Example: $key->withPadding(RSA::ENCRYPTION_PKCS1 | RSA::SIGNATURE_PKCS1); - * - * @param int $padding - */ - public function withPadding($padding) - { - $masks = [ - self::ENCRYPTION_OAEP, - self::ENCRYPTION_PKCS1, - self::ENCRYPTION_NONE - ]; - $encryptedCount = 0; - $selected = 0; - foreach ($masks as $mask) { - if ($padding & $mask) { - $selected = $mask; - $encryptedCount++; - } - } - if ($encryptedCount > 1) { - throw new InconsistentSetupException('Multiple encryption padding modes have been selected; at most only one should be selected'); - } - $encryptionPadding = $selected; - - $masks = [ - self::SIGNATURE_PSS, - self::SIGNATURE_RELAXED_PKCS1, - self::SIGNATURE_PKCS1 - ]; - $signatureCount = 0; - $selected = 0; - foreach ($masks as $mask) { - if ($padding & $mask) { - $selected = $mask; - $signatureCount++; - } - } - if ($signatureCount > 1) { - throw new InconsistentSetupException('Multiple signature padding modes have been selected; at most only one should be selected'); - } - $signaturePadding = $selected; - - $new = clone $this; - if ($encryptedCount) { - $new->encryptionPadding = $encryptionPadding; - } - if ($signatureCount) { - $new->signaturePadding = $signaturePadding; - } - return $new; - } - - /** - * Returns the padding currently being used - * - */ - public function getPadding() - { - return $this->signaturePadding | $this->encryptionPadding; - } - - /** - * Returns the current engine being used - * - * OpenSSL is only used in this class (and it's subclasses) for key generation - * Even then it depends on the parameters you're using. It's not used for - * multi-prime RSA nor is it used if the key length is outside of the range - * supported by OpenSSL - * - * @see self::useInternalEngine() - * @see self::useBestEngine() - * @return string - */ - public function getEngine() - { - if (!isset(self::$engines['PHP'])) { - self::useBestEngine(); - } - return self::$engines['OpenSSL'] && self::$defaultExponent == 65537 ? - 'OpenSSL' : - 'PHP'; - } - - /** - * Enable RSA Blinding - * - */ - public static function enableBlinding() - { - static::$enableBlinding = true; - } - - /** - * Disable RSA Blinding - * - */ - public static function disableBlinding() - { - static::$enableBlinding = false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php deleted file mode 100644 index 87f543d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/JWK.php +++ /dev/null @@ -1,142 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\JWK as Progenitor; -use phpseclib3\Math\BigInteger; - -/** - * JWK Formatted RSA Handler - * - * @author Jim Wigginton - */ -abstract class JWK extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - if ($key->kty != 'RSA') { - throw new \RuntimeException('Only RSA JWK keys are supported'); - } - - $count = $publicCount = 0; - $vars = ['n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi']; - foreach ($vars as $var) { - if (!isset($key->$var) || !is_string($key->$var)) { - continue; - } - $count++; - $value = new BigInteger(Strings::base64url_decode($key->$var), 256); - switch ($var) { - case 'n': - $publicCount++; - $components['modulus'] = $value; - break; - case 'e': - $publicCount++; - $components['publicExponent'] = $value; - break; - case 'd': - $components['privateExponent'] = $value; - break; - case 'p': - $components['primes'][1] = $value; - break; - case 'q': - $components['primes'][2] = $value; - break; - case 'dp': - $components['exponents'][1] = $value; - break; - case 'dq': - $components['exponents'][2] = $value; - break; - case 'qi': - $components['coefficients'][2] = $value; - } - } - - if ($count == count($vars)) { - return $components + ['isPublicKey' => false]; - } - - if ($count == 2 && $publicCount == 2) { - return $components + ['isPublicKey' => true]; - } - - throw new \UnexpectedValueException('Key does not have an appropriate number of RSA parameters'); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('JWK does not support multi-prime RSA keys'); - } - - $key = [ - 'kty' => 'RSA', - 'n' => Strings::base64url_encode($n->toBytes()), - 'e' => Strings::base64url_encode($e->toBytes()), - 'd' => Strings::base64url_encode($d->toBytes()), - 'p' => Strings::base64url_encode($primes[1]->toBytes()), - 'q' => Strings::base64url_encode($primes[2]->toBytes()), - 'dp' => Strings::base64url_encode($exponents[1]->toBytes()), - 'dq' => Strings::base64url_encode($exponents[2]->toBytes()), - 'qi' => Strings::base64url_encode($coefficients[2]->toBytes()) - ]; - - return self::wrapKey($key, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - $key = [ - 'kty' => 'RSA', - 'n' => Strings::base64url_encode($n->toBytes()), - 'e' => Strings::base64url_encode($e->toBytes()) - ]; - - return self::wrapKey($key, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php deleted file mode 100644 index e9a0c4f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/MSBLOB.php +++ /dev/null @@ -1,228 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Math\BigInteger; - -/** - * Microsoft BLOB Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class MSBLOB -{ - /** - * Public/Private Key Pair - * - */ - const PRIVATEKEYBLOB = 0x7; - /** - * Public Key - * - */ - const PUBLICKEYBLOB = 0x6; - /** - * Public Key - * - */ - const PUBLICKEYBLOBEX = 0xA; - /** - * RSA public key exchange algorithm - * - */ - const CALG_RSA_KEYX = 0x0000A400; - /** - * RSA public key exchange algorithm - * - */ - const CALG_RSA_SIGN = 0x00002400; - /** - * Public Key - * - */ - const RSA1 = 0x31415352; - /** - * Private Key - * - */ - const RSA2 = 0x32415352; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $key = Strings::base64_decode($key); - - if (!is_string($key)) { - throw new \UnexpectedValueException('Base64 decoding produced an error'); - } - if (strlen($key) < 20) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - // PUBLICKEYSTRUC publickeystruc - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387453(v=vs.85).aspx - extract(unpack('atype/aversion/vreserved/Valgo', Strings::shift($key, 8))); - /** - * @var string $type - * @var string $version - * @var integer $reserved - * @var integer $algo - */ - switch (ord($type)) { - case self::PUBLICKEYBLOB: - case self::PUBLICKEYBLOBEX: - $publickey = true; - break; - case self::PRIVATEKEYBLOB: - $publickey = false; - break; - default: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $components = ['isPublicKey' => $publickey]; - - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa375549(v=vs.85).aspx - switch ($algo) { - case self::CALG_RSA_KEYX: - case self::CALG_RSA_SIGN: - break; - default: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - // RSAPUBKEY rsapubkey - // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387685(v=vs.85).aspx - // could do V for pubexp but that's unsigned 32-bit whereas some PHP installs only do signed 32-bit - extract(unpack('Vmagic/Vbitlen/a4pubexp', Strings::shift($key, 12))); - /** - * @var integer $magic - * @var integer $bitlen - * @var string $pubexp - */ - switch ($magic) { - case self::RSA2: - $components['isPublicKey'] = false; - // fall-through - case self::RSA1: - break; - default: - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $baseLength = $bitlen / 16; - if (strlen($key) != 2 * $baseLength && strlen($key) != 9 * $baseLength) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - - $components[$components['isPublicKey'] ? 'publicExponent' : 'privateExponent'] = new BigInteger(strrev($pubexp), 256); - // BYTE modulus[rsapubkey.bitlen/8] - $components['modulus'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); - - if ($publickey) { - return $components; - } - - $components['isPublicKey'] = false; - - // BYTE prime1[rsapubkey.bitlen/16] - $components['primes'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; - // BYTE prime2[rsapubkey.bitlen/16] - $components['primes'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); - // BYTE exponent1[rsapubkey.bitlen/16] - $components['exponents'] = [1 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; - // BYTE exponent2[rsapubkey.bitlen/16] - $components['exponents'][] = new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256); - // BYTE coefficient[rsapubkey.bitlen/16] - $components['coefficients'] = [2 => new BigInteger(strrev(Strings::shift($key, $bitlen / 16)), 256)]; - if (isset($components['privateExponent'])) { - $components['publicExponent'] = $components['privateExponent']; - } - // BYTE privateExponent[rsapubkey.bitlen/8] - $components['privateExponent'] = new BigInteger(strrev(Strings::shift($key, $bitlen / 8)), 256); - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('MSBLOB does not support multi-prime RSA keys'); - } - - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('MSBLOB private keys do not support encryption'); - } - - $n = strrev($n->toBytes()); - $e = str_pad(strrev($e->toBytes()), 4, "\0"); - $key = pack('aavV', chr(self::PRIVATEKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); - $key .= pack('VVa*', self::RSA2, 8 * strlen($n), $e); - $key .= $n; - $key .= strrev($primes[1]->toBytes()); - $key .= strrev($primes[2]->toBytes()); - $key .= strrev($exponents[1]->toBytes()); - $key .= strrev($exponents[2]->toBytes()); - $key .= strrev($coefficients[2]->toBytes()); - $key .= strrev($d->toBytes()); - - return Strings::base64_encode($key); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - $n = strrev($n->toBytes()); - $e = str_pad(strrev($e->toBytes()), 4, "\0"); - $key = pack('aavV', chr(self::PUBLICKEYBLOB), chr(2), 0, self::CALG_RSA_KEYX); - $key .= pack('VVa*', self::RSA1, 8 * strlen($n), $e); - $key .= $n; - - return Strings::base64_encode($key); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php deleted file mode 100644 index 2367810..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/OpenSSH.php +++ /dev/null @@ -1,132 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\OpenSSH as Progenitor; -use phpseclib3\Math\BigInteger; - -/** - * OpenSSH Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class OpenSSH extends Progenitor -{ - /** - * Supported Key Types - * - * @var array - */ - protected static $types = ['ssh-rsa']; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $parsed = parent::load($key, $password); - - if (isset($parsed['paddedKey'])) { - list($type) = Strings::unpackSSH2('s', $parsed['paddedKey']); - if ($type != $parsed['type']) { - throw new \RuntimeException("The public and private keys are not of the same type ($type vs $parsed[type])"); - } - - $primes = $coefficients = []; - - list( - $modulus, - $publicExponent, - $privateExponent, - $coefficients[2], - $primes[1], - $primes[2], - $comment, - ) = Strings::unpackSSH2('i6s', $parsed['paddedKey']); - - $temp = $primes[1]->subtract($one); - $exponents = [1 => $publicExponent->modInverse($temp)]; - $temp = $primes[2]->subtract($one); - $exponents[] = $publicExponent->modInverse($temp); - - $isPublicKey = false; - - return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); - } - - list($publicExponent, $modulus) = Strings::unpackSSH2('ii', $parsed['publicKey']); - - return [ - 'isPublicKey' => true, - 'modulus' => $modulus, - 'publicExponent' => $publicExponent, - 'comment' => $parsed['comment'] - ]; - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - $RSAPublicKey = Strings::packSSH2('sii', 'ssh-rsa', $e, $n); - - if (isset($options['binary']) ? $options['binary'] : self::$binary) { - return $RSAPublicKey; - } - - $comment = isset($options['comment']) ? $options['comment'] : self::$comment; - $RSAPublicKey = 'ssh-rsa ' . base64_encode($RSAPublicKey) . ' ' . $comment; - - return $RSAPublicKey; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - $publicKey = self::savePublicKey($n, $e, ['binary' => true]); - $privateKey = Strings::packSSH2('si6', 'ssh-rsa', $n, $e, $d, $coefficients[2], $primes[1], $primes[2]); - - return self::wrapPrivateKey($publicKey, $privateKey, $password, $options); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php deleted file mode 100644 index 276c602..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS1.php +++ /dev/null @@ -1,160 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS1 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#1 Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS1 extends Progenitor -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (strpos($key, 'PUBLIC') !== false) { - $components = ['isPublicKey' => true]; - } elseif (strpos($key, 'PRIVATE') !== false) { - $components = ['isPublicKey' => false]; - } else { - $components = []; - } - - $key = parent::load($key, $password); - - $decoded = ASN1::decodeBER($key); - if (!$decoded) { - throw new \RuntimeException('Unable to decode BER'); - } - - $key = ASN1::asn1map($decoded[0], Maps\RSAPrivateKey::MAP); - if (is_array($key)) { - $components += [ - 'modulus' => $key['modulus'], - 'publicExponent' => $key['publicExponent'], - 'privateExponent' => $key['privateExponent'], - 'primes' => [1 => $key['prime1'], $key['prime2']], - 'exponents' => [1 => $key['exponent1'], $key['exponent2']], - 'coefficients' => [2 => $key['coefficient']] - ]; - if ($key['version'] == 'multi') { - foreach ($key['otherPrimeInfos'] as $primeInfo) { - $components['primes'][] = $primeInfo['prime']; - $components['exponents'][] = $primeInfo['exponent']; - $components['coefficients'][] = $primeInfo['coefficient']; - } - } - if (!isset($components['isPublicKey'])) { - $components['isPublicKey'] = false; - } - return $components; - } - - $key = ASN1::asn1map($decoded[0], Maps\RSAPublicKey::MAP); - - if (!is_array($key)) { - throw new \RuntimeException('Unable to perform ASN1 mapping'); - } - - if (!isset($components['isPublicKey'])) { - $components['isPublicKey'] = true; - } - - return $components + $key; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - $num_primes = count($primes); - $key = [ - 'version' => $num_primes == 2 ? 'two-prime' : 'multi', - 'modulus' => $n, - 'publicExponent' => $e, - 'privateExponent' => $d, - 'prime1' => $primes[1], - 'prime2' => $primes[2], - 'exponent1' => $exponents[1], - 'exponent2' => $exponents[2], - 'coefficient' => $coefficients[2] - ]; - for ($i = 3; $i <= $num_primes; $i++) { - $key['otherPrimeInfos'][] = [ - 'prime' => $primes[$i], - 'exponent' => $exponents[$i], - 'coefficient' => $coefficients[$i] - ]; - } - - $key = ASN1::encodeDER($key, Maps\RSAPrivateKey::MAP); - - return self::wrapPrivateKey($key, 'RSA', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - $key = [ - 'modulus' => $n, - 'publicExponent' => $e - ]; - - $key = ASN1::encodeDER($key, Maps\RSAPublicKey::MAP); - - return self::wrapPublicKey($key, 'RSA'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php deleted file mode 100644 index 1eaac6e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PKCS8.php +++ /dev/null @@ -1,122 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#8 Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class PKCS8 extends Progenitor -{ - /** - * OID Name - * - * @var string - */ - const OID_NAME = 'rsaEncryption'; - - /** - * OID Value - * - * @var string - */ - const OID_VALUE = '1.2.840.113549.1.1.1'; - - /** - * Child OIDs loaded - * - * @var bool - */ - protected static $childOIDsLoaded = false; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - $key = parent::load($key, $password); - - if (isset($key['privateKey'])) { - $components['isPublicKey'] = false; - $type = 'private'; - } else { - $components['isPublicKey'] = true; - $type = 'public'; - } - - $result = $components + PKCS1::load($key[$type . 'Key']); - - if (isset($key['meta'])) { - $result['meta'] = $key['meta']; - } - - return $result; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); - $key = ASN1::extractBER($key); - return self::wrapPrivateKey($key, [], null, $password, null, '', $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - $key = PKCS1::savePublicKey($n, $e); - $key = ASN1::extractBER($key); - return self::wrapPublicKey($key, null); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php deleted file mode 100644 index ed75b9b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PSS.php +++ /dev/null @@ -1,238 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PKCS8 as Progenitor; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * PKCS#8 Formatted RSA-PSS Key Handler - * - * @author Jim Wigginton - */ -abstract class PSS extends Progenitor -{ - /** - * OID Name - * - * @var string - */ - const OID_NAME = 'id-RSASSA-PSS'; - - /** - * OID Value - * - * @var string - */ - const OID_VALUE = '1.2.840.113549.1.1.10'; - - /** - * OIDs loaded - * - * @var bool - */ - private static $oidsLoaded = false; - - /** - * Child OIDs loaded - * - * @var bool - */ - protected static $childOIDsLoaded = false; - - /** - * Initialize static variables - */ - private static function initialize_static_variables() - { - if (!self::$oidsLoaded) { - ASN1::loadOIDs([ - 'md2' => '1.2.840.113549.2.2', - 'md4' => '1.2.840.113549.2.4', - 'md5' => '1.2.840.113549.2.5', - 'id-sha1' => '1.3.14.3.2.26', - 'id-sha256' => '2.16.840.1.101.3.4.2.1', - 'id-sha384' => '2.16.840.1.101.3.4.2.2', - 'id-sha512' => '2.16.840.1.101.3.4.2.3', - 'id-sha224' => '2.16.840.1.101.3.4.2.4', - 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', - 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', - - 'id-mgf1' => '1.2.840.113549.1.1.8' - ]); - self::$oidsLoaded = true; - } - } - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - self::initialize_static_variables(); - - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - $components = ['isPublicKey' => strpos($key, 'PUBLIC') !== false]; - - $key = parent::load($key, $password); - - $type = isset($key['privateKey']) ? 'private' : 'public'; - - $result = $components + PKCS1::load($key[$type . 'Key']); - - if (isset($key[$type . 'KeyAlgorithm']['parameters'])) { - $decoded = ASN1::decodeBER($key[$type . 'KeyAlgorithm']['parameters']); - if ($decoded === false) { - throw new \UnexpectedValueException('Unable to decode parameters'); - } - $params = ASN1::asn1map($decoded[0], Maps\RSASSA_PSS_params::MAP); - } else { - $params = []; - } - - if (isset($params['maskGenAlgorithm']['parameters'])) { - $decoded = ASN1::decodeBER($params['maskGenAlgorithm']['parameters']); - if ($decoded === false) { - throw new \UnexpectedValueException('Unable to decode parameters'); - } - $params['maskGenAlgorithm']['parameters'] = ASN1::asn1map($decoded[0], Maps\HashAlgorithm::MAP); - } else { - $params['maskGenAlgorithm'] = [ - 'algorithm' => 'id-mgf1', - 'parameters' => ['algorithm' => 'id-sha1'] - ]; - } - - if (!isset($params['hashAlgorithm']['algorithm'])) { - $params['hashAlgorithm']['algorithm'] = 'id-sha1'; - } - - $result['hash'] = str_replace('id-', '', $params['hashAlgorithm']['algorithm']); - $result['MGFHash'] = str_replace('id-', '', $params['maskGenAlgorithm']['parameters']['algorithm']); - if (isset($params['saltLength'])) { - $result['saltLength'] = (int) $params['saltLength']->toString(); - } - - if (isset($key['meta'])) { - $result['meta'] = $key['meta']; - } - - return $result; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - self::initialize_static_variables(); - - $key = PKCS1::savePrivateKey($n, $e, $d, $primes, $exponents, $coefficients); - $key = ASN1::extractBER($key); - $params = self::savePSSParams($options); - return self::wrapPrivateKey($key, [], $params, $password, null, '', $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param array $options optional - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e, array $options = []) - { - self::initialize_static_variables(); - - $key = PKCS1::savePublicKey($n, $e); - $key = ASN1::extractBER($key); - $params = self::savePSSParams($options); - return self::wrapPublicKey($key, $params); - } - - /** - * Encodes PSS parameters - * - * @param array $options - * @return string - */ - public static function savePSSParams(array $options) - { - /* - The trailerField field is an integer. It provides - compatibility with IEEE Std 1363a-2004 [P1363A]. The value - MUST be 1, which represents the trailer field with hexadecimal - value 0xBC. Other trailer fields, including the trailer field - composed of HashID concatenated with 0xCC that is specified in - IEEE Std 1363a, are not supported. Implementations that - perform signature generation MUST omit the trailerField field, - indicating that the default trailer field value was used. - Implementations that perform signature validation MUST - recognize both a present trailerField field with value 1 and an - absent trailerField field. - - source: https://tools.ietf.org/html/rfc4055#page-9 - */ - $params = [ - 'trailerField' => new BigInteger(1) - ]; - if (isset($options['hash'])) { - $params['hashAlgorithm']['algorithm'] = 'id-' . $options['hash']; - } - if (isset($options['MGFHash'])) { - $temp = ['algorithm' => 'id-' . $options['MGFHash']]; - $temp = ASN1::encodeDER($temp, Maps\HashAlgorithm::MAP); - $params['maskGenAlgorithm'] = [ - 'algorithm' => 'id-mgf1', - 'parameters' => new ASN1\Element($temp) - ]; - } - if (isset($options['saltLength'])) { - $params['saltLength'] = new BigInteger($options['saltLength']); - } - - return new ASN1\Element(ASN1::encodeDER($params, Maps\RSASSA_PSS_params::MAP)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php deleted file mode 100644 index fe35717..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/PuTTY.php +++ /dev/null @@ -1,121 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\Formats\Keys\PuTTY as Progenitor; -use phpseclib3\Math\BigInteger; - -/** - * PuTTY Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class PuTTY extends Progenitor -{ - /** - * Public Handler - * - * @var string - */ - const PUBLIC_HANDLER = 'phpseclib3\Crypt\RSA\Formats\Keys\OpenSSH'; - - /** - * Algorithm Identifier - * - * @var array - */ - protected static $types = ['ssh-rsa']; - - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - $components = parent::load($key, $password); - if (!isset($components['private'])) { - return $components; - } - extract($components); - unset($components['public'], $components['private']); - - $isPublicKey = false; - - $result = Strings::unpackSSH2('ii', $public); - if ($result === false) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - list($publicExponent, $modulus) = $result; - - $result = Strings::unpackSSH2('iiii', $private); - if ($result === false) { - throw new \UnexpectedValueException('Key appears to be malformed'); - } - $primes = $coefficients = []; - list($privateExponent, $primes[1], $primes[2], $coefficients[2]) = $result; - - $temp = $primes[1]->subtract($one); - $exponents = [1 => $publicExponent->modInverse($temp)]; - $temp = $primes[2]->subtract($one); - $exponents[] = $publicExponent->modInverse($temp); - - return compact('publicExponent', 'modulus', 'privateExponent', 'primes', 'coefficients', 'exponents', 'comment', 'isPublicKey'); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('PuTTY does not support multi-prime RSA keys'); - } - - $public = Strings::packSSH2('ii', $e, $n); - $private = Strings::packSSH2('iiii', $d, $primes[1], $primes[2], $coefficients[2]); - - return self::wrapPrivateKey($public, $private, 'ssh-rsa', $password, $options); - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - return self::wrapPublicKey(Strings::packSSH2('ii', $e, $n), 'ssh-rsa'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php deleted file mode 100644 index db72878..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/Raw.php +++ /dev/null @@ -1,184 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Math\BigInteger; - -/** - * Raw RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class Raw -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!is_array($key)) { - throw new \UnexpectedValueException('Key should be a array - not a ' . gettype($key)); - } - - $key = array_change_key_case($key, CASE_LOWER); - - $components = ['isPublicKey' => false]; - - foreach (['e', 'exponent', 'publicexponent', 0, 'privateexponent', 'd'] as $index) { - if (isset($key[$index])) { - $components['publicExponent'] = $key[$index]; - break; - } - } - - foreach (['n', 'modulo', 'modulus', 1] as $index) { - if (isset($key[$index])) { - $components['modulus'] = $key[$index]; - break; - } - } - - if (!isset($components['publicExponent']) || !isset($components['modulus'])) { - throw new \UnexpectedValueException('Modulus / exponent not present'); - } - - if (isset($key['primes'])) { - $components['primes'] = $key['primes']; - } elseif (isset($key['p']) && isset($key['q'])) { - $indices = [ - ['p', 'q'], - ['prime1', 'prime2'] - ]; - foreach ($indices as $index) { - list($i0, $i1) = $index; - if (isset($key[$i0]) && isset($key[$i1])) { - $components['primes'] = [1 => $key[$i0], $key[$i1]]; - } - } - } - - if (isset($key['exponents'])) { - $components['exponents'] = $key['exponents']; - } else { - $indices = [ - ['dp', 'dq'], - ['exponent1', 'exponent2'] - ]; - foreach ($indices as $index) { - list($i0, $i1) = $index; - if (isset($key[$i0]) && isset($key[$i1])) { - $components['exponents'] = [1 => $key[$i0], $key[$i1]]; - } - } - } - - if (isset($key['coefficients'])) { - $components['coefficients'] = $key['coefficients']; - } else { - foreach (['inverseq', 'q\'', 'coefficient'] as $index) { - if (isset($key[$index])) { - $components['coefficients'] = [2 => $key[$index]]; - } - } - } - - if (!isset($components['primes'])) { - $components['isPublicKey'] = true; - return $components; - } - - if (!isset($components['exponents'])) { - $one = new BigInteger(1); - $temp = $components['primes'][1]->subtract($one); - $exponents = [1 => $components['publicExponent']->modInverse($temp)]; - $temp = $components['primes'][2]->subtract($one); - $exponents[] = $components['publicExponent']->modInverse($temp); - $components['exponents'] = $exponents; - } - - if (!isset($components['coefficients'])) { - $components['coefficients'] = [2 => $components['primes'][2]->modInverse($components['primes'][1])]; - } - - foreach (['privateexponent', 'd'] as $index) { - if (isset($key[$index])) { - $components['privateExponent'] = $key[$index]; - break; - } - } - - return $components; - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @param array $options optional - * @return array - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '', array $options = []) - { - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('Raw private keys do not support encryption'); - } - - return [ - 'e' => clone $e, - 'n' => clone $n, - 'd' => clone $d, - 'primes' => array_map(function ($var) { - return clone $var; - }, $primes), - 'exponents' => array_map(function ($var) { - return clone $var; - }, $exponents), - 'coefficients' => array_map(function ($var) { - return clone $var; - }, $coefficients) - ]; - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return array - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - return ['e' => clone $e, 'n' => clone $n]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php deleted file mode 100644 index 280048c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/Formats/Keys/XML.php +++ /dev/null @@ -1,171 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA\Formats\Keys; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Math\BigInteger; - -/** - * XML Formatted RSA Key Handler - * - * @author Jim Wigginton - */ -abstract class XML -{ - /** - * Break a public or private key down into its constituent components - * - * @param string $key - * @param string $password optional - * @return array - */ - public static function load($key, $password = '') - { - if (!Strings::is_stringable($key)) { - throw new \UnexpectedValueException('Key should be a string - not a ' . gettype($key)); - } - - if (!class_exists('DOMDocument')) { - throw new BadConfigurationException('The dom extension is not setup correctly on this system'); - } - - $components = [ - 'isPublicKey' => false, - 'primes' => [], - 'exponents' => [], - 'coefficients' => [] - ]; - - $use_errors = libxml_use_internal_errors(true); - - $dom = new \DOMDocument(); - if (substr($key, 0, 5) != '' . $key . ''; - } - if (!$dom->loadXML($key)) { - libxml_use_internal_errors($use_errors); - throw new \UnexpectedValueException('Key does not appear to contain XML'); - } - $xpath = new \DOMXPath($dom); - $keys = ['modulus', 'exponent', 'p', 'q', 'dp', 'dq', 'inverseq', 'd']; - foreach ($keys as $key) { - // $dom->getElementsByTagName($key) is case-sensitive - $temp = $xpath->query("//*[translate(local-name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='$key']"); - if (!$temp->length) { - continue; - } - $value = new BigInteger(Strings::base64_decode($temp->item(0)->nodeValue), 256); - switch ($key) { - case 'modulus': - $components['modulus'] = $value; - break; - case 'exponent': - $components['publicExponent'] = $value; - break; - case 'p': - $components['primes'][1] = $value; - break; - case 'q': - $components['primes'][2] = $value; - break; - case 'dp': - $components['exponents'][1] = $value; - break; - case 'dq': - $components['exponents'][2] = $value; - break; - case 'inverseq': - $components['coefficients'][2] = $value; - break; - case 'd': - $components['privateExponent'] = $value; - } - } - - libxml_use_internal_errors($use_errors); - - foreach ($components as $key => $value) { - if (is_array($value) && !count($value)) { - unset($components[$key]); - } - } - - if (isset($components['modulus']) && isset($components['publicExponent'])) { - if (count($components) == 3) { - $components['isPublicKey'] = true; - } - return $components; - } - - throw new \UnexpectedValueException('Modulus / exponent not present'); - } - - /** - * Convert a private key to the appropriate format. - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @param \phpseclib3\Math\BigInteger $d - * @param array $primes - * @param array $exponents - * @param array $coefficients - * @param string $password optional - * @return string - */ - public static function savePrivateKey(BigInteger $n, BigInteger $e, BigInteger $d, array $primes, array $exponents, array $coefficients, $password = '') - { - if (count($primes) != 2) { - throw new \InvalidArgumentException('XML does not support multi-prime RSA keys'); - } - - if (!empty($password) && is_string($password)) { - throw new UnsupportedFormatException('XML private keys do not support encryption'); - } - - return "\r\n" . - ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . - '

          ' . Strings::base64_encode($primes[1]->toBytes()) . "

          \r\n" . - ' ' . Strings::base64_encode($primes[2]->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($exponents[1]->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($exponents[2]->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($coefficients[2]->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($d->toBytes()) . "\r\n" . - '
          '; - } - - /** - * Convert a public key to the appropriate format - * - * @param \phpseclib3\Math\BigInteger $n - * @param \phpseclib3\Math\BigInteger $e - * @return string - */ - public static function savePublicKey(BigInteger $n, BigInteger $e) - { - return "\r\n" . - ' ' . Strings::base64_encode($n->toBytes()) . "\r\n" . - ' ' . Strings::base64_encode($e->toBytes()) . "\r\n" . - ''; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php deleted file mode 100644 index 37dd09a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PrivateKey.php +++ /dev/null @@ -1,530 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA; - -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\Math\BigInteger; - -/** - * Raw RSA Key Handler - * - * @author Jim Wigginton - */ -final class PrivateKey extends RSA implements Common\PrivateKey -{ - use Common\Traits\PasswordProtected; - - /** - * Primes for Chinese Remainder Theorem (ie. p and q) - * - * @var array - */ - protected $primes; - - /** - * Exponents for Chinese Remainder Theorem (ie. dP and dQ) - * - * @var array - */ - protected $exponents; - - /** - * Coefficients for Chinese Remainder Theorem (ie. qInv) - * - * @var array - */ - protected $coefficients; - - /** - * Private Exponent - * - * @var \phpseclib3\Math\BigInteger - */ - protected $privateExponent; - - /** - * RSADP - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.2 RFC3447#section-5.1.2}. - * - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsadp(BigInteger $c) - { - if ($c->compare(self::$zero) < 0 || $c->compare($this->modulus) > 0) { - throw new \OutOfRangeException('Ciphertext representative out of range'); - } - return $this->exponentiate($c); - } - - /** - * RSASP1 - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.1 RFC3447#section-5.2.1}. - * - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsasp1(BigInteger $m) - { - if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { - throw new \OutOfRangeException('Signature representative out of range'); - } - return $this->exponentiate($m); - } - - /** - * Exponentiate - * - * @param \phpseclib3\Math\BigInteger $x - * @return \phpseclib3\Math\BigInteger - */ - protected function exponentiate(BigInteger $x) - { - switch (true) { - case empty($this->primes): - case $this->primes[1]->equals(self::$zero): - case empty($this->coefficients): - case $this->coefficients[2]->equals(self::$zero): - case empty($this->exponents): - case $this->exponents[1]->equals(self::$zero): - return $x->modPow($this->exponent, $this->modulus); - } - - $num_primes = count($this->primes); - - if (!static::$enableBlinding) { - $m_i = [ - 1 => $x->modPow($this->exponents[1], $this->primes[1]), - 2 => $x->modPow($this->exponents[2], $this->primes[2]) - ]; - $h = $m_i[1]->subtract($m_i[2]); - $h = $h->multiply($this->coefficients[2]); - list(, $h) = $h->divide($this->primes[1]); - $m = $m_i[2]->add($h->multiply($this->primes[2])); - - $r = $this->primes[1]; - for ($i = 3; $i <= $num_primes; $i++) { - $m_i = $x->modPow($this->exponents[$i], $this->primes[$i]); - - $r = $r->multiply($this->primes[$i - 1]); - - $h = $m_i->subtract($m); - $h = $h->multiply($this->coefficients[$i]); - list(, $h) = $h->divide($this->primes[$i]); - - $m = $m->add($r->multiply($h)); - } - } else { - $smallest = $this->primes[1]; - for ($i = 2; $i <= $num_primes; $i++) { - if ($smallest->compare($this->primes[$i]) > 0) { - $smallest = $this->primes[$i]; - } - } - - $r = BigInteger::randomRange(self::$one, $smallest->subtract(self::$one)); - - $m_i = [ - 1 => $this->blind($x, $r, 1), - 2 => $this->blind($x, $r, 2) - ]; - $h = $m_i[1]->subtract($m_i[2]); - $h = $h->multiply($this->coefficients[2]); - list(, $h) = $h->divide($this->primes[1]); - $m = $m_i[2]->add($h->multiply($this->primes[2])); - - $r = $this->primes[1]; - for ($i = 3; $i <= $num_primes; $i++) { - $m_i = $this->blind($x, $r, $i); - - $r = $r->multiply($this->primes[$i - 1]); - - $h = $m_i->subtract($m); - $h = $h->multiply($this->coefficients[$i]); - list(, $h) = $h->divide($this->primes[$i]); - - $m = $m->add($r->multiply($h)); - } - } - - return $m; - } - - /** - * Performs RSA Blinding - * - * Protects against timing attacks by employing RSA Blinding. - * Returns $x->modPow($this->exponents[$i], $this->primes[$i]) - * - * @param \phpseclib3\Math\BigInteger $x - * @param \phpseclib3\Math\BigInteger $r - * @param int $i - * @return \phpseclib3\Math\BigInteger - */ - private function blind(BigInteger $x, BigInteger $r, $i) - { - $x = $x->multiply($r->modPow($this->publicExponent, $this->primes[$i])); - $x = $x->modPow($this->exponents[$i], $this->primes[$i]); - - $r = $r->modInverse($this->primes[$i]); - $x = $x->multiply($r); - list(, $x) = $x->divide($this->primes[$i]); - - return $x; - } - - /** - * EMSA-PSS-ENCODE - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.1 RFC3447#section-9.1.1}. - * - * @return string - * @param string $m - * @throws \RuntimeException on encoding error - * @param int $emBits - */ - private function emsa_pss_encode($m, $emBits) - { - // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - $emLen = ($emBits + 1) >> 3; // ie. ceil($emBits / 8) - $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; - - $mHash = $this->hash->hash($m); - if ($emLen < $this->hLen + $sLen + 2) { - throw new \LengthException('RSA modulus too short'); - } - - $salt = Random::string($sLen); - $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; - $h = $this->hash->hash($m2); - $ps = str_repeat(chr(0), $emLen - $sLen - $this->hLen - 2); - $db = $ps . chr(1) . $salt; - $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); // ie. stlren($db) - $maskedDB = $db ^ $dbMask; - $maskedDB[0] = ~chr(0xFF << ($emBits & 7)) & $maskedDB[0]; - $em = $maskedDB . $h . chr(0xBC); - - return $em; - } - - /** - * RSASSA-PSS-SIGN - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.1 RFC3447#section-8.1.1}. - * - * @param string $m - * @return bool|string - */ - private function rsassa_pss_sign($m) - { - // EMSA-PSS encoding - - $em = $this->emsa_pss_encode($m, 8 * $this->k - 1); - - // RSA signature - - $m = $this->os2ip($em); - $s = $this->rsasp1($m); - $s = $this->i2osp($s, $this->k); - - // Output the signature S - - return $s; - } - - /** - * RSASSA-PKCS1-V1_5-SIGN - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.1 RFC3447#section-8.2.1}. - * - * @param string $m - * @throws \LengthException if the RSA modulus is too short - * @return bool|string - */ - private function rsassa_pkcs1_v1_5_sign($m) - { - // EMSA-PKCS1-v1_5 encoding - - // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus - // too short" and stop. - try { - $em = $this->emsa_pkcs1_v1_5_encode($m, $this->k); - } catch (\LengthException $e) { - throw new \LengthException('RSA modulus too short'); - } - - // RSA signature - - $m = $this->os2ip($em); - $s = $this->rsasp1($m); - $s = $this->i2osp($s, $this->k); - - // Output the signature S - - return $s; - } - - /** - * Create a signature - * - * @see self::verify() - * @param string $message - * @return string - */ - public function sign($message) - { - switch ($this->signaturePadding) { - case self::SIGNATURE_PKCS1: - case self::SIGNATURE_RELAXED_PKCS1: - return $this->rsassa_pkcs1_v1_5_sign($message); - //case self::SIGNATURE_PSS: - default: - return $this->rsassa_pss_sign($message); - } - } - - /** - * RSAES-PKCS1-V1_5-DECRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.2 RFC3447#section-7.2.2}. - * - * @param string $c - * @return bool|string - */ - private function rsaes_pkcs1_v1_5_decrypt($c) - { - // Length checking - - if (strlen($c) != $this->k) { // or if k < 11 - throw new \LengthException('Ciphertext representative too long'); - } - - // RSA decryption - - $c = $this->os2ip($c); - $m = $this->rsadp($c); - $em = $this->i2osp($m, $this->k); - - // EME-PKCS1-v1_5 decoding - - if (ord($em[0]) != 0 || ord($em[1]) > 2) { - throw new \RuntimeException('Decryption error'); - } - - $ps = substr($em, 2, strpos($em, chr(0), 2) - 2); - $m = substr($em, strlen($ps) + 3); - - if (strlen($ps) < 8) { - throw new \RuntimeException('Decryption error'); - } - - // Output M - - return $m; - } - - /** - * RSAES-OAEP-DECRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.2 RFC3447#section-7.1.2}. The fact that the error - * messages aren't distinguishable from one another hinders debugging, but, to quote from RFC3447#section-7.1.2: - * - * Note. Care must be taken to ensure that an opponent cannot - * distinguish the different error conditions in Step 3.g, whether by - * error message or timing, or, more generally, learn partial - * information about the encoded message EM. Otherwise an opponent may - * be able to obtain useful information about the decryption of the - * ciphertext C, leading to a chosen-ciphertext attack such as the one - * observed by Manger [36]. - * - * @param string $c - * @return bool|string - */ - private function rsaes_oaep_decrypt($c) - { - // Length checking - - // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - if (strlen($c) != $this->k || $this->k < 2 * $this->hLen + 2) { - throw new \LengthException('Ciphertext representative too long'); - } - - // RSA decryption - - $c = $this->os2ip($c); - $m = $this->rsadp($c); - $em = $this->i2osp($m, $this->k); - - // EME-OAEP decoding - - $lHash = $this->hash->hash($this->label); - $y = ord($em[0]); - $maskedSeed = substr($em, 1, $this->hLen); - $maskedDB = substr($em, $this->hLen + 1); - $seedMask = $this->mgf1($maskedDB, $this->hLen); - $seed = $maskedSeed ^ $seedMask; - $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); - $db = $maskedDB ^ $dbMask; - $lHash2 = substr($db, 0, $this->hLen); - $m = substr($db, $this->hLen); - $hashesMatch = hash_equals($lHash, $lHash2); - $leadingZeros = 1; - $patternMatch = 0; - $offset = 0; - for ($i = 0; $i < strlen($m); $i++) { - $patternMatch |= $leadingZeros & ($m[$i] === "\1"); - $leadingZeros &= $m[$i] === "\0"; - $offset += $patternMatch ? 0 : 1; - } - - // we do | instead of || to avoid https://en.wikipedia.org/wiki/Short-circuit_evaluation - // to protect against timing attacks - if (!$hashesMatch | !$patternMatch) { - throw new \RuntimeException('Decryption error'); - } - - // Output the message M - - return substr($m, $offset + 1); - } - - /** - * Raw Encryption / Decryption - * - * Doesn't use padding and is not recommended. - * - * @param string $m - * @return bool|string - * @throws \LengthException if strlen($m) > $this->k - */ - private function raw_encrypt($m) - { - if (strlen($m) > $this->k) { - throw new \LengthException('Ciphertext representative too long'); - } - - $temp = $this->os2ip($m); - $temp = $this->rsadp($temp); - return $this->i2osp($temp, $this->k); - } - - /** - * Decryption - * - * @see self::encrypt() - * @param string $ciphertext - * @return bool|string - */ - public function decrypt($ciphertext) - { - switch ($this->encryptionPadding) { - case self::ENCRYPTION_NONE: - return $this->raw_encrypt($ciphertext); - case self::ENCRYPTION_PKCS1: - return $this->rsaes_pkcs1_v1_5_decrypt($ciphertext); - //case self::ENCRYPTION_OAEP: - default: - return $this->rsaes_oaep_decrypt($ciphertext); - } - } - - /** - * Returns the public key - * - * @return mixed - */ - public function getPublicKey() - { - $type = self::validatePlugin('Keys', 'PKCS8', 'savePublicKey'); - if (empty($this->modulus) || empty($this->publicExponent)) { - throw new \RuntimeException('Public key components not found'); - } - - $key = $type::savePublicKey($this->modulus, $this->publicExponent); - return RSA::loadFormat('PKCS8', $key) - ->withHash($this->hash->getHash()) - ->withMGFHash($this->mgfHash->getHash()) - ->withSaltLength($this->sLen) - ->withLabel($this->label) - ->withPadding($this->signaturePadding | $this->encryptionPadding); - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin( - 'Keys', - $type, - empty($this->primes) ? 'savePublicKey' : 'savePrivateKey' - ); - - if ($type == PSS::class) { - if ($this->signaturePadding == self::SIGNATURE_PSS) { - $options += [ - 'hash' => $this->hash->getHash(), - 'MGFHash' => $this->mgfHash->getHash(), - 'saltLength' => $this->getSaltLength() - ]; - } else { - throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); - } - } - - if (empty($this->primes)) { - return $type::savePublicKey($this->modulus, $this->exponent, $options); - } - - return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); - - /* - $key = $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $this->primes, $this->exponents, $this->coefficients, $this->password, $options); - if ($key !== false || count($this->primes) == 2) { - return $key; - } - - $nSize = $this->getSize() >> 1; - - $primes = [1 => clone self::$one, clone self::$one]; - $i = 1; - foreach ($this->primes as $prime) { - $primes[$i] = $primes[$i]->multiply($prime); - if ($primes[$i]->getLength() >= $nSize) { - $i++; - } - } - - $exponents = []; - $coefficients = [2 => $primes[2]->modInverse($primes[1])]; - - foreach ($primes as $i => $prime) { - $temp = $prime->subtract(self::$one); - $exponents[$i] = $this->modulus->modInverse($temp); - } - - return $type::savePrivateKey($this->modulus, $this->publicExponent, $this->exponent, $primes, $exponents, $coefficients, $this->password, $options); - */ - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php deleted file mode 100644 index 58939a9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/RSA/PublicKey.php +++ /dev/null @@ -1,513 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt\RSA; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\UnsupportedFormatException; -use phpseclib3\File\ASN1; -use phpseclib3\File\ASN1\Maps\DigestInfo; -use phpseclib3\Math\BigInteger; - -/** - * Raw RSA Key Handler - * - * @author Jim Wigginton - */ -final class PublicKey extends RSA implements Common\PublicKey -{ - use Common\Traits\Fingerprint; - - /** - * Exponentiate - * - * @param \phpseclib3\Math\BigInteger $x - * @return \phpseclib3\Math\BigInteger - */ - private function exponentiate(BigInteger $x) - { - return $x->modPow($this->exponent, $this->modulus); - } - - /** - * RSAVP1 - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.2.2 RFC3447#section-5.2.2}. - * - * @param \phpseclib3\Math\BigInteger $s - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsavp1($s) - { - if ($s->compare(self::$zero) < 0 || $s->compare($this->modulus) > 0) { - return false; - } - return $this->exponentiate($s); - } - - /** - * RSASSA-PKCS1-V1_5-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.2.2 RFC3447#section-8.2.2}. - * - * @param string $m - * @param string $s - * @throws \LengthException if the RSA modulus is too short - * @return bool - */ - private function rsassa_pkcs1_v1_5_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - return false; - } - - // RSA verification - - $s = $this->os2ip($s); - $m2 = $this->rsavp1($s); - if ($m2 === false) { - return false; - } - $em = $this->i2osp($m2, $this->k); - if ($em === false) { - return false; - } - - // EMSA-PKCS1-v1_5 encoding - - $exception = false; - - // If the encoding operation outputs "intended encoded message length too short," output "RSA modulus - // too short" and stop. - try { - $em2 = $this->emsa_pkcs1_v1_5_encode($m, $this->k); - $r1 = hash_equals($em, $em2); - } catch (\LengthException $e) { - $exception = true; - } - - try { - $em3 = $this->emsa_pkcs1_v1_5_encode_without_null($m, $this->k); - $r2 = hash_equals($em, $em3); - } catch (\LengthException $e) { - $exception = true; - } catch (UnsupportedAlgorithmException $e) { - $r2 = false; - } - - if ($exception) { - throw new \LengthException('RSA modulus too short'); - } - - // Compare - return $r1 || $r2; - } - - /** - * RSASSA-PKCS1-V1_5-VERIFY (relaxed matching) - * - * Per {@link http://tools.ietf.org/html/rfc3447#page-43 RFC3447#page-43} PKCS1 v1.5 - * specified the use BER encoding rather than DER encoding that PKCS1 v2.0 specified. - * This means that under rare conditions you can have a perfectly valid v1.5 signature - * that fails to validate with _rsassa_pkcs1_v1_5_verify(). PKCS1 v2.1 also recommends - * that if you're going to validate these types of signatures you "should indicate - * whether the underlying BER encoding is a DER encoding and hence whether the signature - * is valid with respect to the specification given in [PKCS1 v2.0+]". so if you do - * $rsa->getLastPadding() and get RSA::PADDING_RELAXED_PKCS1 back instead of - * RSA::PADDING_PKCS1... that means BER encoding was used. - * - * @param string $m - * @param string $s - * @return bool - */ - private function rsassa_pkcs1_v1_5_relaxed_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - return false; - } - - // RSA verification - - $s = $this->os2ip($s); - $m2 = $this->rsavp1($s); - if ($m2 === false) { - return false; - } - $em = $this->i2osp($m2, $this->k); - if ($em === false) { - return false; - } - - if (Strings::shift($em, 2) != "\0\1") { - return false; - } - - $em = ltrim($em, "\xFF"); - if (Strings::shift($em) != "\0") { - return false; - } - - $decoded = ASN1::decodeBER($em); - if (!is_array($decoded) || empty($decoded[0]) || strlen($em) > $decoded[0]['length']) { - return false; - } - - static $oids; - if (!isset($oids)) { - $oids = [ - 'md2' => '1.2.840.113549.2.2', - 'md4' => '1.2.840.113549.2.4', // from PKCS1 v1.5 - 'md5' => '1.2.840.113549.2.5', - 'id-sha1' => '1.3.14.3.2.26', - 'id-sha256' => '2.16.840.1.101.3.4.2.1', - 'id-sha384' => '2.16.840.1.101.3.4.2.2', - 'id-sha512' => '2.16.840.1.101.3.4.2.3', - // from PKCS1 v2.2 - 'id-sha224' => '2.16.840.1.101.3.4.2.4', - 'id-sha512/224' => '2.16.840.1.101.3.4.2.5', - 'id-sha512/256' => '2.16.840.1.101.3.4.2.6', - ]; - ASN1::loadOIDs($oids); - } - - $decoded = ASN1::asn1map($decoded[0], DigestInfo::MAP); - if (!isset($decoded) || $decoded === false) { - return false; - } - - if (!isset($oids[$decoded['digestAlgorithm']['algorithm']])) { - return false; - } - - if (isset($decoded['digestAlgorithm']['parameters']) && $decoded['digestAlgorithm']['parameters'] !== ['null' => '']) { - return false; - } - - $hash = $decoded['digestAlgorithm']['algorithm']; - $hash = substr($hash, 0, 3) == 'id-' ? - substr($hash, 3) : - $hash; - $hash = new Hash($hash); - $em = $hash->hash($m); - $em2 = $decoded['digest']; - - return hash_equals($em, $em2); - } - - /** - * EMSA-PSS-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-9.1.2 RFC3447#section-9.1.2}. - * - * @param string $m - * @param string $em - * @param int $emBits - * @return string - */ - private function emsa_pss_verify($m, $em, $emBits) - { - // if $m is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - $emLen = ($emBits + 7) >> 3; // ie. ceil($emBits / 8); - $sLen = $this->sLen !== null ? $this->sLen : $this->hLen; - - $mHash = $this->hash->hash($m); - if ($emLen < $this->hLen + $sLen + 2) { - return false; - } - - if ($em[strlen($em) - 1] != chr(0xBC)) { - return false; - } - - $maskedDB = substr($em, 0, -$this->hLen - 1); - $h = substr($em, -$this->hLen - 1, $this->hLen); - $temp = chr(0xFF << ($emBits & 7)); - if ((~$maskedDB[0] & $temp) != $temp) { - return false; - } - $dbMask = $this->mgf1($h, $emLen - $this->hLen - 1); - $db = $maskedDB ^ $dbMask; - $db[0] = ~chr(0xFF << ($emBits & 7)) & $db[0]; - $temp = $emLen - $this->hLen - $sLen - 2; - if (substr($db, 0, $temp) != str_repeat(chr(0), $temp) || ord($db[$temp]) != 1) { - return false; - } - $salt = substr($db, $temp + 1); // should be $sLen long - $m2 = "\0\0\0\0\0\0\0\0" . $mHash . $salt; - $h2 = $this->hash->hash($m2); - return hash_equals($h, $h2); - } - - /** - * RSASSA-PSS-VERIFY - * - * See {@link http://tools.ietf.org/html/rfc3447#section-8.1.2 RFC3447#section-8.1.2}. - * - * @param string $m - * @param string $s - * @return bool|string - */ - private function rsassa_pss_verify($m, $s) - { - // Length checking - - if (strlen($s) != $this->k) { - return false; - } - - // RSA verification - - $modBits = strlen($this->modulus->toBits()); - - $s2 = $this->os2ip($s); - $m2 = $this->rsavp1($s2); - $em = $this->i2osp($m2, $this->k); - if ($em === false) { - return false; - } - - // EMSA-PSS verification - - return $this->emsa_pss_verify($m, $em, $modBits - 1); - } - - /** - * Verifies a signature - * - * @see self::sign() - * @param string $message - * @param string $signature - * @return bool - */ - public function verify($message, $signature) - { - switch ($this->signaturePadding) { - case self::SIGNATURE_RELAXED_PKCS1: - return $this->rsassa_pkcs1_v1_5_relaxed_verify($message, $signature); - case self::SIGNATURE_PKCS1: - return $this->rsassa_pkcs1_v1_5_verify($message, $signature); - //case self::SIGNATURE_PSS: - default: - return $this->rsassa_pss_verify($message, $signature); - } - } - - /** - * RSAES-PKCS1-V1_5-ENCRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.2.1 RFC3447#section-7.2.1}. - * - * @param string $m - * @param bool $pkcs15_compat optional - * @throws \LengthException if strlen($m) > $this->k - 11 - * @return bool|string - */ - private function rsaes_pkcs1_v1_5_encrypt($m, $pkcs15_compat = false) - { - $mLen = strlen($m); - - // Length checking - - if ($mLen > $this->k - 11) { - throw new \LengthException('Message too long'); - } - - // EME-PKCS1-v1_5 encoding - - $psLen = $this->k - $mLen - 3; - $ps = ''; - while (strlen($ps) != $psLen) { - $temp = Random::string($psLen - strlen($ps)); - $temp = str_replace("\x00", '', $temp); - $ps .= $temp; - } - $type = 2; - $em = chr(0) . chr($type) . $ps . chr(0) . $m; - - // RSA encryption - $m = $this->os2ip($em); - $c = $this->rsaep($m); - $c = $this->i2osp($c, $this->k); - - // Output the ciphertext C - - return $c; - } - - /** - * RSAES-OAEP-ENCRYPT - * - * See {@link http://tools.ietf.org/html/rfc3447#section-7.1.1 RFC3447#section-7.1.1} and - * {http://en.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding OAES}. - * - * @param string $m - * @throws \LengthException if strlen($m) > $this->k - 2 * $this->hLen - 2 - * @return string - */ - private function rsaes_oaep_encrypt($m) - { - $mLen = strlen($m); - - // Length checking - - // if $l is larger than two million terrabytes and you're using sha1, PKCS#1 suggests a "Label too long" error - // be output. - - if ($mLen > $this->k - 2 * $this->hLen - 2) { - throw new \LengthException('Message too long'); - } - - // EME-OAEP encoding - - $lHash = $this->hash->hash($this->label); - $ps = str_repeat(chr(0), $this->k - $mLen - 2 * $this->hLen - 2); - $db = $lHash . $ps . chr(1) . $m; - $seed = Random::string($this->hLen); - $dbMask = $this->mgf1($seed, $this->k - $this->hLen - 1); - $maskedDB = $db ^ $dbMask; - $seedMask = $this->mgf1($maskedDB, $this->hLen); - $maskedSeed = $seed ^ $seedMask; - $em = chr(0) . $maskedSeed . $maskedDB; - - // RSA encryption - - $m = $this->os2ip($em); - $c = $this->rsaep($m); - $c = $this->i2osp($c, $this->k); - - // Output the ciphertext C - - return $c; - } - - /** - * RSAEP - * - * See {@link http://tools.ietf.org/html/rfc3447#section-5.1.1 RFC3447#section-5.1.1}. - * - * @param \phpseclib3\Math\BigInteger $m - * @return bool|\phpseclib3\Math\BigInteger - */ - private function rsaep($m) - { - if ($m->compare(self::$zero) < 0 || $m->compare($this->modulus) > 0) { - throw new \OutOfRangeException('Message representative out of range'); - } - return $this->exponentiate($m); - } - - /** - * Raw Encryption / Decryption - * - * Doesn't use padding and is not recommended. - * - * @param string $m - * @return bool|string - * @throws \LengthException if strlen($m) > $this->k - */ - private function raw_encrypt($m) - { - if (strlen($m) > $this->k) { - throw new \LengthException('Message too long'); - } - - $temp = $this->os2ip($m); - $temp = $this->rsaep($temp); - return $this->i2osp($temp, $this->k); - } - - /** - * Encryption - * - * Both self::PADDING_OAEP and self::PADDING_PKCS1 both place limits on how long $plaintext can be. - * If $plaintext exceeds those limits it will be broken up so that it does and the resultant ciphertext's will - * be concatenated together. - * - * @see self::decrypt() - * @param string $plaintext - * @return bool|string - * @throws \LengthException if the RSA modulus is too short - */ - public function encrypt($plaintext) - { - switch ($this->encryptionPadding) { - case self::ENCRYPTION_NONE: - return $this->raw_encrypt($plaintext); - case self::ENCRYPTION_PKCS1: - return $this->rsaes_pkcs1_v1_5_encrypt($plaintext); - //case self::ENCRYPTION_OAEP: - default: - return $this->rsaes_oaep_encrypt($plaintext); - } - } - - /** - * Returns the public key - * - * The public key is only returned under two circumstances - if the private key had the public key embedded within it - * or if the public key was set via setPublicKey(). If the currently loaded key is supposed to be the public key this - * function won't return it since this library, for the most part, doesn't distinguish between public and private keys. - * - * @param string $type - * @param array $options optional - * @return mixed - */ - public function toString($type, array $options = []) - { - $type = self::validatePlugin('Keys', $type, 'savePublicKey'); - - if ($type == PSS::class) { - if ($this->signaturePadding == self::SIGNATURE_PSS) { - $options += [ - 'hash' => $this->hash->getHash(), - 'MGFHash' => $this->mgfHash->getHash(), - 'saltLength' => $this->getSaltLength() - ]; - } else { - throw new UnsupportedFormatException('The PSS format can only be used when the signature method has been explicitly set to PSS'); - } - } - - return $type::savePublicKey($this->modulus, $this->publicExponent, $options); - } - - /** - * Converts a public key to a private key - * - * @return RSA - */ - public function asPrivateKey() - { - $new = new PrivateKey(); - $new->exponent = $this->exponent; - $new->modulus = $this->modulus; - $new->k = $this->k; - $new->format = $this->format; - return $new - ->withHash($this->hash->getHash()) - ->withMGFHash($this->mgfHash->getHash()) - ->withSaltLength($this->sLen) - ->withLabel($this->label) - ->withPadding($this->signaturePadding | $this->encryptionPadding); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php deleted file mode 100644 index f813a2e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php +++ /dev/null @@ -1,222 +0,0 @@ - - * - * - * - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -/** - * Pure-PHP Random Number Generator - * - * @author Jim Wigginton - */ -abstract class Random -{ - /** - * Generate a random string. - * - * Although microoptimizations are generally discouraged as they impair readability this function is ripe with - * microoptimizations because this function has the potential of being called a huge number of times. - * eg. for RSA key generation. - * - * @param int $length - * @throws \RuntimeException if a symmetric cipher is needed but not loaded - * @return string - */ - public static function string($length) - { - if (!$length) { - return ''; - } - - try { - return random_bytes($length); - } catch (\Exception $e) { - // random_compat will throw an Exception, which in PHP 5 does not implement Throwable - } catch (\Throwable $e) { - // If a sufficient source of randomness is unavailable, random_bytes() will throw an - // object that implements the Throwable interface (Exception, TypeError, Error). - // We don't actually need to do anything here. The string() method should just continue - // as normal. Note, however, that if we don't have a sufficient source of randomness for - // random_bytes(), most of the other calls here will fail too, so we'll end up using - // the PHP implementation. - } - // at this point we have no choice but to use a pure-PHP CSPRNG - - // cascade entropy across multiple PHP instances by fixing the session and collecting all - // environmental variables, including the previous session data and the current session - // data. - // - // mt_rand seeds itself by looking at the PID and the time, both of which are (relatively) - // easy to guess at. linux uses mouse clicks, keyboard timings, etc, as entropy sources, but - // PHP isn't low level to be able to use those as sources and on a web server there's not likely - // going to be a ton of keyboard or mouse action. web servers do have one thing that we can use - // however, a ton of people visiting the website. obviously you don't want to base your seeding - // solely on parameters a potential attacker sends but (1) not everything in $_SERVER is controlled - // by the user and (2) this isn't just looking at the data sent by the current user - it's based - // on the data sent by all users. one user requests the page and a hash of their info is saved. - // another user visits the page and the serialization of their data is utilized along with the - // server environment stuff and a hash of the previous http request data (which itself utilizes - // a hash of the session data before that). certainly an attacker should be assumed to have - // full control over his own http requests. he, however, is not going to have control over - // everyone's http requests. - static $crypto = false, $v; - if ($crypto === false) { - // save old session data - $old_session_id = session_id(); - $old_use_cookies = ini_get('session.use_cookies'); - $old_session_cache_limiter = session_cache_limiter(); - $_OLD_SESSION = isset($_SESSION) ? $_SESSION : false; - if ($old_session_id != '') { - session_write_close(); - } - - session_id(1); - ini_set('session.use_cookies', 0); - session_cache_limiter(''); - session_start(); - - $v = (isset($_SERVER) ? self::safe_serialize($_SERVER) : '') . - (isset($_POST) ? self::safe_serialize($_POST) : '') . - (isset($_GET) ? self::safe_serialize($_GET) : '') . - (isset($_COOKIE) ? self::safe_serialize($_COOKIE) : '') . - // as of PHP 8.1 $GLOBALS can't be accessed by reference, which eliminates - // the need for phpseclib_safe_serialize. see https://wiki.php.net/rfc/restrict_globals_usage - // for more info - (version_compare(PHP_VERSION, '8.1.0', '>=') ? serialize($GLOBALS) : self::safe_serialize($GLOBALS)) . - self::safe_serialize($_SESSION) . - self::safe_serialize($_OLD_SESSION); - $v = $seed = $_SESSION['seed'] = sha1($v, true); - if (!isset($_SESSION['count'])) { - $_SESSION['count'] = 0; - } - $_SESSION['count']++; - - session_write_close(); - - // restore old session data - if ($old_session_id != '') { - session_id($old_session_id); - session_start(); - ini_set('session.use_cookies', $old_use_cookies); - session_cache_limiter($old_session_cache_limiter); - } else { - if ($_OLD_SESSION !== false) { - $_SESSION = $_OLD_SESSION; - unset($_OLD_SESSION); - } else { - unset($_SESSION); - } - } - - // in SSH2 a shared secret and an exchange hash are generated through the key exchange process. - // the IV client to server is the hash of that "nonce" with the letter A and for the encryption key it's the letter C. - // if the hash doesn't produce enough a key or an IV that's long enough concat successive hashes of the - // original hash and the current hash. we'll be emulating that. for more info see the following URL: - // - // http://tools.ietf.org/html/rfc4253#section-7.2 - // - // see the is_string($crypto) part for an example of how to expand the keys - $key = sha1($seed . 'A', true); - $iv = sha1($seed . 'C', true); - - // ciphers are used as per the nist.gov link below. also, see this link: - // - // http://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator#Designs_based_on_cryptographic_primitives - switch (true) { - case class_exists('\phpseclib3\Crypt\AES'): - $crypto = new AES('ctr'); - break; - case class_exists('\phpseclib3\Crypt\Twofish'): - $crypto = new Twofish('ctr'); - break; - case class_exists('\phpseclib3\Crypt\Blowfish'): - $crypto = new Blowfish('ctr'); - break; - case class_exists('\phpseclib3\Crypt\TripleDES'): - $crypto = new TripleDES('ctr'); - break; - case class_exists('\phpseclib3\Crypt\DES'): - $crypto = new DES('ctr'); - break; - case class_exists('\phpseclib3\Crypt\RC4'): - $crypto = new RC4(); - break; - default: - throw new \RuntimeException(__CLASS__ . ' requires at least one symmetric cipher be loaded'); - } - - $crypto->setKey(substr($key, 0, $crypto->getKeyLength() >> 3)); - $crypto->setIV(substr($iv, 0, $crypto->getBlockLength() >> 3)); - $crypto->enableContinuousBuffer(); - } - - //return $crypto->encrypt(str_repeat("\0", $length)); - - // the following is based off of ANSI X9.31: - // - // http://csrc.nist.gov/groups/STM/cavp/documents/rng/931rngext.pdf - // - // OpenSSL uses that same standard for it's random numbers: - // - // http://www.opensource.apple.com/source/OpenSSL/OpenSSL-38/openssl/fips-1.0/rand/fips_rand.c - // (do a search for "ANS X9.31 A.2.4") - $result = ''; - while (strlen($result) < $length) { - $i = $crypto->encrypt(microtime()); // strlen(microtime()) == 21 - $r = $crypto->encrypt($i ^ $v); // strlen($v) == 20 - $v = $crypto->encrypt($r ^ $i); // strlen($r) == 20 - $result .= $r; - } - - return substr($result, 0, $length); - } - - /** - * Safely serialize variables - * - * If a class has a private __sleep() it'll emit a warning - * @return mixed - * @param mixed $arr - */ - private static function safe_serialize(&$arr) - { - if (is_object($arr)) { - return ''; - } - if (!is_array($arr)) { - return serialize($arr); - } - // prevent circular array recursion - if (isset($arr['__phpseclib_marker'])) { - return ''; - } - $safearr = []; - $arr['__phpseclib_marker'] = true; - foreach (array_keys($arr) as $key) { - // do not recurse on the '__phpseclib_marker' key itself, for smaller memory usage - if ($key !== '__phpseclib_marker') { - $safearr[$key] = self::safe_serialize($arr[$key]); - } - } - unset($arr['__phpseclib_marker']); - return serialize($safearr); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php deleted file mode 100644 index ff31f9c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Rijndael.php +++ /dev/null @@ -1,1036 +0,0 @@ - - * setKey('abcdefghijklmnop'); - * - * $size = 10 * 1024; - * $plaintext = ''; - * for ($i = 0; $i < $size; $i++) { - * $plaintext.= 'a'; - * } - * - * echo $rijndael->decrypt($rijndael->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2008 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadDecryptionException; -use phpseclib3\Exception\BadModeException; -use phpseclib3\Exception\InconsistentSetupException; -use phpseclib3\Exception\InsufficientSetupException; - -/** - * Pure-PHP implementation of Rijndael. - * - * @author Jim Wigginton - */ -class Rijndael extends BlockCipher -{ - /** - * The mcrypt specific name of the cipher - * - * Mcrypt is useable for 128/192/256-bit $block_size/$key_length. For 160/224 not. - * \phpseclib3\Crypt\Rijndael determines automatically whether mcrypt is useable - * or not for the current $block_size/$key_length. - * In case of, $cipher_name_mcrypt will be set dynamically at run time accordingly. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @see \phpseclib3\Crypt\Common\SymmetricKey::engine - * @see self::isValidEngine() - * @var string - */ - protected $cipher_name_mcrypt = 'rijndael-128'; - - /** - * The Key Schedule - * - * @see self::setup() - * @var array - */ - private $w; - - /** - * The Inverse Key Schedule - * - * @see self::setup() - * @var array - */ - private $dw; - - /** - * The Block Length divided by 32 - * - * {@internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4. Exists in conjunction with $block_size - * because the encryption / decryption / key schedule creation requires this number and not $block_size. We could - * derive this from $block_size or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once.} - * - * @see self::setBlockLength() - * @var int - */ - private $Nb = 4; - - /** - * The Key Length (in bytes) - * - * {@internal The max value is 256 / 8 = 32, the min value is 128 / 8 = 16. Exists in conjunction with $Nk - * because the encryption / decryption / key schedule creation requires this number and not $key_length. We could - * derive this from $key_length or vice versa, but that'd mean we'd have to do multiple shift operations, so in lieu - * of that, we'll just precompute it once.} - * - * @see self::setKeyLength() - * @var int - */ - protected $key_length = 16; - - /** - * The Key Length divided by 32 - * - * @see self::setKeyLength() - * @var int - * @internal The max value is 256 / 32 = 8, the min value is 128 / 32 = 4 - */ - private $Nk = 4; - - /** - * The Number of Rounds - * - * {@internal The max value is 14, the min value is 10.} - * - * @var int - */ - private $Nr; - - /** - * Shift offsets - * - * @var array - */ - private $c; - - /** - * Holds the last used key- and block_size information - * - * @var array - */ - private $kl; - - /** - * Default Constructor. - * - * @param string $mode - * @throws \InvalidArgumentException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } - - /** - * Sets the key length. - * - * Valid key lengths are 128, 160, 192, 224, and 256. - * - * Note: phpseclib extends Rijndael (and AES) for using 160- and 224-bit keys but they are officially not defined - * and the most (if not all) implementations are not able using 160/224-bit keys but round/pad them up to - * 192/256 bits as, for example, mcrypt will do. - * - * That said, if you want be compatible with other Rijndael and AES implementations, - * you should not setKeyLength(160) or setKeyLength(224). - * - * Additional: In case of 160- and 224-bit keys, phpseclib will/can, for that reason, not use - * the mcrypt php extension, even if available. - * This results then in slower encryption. - * - * @throws \LengthException if the key length is invalid - * @param int $length - */ - public function setKeyLength($length) - { - switch ($length) { - case 128: - case 160: - case 192: - case 224: - case 256: - $this->key_length = $length >> 3; - break; - default: - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); - } - - parent::setKeyLength($length); - } - - /** - * Sets the key. - * - * Rijndael supports five different key lengths - * - * @see setKeyLength() - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 20: - case 24: - case 28: - case 32: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 20, 24, 28 or 32 are supported'); - } - - parent::setKey($key); - } - - /** - * Sets the block length - * - * Valid block lengths are 128, 160, 192, 224, and 256. - * - * @param int $length - */ - public function setBlockLength($length) - { - switch ($length) { - case 128: - case 160: - case 192: - case 224: - case 256: - break; - default: - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128, 160, 192, 224 or 256 bits are supported'); - } - - $this->Nb = $length >> 5; - $this->block_size = $length >> 3; - $this->changed = $this->nonIVChanged = true; - $this->setEngine(); - } - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - switch ($engine) { - case self::ENGINE_LIBSODIUM: - return function_exists('sodium_crypto_aead_aes256gcm_is_available') && - sodium_crypto_aead_aes256gcm_is_available() && - $this->mode == self::MODE_GCM && - $this->key_length == 32 && - $this->nonce && strlen($this->nonce) == 12 && - $this->block_size == 16; - case self::ENGINE_OPENSSL_GCM: - if (!extension_loaded('openssl')) { - return false; - } - $methods = openssl_get_cipher_methods(); - return $this->mode == self::MODE_GCM && - version_compare(PHP_VERSION, '7.1.0', '>=') && - in_array('aes-' . $this->getKeyLength() . '-gcm', $methods) && - $this->block_size == 16; - case self::ENGINE_OPENSSL: - if ($this->block_size != 16) { - return false; - } - $this->cipher_name_openssl_ecb = 'aes-' . ($this->key_length << 3) . '-ecb'; - $this->cipher_name_openssl = 'aes-' . ($this->key_length << 3) . '-' . $this->openssl_translate_mode(); - break; - case self::ENGINE_MCRYPT: - $this->cipher_name_mcrypt = 'rijndael-' . ($this->block_size << 3); - if ($this->key_length % 8) { // is it a 160/224-bit key? - // mcrypt is not usable for them, only for 128/192/256-bit keys - return false; - } - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Encrypts a block - * - * @param string $in - * @return string - */ - protected function encryptBlock($in) - { - static $tables; - if (empty($tables)) { - $tables = &$this->getTables(); - } - $t0 = $tables[0]; - $t1 = $tables[1]; - $t2 = $tables[2]; - $t3 = $tables[3]; - $sbox = $tables[4]; - - $state = []; - $words = unpack('N*', $in); - - $c = $this->c; - $w = $this->w; - $Nb = $this->Nb; - $Nr = $this->Nr; - - // addRoundKey - $wc = $Nb - 1; - foreach ($words as $word) { - $state[] = $word ^ $w[++$wc]; - } - - // fips-197.pdf#page=19, "Figure 5. Pseudo Code for the Cipher", states that this loop has four components - - // subBytes, shiftRows, mixColumns, and addRoundKey. fips-197.pdf#page=30, "Implementation Suggestions Regarding - // Various Platforms" suggests that performs enhanced implementations are described in Rijndael-ammended.pdf. - // Rijndael-ammended.pdf#page=20, "Implementation aspects / 32-bit processor", discusses such an optimization. - // Unfortunately, the description given there is not quite correct. Per aes.spec.v316.pdf#page=19 [1], - // equation (7.4.7) is supposed to use addition instead of subtraction, so we'll do that here, as well. - - // [1] http://fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.v316.pdf - $temp = []; - for ($round = 1; $round < $Nr; ++$round) { - $i = 0; // $c[0] == 0 - $j = $c[1]; - $k = $c[2]; - $l = $c[3]; - - while ($i < $Nb) { - $temp[$i] = $t0[$state[$i] >> 24 & 0x000000FF] ^ - $t1[$state[$j] >> 16 & 0x000000FF] ^ - $t2[$state[$k] >> 8 & 0x000000FF] ^ - $t3[$state[$l] & 0x000000FF] ^ - $w[++$wc]; - ++$i; - $j = ($j + 1) % $Nb; - $k = ($k + 1) % $Nb; - $l = ($l + 1) % $Nb; - } - $state = $temp; - } - - // subWord - for ($i = 0; $i < $Nb; ++$i) { - $state[$i] = $sbox[$state[$i] & 0x000000FF] | - ($sbox[$state[$i] >> 8 & 0x000000FF] << 8) | - ($sbox[$state[$i] >> 16 & 0x000000FF] << 16) | - ($sbox[$state[$i] >> 24 & 0x000000FF] << 24); - } - - // shiftRows + addRoundKey - $i = 0; // $c[0] == 0 - $j = $c[1]; - $k = $c[2]; - $l = $c[3]; - while ($i < $Nb) { - $temp[$i] = ($state[$i] & intval(0xFF000000)) ^ - ($state[$j] & 0x00FF0000) ^ - ($state[$k] & 0x0000FF00) ^ - ($state[$l] & 0x000000FF) ^ - $w[$i]; - ++$i; - $j = ($j + 1) % $Nb; - $k = ($k + 1) % $Nb; - $l = ($l + 1) % $Nb; - } - - return pack('N*', ...$temp); - } - - /** - * Decrypts a block - * - * @param string $in - * @return string - */ - protected function decryptBlock($in) - { - static $invtables; - if (empty($invtables)) { - $invtables = &$this->getInvTables(); - } - $dt0 = $invtables[0]; - $dt1 = $invtables[1]; - $dt2 = $invtables[2]; - $dt3 = $invtables[3]; - $isbox = $invtables[4]; - - $state = []; - $words = unpack('N*', $in); - - $c = $this->c; - $dw = $this->dw; - $Nb = $this->Nb; - $Nr = $this->Nr; - - // addRoundKey - $wc = $Nb - 1; - foreach ($words as $word) { - $state[] = $word ^ $dw[++$wc]; - } - - $temp = []; - for ($round = $Nr - 1; $round > 0; --$round) { - $i = 0; // $c[0] == 0 - $j = $Nb - $c[1]; - $k = $Nb - $c[2]; - $l = $Nb - $c[3]; - - while ($i < $Nb) { - $temp[$i] = $dt0[$state[$i] >> 24 & 0x000000FF] ^ - $dt1[$state[$j] >> 16 & 0x000000FF] ^ - $dt2[$state[$k] >> 8 & 0x000000FF] ^ - $dt3[$state[$l] & 0x000000FF] ^ - $dw[++$wc]; - ++$i; - $j = ($j + 1) % $Nb; - $k = ($k + 1) % $Nb; - $l = ($l + 1) % $Nb; - } - $state = $temp; - } - - // invShiftRows + invSubWord + addRoundKey - $i = 0; // $c[0] == 0 - $j = $Nb - $c[1]; - $k = $Nb - $c[2]; - $l = $Nb - $c[3]; - - while ($i < $Nb) { - $word = ($state[$i] & intval(0xFF000000)) | - ($state[$j] & 0x00FF0000) | - ($state[$k] & 0x0000FF00) | - ($state[$l] & 0x000000FF); - - $temp[$i] = $dw[$i] ^ ($isbox[$word & 0x000000FF] | - ($isbox[$word >> 8 & 0x000000FF] << 8) | - ($isbox[$word >> 16 & 0x000000FF] << 16) | - ($isbox[$word >> 24 & 0x000000FF] << 24)); - ++$i; - $j = ($j + 1) % $Nb; - $k = ($k + 1) % $Nb; - $l = ($l + 1) % $Nb; - } - - return pack('N*', ...$temp); - } - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine and flush all $buffers - * Used (only) if $engine == self::ENGINE_INTERNAL - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setIV() - * - * - disableContinuousBuffer() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * {@internal setup() is always called before en/decryption.} - * - * {@internal Could, but not must, extend by the child Crypt_* class} - * - * @see self::setKey() - * @see self::setIV() - * @see self::disableContinuousBuffer() - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - parent::setup(); - - if (is_string($this->iv) && strlen($this->iv) != $this->block_size) { - throw new InconsistentSetupException('The IV length (' . strlen($this->iv) . ') does not match the block size (' . $this->block_size . ')'); - } - } - - /** - * Setup the key (expansion) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() - */ - protected function setupKey() - { - // Each number in $rcon is equal to the previous number multiplied by two in Rijndael's finite field. - // See http://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplicative_inverse - static $rcon; - - if (!isset($rcon)) { - $rcon = [0, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, - 0x6C000000, 0xD8000000, 0xAB000000, 0x4D000000, 0x9A000000, - 0x2F000000, 0x5E000000, 0xBC000000, 0x63000000, 0xC6000000, - 0x97000000, 0x35000000, 0x6A000000, 0xD4000000, 0xB3000000, - 0x7D000000, 0xFA000000, 0xEF000000, 0xC5000000, 0x91000000 - ]; - $rcon = array_map('intval', $rcon); - } - - if (isset($this->kl['key']) && $this->key === $this->kl['key'] && $this->key_length === $this->kl['key_length'] && $this->block_size === $this->kl['block_size']) { - // already expanded - return; - } - $this->kl = ['key' => $this->key, 'key_length' => $this->key_length, 'block_size' => $this->block_size]; - - $this->Nk = $this->key_length >> 2; - // see Rijndael-ammended.pdf#page=44 - $this->Nr = max($this->Nk, $this->Nb) + 6; - - // shift offsets for Nb = 5, 7 are defined in Rijndael-ammended.pdf#page=44, - // "Table 8: Shift offsets in Shiftrow for the alternative block lengths" - // shift offsets for Nb = 4, 6, 8 are defined in Rijndael-ammended.pdf#page=14, - // "Table 2: Shift offsets for different block lengths" - switch ($this->Nb) { - case 4: - case 5: - case 6: - $this->c = [0, 1, 2, 3]; - break; - case 7: - $this->c = [0, 1, 2, 4]; - break; - case 8: - $this->c = [0, 1, 3, 4]; - } - - $w = array_values(unpack('N*words', $this->key)); - - $length = $this->Nb * ($this->Nr + 1); - for ($i = $this->Nk; $i < $length; $i++) { - $temp = $w[$i - 1]; - if ($i % $this->Nk == 0) { - // according to , "the size of an integer is platform-dependent". - // on a 32-bit machine, it's 32-bits, and on a 64-bit machine, it's 64-bits. on a 32-bit machine, - // 0xFFFFFFFF << 8 == 0xFFFFFF00, but on a 64-bit machine, it equals 0xFFFFFFFF00. as such, doing 'and' - // with 0xFFFFFFFF (or 0xFFFFFF00) on a 32-bit machine is unnecessary, but on a 64-bit machine, it is. - $temp = (($temp << 8) & intval(0xFFFFFF00)) | (($temp >> 24) & 0x000000FF); // rotWord - $temp = $this->subWord($temp) ^ $rcon[$i / $this->Nk]; - } elseif ($this->Nk > 6 && $i % $this->Nk == 4) { - $temp = $this->subWord($temp); - } - $w[$i] = $w[$i - $this->Nk] ^ $temp; - } - - // convert the key schedule from a vector of $Nb * ($Nr + 1) length to a matrix with $Nr + 1 rows and $Nb columns - // and generate the inverse key schedule. more specifically, - // according to (section 5.3.3), - // "The key expansion for the Inverse Cipher is defined as follows: - // 1. Apply the Key Expansion. - // 2. Apply InvMixColumn to all Round Keys except the first and the last one." - // also, see fips-197.pdf#page=27, "5.3.5 Equivalent Inverse Cipher" - list($dt0, $dt1, $dt2, $dt3) = $this->getInvTables(); - $temp = $this->w = $this->dw = []; - for ($i = $row = $col = 0; $i < $length; $i++, $col++) { - if ($col == $this->Nb) { - if ($row == 0) { - $this->dw[0] = $this->w[0]; - } else { - // subWord + invMixColumn + invSubWord = invMixColumn - $j = 0; - while ($j < $this->Nb) { - $dw = $this->subWord($this->w[$row][$j]); - $temp[$j] = $dt0[$dw >> 24 & 0x000000FF] ^ - $dt1[$dw >> 16 & 0x000000FF] ^ - $dt2[$dw >> 8 & 0x000000FF] ^ - $dt3[$dw & 0x000000FF]; - $j++; - } - $this->dw[$row] = $temp; - } - - $col = 0; - $row++; - } - $this->w[$row][$col] = $w[$i]; - } - - $this->dw[$row] = $this->w[$row]; - - // Converting to 1-dim key arrays (both ascending) - $this->dw = array_reverse($this->dw); - $w = array_pop($this->w); - $dw = array_pop($this->dw); - foreach ($this->w as $r => $wr) { - foreach ($wr as $c => $wc) { - $w[] = $wc; - $dw[] = $this->dw[$r][$c]; - } - } - $this->w = $w; - $this->dw = $dw; - } - - /** - * Performs S-Box substitutions - * - * @return array - * @param int $word - */ - private function subWord($word) - { - static $sbox; - if (empty($sbox)) { - list(, , , , $sbox) = self::getTables(); - } - - return $sbox[$word & 0x000000FF] | - ($sbox[$word >> 8 & 0x000000FF] << 8) | - ($sbox[$word >> 16 & 0x000000FF] << 16) | - ($sbox[$word >> 24 & 0x000000FF] << 24); - } - - /** - * Provides the mixColumns and sboxes tables - * - * @see self::encryptBlock() - * @see self::setupInlineCrypt() - * @see self::subWord() - * @return array &$tables - */ - protected function &getTables() - { - static $tables; - if (empty($tables)) { - // according to (section 5.2.1), - // precomputed tables can be used in the mixColumns phase. in that example, they're assigned t0...t3, so - // those are the names we'll use. - $t3 = array_map('intval', [ - // with array_map('intval', ...) we ensure we have only int's and not - // some slower floats converted by php automatically on high values - 0x6363A5C6, 0x7C7C84F8, 0x777799EE, 0x7B7B8DF6, 0xF2F20DFF, 0x6B6BBDD6, 0x6F6FB1DE, 0xC5C55491, - 0x30305060, 0x01010302, 0x6767A9CE, 0x2B2B7D56, 0xFEFE19E7, 0xD7D762B5, 0xABABE64D, 0x76769AEC, - 0xCACA458F, 0x82829D1F, 0xC9C94089, 0x7D7D87FA, 0xFAFA15EF, 0x5959EBB2, 0x4747C98E, 0xF0F00BFB, - 0xADADEC41, 0xD4D467B3, 0xA2A2FD5F, 0xAFAFEA45, 0x9C9CBF23, 0xA4A4F753, 0x727296E4, 0xC0C05B9B, - 0xB7B7C275, 0xFDFD1CE1, 0x9393AE3D, 0x26266A4C, 0x36365A6C, 0x3F3F417E, 0xF7F702F5, 0xCCCC4F83, - 0x34345C68, 0xA5A5F451, 0xE5E534D1, 0xF1F108F9, 0x717193E2, 0xD8D873AB, 0x31315362, 0x15153F2A, - 0x04040C08, 0xC7C75295, 0x23236546, 0xC3C35E9D, 0x18182830, 0x9696A137, 0x05050F0A, 0x9A9AB52F, - 0x0707090E, 0x12123624, 0x80809B1B, 0xE2E23DDF, 0xEBEB26CD, 0x2727694E, 0xB2B2CD7F, 0x75759FEA, - 0x09091B12, 0x83839E1D, 0x2C2C7458, 0x1A1A2E34, 0x1B1B2D36, 0x6E6EB2DC, 0x5A5AEEB4, 0xA0A0FB5B, - 0x5252F6A4, 0x3B3B4D76, 0xD6D661B7, 0xB3B3CE7D, 0x29297B52, 0xE3E33EDD, 0x2F2F715E, 0x84849713, - 0x5353F5A6, 0xD1D168B9, 0x00000000, 0xEDED2CC1, 0x20206040, 0xFCFC1FE3, 0xB1B1C879, 0x5B5BEDB6, - 0x6A6ABED4, 0xCBCB468D, 0xBEBED967, 0x39394B72, 0x4A4ADE94, 0x4C4CD498, 0x5858E8B0, 0xCFCF4A85, - 0xD0D06BBB, 0xEFEF2AC5, 0xAAAAE54F, 0xFBFB16ED, 0x4343C586, 0x4D4DD79A, 0x33335566, 0x85859411, - 0x4545CF8A, 0xF9F910E9, 0x02020604, 0x7F7F81FE, 0x5050F0A0, 0x3C3C4478, 0x9F9FBA25, 0xA8A8E34B, - 0x5151F3A2, 0xA3A3FE5D, 0x4040C080, 0x8F8F8A05, 0x9292AD3F, 0x9D9DBC21, 0x38384870, 0xF5F504F1, - 0xBCBCDF63, 0xB6B6C177, 0xDADA75AF, 0x21216342, 0x10103020, 0xFFFF1AE5, 0xF3F30EFD, 0xD2D26DBF, - 0xCDCD4C81, 0x0C0C1418, 0x13133526, 0xECEC2FC3, 0x5F5FE1BE, 0x9797A235, 0x4444CC88, 0x1717392E, - 0xC4C45793, 0xA7A7F255, 0x7E7E82FC, 0x3D3D477A, 0x6464ACC8, 0x5D5DE7BA, 0x19192B32, 0x737395E6, - 0x6060A0C0, 0x81819819, 0x4F4FD19E, 0xDCDC7FA3, 0x22226644, 0x2A2A7E54, 0x9090AB3B, 0x8888830B, - 0x4646CA8C, 0xEEEE29C7, 0xB8B8D36B, 0x14143C28, 0xDEDE79A7, 0x5E5EE2BC, 0x0B0B1D16, 0xDBDB76AD, - 0xE0E03BDB, 0x32325664, 0x3A3A4E74, 0x0A0A1E14, 0x4949DB92, 0x06060A0C, 0x24246C48, 0x5C5CE4B8, - 0xC2C25D9F, 0xD3D36EBD, 0xACACEF43, 0x6262A6C4, 0x9191A839, 0x9595A431, 0xE4E437D3, 0x79798BF2, - 0xE7E732D5, 0xC8C8438B, 0x3737596E, 0x6D6DB7DA, 0x8D8D8C01, 0xD5D564B1, 0x4E4ED29C, 0xA9A9E049, - 0x6C6CB4D8, 0x5656FAAC, 0xF4F407F3, 0xEAEA25CF, 0x6565AFCA, 0x7A7A8EF4, 0xAEAEE947, 0x08081810, - 0xBABAD56F, 0x787888F0, 0x25256F4A, 0x2E2E725C, 0x1C1C2438, 0xA6A6F157, 0xB4B4C773, 0xC6C65197, - 0xE8E823CB, 0xDDDD7CA1, 0x74749CE8, 0x1F1F213E, 0x4B4BDD96, 0xBDBDDC61, 0x8B8B860D, 0x8A8A850F, - 0x707090E0, 0x3E3E427C, 0xB5B5C471, 0x6666AACC, 0x4848D890, 0x03030506, 0xF6F601F7, 0x0E0E121C, - 0x6161A3C2, 0x35355F6A, 0x5757F9AE, 0xB9B9D069, 0x86869117, 0xC1C15899, 0x1D1D273A, 0x9E9EB927, - 0xE1E138D9, 0xF8F813EB, 0x9898B32B, 0x11113322, 0x6969BBD2, 0xD9D970A9, 0x8E8E8907, 0x9494A733, - 0x9B9BB62D, 0x1E1E223C, 0x87879215, 0xE9E920C9, 0xCECE4987, 0x5555FFAA, 0x28287850, 0xDFDF7AA5, - 0x8C8C8F03, 0xA1A1F859, 0x89898009, 0x0D0D171A, 0xBFBFDA65, 0xE6E631D7, 0x4242C684, 0x6868B8D0, - 0x4141C382, 0x9999B029, 0x2D2D775A, 0x0F0F111E, 0xB0B0CB7B, 0x5454FCA8, 0xBBBBD66D, 0x16163A2C - ]); - - foreach ($t3 as $t3i) { - $t0[] = (($t3i << 24) & intval(0xFF000000)) | (($t3i >> 8) & 0x00FFFFFF); - $t1[] = (($t3i << 16) & intval(0xFFFF0000)) | (($t3i >> 16) & 0x0000FFFF); - $t2[] = (($t3i << 8) & intval(0xFFFFFF00)) | (($t3i >> 24) & 0x000000FF); - } - - $tables = [ - // The Precomputed mixColumns tables t0 - t3 - $t0, - $t1, - $t2, - $t3, - // The SubByte S-Box - [ - 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, - 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, - 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, - 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, - 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, - 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, - 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, - 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, - 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, - 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, - 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, - 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, - 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, - 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, - 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, - 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 - ] - ]; - } - return $tables; - } - - /** - * Provides the inverse mixColumns and inverse sboxes tables - * - * @see self::decryptBlock() - * @see self::setupInlineCrypt() - * @see self::setupKey() - * @return array &$tables - */ - protected function &getInvTables() - { - static $tables; - if (empty($tables)) { - $dt3 = array_map('intval', [ - 0xF4A75051, 0x4165537E, 0x17A4C31A, 0x275E963A, 0xAB6BCB3B, 0x9D45F11F, 0xFA58ABAC, 0xE303934B, - 0x30FA5520, 0x766DF6AD, 0xCC769188, 0x024C25F5, 0xE5D7FC4F, 0x2ACBD7C5, 0x35448026, 0x62A38FB5, - 0xB15A49DE, 0xBA1B6725, 0xEA0E9845, 0xFEC0E15D, 0x2F7502C3, 0x4CF01281, 0x4697A38D, 0xD3F9C66B, - 0x8F5FE703, 0x929C9515, 0x6D7AEBBF, 0x5259DA95, 0xBE832DD4, 0x7421D358, 0xE0692949, 0xC9C8448E, - 0xC2896A75, 0x8E7978F4, 0x583E6B99, 0xB971DD27, 0xE14FB6BE, 0x88AD17F0, 0x20AC66C9, 0xCE3AB47D, - 0xDF4A1863, 0x1A3182E5, 0x51336097, 0x537F4562, 0x6477E0B1, 0x6BAE84BB, 0x81A01CFE, 0x082B94F9, - 0x48685870, 0x45FD198F, 0xDE6C8794, 0x7BF8B752, 0x73D323AB, 0x4B02E272, 0x1F8F57E3, 0x55AB2A66, - 0xEB2807B2, 0xB5C2032F, 0xC57B9A86, 0x3708A5D3, 0x2887F230, 0xBFA5B223, 0x036ABA02, 0x16825CED, - 0xCF1C2B8A, 0x79B492A7, 0x07F2F0F3, 0x69E2A14E, 0xDAF4CD65, 0x05BED506, 0x34621FD1, 0xA6FE8AC4, - 0x2E539D34, 0xF355A0A2, 0x8AE13205, 0xF6EB75A4, 0x83EC390B, 0x60EFAA40, 0x719F065E, 0x6E1051BD, - 0x218AF93E, 0xDD063D96, 0x3E05AEDD, 0xE6BD464D, 0x548DB591, 0xC45D0571, 0x06D46F04, 0x5015FF60, - 0x98FB2419, 0xBDE997D6, 0x4043CC89, 0xD99E7767, 0xE842BDB0, 0x898B8807, 0x195B38E7, 0xC8EEDB79, - 0x7C0A47A1, 0x420FE97C, 0x841EC9F8, 0x00000000, 0x80868309, 0x2BED4832, 0x1170AC1E, 0x5A724E6C, - 0x0EFFFBFD, 0x8538560F, 0xAED51E3D, 0x2D392736, 0x0FD9640A, 0x5CA62168, 0x5B54D19B, 0x362E3A24, - 0x0A67B10C, 0x57E70F93, 0xEE96D2B4, 0x9B919E1B, 0xC0C54F80, 0xDC20A261, 0x774B695A, 0x121A161C, - 0x93BA0AE2, 0xA02AE5C0, 0x22E0433C, 0x1B171D12, 0x090D0B0E, 0x8BC7ADF2, 0xB6A8B92D, 0x1EA9C814, - 0xF1198557, 0x75074CAF, 0x99DDBBEE, 0x7F60FDA3, 0x01269FF7, 0x72F5BC5C, 0x663BC544, 0xFB7E345B, - 0x4329768B, 0x23C6DCCB, 0xEDFC68B6, 0xE4F163B8, 0x31DCCAD7, 0x63851042, 0x97224013, 0xC6112084, - 0x4A247D85, 0xBB3DF8D2, 0xF93211AE, 0x29A16DC7, 0x9E2F4B1D, 0xB230F3DC, 0x8652EC0D, 0xC1E3D077, - 0xB3166C2B, 0x70B999A9, 0x9448FA11, 0xE9642247, 0xFC8CC4A8, 0xF03F1AA0, 0x7D2CD856, 0x3390EF22, - 0x494EC787, 0x38D1C1D9, 0xCAA2FE8C, 0xD40B3698, 0xF581CFA6, 0x7ADE28A5, 0xB78E26DA, 0xADBFA43F, - 0x3A9DE42C, 0x78920D50, 0x5FCC9B6A, 0x7E466254, 0x8D13C2F6, 0xD8B8E890, 0x39F75E2E, 0xC3AFF582, - 0x5D80BE9F, 0xD0937C69, 0xD52DA96F, 0x2512B3CF, 0xAC993BC8, 0x187DA710, 0x9C636EE8, 0x3BBB7BDB, - 0x267809CD, 0x5918F46E, 0x9AB701EC, 0x4F9AA883, 0x956E65E6, 0xFFE67EAA, 0xBCCF0821, 0x15E8E6EF, - 0xE79BD9BA, 0x6F36CE4A, 0x9F09D4EA, 0xB07CD629, 0xA4B2AF31, 0x3F23312A, 0xA59430C6, 0xA266C035, - 0x4EBC3774, 0x82CAA6FC, 0x90D0B0E0, 0xA7D81533, 0x04984AF1, 0xECDAF741, 0xCD500E7F, 0x91F62F17, - 0x4DD68D76, 0xEFB04D43, 0xAA4D54CC, 0x9604DFE4, 0xD1B5E39E, 0x6A881B4C, 0x2C1FB8C1, 0x65517F46, - 0x5EEA049D, 0x8C355D01, 0x877473FA, 0x0B412EFB, 0x671D5AB3, 0xDBD25292, 0x105633E9, 0xD647136D, - 0xD7618C9A, 0xA10C7A37, 0xF8148E59, 0x133C89EB, 0xA927EECE, 0x61C935B7, 0x1CE5EDE1, 0x47B13C7A, - 0xD2DF599C, 0xF2733F55, 0x14CE7918, 0xC737BF73, 0xF7CDEA53, 0xFDAA5B5F, 0x3D6F14DF, 0x44DB8678, - 0xAFF381CA, 0x68C43EB9, 0x24342C38, 0xA3405FC2, 0x1DC37216, 0xE2250CBC, 0x3C498B28, 0x0D9541FF, - 0xA8017139, 0x0CB3DE08, 0xB4E49CD8, 0x56C19064, 0xCB84617B, 0x32B670D5, 0x6C5C7448, 0xB85742D0 - ]); - - foreach ($dt3 as $dt3i) { - $dt0[] = (($dt3i << 24) & intval(0xFF000000)) | (($dt3i >> 8) & 0x00FFFFFF); - $dt1[] = (($dt3i << 16) & intval(0xFFFF0000)) | (($dt3i >> 16) & 0x0000FFFF); - $dt2[] = (($dt3i << 8) & intval(0xFFFFFF00)) | (($dt3i >> 24) & 0x000000FF); - }; - - $tables = [ - // The Precomputed inverse mixColumns tables dt0 - dt3 - $dt0, - $dt1, - $dt2, - $dt3, - // The inverse SubByte S-Box - [ - 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, - 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, - 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, - 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, - 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, - 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, - 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, - 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, - 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, - 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, - 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, - 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, - 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, - 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, - 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D - ] - ]; - } - return $tables; - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupInlineCrypt() - */ - protected function setupInlineCrypt() - { - $w = $this->w; - $dw = $this->dw; - $init_encrypt = ''; - $init_decrypt = ''; - - $Nr = $this->Nr; - $Nb = $this->Nb; - $c = $this->c; - - // Generating encrypt code: - $init_encrypt .= ' - if (empty($tables)) { - $tables = &$this->getTables(); - } - $t0 = $tables[0]; - $t1 = $tables[1]; - $t2 = $tables[2]; - $t3 = $tables[3]; - $sbox = $tables[4]; - '; - - $s = 'e'; - $e = 's'; - $wc = $Nb - 1; - - // Preround: addRoundKey - $encrypt_block = '$in = unpack("N*", $in);' . "\n"; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $w[++$wc] . ";\n"; - } - - // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey - for ($round = 1; $round < $Nr; ++$round) { - list($s, $e) = [$e, $s]; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block .= - '$' . $e . $i . ' = - $t0[($' . $s . $i . ' >> 24) & 0xff] ^ - $t1[($' . $s . (($i + $c[1]) % $Nb) . ' >> 16) & 0xff] ^ - $t2[($' . $s . (($i + $c[2]) % $Nb) . ' >> 8) & 0xff] ^ - $t3[ $' . $s . (($i + $c[3]) % $Nb) . ' & 0xff] ^ - ' . $w[++$wc] . ";\n"; - } - } - - // Finalround: subWord + shiftRows + addRoundKey - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block .= - '$' . $e . $i . ' = - $sbox[ $' . $e . $i . ' & 0xff] | - ($sbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | - ($sbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | - ($sbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; - } - $encrypt_block .= '$in = pack("N*"' . "\n"; - for ($i = 0; $i < $Nb; ++$i) { - $encrypt_block .= ', - ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ - ($' . $e . (($i + $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ - ($' . $e . (($i + $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ - ($' . $e . (($i + $c[3]) % $Nb) . ' & 0x000000FF ) ^ - ' . $w[$i] . "\n"; - } - $encrypt_block .= ');'; - - // Generating decrypt code: - $init_decrypt .= ' - if (empty($invtables)) { - $invtables = &$this->getInvTables(); - } - $dt0 = $invtables[0]; - $dt1 = $invtables[1]; - $dt2 = $invtables[2]; - $dt3 = $invtables[3]; - $isbox = $invtables[4]; - '; - - $s = 'e'; - $e = 's'; - $wc = $Nb - 1; - - // Preround: addRoundKey - $decrypt_block = '$in = unpack("N*", $in);' . "\n"; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block .= '$s' . $i . ' = $in[' . ($i + 1) . '] ^ ' . $dw[++$wc] . ';' . "\n"; - } - - // Mainrounds: shiftRows + subWord + mixColumns + addRoundKey - for ($round = 1; $round < $Nr; ++$round) { - list($s, $e) = [$e, $s]; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block .= - '$' . $e . $i . ' = - $dt0[($' . $s . $i . ' >> 24) & 0xff] ^ - $dt1[($' . $s . (($Nb + $i - $c[1]) % $Nb) . ' >> 16) & 0xff] ^ - $dt2[($' . $s . (($Nb + $i - $c[2]) % $Nb) . ' >> 8) & 0xff] ^ - $dt3[ $' . $s . (($Nb + $i - $c[3]) % $Nb) . ' & 0xff] ^ - ' . $dw[++$wc] . ";\n"; - } - } - - // Finalround: subWord + shiftRows + addRoundKey - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block .= - '$' . $e . $i . ' = - $isbox[ $' . $e . $i . ' & 0xff] | - ($isbox[($' . $e . $i . ' >> 8) & 0xff] << 8) | - ($isbox[($' . $e . $i . ' >> 16) & 0xff] << 16) | - ($isbox[($' . $e . $i . ' >> 24) & 0xff] << 24);' . "\n"; - } - $decrypt_block .= '$in = pack("N*"' . "\n"; - for ($i = 0; $i < $Nb; ++$i) { - $decrypt_block .= ', - ($' . $e . $i . ' & ' . ((int)0xFF000000) . ') ^ - ($' . $e . (($Nb + $i - $c[1]) % $Nb) . ' & 0x00FF0000 ) ^ - ($' . $e . (($Nb + $i - $c[2]) % $Nb) . ' & 0x0000FF00 ) ^ - ($' . $e . (($Nb + $i - $c[3]) % $Nb) . ' & 0x000000FF ) ^ - ' . $dw[$i] . "\n"; - } - $decrypt_block .= ');'; - - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => 'static $tables; static $invtables;', - 'init_encrypt' => $init_encrypt, - 'init_decrypt' => $init_decrypt, - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); - } - - /** - * Encrypts a message. - * - * @see self::decrypt() - * @see parent::encrypt() - * @param string $plaintext - * @return string - */ - public function encrypt($plaintext) - { - $this->setup(); - - switch ($this->engine) { - case self::ENGINE_LIBSODIUM: - $this->newtag = sodium_crypto_aead_aes256gcm_encrypt($plaintext, $this->aad, $this->nonce, $this->key); - return Strings::shift($this->newtag, strlen($plaintext)); - case self::ENGINE_OPENSSL_GCM: - return openssl_encrypt( - $plaintext, - 'aes-' . $this->getKeyLength() . '-gcm', - $this->key, - OPENSSL_RAW_DATA, - $this->nonce, - $this->newtag, - $this->aad - ); - } - - return parent::encrypt($plaintext); - } - - /** - * Decrypts a message. - * - * @see self::encrypt() - * @see parent::decrypt() - * @param string $ciphertext - * @return string - */ - public function decrypt($ciphertext) - { - $this->setup(); - - switch ($this->engine) { - case self::ENGINE_LIBSODIUM: - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - if (strlen($this->oldtag) != 16) { - break; - } - $plaintext = sodium_crypto_aead_aes256gcm_decrypt($ciphertext . $this->oldtag, $this->aad, $this->nonce, $this->key); - if ($plaintext === false) { - $this->oldtag = false; - throw new BadDecryptionException('Error decrypting ciphertext with libsodium'); - } - return $plaintext; - case self::ENGINE_OPENSSL_GCM: - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - $plaintext = openssl_decrypt( - $ciphertext, - 'aes-' . $this->getKeyLength() . '-gcm', - $this->key, - OPENSSL_RAW_DATA, - $this->nonce, - $this->oldtag, - $this->aad - ); - if ($plaintext === false) { - $this->oldtag = false; - throw new BadDecryptionException('Error decrypting ciphertext with OpenSSL'); - } - return $plaintext; - } - - return parent::decrypt($ciphertext); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php deleted file mode 100644 index 0a35f47..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Salsa20.php +++ /dev/null @@ -1,526 +0,0 @@ - - * @copyright 2019 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\StreamCipher; -use phpseclib3\Exception\BadDecryptionException; -use phpseclib3\Exception\InsufficientSetupException; - -/** - * Pure-PHP implementation of Salsa20. - * - * @author Jim Wigginton - */ -class Salsa20 extends StreamCipher -{ - /** - * Part 1 of the state - * - * @var string|false - */ - protected $p1 = false; - - /** - * Part 2 of the state - * - * @var string|false - */ - protected $p2 = false; - - /** - * Key Length (in bytes) - * - * @var int - */ - protected $key_length = 32; // = 256 bits - - /** - * @see \phpseclib3\Crypt\Salsa20::crypt() - */ - const ENCRYPT = 0; - - /** - * @see \phpseclib3\Crypt\Salsa20::crypt() - */ - const DECRYPT = 1; - - /** - * Encryption buffer for continuous mode - * - * @var array - */ - protected $enbuffer; - - /** - * Decryption buffer for continuous mode - * - * @var array - */ - protected $debuffer; - - /** - * Counter - * - * @var int - */ - protected $counter = 0; - - /** - * Using Generated Poly1305 Key - * - * @var boolean - */ - protected $usingGeneratedPoly1305Key = false; - - /** - * Salsa20 uses a nonce - * - * @return bool - */ - public function usesNonce() - { - return true; - } - - /** - * Sets the key. - * - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 32: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 32 are supported'); - } - - parent::setKey($key); - } - - /** - * Sets the nonce. - * - * @param string $nonce - */ - public function setNonce($nonce) - { - if (strlen($nonce) != 8) { - throw new \LengthException('Nonce of size ' . strlen($key) . ' not supported by this algorithm. Only an 64-bit nonce is supported'); - } - - $this->nonce = $nonce; - $this->changed = true; - $this->setEngine(); - } - - /** - * Sets the counter. - * - * @param int $counter - */ - public function setCounter($counter) - { - $this->counter = $counter; - $this->setEngine(); - } - - /** - * Creates a Poly1305 key using the method discussed in RFC8439 - * - * See https://tools.ietf.org/html/rfc8439#section-2.6.1 - */ - protected function createPoly1305Key() - { - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - $c = clone $this; - $c->setCounter(0); - $c->usePoly1305 = false; - $block = $c->encrypt(str_repeat("\0", 256)); - $this->setPoly1305Key(substr($block, 0, 32)); - - if ($this->counter == 0) { - $this->counter++; - } - } - - /** - * Setup the self::ENGINE_INTERNAL $engine - * - * (re)init, if necessary, the internal cipher $engine - * - * _setup() will be called each time if $changed === true - * typically this happens when using one or more of following public methods: - * - * - setKey() - * - * - setNonce() - * - * - First run of encrypt() / decrypt() with no init-settings - * - * @see self::setKey() - * @see self::setNonce() - * @see self::disableContinuousBuffer() - */ - protected function setup() - { - if (!$this->changed) { - return; - } - - $this->enbuffer = $this->debuffer = ['ciphertext' => '', 'counter' => $this->counter]; - - $this->changed = $this->nonIVChanged = false; - - if ($this->nonce === false) { - throw new InsufficientSetupException('No nonce has been defined'); - } - - if ($this->key === false) { - throw new InsufficientSetupException('No key has been defined'); - } - - if ($this->usePoly1305 && !isset($this->poly1305Key)) { - $this->usingGeneratedPoly1305Key = true; - $this->createPoly1305Key(); - } - - $key = $this->key; - if (strlen($key) == 16) { - $constant = 'expand 16-byte k'; - $key .= $key; - } else { - $constant = 'expand 32-byte k'; - } - - $this->p1 = substr($constant, 0, 4) . - substr($key, 0, 16) . - substr($constant, 4, 4) . - $this->nonce . - "\0\0\0\0"; - $this->p2 = substr($constant, 8, 4) . - substr($key, 16, 16) . - substr($constant, 12, 4); - } - - /** - * Setup the key (expansion) - */ - protected function setupKey() - { - // Salsa20 does not utilize this method - } - - /** - * Encrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @see self::crypt() - * @param string $plaintext - * @return string $ciphertext - */ - public function encrypt($plaintext) - { - $ciphertext = $this->crypt($plaintext, self::ENCRYPT); - if (isset($this->poly1305Key)) { - $this->newtag = $this->poly1305($ciphertext); - } - return $ciphertext; - } - - /** - * Decrypts a message. - * - * $this->decrypt($this->encrypt($plaintext)) == $this->encrypt($this->encrypt($plaintext)). - * At least if the continuous buffer is disabled. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @see self::crypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - if (isset($this->poly1305Key)) { - if ($this->oldtag === false) { - throw new InsufficientSetupException('Authentication Tag has not been set'); - } - $newtag = $this->poly1305($ciphertext); - if ($this->oldtag != substr($newtag, 0, strlen($this->oldtag))) { - $this->oldtag = false; - throw new BadDecryptionException('Derived authentication tag and supplied authentication tag do not match'); - } - $this->oldtag = false; - } - - return $this->crypt($ciphertext, self::DECRYPT); - } - - /** - * Encrypts a block - * - * @param string $in - */ - protected function encryptBlock($in) - { - // Salsa20 does not utilize this method - } - - /** - * Decrypts a block - * - * @param string $in - */ - protected function decryptBlock($in) - { - // Salsa20 does not utilize this method - } - - /** - * Encrypts or decrypts a message. - * - * @see self::encrypt() - * @see self::decrypt() - * @param string $text - * @param int $mode - * @return string $text - */ - private function crypt($text, $mode) - { - $this->setup(); - if (!$this->continuousBuffer) { - if ($this->engine == self::ENGINE_OPENSSL) { - $iv = pack('V', $this->counter) . $this->p2; - return openssl_encrypt( - $text, - $this->cipher_name_openssl, - $this->key, - OPENSSL_RAW_DATA, - $iv - ); - } - $i = $this->counter; - $blocks = str_split($text, 64); - foreach ($blocks as &$block) { - $block ^= static::salsa20($this->p1 . pack('V', $i++) . $this->p2); - } - - return implode('', $blocks); - } - - if ($mode == self::ENCRYPT) { - $buffer = &$this->enbuffer; - } else { - $buffer = &$this->debuffer; - } - if (!strlen($buffer['ciphertext'])) { - $ciphertext = ''; - } else { - $ciphertext = $text ^ Strings::shift($buffer['ciphertext'], strlen($text)); - $text = substr($text, strlen($ciphertext)); - if (!strlen($text)) { - return $ciphertext; - } - } - - $overflow = strlen($text) % 64; // & 0x3F - if ($overflow) { - $text2 = Strings::pop($text, $overflow); - if ($this->engine == self::ENGINE_OPENSSL) { - $iv = pack('V', $buffer['counter']) . $this->p2; - // at this point $text should be a multiple of 64 - $buffer['counter'] += (strlen($text) >> 6) + 1; // ie. divide by 64 - $encrypted = openssl_encrypt( - $text . str_repeat("\0", 64), - $this->cipher_name_openssl, - $this->key, - OPENSSL_RAW_DATA, - $iv - ); - $temp = Strings::pop($encrypted, 64); - } else { - $blocks = str_split($text, 64); - if (strlen($text)) { - foreach ($blocks as &$block) { - $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); - } - } - $encrypted = implode('', $blocks); - $temp = static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); - } - $ciphertext .= $encrypted . ($text2 ^ $temp); - $buffer['ciphertext'] = substr($temp, $overflow); - } elseif (!strlen($buffer['ciphertext'])) { - if ($this->engine == self::ENGINE_OPENSSL) { - $iv = pack('V', $buffer['counter']) . $this->p2; - $buffer['counter'] += (strlen($text) >> 6); - $ciphertext .= openssl_encrypt( - $text, - $this->cipher_name_openssl, - $this->key, - OPENSSL_RAW_DATA, - $iv - ); - } else { - $blocks = str_split($text, 64); - foreach ($blocks as &$block) { - $block ^= static::salsa20($this->p1 . pack('V', $buffer['counter']++) . $this->p2); - } - $ciphertext .= implode('', $blocks); - } - } - - return $ciphertext; - } - - /** - * Left Rotate - * - * @param int $x - * @param int $n - * @return int - */ - protected static function leftRotate($x, $n) - { - if (PHP_INT_SIZE == 8) { - $r1 = $x << $n; - $r1 &= 0xFFFFFFFF; - $r2 = ($x & 0xFFFFFFFF) >> (32 - $n); - } else { - $x = (int) $x; - $r1 = $x << $n; - $r2 = $x >> (32 - $n); - $r2 &= (1 << $n) - 1; - } - return $r1 | $r2; - } - - /** - * The quarterround function - * - * @param int $a - * @param int $b - * @param int $c - * @param int $d - */ - protected static function quarterRound(&$a, &$b, &$c, &$d) - { - $b ^= self::leftRotate($a + $d, 7); - $c ^= self::leftRotate($b + $a, 9); - $d ^= self::leftRotate($c + $b, 13); - $a ^= self::leftRotate($d + $c, 18); - } - - /** - * The doubleround function - * - * @param int $x0 (by reference) - * @param int $x1 (by reference) - * @param int $x2 (by reference) - * @param int $x3 (by reference) - * @param int $x4 (by reference) - * @param int $x5 (by reference) - * @param int $x6 (by reference) - * @param int $x7 (by reference) - * @param int $x8 (by reference) - * @param int $x9 (by reference) - * @param int $x10 (by reference) - * @param int $x11 (by reference) - * @param int $x12 (by reference) - * @param int $x13 (by reference) - * @param int $x14 (by reference) - * @param int $x15 (by reference) - */ - protected static function doubleRound(&$x0, &$x1, &$x2, &$x3, &$x4, &$x5, &$x6, &$x7, &$x8, &$x9, &$x10, &$x11, &$x12, &$x13, &$x14, &$x15) - { - // columnRound - static::quarterRound($x0, $x4, $x8, $x12); - static::quarterRound($x5, $x9, $x13, $x1); - static::quarterRound($x10, $x14, $x2, $x6); - static::quarterRound($x15, $x3, $x7, $x11); - // rowRound - static::quarterRound($x0, $x1, $x2, $x3); - static::quarterRound($x5, $x6, $x7, $x4); - static::quarterRound($x10, $x11, $x8, $x9); - static::quarterRound($x15, $x12, $x13, $x14); - } - - /** - * The Salsa20 hash function function - * - * @param string $x - */ - protected static function salsa20($x) - { - $z = $x = unpack('V*', $x); - for ($i = 0; $i < 10; $i++) { - static::doubleRound($z[1], $z[2], $z[3], $z[4], $z[5], $z[6], $z[7], $z[8], $z[9], $z[10], $z[11], $z[12], $z[13], $z[14], $z[15], $z[16]); - } - - for ($i = 1; $i <= 16; $i++) { - $x[$i] += $z[$i]; - } - - return pack('V*', ...$x); - } - - /** - * Calculates Poly1305 MAC - * - * @see self::decrypt() - * @see self::encrypt() - * @param string $ciphertext - * @return string - */ - protected function poly1305($ciphertext) - { - if (!$this->usingGeneratedPoly1305Key) { - return parent::poly1305($this->aad . $ciphertext); - } else { - /* - sodium_crypto_aead_chacha20poly1305_encrypt does not calculate the poly1305 tag - the same way sodium_crypto_aead_chacha20poly1305_ietf_encrypt does. you can see - how the latter encrypts it in Salsa20::encrypt(). here's how the former encrypts - it: - - $this->newtag = $this->poly1305( - $this->aad . - pack('V', strlen($this->aad)) . "\0\0\0\0" . - $ciphertext . - pack('V', strlen($ciphertext)) . "\0\0\0\0" - ); - - phpseclib opts to use the IETF construction, even when the nonce is 64-bits - instead of 96-bits - */ - return parent::poly1305( - self::nullPad128($this->aad) . - self::nullPad128($ciphertext) . - pack('V', strlen($this->aad)) . "\0\0\0\0" . - pack('V', strlen($ciphertext)) . "\0\0\0\0" - ); - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php deleted file mode 100644 index 1ff5ed0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/TripleDES.php +++ /dev/null @@ -1,436 +0,0 @@ - - * setKey('abcdefghijklmnopqrstuvwx'); - * - * $size = 10 * 1024; - * $plaintext = ''; - * for ($i = 0; $i < $size; $i++) { - * $plaintext.= 'a'; - * } - * - * echo $des->decrypt($des->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -/** - * Pure-PHP implementation of Triple DES. - * - * @author Jim Wigginton - */ -class TripleDES extends DES -{ - /** - * Encrypt / decrypt using inner chaining - * - * Inner chaining is used by SSH-1 and is generally considered to be less secure then outer chaining (self::MODE_CBC3). - */ - const MODE_3CBC = -2; - - /** - * Encrypt / decrypt using outer chaining - * - * Outer chaining is used by SSH-2 and when the mode is set to \phpseclib3\Crypt\Common\BlockCipher::MODE_CBC. - */ - const MODE_CBC3 = self::MODE_CBC; - - /** - * Key Length (in bytes) - * - * @see \phpseclib3\Crypt\TripleDES::setKeyLength() - * @var int - */ - protected $key_length = 24; - - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib3\Crypt\DES::cipher_name_mcrypt - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @var string - */ - protected $cipher_name_mcrypt = 'tripledes'; - - /** - * Optimizing value while CFB-encrypting - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len - * @var int - */ - protected $cfb_init_len = 750; - - /** - * max possible size of $key - * - * @see self::setKey() - * @see \phpseclib3\Crypt\DES::setKey() - * @var string - */ - protected $key_length_max = 24; - - /** - * Internal flag whether using self::MODE_3CBC or not - * - * @var bool - */ - private $mode_3cbc; - - /** - * The \phpseclib3\Crypt\DES objects - * - * Used only if $mode_3cbc === true - * - * @var array - */ - private $des; - - /** - * Default Constructor. - * - * Determines whether or not the mcrypt or OpenSSL extensions should be used. - * - * $mode could be: - * - * - ecb - * - * - cbc - * - * - ctr - * - * - cfb - * - * - ofb - * - * - 3cbc - * - * - cbc3 (same as cbc) - * - * @see \phpseclib3\Crypt\DES::__construct() - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param string $mode - */ - public function __construct($mode) - { - switch (strtolower($mode)) { - // In case of self::MODE_3CBC, we init as CRYPT_DES_MODE_CBC - // and additional flag us internally as 3CBC - case '3cbc': - parent::__construct('cbc'); - $this->mode_3cbc = true; - - // This three $des'es will do the 3CBC work (if $key > 64bits) - $this->des = [ - new DES('cbc'), - new DES('cbc'), - new DES('cbc'), - ]; - - // we're going to be doing the padding, ourselves, so disable it in the \phpseclib3\Crypt\DES objects - $this->des[0]->disablePadding(); - $this->des[1]->disablePadding(); - $this->des[2]->disablePadding(); - break; - case 'cbc3': - $mode = 'cbc'; - // fall-through - // If not 3CBC, we init as usual - default: - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } - } - - /** - * Test for engine validity - * - * This is mainly just a wrapper to set things up for \phpseclib3\Crypt\Common\SymmetricKey::isValidEngine() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @param int $engine - * @return bool - */ - protected function isValidEngineHelper($engine) - { - if ($engine == self::ENGINE_OPENSSL) { - $this->cipher_name_openssl_ecb = 'des-ede3'; - $mode = $this->openssl_translate_mode(); - $this->cipher_name_openssl = $mode == 'ecb' ? 'des-ede3' : 'des-ede3-' . $mode; - } - - return parent::isValidEngineHelper($engine); - } - - /** - * Sets the initialization vector. - * - * SetIV is not required when \phpseclib3\Crypt\Common\SymmetricKey::MODE_ECB is being used. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::setIV() - * @param string $iv - */ - public function setIV($iv) - { - parent::setIV($iv); - if ($this->mode_3cbc) { - $this->des[0]->setIV($iv); - $this->des[1]->setIV($iv); - $this->des[2]->setIV($iv); - } - } - - /** - * Sets the key length. - * - * Valid key lengths are 128 and 192 bits. - * - * If you want to use a 64-bit key use DES.php - * - * @see \phpseclib3\Crypt\Common\SymmetricKey:setKeyLength() - * @throws \LengthException if the key length is invalid - * @param int $length - */ - public function setKeyLength($length) - { - switch ($length) { - case 128: - case 192: - break; - default: - throw new \LengthException('Key size of ' . $length . ' bits is not supported by this algorithm. Only keys of sizes 128 or 192 bits are supported'); - } - - parent::setKeyLength($length); - } - - /** - * Sets the key. - * - * Triple DES can use 128-bit (eg. strlen($key) == 16) or 192-bit (eg. strlen($key) == 24) keys. - * - * DES also requires that every eighth bit be a parity bit, however, we'll ignore that. - * - * @see \phpseclib3\Crypt\DES::setKey() - * @see \phpseclib3\Crypt\Common\SymmetricKey::setKey() - * @throws \LengthException if the key length is invalid - * @param string $key - */ - public function setKey($key) - { - if ($this->explicit_key_length !== false && strlen($key) != $this->explicit_key_length) { - throw new \LengthException('Key length has already been set to ' . $this->explicit_key_length . ' bytes and this key is ' . strlen($key) . ' bytes'); - } - - switch (strlen($key)) { - case 16: - $key .= substr($key, 0, 8); - break; - case 24: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16 or 24 are supported'); - } - - // copied from self::setKey() - $this->key = $key; - $this->key_length = strlen($key); - $this->changed = $this->nonIVChanged = true; - $this->setEngine(); - - if ($this->mode_3cbc) { - $this->des[0]->setKey(substr($key, 0, 8)); - $this->des[1]->setKey(substr($key, 8, 8)); - $this->des[2]->setKey(substr($key, 16, 8)); - } - } - - /** - * Encrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::encrypt() - * @param string $plaintext - * @return string $cipertext - */ - public function encrypt($plaintext) - { - // parent::en/decrypt() is able to do all the work for all modes and keylengths, - // except for: self::MODE_3CBC (inner chaining CBC) with a key > 64bits - - // if the key is smaller then 8, do what we'd normally do - if ($this->mode_3cbc && strlen($this->key) > 8) { - return $this->des[2]->encrypt( - $this->des[1]->decrypt( - $this->des[0]->encrypt( - $this->pad($plaintext) - ) - ) - ); - } - - return parent::encrypt($plaintext); - } - - /** - * Decrypts a message. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::decrypt() - * @param string $ciphertext - * @return string $plaintext - */ - public function decrypt($ciphertext) - { - if ($this->mode_3cbc && strlen($this->key) > 8) { - return $this->unpad( - $this->des[0]->decrypt( - $this->des[1]->encrypt( - $this->des[2]->decrypt( - str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, "\0") - ) - ) - ) - ); - } - - return parent::decrypt($ciphertext); - } - - /** - * Treat consecutive "packets" as if they are a continuous buffer. - * - * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets - * will yield different outputs: - * - * - * echo $des->encrypt(substr($plaintext, 0, 8)); - * echo $des->encrypt(substr($plaintext, 8, 8)); - * - * - * echo $des->encrypt($plaintext); - * - * - * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates - * another, as demonstrated with the following: - * - * - * $des->encrypt(substr($plaintext, 0, 8)); - * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); - * - * - * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8))); - * - * - * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different - * outputs. The reason is due to the fact that the initialization vector's change after every encryption / - * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant. - * - * Put another way, when the continuous buffer is enabled, the state of the \phpseclib3\Crypt\DES() object changes after each - * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that - * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them), - * however, they are also less intuitive and more likely to cause you problems. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::enableContinuousBuffer() - * @see self::disableContinuousBuffer() - */ - public function enableContinuousBuffer() - { - parent::enableContinuousBuffer(); - if ($this->mode_3cbc) { - $this->des[0]->enableContinuousBuffer(); - $this->des[1]->enableContinuousBuffer(); - $this->des[2]->enableContinuousBuffer(); - } - } - - /** - * Treat consecutive packets as if they are a discontinuous buffer. - * - * The default behavior. - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::disableContinuousBuffer() - * @see self::enableContinuousBuffer() - */ - public function disableContinuousBuffer() - { - parent::disableContinuousBuffer(); - if ($this->mode_3cbc) { - $this->des[0]->disableContinuousBuffer(); - $this->des[1]->disableContinuousBuffer(); - $this->des[2]->disableContinuousBuffer(); - } - } - - /** - * Creates the key schedule - * - * @see \phpseclib3\Crypt\DES::setupKey() - * @see \phpseclib3\Crypt\Common\SymmetricKey::setupKey() - */ - protected function setupKey() - { - switch (true) { - // if $key <= 64bits we configure our internal pure-php cipher engine - // to act as regular [1]DES, not as 3DES. mcrypt.so::tripledes does the same. - case strlen($this->key) <= 8: - $this->des_rounds = 1; - break; - - // otherwise, if $key > 64bits, we configure our engine to work as 3DES. - default: - $this->des_rounds = 3; - - // (only) if 3CBC is used we have, of course, to setup the $des[0-2] keys also separately. - if ($this->mode_3cbc) { - $this->des[0]->setupKey(); - $this->des[1]->setupKey(); - $this->des[2]->setupKey(); - - // because $des[0-2] will, now, do all the work we can return here - // not need unnecessary stress parent::setupKey() with our, now unused, $key. - return; - } - } - // setup our key - parent::setupKey(); - } - - /** - * Sets the internal crypt engine - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::__construct() - * @see \phpseclib3\Crypt\Common\SymmetricKey::setPreferredEngine() - * @param int $engine - */ - public function setPreferredEngine($engine) - { - if ($this->mode_3cbc) { - $this->des[0]->setPreferredEngine($engine); - $this->des[1]->setPreferredEngine($engine); - $this->des[2]->setPreferredEngine($engine); - } - - parent::setPreferredEngine($engine); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php deleted file mode 100644 index bf76563..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Crypt/Twofish.php +++ /dev/null @@ -1,816 +0,0 @@ - - * setKey('12345678901234567890123456789012'); - * - * $plaintext = str_repeat('a', 1024); - * - * echo $twofish->decrypt($twofish->encrypt($plaintext)); - * ?> - * - * - * @author Jim Wigginton - * @author Hans-Juergen Petrich - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Crypt; - -use phpseclib3\Crypt\Common\BlockCipher; -use phpseclib3\Exception\BadModeException; - -/** - * Pure-PHP implementation of Twofish. - * - * @author Jim Wigginton - * @author Hans-Juergen Petrich - */ -class Twofish extends BlockCipher -{ - /** - * The mcrypt specific name of the cipher - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cipher_name_mcrypt - * @var string - */ - protected $cipher_name_mcrypt = 'twofish'; - - /** - * Optimizing value while CFB-encrypting - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::cfb_init_len - * @var int - */ - protected $cfb_init_len = 800; - - /** - * Q-Table - * - * @var array - */ - private static $q0 = [ - 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, - 0x9A, 0x92, 0x80, 0x78, 0xE4, 0xDD, 0xD1, 0x38, - 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, - 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, - 0xF2, 0xD0, 0x8B, 0x30, 0x84, 0x54, 0xDF, 0x23, - 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, - 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, - 0xA6, 0xEB, 0xA5, 0xBE, 0x16, 0x0C, 0xE3, 0x61, - 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, - 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, - 0xE1, 0xE6, 0xBD, 0x45, 0xE2, 0xF4, 0xB6, 0x66, - 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, - 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, - 0xEA, 0x77, 0x39, 0xAF, 0x33, 0xC9, 0x62, 0x71, - 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, - 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, - 0xA1, 0x1D, 0xAA, 0xED, 0x06, 0x70, 0xB2, 0xD2, - 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, - 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, - 0x9E, 0x9C, 0x52, 0x1B, 0x5F, 0x93, 0x0A, 0xEF, - 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, - 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, - 0x2A, 0xCE, 0xCB, 0x2F, 0xFC, 0x97, 0x05, 0x7A, - 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, - 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, - 0xB8, 0xDA, 0xB0, 0x17, 0x55, 0x1F, 0x8A, 0x7D, - 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, - 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, - 0x6E, 0x50, 0xDE, 0x68, 0x65, 0xBC, 0xDB, 0xF8, - 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, - 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, - 0x6F, 0x9D, 0x36, 0x42, 0x4A, 0x5E, 0xC1, 0xE0 - ]; - - /** - * Q-Table - * - * @var array - */ - private static $q1 = [ - 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, - 0x4A, 0xD3, 0xE6, 0x6B, 0x45, 0x7D, 0xE8, 0x4B, - 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, - 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, - 0x5E, 0xBA, 0xAE, 0x5B, 0x8A, 0x00, 0xBC, 0x9D, - 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, - 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, - 0xB2, 0x73, 0x4C, 0x54, 0x92, 0x74, 0x36, 0x51, - 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, - 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, - 0x13, 0x95, 0x9C, 0xC7, 0x24, 0x46, 0x3B, 0x70, - 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, - 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, - 0x03, 0x6F, 0x08, 0xBF, 0x40, 0xE7, 0x2B, 0xE2, - 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, - 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, - 0x66, 0x94, 0xA1, 0x1D, 0x3D, 0xF0, 0xDE, 0xB3, - 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, - 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, - 0x81, 0x88, 0xEE, 0x21, 0xC4, 0x1A, 0xEB, 0xD9, - 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, - 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, - 0x4F, 0xF2, 0x65, 0x8E, 0x78, 0x5C, 0x58, 0x19, - 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, - 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, - 0xCE, 0xE9, 0x68, 0x44, 0xE0, 0x4D, 0x43, 0x69, - 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, - 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, - 0x22, 0xC9, 0xC0, 0x9B, 0x89, 0xD4, 0xED, 0xAB, - 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, - 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, - 0x16, 0x25, 0x86, 0x56, 0x55, 0x09, 0xBE, 0x91 - ]; - - /** - * M-Table - * - * @var array - */ - private static $m0 = [ - 0xBCBC3275, 0xECEC21F3, 0x202043C6, 0xB3B3C9F4, 0xDADA03DB, 0x02028B7B, 0xE2E22BFB, 0x9E9EFAC8, - 0xC9C9EC4A, 0xD4D409D3, 0x18186BE6, 0x1E1E9F6B, 0x98980E45, 0xB2B2387D, 0xA6A6D2E8, 0x2626B74B, - 0x3C3C57D6, 0x93938A32, 0x8282EED8, 0x525298FD, 0x7B7BD437, 0xBBBB3771, 0x5B5B97F1, 0x474783E1, - 0x24243C30, 0x5151E20F, 0xBABAC6F8, 0x4A4AF31B, 0xBFBF4887, 0x0D0D70FA, 0xB0B0B306, 0x7575DE3F, - 0xD2D2FD5E, 0x7D7D20BA, 0x666631AE, 0x3A3AA35B, 0x59591C8A, 0x00000000, 0xCDCD93BC, 0x1A1AE09D, - 0xAEAE2C6D, 0x7F7FABC1, 0x2B2BC7B1, 0xBEBEB90E, 0xE0E0A080, 0x8A8A105D, 0x3B3B52D2, 0x6464BAD5, - 0xD8D888A0, 0xE7E7A584, 0x5F5FE807, 0x1B1B1114, 0x2C2CC2B5, 0xFCFCB490, 0x3131272C, 0x808065A3, - 0x73732AB2, 0x0C0C8173, 0x79795F4C, 0x6B6B4154, 0x4B4B0292, 0x53536974, 0x94948F36, 0x83831F51, - 0x2A2A3638, 0xC4C49CB0, 0x2222C8BD, 0xD5D5F85A, 0xBDBDC3FC, 0x48487860, 0xFFFFCE62, 0x4C4C0796, - 0x4141776C, 0xC7C7E642, 0xEBEB24F7, 0x1C1C1410, 0x5D5D637C, 0x36362228, 0x6767C027, 0xE9E9AF8C, - 0x4444F913, 0x1414EA95, 0xF5F5BB9C, 0xCFCF18C7, 0x3F3F2D24, 0xC0C0E346, 0x7272DB3B, 0x54546C70, - 0x29294CCA, 0xF0F035E3, 0x0808FE85, 0xC6C617CB, 0xF3F34F11, 0x8C8CE4D0, 0xA4A45993, 0xCACA96B8, - 0x68683BA6, 0xB8B84D83, 0x38382820, 0xE5E52EFF, 0xADAD569F, 0x0B0B8477, 0xC8C81DC3, 0x9999FFCC, - 0x5858ED03, 0x19199A6F, 0x0E0E0A08, 0x95957EBF, 0x70705040, 0xF7F730E7, 0x6E6ECF2B, 0x1F1F6EE2, - 0xB5B53D79, 0x09090F0C, 0x616134AA, 0x57571682, 0x9F9F0B41, 0x9D9D803A, 0x111164EA, 0x2525CDB9, - 0xAFAFDDE4, 0x4545089A, 0xDFDF8DA4, 0xA3A35C97, 0xEAEAD57E, 0x353558DA, 0xEDEDD07A, 0x4343FC17, - 0xF8F8CB66, 0xFBFBB194, 0x3737D3A1, 0xFAFA401D, 0xC2C2683D, 0xB4B4CCF0, 0x32325DDE, 0x9C9C71B3, - 0x5656E70B, 0xE3E3DA72, 0x878760A7, 0x15151B1C, 0xF9F93AEF, 0x6363BFD1, 0x3434A953, 0x9A9A853E, - 0xB1B1428F, 0x7C7CD133, 0x88889B26, 0x3D3DA65F, 0xA1A1D7EC, 0xE4E4DF76, 0x8181942A, 0x91910149, - 0x0F0FFB81, 0xEEEEAA88, 0x161661EE, 0xD7D77321, 0x9797F5C4, 0xA5A5A81A, 0xFEFE3FEB, 0x6D6DB5D9, - 0x7878AEC5, 0xC5C56D39, 0x1D1DE599, 0x7676A4CD, 0x3E3EDCAD, 0xCBCB6731, 0xB6B6478B, 0xEFEF5B01, - 0x12121E18, 0x6060C523, 0x6A6AB0DD, 0x4D4DF61F, 0xCECEE94E, 0xDEDE7C2D, 0x55559DF9, 0x7E7E5A48, - 0x2121B24F, 0x03037AF2, 0xA0A02665, 0x5E5E198E, 0x5A5A6678, 0x65654B5C, 0x62624E58, 0xFDFD4519, - 0x0606F48D, 0x404086E5, 0xF2F2BE98, 0x3333AC57, 0x17179067, 0x05058E7F, 0xE8E85E05, 0x4F4F7D64, - 0x89896AAF, 0x10109563, 0x74742FB6, 0x0A0A75FE, 0x5C5C92F5, 0x9B9B74B7, 0x2D2D333C, 0x3030D6A5, - 0x2E2E49CE, 0x494989E9, 0x46467268, 0x77775544, 0xA8A8D8E0, 0x9696044D, 0x2828BD43, 0xA9A92969, - 0xD9D97929, 0x8686912E, 0xD1D187AC, 0xF4F44A15, 0x8D8D1559, 0xD6D682A8, 0xB9B9BC0A, 0x42420D9E, - 0xF6F6C16E, 0x2F2FB847, 0xDDDD06DF, 0x23233934, 0xCCCC6235, 0xF1F1C46A, 0xC1C112CF, 0x8585EBDC, - 0x8F8F9E22, 0x7171A1C9, 0x9090F0C0, 0xAAAA539B, 0x0101F189, 0x8B8BE1D4, 0x4E4E8CED, 0x8E8E6FAB, - 0xABABA212, 0x6F6F3EA2, 0xE6E6540D, 0xDBDBF252, 0x92927BBB, 0xB7B7B602, 0x6969CA2F, 0x3939D9A9, - 0xD3D30CD7, 0xA7A72361, 0xA2A2AD1E, 0xC3C399B4, 0x6C6C4450, 0x07070504, 0x04047FF6, 0x272746C2, - 0xACACA716, 0xD0D07625, 0x50501386, 0xDCDCF756, 0x84841A55, 0xE1E15109, 0x7A7A25BE, 0x1313EF91 - ]; - - /** - * M-Table - * - * @var array - */ - private static $m1 = [ - 0xA9D93939, 0x67901717, 0xB3719C9C, 0xE8D2A6A6, 0x04050707, 0xFD985252, 0xA3658080, 0x76DFE4E4, - 0x9A084545, 0x92024B4B, 0x80A0E0E0, 0x78665A5A, 0xE4DDAFAF, 0xDDB06A6A, 0xD1BF6363, 0x38362A2A, - 0x0D54E6E6, 0xC6432020, 0x3562CCCC, 0x98BEF2F2, 0x181E1212, 0xF724EBEB, 0xECD7A1A1, 0x6C774141, - 0x43BD2828, 0x7532BCBC, 0x37D47B7B, 0x269B8888, 0xFA700D0D, 0x13F94444, 0x94B1FBFB, 0x485A7E7E, - 0xF27A0303, 0xD0E48C8C, 0x8B47B6B6, 0x303C2424, 0x84A5E7E7, 0x54416B6B, 0xDF06DDDD, 0x23C56060, - 0x1945FDFD, 0x5BA33A3A, 0x3D68C2C2, 0x59158D8D, 0xF321ECEC, 0xAE316666, 0xA23E6F6F, 0x82165757, - 0x63951010, 0x015BEFEF, 0x834DB8B8, 0x2E918686, 0xD9B56D6D, 0x511F8383, 0x9B53AAAA, 0x7C635D5D, - 0xA63B6868, 0xEB3FFEFE, 0xA5D63030, 0xBE257A7A, 0x16A7ACAC, 0x0C0F0909, 0xE335F0F0, 0x6123A7A7, - 0xC0F09090, 0x8CAFE9E9, 0x3A809D9D, 0xF5925C5C, 0x73810C0C, 0x2C273131, 0x2576D0D0, 0x0BE75656, - 0xBB7B9292, 0x4EE9CECE, 0x89F10101, 0x6B9F1E1E, 0x53A93434, 0x6AC4F1F1, 0xB499C3C3, 0xF1975B5B, - 0xE1834747, 0xE66B1818, 0xBDC82222, 0x450E9898, 0xE26E1F1F, 0xF4C9B3B3, 0xB62F7474, 0x66CBF8F8, - 0xCCFF9999, 0x95EA1414, 0x03ED5858, 0x56F7DCDC, 0xD4E18B8B, 0x1C1B1515, 0x1EADA2A2, 0xD70CD3D3, - 0xFB2BE2E2, 0xC31DC8C8, 0x8E195E5E, 0xB5C22C2C, 0xE9894949, 0xCF12C1C1, 0xBF7E9595, 0xBA207D7D, - 0xEA641111, 0x77840B0B, 0x396DC5C5, 0xAF6A8989, 0x33D17C7C, 0xC9A17171, 0x62CEFFFF, 0x7137BBBB, - 0x81FB0F0F, 0x793DB5B5, 0x0951E1E1, 0xADDC3E3E, 0x242D3F3F, 0xCDA47676, 0xF99D5555, 0xD8EE8282, - 0xE5864040, 0xC5AE7878, 0xB9CD2525, 0x4D049696, 0x44557777, 0x080A0E0E, 0x86135050, 0xE730F7F7, - 0xA1D33737, 0x1D40FAFA, 0xAA346161, 0xED8C4E4E, 0x06B3B0B0, 0x706C5454, 0xB22A7373, 0xD2523B3B, - 0x410B9F9F, 0x7B8B0202, 0xA088D8D8, 0x114FF3F3, 0x3167CBCB, 0xC2462727, 0x27C06767, 0x90B4FCFC, - 0x20283838, 0xF67F0404, 0x60784848, 0xFF2EE5E5, 0x96074C4C, 0x5C4B6565, 0xB1C72B2B, 0xAB6F8E8E, - 0x9E0D4242, 0x9CBBF5F5, 0x52F2DBDB, 0x1BF34A4A, 0x5FA63D3D, 0x9359A4A4, 0x0ABCB9B9, 0xEF3AF9F9, - 0x91EF1313, 0x85FE0808, 0x49019191, 0xEE611616, 0x2D7CDEDE, 0x4FB22121, 0x8F42B1B1, 0x3BDB7272, - 0x47B82F2F, 0x8748BFBF, 0x6D2CAEAE, 0x46E3C0C0, 0xD6573C3C, 0x3E859A9A, 0x6929A9A9, 0x647D4F4F, - 0x2A948181, 0xCE492E2E, 0xCB17C6C6, 0x2FCA6969, 0xFCC3BDBD, 0x975CA3A3, 0x055EE8E8, 0x7AD0EDED, - 0xAC87D1D1, 0x7F8E0505, 0xD5BA6464, 0x1AA8A5A5, 0x4BB72626, 0x0EB9BEBE, 0xA7608787, 0x5AF8D5D5, - 0x28223636, 0x14111B1B, 0x3FDE7575, 0x2979D9D9, 0x88AAEEEE, 0x3C332D2D, 0x4C5F7979, 0x02B6B7B7, - 0xB896CACA, 0xDA583535, 0xB09CC4C4, 0x17FC4343, 0x551A8484, 0x1FF64D4D, 0x8A1C5959, 0x7D38B2B2, - 0x57AC3333, 0xC718CFCF, 0x8DF40606, 0x74695353, 0xB7749B9B, 0xC4F59797, 0x9F56ADAD, 0x72DAE3E3, - 0x7ED5EAEA, 0x154AF4F4, 0x229E8F8F, 0x12A2ABAB, 0x584E6262, 0x07E85F5F, 0x99E51D1D, 0x34392323, - 0x6EC1F6F6, 0x50446C6C, 0xDE5D3232, 0x68724646, 0x6526A0A0, 0xBC93CDCD, 0xDB03DADA, 0xF8C6BABA, - 0xC8FA9E9E, 0xA882D6D6, 0x2BCF6E6E, 0x40507070, 0xDCEB8585, 0xFE750A0A, 0x328A9393, 0xA48DDFDF, - 0xCA4C2929, 0x10141C1C, 0x2173D7D7, 0xF0CCB4B4, 0xD309D4D4, 0x5D108A8A, 0x0FE25151, 0x00000000, - 0x6F9A1919, 0x9DE01A1A, 0x368F9494, 0x42E6C7C7, 0x4AECC9C9, 0x5EFDD2D2, 0xC1AB7F7F, 0xE0D8A8A8 - ]; - - /** - * M-Table - * - * @var array - */ - private static $m2 = [ - 0xBC75BC32, 0xECF3EC21, 0x20C62043, 0xB3F4B3C9, 0xDADBDA03, 0x027B028B, 0xE2FBE22B, 0x9EC89EFA, - 0xC94AC9EC, 0xD4D3D409, 0x18E6186B, 0x1E6B1E9F, 0x9845980E, 0xB27DB238, 0xA6E8A6D2, 0x264B26B7, - 0x3CD63C57, 0x9332938A, 0x82D882EE, 0x52FD5298, 0x7B377BD4, 0xBB71BB37, 0x5BF15B97, 0x47E14783, - 0x2430243C, 0x510F51E2, 0xBAF8BAC6, 0x4A1B4AF3, 0xBF87BF48, 0x0DFA0D70, 0xB006B0B3, 0x753F75DE, - 0xD25ED2FD, 0x7DBA7D20, 0x66AE6631, 0x3A5B3AA3, 0x598A591C, 0x00000000, 0xCDBCCD93, 0x1A9D1AE0, - 0xAE6DAE2C, 0x7FC17FAB, 0x2BB12BC7, 0xBE0EBEB9, 0xE080E0A0, 0x8A5D8A10, 0x3BD23B52, 0x64D564BA, - 0xD8A0D888, 0xE784E7A5, 0x5F075FE8, 0x1B141B11, 0x2CB52CC2, 0xFC90FCB4, 0x312C3127, 0x80A38065, - 0x73B2732A, 0x0C730C81, 0x794C795F, 0x6B546B41, 0x4B924B02, 0x53745369, 0x9436948F, 0x8351831F, - 0x2A382A36, 0xC4B0C49C, 0x22BD22C8, 0xD55AD5F8, 0xBDFCBDC3, 0x48604878, 0xFF62FFCE, 0x4C964C07, - 0x416C4177, 0xC742C7E6, 0xEBF7EB24, 0x1C101C14, 0x5D7C5D63, 0x36283622, 0x672767C0, 0xE98CE9AF, - 0x441344F9, 0x149514EA, 0xF59CF5BB, 0xCFC7CF18, 0x3F243F2D, 0xC046C0E3, 0x723B72DB, 0x5470546C, - 0x29CA294C, 0xF0E3F035, 0x088508FE, 0xC6CBC617, 0xF311F34F, 0x8CD08CE4, 0xA493A459, 0xCAB8CA96, - 0x68A6683B, 0xB883B84D, 0x38203828, 0xE5FFE52E, 0xAD9FAD56, 0x0B770B84, 0xC8C3C81D, 0x99CC99FF, - 0x580358ED, 0x196F199A, 0x0E080E0A, 0x95BF957E, 0x70407050, 0xF7E7F730, 0x6E2B6ECF, 0x1FE21F6E, - 0xB579B53D, 0x090C090F, 0x61AA6134, 0x57825716, 0x9F419F0B, 0x9D3A9D80, 0x11EA1164, 0x25B925CD, - 0xAFE4AFDD, 0x459A4508, 0xDFA4DF8D, 0xA397A35C, 0xEA7EEAD5, 0x35DA3558, 0xED7AEDD0, 0x431743FC, - 0xF866F8CB, 0xFB94FBB1, 0x37A137D3, 0xFA1DFA40, 0xC23DC268, 0xB4F0B4CC, 0x32DE325D, 0x9CB39C71, - 0x560B56E7, 0xE372E3DA, 0x87A78760, 0x151C151B, 0xF9EFF93A, 0x63D163BF, 0x345334A9, 0x9A3E9A85, - 0xB18FB142, 0x7C337CD1, 0x8826889B, 0x3D5F3DA6, 0xA1ECA1D7, 0xE476E4DF, 0x812A8194, 0x91499101, - 0x0F810FFB, 0xEE88EEAA, 0x16EE1661, 0xD721D773, 0x97C497F5, 0xA51AA5A8, 0xFEEBFE3F, 0x6DD96DB5, - 0x78C578AE, 0xC539C56D, 0x1D991DE5, 0x76CD76A4, 0x3EAD3EDC, 0xCB31CB67, 0xB68BB647, 0xEF01EF5B, - 0x1218121E, 0x602360C5, 0x6ADD6AB0, 0x4D1F4DF6, 0xCE4ECEE9, 0xDE2DDE7C, 0x55F9559D, 0x7E487E5A, - 0x214F21B2, 0x03F2037A, 0xA065A026, 0x5E8E5E19, 0x5A785A66, 0x655C654B, 0x6258624E, 0xFD19FD45, - 0x068D06F4, 0x40E54086, 0xF298F2BE, 0x335733AC, 0x17671790, 0x057F058E, 0xE805E85E, 0x4F644F7D, - 0x89AF896A, 0x10631095, 0x74B6742F, 0x0AFE0A75, 0x5CF55C92, 0x9BB79B74, 0x2D3C2D33, 0x30A530D6, - 0x2ECE2E49, 0x49E94989, 0x46684672, 0x77447755, 0xA8E0A8D8, 0x964D9604, 0x284328BD, 0xA969A929, - 0xD929D979, 0x862E8691, 0xD1ACD187, 0xF415F44A, 0x8D598D15, 0xD6A8D682, 0xB90AB9BC, 0x429E420D, - 0xF66EF6C1, 0x2F472FB8, 0xDDDFDD06, 0x23342339, 0xCC35CC62, 0xF16AF1C4, 0xC1CFC112, 0x85DC85EB, - 0x8F228F9E, 0x71C971A1, 0x90C090F0, 0xAA9BAA53, 0x018901F1, 0x8BD48BE1, 0x4EED4E8C, 0x8EAB8E6F, - 0xAB12ABA2, 0x6FA26F3E, 0xE60DE654, 0xDB52DBF2, 0x92BB927B, 0xB702B7B6, 0x692F69CA, 0x39A939D9, - 0xD3D7D30C, 0xA761A723, 0xA21EA2AD, 0xC3B4C399, 0x6C506C44, 0x07040705, 0x04F6047F, 0x27C22746, - 0xAC16ACA7, 0xD025D076, 0x50865013, 0xDC56DCF7, 0x8455841A, 0xE109E151, 0x7ABE7A25, 0x139113EF - ]; - - /** - * M-Table - * - * @var array - */ - private static $m3 = [ - 0xD939A9D9, 0x90176790, 0x719CB371, 0xD2A6E8D2, 0x05070405, 0x9852FD98, 0x6580A365, 0xDFE476DF, - 0x08459A08, 0x024B9202, 0xA0E080A0, 0x665A7866, 0xDDAFE4DD, 0xB06ADDB0, 0xBF63D1BF, 0x362A3836, - 0x54E60D54, 0x4320C643, 0x62CC3562, 0xBEF298BE, 0x1E12181E, 0x24EBF724, 0xD7A1ECD7, 0x77416C77, - 0xBD2843BD, 0x32BC7532, 0xD47B37D4, 0x9B88269B, 0x700DFA70, 0xF94413F9, 0xB1FB94B1, 0x5A7E485A, - 0x7A03F27A, 0xE48CD0E4, 0x47B68B47, 0x3C24303C, 0xA5E784A5, 0x416B5441, 0x06DDDF06, 0xC56023C5, - 0x45FD1945, 0xA33A5BA3, 0x68C23D68, 0x158D5915, 0x21ECF321, 0x3166AE31, 0x3E6FA23E, 0x16578216, - 0x95106395, 0x5BEF015B, 0x4DB8834D, 0x91862E91, 0xB56DD9B5, 0x1F83511F, 0x53AA9B53, 0x635D7C63, - 0x3B68A63B, 0x3FFEEB3F, 0xD630A5D6, 0x257ABE25, 0xA7AC16A7, 0x0F090C0F, 0x35F0E335, 0x23A76123, - 0xF090C0F0, 0xAFE98CAF, 0x809D3A80, 0x925CF592, 0x810C7381, 0x27312C27, 0x76D02576, 0xE7560BE7, - 0x7B92BB7B, 0xE9CE4EE9, 0xF10189F1, 0x9F1E6B9F, 0xA93453A9, 0xC4F16AC4, 0x99C3B499, 0x975BF197, - 0x8347E183, 0x6B18E66B, 0xC822BDC8, 0x0E98450E, 0x6E1FE26E, 0xC9B3F4C9, 0x2F74B62F, 0xCBF866CB, - 0xFF99CCFF, 0xEA1495EA, 0xED5803ED, 0xF7DC56F7, 0xE18BD4E1, 0x1B151C1B, 0xADA21EAD, 0x0CD3D70C, - 0x2BE2FB2B, 0x1DC8C31D, 0x195E8E19, 0xC22CB5C2, 0x8949E989, 0x12C1CF12, 0x7E95BF7E, 0x207DBA20, - 0x6411EA64, 0x840B7784, 0x6DC5396D, 0x6A89AF6A, 0xD17C33D1, 0xA171C9A1, 0xCEFF62CE, 0x37BB7137, - 0xFB0F81FB, 0x3DB5793D, 0x51E10951, 0xDC3EADDC, 0x2D3F242D, 0xA476CDA4, 0x9D55F99D, 0xEE82D8EE, - 0x8640E586, 0xAE78C5AE, 0xCD25B9CD, 0x04964D04, 0x55774455, 0x0A0E080A, 0x13508613, 0x30F7E730, - 0xD337A1D3, 0x40FA1D40, 0x3461AA34, 0x8C4EED8C, 0xB3B006B3, 0x6C54706C, 0x2A73B22A, 0x523BD252, - 0x0B9F410B, 0x8B027B8B, 0x88D8A088, 0x4FF3114F, 0x67CB3167, 0x4627C246, 0xC06727C0, 0xB4FC90B4, - 0x28382028, 0x7F04F67F, 0x78486078, 0x2EE5FF2E, 0x074C9607, 0x4B655C4B, 0xC72BB1C7, 0x6F8EAB6F, - 0x0D429E0D, 0xBBF59CBB, 0xF2DB52F2, 0xF34A1BF3, 0xA63D5FA6, 0x59A49359, 0xBCB90ABC, 0x3AF9EF3A, - 0xEF1391EF, 0xFE0885FE, 0x01914901, 0x6116EE61, 0x7CDE2D7C, 0xB2214FB2, 0x42B18F42, 0xDB723BDB, - 0xB82F47B8, 0x48BF8748, 0x2CAE6D2C, 0xE3C046E3, 0x573CD657, 0x859A3E85, 0x29A96929, 0x7D4F647D, - 0x94812A94, 0x492ECE49, 0x17C6CB17, 0xCA692FCA, 0xC3BDFCC3, 0x5CA3975C, 0x5EE8055E, 0xD0ED7AD0, - 0x87D1AC87, 0x8E057F8E, 0xBA64D5BA, 0xA8A51AA8, 0xB7264BB7, 0xB9BE0EB9, 0x6087A760, 0xF8D55AF8, - 0x22362822, 0x111B1411, 0xDE753FDE, 0x79D92979, 0xAAEE88AA, 0x332D3C33, 0x5F794C5F, 0xB6B702B6, - 0x96CAB896, 0x5835DA58, 0x9CC4B09C, 0xFC4317FC, 0x1A84551A, 0xF64D1FF6, 0x1C598A1C, 0x38B27D38, - 0xAC3357AC, 0x18CFC718, 0xF4068DF4, 0x69537469, 0x749BB774, 0xF597C4F5, 0x56AD9F56, 0xDAE372DA, - 0xD5EA7ED5, 0x4AF4154A, 0x9E8F229E, 0xA2AB12A2, 0x4E62584E, 0xE85F07E8, 0xE51D99E5, 0x39233439, - 0xC1F66EC1, 0x446C5044, 0x5D32DE5D, 0x72466872, 0x26A06526, 0x93CDBC93, 0x03DADB03, 0xC6BAF8C6, - 0xFA9EC8FA, 0x82D6A882, 0xCF6E2BCF, 0x50704050, 0xEB85DCEB, 0x750AFE75, 0x8A93328A, 0x8DDFA48D, - 0x4C29CA4C, 0x141C1014, 0x73D72173, 0xCCB4F0CC, 0x09D4D309, 0x108A5D10, 0xE2510FE2, 0x00000000, - 0x9A196F9A, 0xE01A9DE0, 0x8F94368F, 0xE6C742E6, 0xECC94AEC, 0xFDD25EFD, 0xAB7FC1AB, 0xD8A8E0D8 - ]; - - /** - * The Key Schedule Array - * - * @var array - */ - private $K = []; - - /** - * The Key depended S-Table 0 - * - * @var array - */ - private $S0 = []; - - /** - * The Key depended S-Table 1 - * - * @var array - */ - private $S1 = []; - - /** - * The Key depended S-Table 2 - * - * @var array - */ - private $S2 = []; - - /** - * The Key depended S-Table 3 - * - * @var array - */ - private $S3 = []; - - /** - * Holds the last used key - * - * @var array - */ - private $kl; - - /** - * The Key Length (in bytes) - * - * @see Crypt_Twofish::setKeyLength() - * @var int - */ - protected $key_length = 16; - - /** - * Default Constructor. - * - * @param string $mode - * @throws BadModeException if an invalid / unsupported mode is provided - */ - public function __construct($mode) - { - parent::__construct($mode); - - if ($this->mode == self::MODE_STREAM) { - throw new BadModeException('Block ciphers cannot be ran in stream mode'); - } - } - - /** - * Initialize Static Variables - */ - protected static function initialize_static_variables() - { - if (is_float(self::$m3[0])) { - self::$m0 = array_map('intval', self::$m0); - self::$m1 = array_map('intval', self::$m1); - self::$m2 = array_map('intval', self::$m2); - self::$m3 = array_map('intval', self::$m3); - self::$q0 = array_map('intval', self::$q0); - self::$q1 = array_map('intval', self::$q1); - } - - parent::initialize_static_variables(); - } - - /** - * Sets the key length. - * - * Valid key lengths are 128, 192 or 256 bits - * - * @param int $length - */ - public function setKeyLength($length) - { - switch ($length) { - case 128: - case 192: - case 256: - break; - default: - throw new \LengthException('Key of size ' . $length . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); - } - - parent::setKeyLength($length); - } - - /** - * Sets the key. - * - * Rijndael supports five different key lengths - * - * @see setKeyLength() - * @param string $key - * @throws \LengthException if the key length isn't supported - */ - public function setKey($key) - { - switch (strlen($key)) { - case 16: - case 24: - case 32: - break; - default: - throw new \LengthException('Key of size ' . strlen($key) . ' not supported by this algorithm. Only keys of sizes 16, 24 or 32 supported'); - } - - parent::setKey($key); - } - - /** - * Setup the key (expansion) - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupKey() - */ - protected function setupKey() - { - if (isset($this->kl['key']) && $this->key === $this->kl['key']) { - // already expanded - return; - } - $this->kl = ['key' => $this->key]; - - /* Key expanding and generating the key-depended s-boxes */ - $le_longs = unpack('V*', $this->key); - $key = unpack('C*', $this->key); - $m0 = self::$m0; - $m1 = self::$m1; - $m2 = self::$m2; - $m3 = self::$m3; - $q0 = self::$q0; - $q1 = self::$q1; - - $K = $S0 = $S1 = $S2 = $S3 = []; - - switch (strlen($this->key)) { - case 16: - list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[1], $le_longs[2]); - list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[3], $le_longs[4]); - for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { - $A = $m0[$q0[$q0[$i] ^ $key[ 9]] ^ $key[1]] ^ - $m1[$q0[$q1[$i] ^ $key[10]] ^ $key[2]] ^ - $m2[$q1[$q0[$i] ^ $key[11]] ^ $key[3]] ^ - $m3[$q1[$q1[$i] ^ $key[12]] ^ $key[4]]; - $B = $m0[$q0[$q0[$j] ^ $key[13]] ^ $key[5]] ^ - $m1[$q0[$q1[$j] ^ $key[14]] ^ $key[6]] ^ - $m2[$q1[$q0[$j] ^ $key[15]] ^ $key[7]] ^ - $m3[$q1[$q1[$j] ^ $key[16]] ^ $key[8]]; - $B = ($B << 8) | ($B >> 24 & 0xff); - $A = self::safe_intval($A + $B); - $K[] = $A; - $A = self::safe_intval($A + $B); - $K[] = ($A << 9 | $A >> 23 & 0x1ff); - } - for ($i = 0; $i < 256; ++$i) { - $S0[$i] = $m0[$q0[$q0[$i] ^ $s4] ^ $s0]; - $S1[$i] = $m1[$q0[$q1[$i] ^ $s5] ^ $s1]; - $S2[$i] = $m2[$q1[$q0[$i] ^ $s6] ^ $s2]; - $S3[$i] = $m3[$q1[$q1[$i] ^ $s7] ^ $s3]; - } - break; - case 24: - list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[1], $le_longs[2]); - list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[3], $le_longs[4]); - list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[5], $le_longs[6]); - for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { - $A = $m0[$q0[$q0[$q1[$i] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ - $m1[$q0[$q1[$q1[$i] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ - $m2[$q1[$q0[$q0[$i] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ - $m3[$q1[$q1[$q0[$i] ^ $key[20]] ^ $key[12]] ^ $key[4]]; - $B = $m0[$q0[$q0[$q1[$j] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ - $m1[$q0[$q1[$q1[$j] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ - $m2[$q1[$q0[$q0[$j] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ - $m3[$q1[$q1[$q0[$j] ^ $key[24]] ^ $key[16]] ^ $key[8]]; - $B = ($B << 8) | ($B >> 24 & 0xff); - $A = self::safe_intval($A + $B); - $K[] = $A; - $A = self::safe_intval($A + $B); - $K[] = ($A << 9 | $A >> 23 & 0x1ff); - } - for ($i = 0; $i < 256; ++$i) { - $S0[$i] = $m0[$q0[$q0[$q1[$i] ^ $s8] ^ $s4] ^ $s0]; - $S1[$i] = $m1[$q0[$q1[$q1[$i] ^ $s9] ^ $s5] ^ $s1]; - $S2[$i] = $m2[$q1[$q0[$q0[$i] ^ $sa] ^ $s6] ^ $s2]; - $S3[$i] = $m3[$q1[$q1[$q0[$i] ^ $sb] ^ $s7] ^ $s3]; - } - break; - default: // 32 - list($sf, $se, $sd, $sc) = $this->mdsrem($le_longs[1], $le_longs[2]); - list($sb, $sa, $s9, $s8) = $this->mdsrem($le_longs[3], $le_longs[4]); - list($s7, $s6, $s5, $s4) = $this->mdsrem($le_longs[5], $le_longs[6]); - list($s3, $s2, $s1, $s0) = $this->mdsrem($le_longs[7], $le_longs[8]); - for ($i = 0, $j = 1; $i < 40; $i += 2, $j += 2) { - $A = $m0[$q0[$q0[$q1[$q1[$i] ^ $key[25]] ^ $key[17]] ^ $key[ 9]] ^ $key[1]] ^ - $m1[$q0[$q1[$q1[$q0[$i] ^ $key[26]] ^ $key[18]] ^ $key[10]] ^ $key[2]] ^ - $m2[$q1[$q0[$q0[$q0[$i] ^ $key[27]] ^ $key[19]] ^ $key[11]] ^ $key[3]] ^ - $m3[$q1[$q1[$q0[$q1[$i] ^ $key[28]] ^ $key[20]] ^ $key[12]] ^ $key[4]]; - $B = $m0[$q0[$q0[$q1[$q1[$j] ^ $key[29]] ^ $key[21]] ^ $key[13]] ^ $key[5]] ^ - $m1[$q0[$q1[$q1[$q0[$j] ^ $key[30]] ^ $key[22]] ^ $key[14]] ^ $key[6]] ^ - $m2[$q1[$q0[$q0[$q0[$j] ^ $key[31]] ^ $key[23]] ^ $key[15]] ^ $key[7]] ^ - $m3[$q1[$q1[$q0[$q1[$j] ^ $key[32]] ^ $key[24]] ^ $key[16]] ^ $key[8]]; - $B = ($B << 8) | ($B >> 24 & 0xff); - $A = self::safe_intval($A + $B); - $K[] = $A; - $A = self::safe_intval($A + $B); - $K[] = ($A << 9 | $A >> 23 & 0x1ff); - } - for ($i = 0; $i < 256; ++$i) { - $S0[$i] = $m0[$q0[$q0[$q1[$q1[$i] ^ $sc] ^ $s8] ^ $s4] ^ $s0]; - $S1[$i] = $m1[$q0[$q1[$q1[$q0[$i] ^ $sd] ^ $s9] ^ $s5] ^ $s1]; - $S2[$i] = $m2[$q1[$q0[$q0[$q0[$i] ^ $se] ^ $sa] ^ $s6] ^ $s2]; - $S3[$i] = $m3[$q1[$q1[$q0[$q1[$i] ^ $sf] ^ $sb] ^ $s7] ^ $s3]; - } - } - - $this->K = $K; - $this->S0 = $S0; - $this->S1 = $S1; - $this->S2 = $S2; - $this->S3 = $S3; - } - - /** - * _mdsrem function using by the twofish cipher algorithm - * - * @param string $A - * @param string $B - * @return array - */ - private function mdsrem($A, $B) - { - // No gain by unrolling this loop. - for ($i = 0; $i < 8; ++$i) { - // Get most significant coefficient. - $t = 0xff & ($B >> 24); - - // Shift the others up. - $B = ($B << 8) | (0xff & ($A >> 24)); - $A <<= 8; - - $u = $t << 1; - - // Subtract the modular polynomial on overflow. - if ($t & 0x80) { - $u ^= 0x14d; - } - - // Remove t * (a * x^2 + 1). - $B ^= $t ^ ($u << 16); - - // Form u = a*t + t/a = t*(a + 1/a). - $u ^= 0x7fffffff & ($t >> 1); - - // Add the modular polynomial on underflow. - if ($t & 0x01) { - $u ^= 0xa6 ; - } - - // Remove t * (a + 1/a) * (x^3 + x). - $B ^= ($u << 24) | ($u << 8); - } - - return [ - 0xff & $B >> 24, - 0xff & $B >> 16, - 0xff & $B >> 8, - 0xff & $B]; - } - - /** - * Encrypts a block - * - * @param string $in - * @return string - */ - protected function encryptBlock($in) - { - $S0 = $this->S0; - $S1 = $this->S1; - $S2 = $this->S2; - $S3 = $this->S3; - $K = $this->K; - - $in = unpack("V4", $in); - $R0 = $K[0] ^ $in[1]; - $R1 = $K[1] ^ $in[2]; - $R2 = $K[2] ^ $in[3]; - $R3 = $K[3] ^ $in[4]; - - $ki = 7; - while ($ki < 39) { - $t0 = $S0[ $R0 & 0xff] ^ - $S1[($R0 >> 8) & 0xff] ^ - $S2[($R0 >> 16) & 0xff] ^ - $S3[($R0 >> 24) & 0xff]; - $t1 = $S0[($R1 >> 24) & 0xff] ^ - $S1[ $R1 & 0xff] ^ - $S2[($R1 >> 8) & 0xff] ^ - $S3[($R1 >> 16) & 0xff]; - $R2 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); - $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); - $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); - - $t0 = $S0[ $R2 & 0xff] ^ - $S1[($R2 >> 8) & 0xff] ^ - $S2[($R2 >> 16) & 0xff] ^ - $S3[($R2 >> 24) & 0xff]; - $t1 = $S0[($R3 >> 24) & 0xff] ^ - $S1[ $R3 & 0xff] ^ - $S2[($R3 >> 8) & 0xff] ^ - $S3[($R3 >> 16) & 0xff]; - $R0 ^= self::safe_intval($t0 + $t1 + $K[++$ki]); - $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); - $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ self::safe_intval($t0 + ($t1 << 1) + $K[++$ki]); - } - - // @codingStandardsIgnoreStart - return pack("V4", $K[4] ^ $R2, - $K[5] ^ $R3, - $K[6] ^ $R0, - $K[7] ^ $R1); - // @codingStandardsIgnoreEnd - } - - /** - * Decrypts a block - * - * @param string $in - * @return string - */ - protected function decryptBlock($in) - { - $S0 = $this->S0; - $S1 = $this->S1; - $S2 = $this->S2; - $S3 = $this->S3; - $K = $this->K; - - $in = unpack("V4", $in); - $R0 = $K[4] ^ $in[1]; - $R1 = $K[5] ^ $in[2]; - $R2 = $K[6] ^ $in[3]; - $R3 = $K[7] ^ $in[4]; - - $ki = 40; - while ($ki > 8) { - $t0 = $S0[$R0 & 0xff] ^ - $S1[$R0 >> 8 & 0xff] ^ - $S2[$R0 >> 16 & 0xff] ^ - $S3[$R0 >> 24 & 0xff]; - $t1 = $S0[$R1 >> 24 & 0xff] ^ - $S1[$R1 & 0xff] ^ - $S2[$R1 >> 8 & 0xff] ^ - $S3[$R1 >> 16 & 0xff]; - $R3 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); - $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; - $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); - - $t0 = $S0[$R2 & 0xff] ^ - $S1[$R2 >> 8 & 0xff] ^ - $S2[$R2 >> 16 & 0xff] ^ - $S3[$R2 >> 24 & 0xff]; - $t1 = $S0[$R3 >> 24 & 0xff] ^ - $S1[$R3 & 0xff] ^ - $S2[$R3 >> 8 & 0xff] ^ - $S3[$R3 >> 16 & 0xff]; - $R1 ^= self::safe_intval($t0 + ($t1 << 1) + $K[--$ki]); - $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; - $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ self::safe_intval($t0 + $t1 + $K[--$ki]); - } - - // @codingStandardsIgnoreStart - return pack("V4", $K[0] ^ $R2, - $K[1] ^ $R3, - $K[2] ^ $R0, - $K[3] ^ $R1); - // @codingStandardsIgnoreEnd - } - - /** - * Setup the performance-optimized function for de/encrypt() - * - * @see \phpseclib3\Crypt\Common\SymmetricKey::_setupInlineCrypt() - */ - protected function setupInlineCrypt() - { - $K = $this->K; - $init_crypt = ' - static $S0, $S1, $S2, $S3; - if (!$S0) { - for ($i = 0; $i < 256; ++$i) { - $S0[] = (int)$this->S0[$i]; - $S1[] = (int)$this->S1[$i]; - $S2[] = (int)$this->S2[$i]; - $S3[] = (int)$this->S3[$i]; - } - } - '; - - $safeint = self::safe_intval_inline(); - - // Generating encrypt code: - $encrypt_block = ' - $in = unpack("V4", $in); - $R0 = ' . $K[0] . ' ^ $in[1]; - $R1 = ' . $K[1] . ' ^ $in[2]; - $R2 = ' . $K[2] . ' ^ $in[3]; - $R3 = ' . $K[3] . ' ^ $in[4]; - '; - for ($ki = 7, $i = 0; $i < 8; ++$i) { - $encrypt_block .= ' - $t0 = $S0[ $R0 & 0xff] ^ - $S1[($R0 >> 8) & 0xff] ^ - $S2[($R0 >> 16) & 0xff] ^ - $S3[($R0 >> 24) & 0xff]; - $t1 = $S0[($R1 >> 24) & 0xff] ^ - $S1[ $R1 & 0xff] ^ - $S2[($R1 >> 8) & 0xff] ^ - $S3[($R1 >> 16) & 0xff]; - $R2^= ' . sprintf($safeint, '$t0 + $t1 + ' . $K[++$ki]) . '; - $R2 = ($R2 >> 1 & 0x7fffffff) | ($R2 << 31); - $R3 = ((($R3 >> 31) & 1) | ($R3 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; - - $t0 = $S0[ $R2 & 0xff] ^ - $S1[($R2 >> 8) & 0xff] ^ - $S2[($R2 >> 16) & 0xff] ^ - $S3[($R2 >> 24) & 0xff]; - $t1 = $S0[($R3 >> 24) & 0xff] ^ - $S1[ $R3 & 0xff] ^ - $S2[($R3 >> 8) & 0xff] ^ - $S3[($R3 >> 16) & 0xff]; - $R0^= ' . sprintf($safeint, '($t0 + $t1 + ' . $K[++$ki] . ')') . '; - $R0 = ($R0 >> 1 & 0x7fffffff) | ($R0 << 31); - $R1 = ((($R1 >> 31) & 1) | ($R1 << 1)) ^ ' . sprintf($safeint, '($t0 + ($t1 << 1) + ' . $K[++$ki] . ')') . '; - '; - } - $encrypt_block .= ' - $in = pack("V4", ' . $K[4] . ' ^ $R2, - ' . $K[5] . ' ^ $R3, - ' . $K[6] . ' ^ $R0, - ' . $K[7] . ' ^ $R1); - '; - - // Generating decrypt code: - $decrypt_block = ' - $in = unpack("V4", $in); - $R0 = ' . $K[4] . ' ^ $in[1]; - $R1 = ' . $K[5] . ' ^ $in[2]; - $R2 = ' . $K[6] . ' ^ $in[3]; - $R3 = ' . $K[7] . ' ^ $in[4]; - '; - for ($ki = 40, $i = 0; $i < 8; ++$i) { - $decrypt_block .= ' - $t0 = $S0[$R0 & 0xff] ^ - $S1[$R0 >> 8 & 0xff] ^ - $S2[$R0 >> 16 & 0xff] ^ - $S3[$R0 >> 24 & 0xff]; - $t1 = $S0[$R1 >> 24 & 0xff] ^ - $S1[$R1 & 0xff] ^ - $S2[$R1 >> 8 & 0xff] ^ - $S3[$R1 >> 16 & 0xff]; - $R3^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; - $R3 = $R3 >> 1 & 0x7fffffff | $R3 << 31; - $R2 = ($R2 >> 31 & 0x1 | $R2 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; - - $t0 = $S0[$R2 & 0xff] ^ - $S1[$R2 >> 8 & 0xff] ^ - $S2[$R2 >> 16 & 0xff] ^ - $S3[$R2 >> 24 & 0xff]; - $t1 = $S0[$R3 >> 24 & 0xff] ^ - $S1[$R3 & 0xff] ^ - $S2[$R3 >> 8 & 0xff] ^ - $S3[$R3 >> 16 & 0xff]; - $R1^= ' . sprintf($safeint, '$t0 + ($t1 << 1) + ' . $K[--$ki]) . '; - $R1 = $R1 >> 1 & 0x7fffffff | $R1 << 31; - $R0 = ($R0 >> 31 & 0x1 | $R0 << 1) ^ ' . sprintf($safeint, '($t0 + $t1 + ' . $K[--$ki] . ')') . '; - '; - } - $decrypt_block .= ' - $in = pack("V4", ' . $K[0] . ' ^ $R2, - ' . $K[1] . ' ^ $R3, - ' . $K[2] . ' ^ $R0, - ' . $K[3] . ' ^ $R1); - '; - - $this->inline_crypt = $this->createInlineCryptFunction( - [ - 'init_crypt' => $init_crypt, - 'init_encrypt' => '', - 'init_decrypt' => '', - 'encrypt_block' => $encrypt_block, - 'decrypt_block' => $decrypt_block - ] - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php deleted file mode 100644 index 1aabcae..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadConfigurationException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * BadConfigurationException - * - * @author Jim Wigginton - */ -class BadConfigurationException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php deleted file mode 100644 index 88331dc..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadDecryptionException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * BadDecryptionException - * - * @author Jim Wigginton - */ -class BadDecryptionException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php deleted file mode 100644 index 87689b2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/BadModeException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * BadModeException - * - * @author Jim Wigginton - */ -class BadModeException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php deleted file mode 100644 index 6aaccba..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/ConnectionClosedException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * ConnectionClosedException - * - * @author Jim Wigginton - */ -class ConnectionClosedException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php deleted file mode 100644 index 66e7270..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/FileNotFoundException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * FileNotFoundException - * - * @author Jim Wigginton - */ -class FileNotFoundException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php deleted file mode 100644 index 23c38fb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InconsistentSetupException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * InconsistentSetupException - * - * @author Jim Wigginton - */ -class InconsistentSetupException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php deleted file mode 100644 index 4f4114d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/InsufficientSetupException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * InsufficientSetupException - * - * @author Jim Wigginton - */ -class InsufficientSetupException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php deleted file mode 100644 index 7ec2fe9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoKeyLoadedException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * NoKeyLoadedException - * - * @author Jim Wigginton - */ -class NoKeyLoadedException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php deleted file mode 100644 index b3ea8f3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/NoSupportedAlgorithmsException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * NoSupportedAlgorithmsException - * - * @author Jim Wigginton - */ -class NoSupportedAlgorithmsException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php deleted file mode 100644 index bfa005b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnableToConnectException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnableToConnectException - * - * @author Jim Wigginton - */ -class UnableToConnectException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php deleted file mode 100644 index 210a9a5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedAlgorithmException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedAlgorithmException - * - * @author Jim Wigginton - */ -class UnsupportedAlgorithmException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php deleted file mode 100644 index 9915215..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedCurveException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedCurveException - * - * @author Jim Wigginton - */ -class UnsupportedCurveException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php deleted file mode 100644 index e207d7e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedFormatException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedFormatException - * - * @author Jim Wigginton - */ -class UnsupportedFormatException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php deleted file mode 100644 index 9a11544..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Exception/UnsupportedOperationException.php +++ /dev/null @@ -1,23 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Exception; - -/** - * UnsupportedOperationException - * - * @author Jim Wigginton - */ -class UnsupportedOperationException extends \RuntimeException -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php deleted file mode 100644 index 5803a37..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ANSI.php +++ /dev/null @@ -1,551 +0,0 @@ - - * @copyright 2012 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File; - -/** - * Pure-PHP ANSI Decoder - * - * @author Jim Wigginton - */ -class ANSI -{ - /** - * Max Width - * - * @var int - */ - private $max_x; - - /** - * Max Height - * - * @var int - */ - private $max_y; - - /** - * Max History - * - * @var int - */ - private $max_history; - - /** - * History - * - * @var array - */ - private $history; - - /** - * History Attributes - * - * @var array - */ - private $history_attrs; - - /** - * Current Column - * - * @var int - */ - private $x; - - /** - * Current Row - * - * @var int - */ - private $y; - - /** - * Old Column - * - * @var int - */ - private $old_x; - - /** - * Old Row - * - * @var int - */ - private $old_y; - - /** - * An empty attribute cell - * - * @var object - */ - private $base_attr_cell; - - /** - * The current attribute cell - * - * @var object - */ - private $attr_cell; - - /** - * An empty attribute row - * - * @var array - */ - private $attr_row; - - /** - * The current screen text - * - * @var list - */ - private $screen; - - /** - * The current screen attributes - * - * @var array - */ - private $attrs; - - /** - * Current ANSI code - * - * @var string - */ - private $ansi; - - /** - * Tokenization - * - * @var array - */ - private $tokenization; - - /** - * Default Constructor. - * - * @return \phpseclib3\File\ANSI - */ - public function __construct() - { - $attr_cell = new \stdClass(); - $attr_cell->bold = false; - $attr_cell->underline = false; - $attr_cell->blink = false; - $attr_cell->background = 'black'; - $attr_cell->foreground = 'white'; - $attr_cell->reverse = false; - $this->base_attr_cell = clone $attr_cell; - $this->attr_cell = clone $attr_cell; - - $this->setHistory(200); - $this->setDimensions(80, 24); - } - - /** - * Set terminal width and height - * - * Resets the screen as well - * - * @param int $x - * @param int $y - */ - public function setDimensions($x, $y) - { - $this->max_x = $x - 1; - $this->max_y = $y - 1; - $this->x = $this->y = 0; - $this->history = $this->history_attrs = []; - $this->attr_row = array_fill(0, $this->max_x + 2, $this->base_attr_cell); - $this->screen = array_fill(0, $this->max_y + 1, ''); - $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row); - $this->ansi = ''; - } - - /** - * Set the number of lines that should be logged past the terminal height - * - * @param int $history - */ - public function setHistory($history) - { - $this->max_history = $history; - } - - /** - * Load a string - * - * @param string $source - */ - public function loadString($source) - { - $this->setDimensions($this->max_x + 1, $this->max_y + 1); - $this->appendString($source); - } - - /** - * Appdend a string - * - * @param string $source - */ - public function appendString($source) - { - $this->tokenization = ['']; - for ($i = 0; $i < strlen($source); $i++) { - if (strlen($this->ansi)) { - $this->ansi .= $source[$i]; - $chr = ord($source[$i]); - // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements - // single character CSI's not currently supported - switch (true) { - case $this->ansi == "\x1B=": - $this->ansi = ''; - continue 2; - case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['): - case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126: - break; - default: - continue 2; - } - $this->tokenization[] = $this->ansi; - $this->tokenization[] = ''; - // http://ascii-table.com/ansi-escape-sequences-vt-100.php - switch ($this->ansi) { - case "\x1B[H": // Move cursor to upper left corner - $this->old_x = $this->x; - $this->old_y = $this->y; - $this->x = $this->y = 0; - break; - case "\x1B[J": // Clear screen from cursor down - $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y)); - $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, '')); - - $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y)); - $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row)); - - if (count($this->history) == $this->max_history) { - array_shift($this->history); - array_shift($this->history_attrs); - } - // fall-through - case "\x1B[K": // Clear screen from cursor right - $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x); - - array_splice($this->attrs[$this->y], $this->x + 1, $this->max_x - $this->x, array_fill($this->x, $this->max_x - ($this->x - 1), $this->base_attr_cell)); - break; - case "\x1B[2K": // Clear entire line - $this->screen[$this->y] = str_repeat(' ', $this->x); - $this->attrs[$this->y] = $this->attr_row; - break; - case "\x1B[?1h": // set cursor key to application - case "\x1B[?25h": // show the cursor - case "\x1B(B": // set united states g0 character set - break; - case "\x1BE": // Move to next line - $this->newLine(); - $this->x = 0; - break; - default: - switch (true) { - case preg_match('#\x1B\[(\d+)B#', $this->ansi, $match): // Move cursor down n lines - $this->old_y = $this->y; - $this->y += (int) $match[1]; - break; - case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h - $this->old_x = $this->x; - $this->old_y = $this->y; - $this->x = $match[2] - 1; - $this->y = (int) $match[1] - 1; - break; - case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines - $this->old_x = $this->x; - $this->x += $match[1]; - break; - case preg_match('#\x1B\[(\d+)D#', $this->ansi, $match): // Move cursor left n lines - $this->old_x = $this->x; - $this->x -= $match[1]; - if ($this->x < 0) { - $this->x = 0; - } - break; - case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window - break; - case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes - $attr_cell = &$this->attr_cell; - $mods = explode(';', $match[1]); - foreach ($mods as $mod) { - switch ($mod) { - case '': - case '0': // Turn off character attributes - $attr_cell = clone $this->base_attr_cell; - break; - case '1': // Turn bold mode on - $attr_cell->bold = true; - break; - case '4': // Turn underline mode on - $attr_cell->underline = true; - break; - case '5': // Turn blinking mode on - $attr_cell->blink = true; - break; - case '7': // Turn reverse video on - $attr_cell->reverse = !$attr_cell->reverse; - $temp = $attr_cell->background; - $attr_cell->background = $attr_cell->foreground; - $attr_cell->foreground = $temp; - break; - default: // set colors - //$front = $attr_cell->reverse ? &$attr_cell->background : &$attr_cell->foreground; - $front = &$attr_cell->{ $attr_cell->reverse ? 'background' : 'foreground' }; - //$back = $attr_cell->reverse ? &$attr_cell->foreground : &$attr_cell->background; - $back = &$attr_cell->{ $attr_cell->reverse ? 'foreground' : 'background' }; - switch ($mod) { - // @codingStandardsIgnoreStart - case '30': $front = 'black'; break; - case '31': $front = 'red'; break; - case '32': $front = 'green'; break; - case '33': $front = 'yellow'; break; - case '34': $front = 'blue'; break; - case '35': $front = 'magenta'; break; - case '36': $front = 'cyan'; break; - case '37': $front = 'white'; break; - - case '40': $back = 'black'; break; - case '41': $back = 'red'; break; - case '42': $back = 'green'; break; - case '43': $back = 'yellow'; break; - case '44': $back = 'blue'; break; - case '45': $back = 'magenta'; break; - case '46': $back = 'cyan'; break; - case '47': $back = 'white'; break; - // @codingStandardsIgnoreEnd - - default: - //user_error('Unsupported attribute: ' . $mod); - $this->ansi = ''; - break 2; - } - } - } - break; - default: - //user_error("{$this->ansi} is unsupported\r\n"); - } - } - $this->ansi = ''; - continue; - } - - $this->tokenization[count($this->tokenization) - 1] .= $source[$i]; - switch ($source[$i]) { - case "\r": - $this->x = 0; - break; - case "\n": - $this->newLine(); - break; - case "\x08": // backspace - if ($this->x) { - $this->x--; - $this->attrs[$this->y][$this->x] = clone $this->base_attr_cell; - $this->screen[$this->y] = substr_replace( - $this->screen[$this->y], - $source[$i], - $this->x, - 1 - ); - } - break; - case "\x0F": // shift - break; - case "\x1B": // start ANSI escape code - $this->tokenization[count($this->tokenization) - 1] = substr($this->tokenization[count($this->tokenization) - 1], 0, -1); - //if (!strlen($this->tokenization[count($this->tokenization) - 1])) { - // array_pop($this->tokenization); - //} - $this->ansi .= "\x1B"; - break; - default: - $this->attrs[$this->y][$this->x] = clone $this->attr_cell; - if ($this->x > strlen($this->screen[$this->y])) { - $this->screen[$this->y] = str_repeat(' ', $this->x); - } - $this->screen[$this->y] = substr_replace( - $this->screen[$this->y], - $source[$i], - $this->x, - 1 - ); - - if ($this->x > $this->max_x) { - $this->x = 0; - $this->newLine(); - } else { - $this->x++; - } - } - } - } - - /** - * Add a new line - * - * Also update the $this->screen and $this->history buffers - * - */ - private function newLine() - { - //if ($this->y < $this->max_y) { - // $this->y++; - //} - - while ($this->y >= $this->max_y) { - $this->history = array_merge($this->history, [array_shift($this->screen)]); - $this->screen[] = ''; - - $this->history_attrs = array_merge($this->history_attrs, [array_shift($this->attrs)]); - $this->attrs[] = $this->attr_row; - - if (count($this->history) >= $this->max_history) { - array_shift($this->history); - array_shift($this->history_attrs); - } - - $this->y--; - } - $this->y++; - } - - /** - * Returns the current coordinate without preformating - * - * @param \stdClass $last_attr - * @param \stdClass $cur_attr - * @param string $char - * @return string - */ - private function processCoordinate(\stdClass $last_attr, \stdClass $cur_attr, $char) - { - $output = ''; - - if ($last_attr != $cur_attr) { - $close = $open = ''; - if ($last_attr->foreground != $cur_attr->foreground) { - if ($cur_attr->foreground != 'white') { - $open .= ''; - } - if ($last_attr->foreground != 'white') { - $close = '' . $close; - } - } - if ($last_attr->background != $cur_attr->background) { - if ($cur_attr->background != 'black') { - $open .= ''; - } - if ($last_attr->background != 'black') { - $close = '' . $close; - } - } - if ($last_attr->bold != $cur_attr->bold) { - if ($cur_attr->bold) { - $open .= ''; - } else { - $close = '' . $close; - } - } - if ($last_attr->underline != $cur_attr->underline) { - if ($cur_attr->underline) { - $open .= ''; - } else { - $close = '' . $close; - } - } - if ($last_attr->blink != $cur_attr->blink) { - if ($cur_attr->blink) { - $open .= ''; - } else { - $close = '' . $close; - } - } - $output .= $close . $open; - } - - $output .= htmlspecialchars($char); - - return $output; - } - - /** - * Returns the current screen without preformating - * - * @return string - */ - private function getScreenHelper() - { - $output = ''; - $last_attr = $this->base_attr_cell; - for ($i = 0; $i <= $this->max_y; $i++) { - for ($j = 0; $j <= $this->max_x; $j++) { - $cur_attr = $this->attrs[$i][$j]; - $output .= $this->processCoordinate($last_attr, $cur_attr, isset($this->screen[$i][$j]) ? $this->screen[$i][$j] : ''); - $last_attr = $this->attrs[$i][$j]; - } - $output .= "\r\n"; - } - $output = substr($output, 0, -2); - // close any remaining open tags - $output .= $this->processCoordinate($last_attr, $this->base_attr_cell, ''); - return rtrim($output); - } - - /** - * Returns the current screen - * - * @return string - */ - public function getScreen() - { - return '
          ' . $this->getScreenHelper() . '
          '; - } - - /** - * Returns the current screen and the x previous lines - * - * @return string - */ - public function getHistory() - { - $scrollback = ''; - $last_attr = $this->base_attr_cell; - for ($i = 0; $i < count($this->history); $i++) { - for ($j = 0; $j <= $this->max_x + 1; $j++) { - $cur_attr = $this->history_attrs[$i][$j]; - $scrollback .= $this->processCoordinate($last_attr, $cur_attr, isset($this->history[$i][$j]) ? $this->history[$i][$j] : ''); - $last_attr = $this->history_attrs[$i][$j]; - } - $scrollback .= "\r\n"; - } - $base_attr_cell = $this->base_attr_cell; - $this->base_attr_cell = $last_attr; - $scrollback .= $this->getScreen(); - $this->base_attr_cell = $base_attr_cell; - - return '
          ' . $scrollback . '
          '; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php deleted file mode 100644 index 3096ff1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1.php +++ /dev/null @@ -1,1508 +0,0 @@ - - * @copyright 2012 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\File\ASN1\Element; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP ASN.1 Parser - * - * @author Jim Wigginton - */ -abstract class ASN1 -{ - // Tag Classes - // http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=12 - const CLASS_UNIVERSAL = 0; - const CLASS_APPLICATION = 1; - const CLASS_CONTEXT_SPECIFIC = 2; - const CLASS_PRIVATE = 3; - - // Tag Classes - // http://www.obj-sys.com/asn1tutorial/node124.html - const TYPE_BOOLEAN = 1; - const TYPE_INTEGER = 2; - const TYPE_BIT_STRING = 3; - const TYPE_OCTET_STRING = 4; - const TYPE_NULL = 5; - const TYPE_OBJECT_IDENTIFIER = 6; - //const TYPE_OBJECT_DESCRIPTOR = 7; - //const TYPE_INSTANCE_OF = 8; // EXTERNAL - const TYPE_REAL = 9; - const TYPE_ENUMERATED = 10; - //const TYPE_EMBEDDED = 11; - const TYPE_UTF8_STRING = 12; - //const TYPE_RELATIVE_OID = 13; - const TYPE_SEQUENCE = 16; // SEQUENCE OF - const TYPE_SET = 17; // SET OF - - // More Tag Classes - // http://www.obj-sys.com/asn1tutorial/node10.html - const TYPE_NUMERIC_STRING = 18; - const TYPE_PRINTABLE_STRING = 19; - const TYPE_TELETEX_STRING = 20; // T61String - const TYPE_VIDEOTEX_STRING = 21; - const TYPE_IA5_STRING = 22; - const TYPE_UTC_TIME = 23; - const TYPE_GENERALIZED_TIME = 24; - const TYPE_GRAPHIC_STRING = 25; - const TYPE_VISIBLE_STRING = 26; // ISO646String - const TYPE_GENERAL_STRING = 27; - const TYPE_UNIVERSAL_STRING = 28; - //const TYPE_CHARACTER_STRING = 29; - const TYPE_BMP_STRING = 30; - - // Tag Aliases - // These tags are kinda place holders for other tags. - const TYPE_CHOICE = -1; - const TYPE_ANY = -2; - - /** - * ASN.1 object identifiers - * - * @var array - * @link http://en.wikipedia.org/wiki/Object_identifier - */ - private static $oids = []; - - /** - * ASN.1 object identifier reverse mapping - * - * @var array - */ - private static $reverseOIDs = []; - - /** - * Default date format - * - * @var string - * @link http://php.net/class.datetime - */ - private static $format = 'D, d M Y H:i:s O'; - - /** - * Filters - * - * If the mapping type is self::TYPE_ANY what do we actually encode it as? - * - * @var array - * @see self::encode_der() - */ - private static $filters; - - /** - * Current Location of most recent ASN.1 encode process - * - * Useful for debug purposes - * - * @var array - * @see self::encode_der() - */ - private static $location; - - /** - * DER Encoded String - * - * In case we need to create ASN1\Element object's.. - * - * @var string - * @see self::decodeDER() - */ - private static $encoded; - - /** - * Type mapping table for the ANY type. - * - * Structured or unknown types are mapped to a \phpseclib3\File\ASN1\Element. - * Unambiguous types get the direct mapping (int/real/bool). - * Others are mapped as a choice, with an extra indexing level. - * - * @var array - */ - const ANY_MAP = [ - self::TYPE_BOOLEAN => true, - self::TYPE_INTEGER => true, - self::TYPE_BIT_STRING => 'bitString', - self::TYPE_OCTET_STRING => 'octetString', - self::TYPE_NULL => 'null', - self::TYPE_OBJECT_IDENTIFIER => 'objectIdentifier', - self::TYPE_REAL => true, - self::TYPE_ENUMERATED => 'enumerated', - self::TYPE_UTF8_STRING => 'utf8String', - self::TYPE_NUMERIC_STRING => 'numericString', - self::TYPE_PRINTABLE_STRING => 'printableString', - self::TYPE_TELETEX_STRING => 'teletexString', - self::TYPE_VIDEOTEX_STRING => 'videotexString', - self::TYPE_IA5_STRING => 'ia5String', - self::TYPE_UTC_TIME => 'utcTime', - self::TYPE_GENERALIZED_TIME => 'generalTime', - self::TYPE_GRAPHIC_STRING => 'graphicString', - self::TYPE_VISIBLE_STRING => 'visibleString', - self::TYPE_GENERAL_STRING => 'generalString', - self::TYPE_UNIVERSAL_STRING => 'universalString', - //self::TYPE_CHARACTER_STRING => 'characterString', - self::TYPE_BMP_STRING => 'bmpString' - ]; - - /** - * String type to character size mapping table. - * - * Non-convertable types are absent from this table. - * size == 0 indicates variable length encoding. - * - * @var array - */ - const STRING_TYPE_SIZE = [ - self::TYPE_UTF8_STRING => 0, - self::TYPE_BMP_STRING => 2, - self::TYPE_UNIVERSAL_STRING => 4, - self::TYPE_PRINTABLE_STRING => 1, - self::TYPE_TELETEX_STRING => 1, - self::TYPE_IA5_STRING => 1, - self::TYPE_VISIBLE_STRING => 1, - ]; - - /** - * Parse BER-encoding - * - * Serves a similar purpose to openssl's asn1parse - * - * @param Element|string $encoded - * @return ?array - */ - public static function decodeBER($encoded) - { - if ($encoded instanceof Element) { - $encoded = $encoded->element; - } - - self::$encoded = $encoded; - - $decoded = self::decode_ber($encoded); - if ($decoded === false) { - return null; - } - - return [$decoded]; - } - - /** - * Parse BER-encoding (Helper function) - * - * Sometimes we want to get the BER encoding of a particular tag. $start lets us do that without having to reencode. - * $encoded is passed by reference for the recursive calls done for self::TYPE_BIT_STRING and - * self::TYPE_OCTET_STRING. In those cases, the indefinite length is used. - * - * @param string $encoded - * @param int $start - * @param int $encoded_pos - * @return array|bool - */ - private static function decode_ber($encoded, $start = 0, $encoded_pos = 0) - { - $current = ['start' => $start]; - - if (!isset($encoded[$encoded_pos])) { - return false; - } - $type = ord($encoded[$encoded_pos++]); - $startOffset = 1; - - $constructed = ($type >> 5) & 1; - - $tag = $type & 0x1F; - if ($tag == 0x1F) { - $tag = 0; - // process septets (since the eighth bit is ignored, it's not an octet) - do { - if (!isset($encoded[$encoded_pos])) { - return false; - } - $temp = ord($encoded[$encoded_pos++]); - $startOffset++; - $loop = $temp >> 7; - $tag <<= 7; - $temp &= 0x7F; - // "bits 7 to 1 of the first subsequent octet shall not all be zero" - if ($startOffset == 2 && $temp == 0) { - return false; - } - $tag |= $temp; - } while ($loop); - } - - $start += $startOffset; - - // Length, as discussed in paragraph 8.1.3 of X.690-0207.pdf#page=13 - if (!isset($encoded[$encoded_pos])) { - return false; - } - $length = ord($encoded[$encoded_pos++]); - $start++; - if ($length == 0x80) { // indefinite length - // "[A sender shall] use the indefinite form (see 8.1.3.6) if the encoding is constructed and is not all - // immediately available." -- paragraph 8.1.3.2.c - $length = strlen($encoded) - $encoded_pos; - } elseif ($length & 0x80) { // definite length, long form - // technically, the long form of the length can be represented by up to 126 octets (bytes), but we'll only - // support it up to four. - $length &= 0x7F; - $temp = substr($encoded, $encoded_pos, $length); - $encoded_pos += $length; - // tags of indefinte length don't really have a header length; this length includes the tag - $current += ['headerlength' => $length + 2]; - $start += $length; - extract(unpack('Nlength', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4))); - /** @var integer $length */ - } else { - $current += ['headerlength' => 2]; - } - - if ($length > (strlen($encoded) - $encoded_pos)) { - return false; - } - - $content = substr($encoded, $encoded_pos, $length); - $content_pos = 0; - - // at this point $length can be overwritten. it's only accurate for definite length things as is - - /* Class is UNIVERSAL, APPLICATION, PRIVATE, or CONTEXT-SPECIFIC. The UNIVERSAL class is restricted to the ASN.1 - built-in types. It defines an application-independent data type that must be distinguishable from all other - data types. The other three classes are user defined. The APPLICATION class distinguishes data types that - have a wide, scattered use within a particular presentation context. PRIVATE distinguishes data types within - a particular organization or country. CONTEXT-SPECIFIC distinguishes members of a sequence or set, the - alternatives of a CHOICE, or universally tagged set members. Only the class number appears in braces for this - data type; the term CONTEXT-SPECIFIC does not appear. - - -- http://www.obj-sys.com/asn1tutorial/node12.html */ - $class = ($type >> 6) & 3; - switch ($class) { - case self::CLASS_APPLICATION: - case self::CLASS_PRIVATE: - case self::CLASS_CONTEXT_SPECIFIC: - if (!$constructed) { - return [ - 'type' => $class, - 'constant' => $tag, - 'content' => $content, - 'length' => $length + $start - $current['start'] - ] + $current; - } - - $newcontent = []; - $remainingLength = $length; - while ($remainingLength > 0) { - $temp = self::decode_ber($content, $start, $content_pos); - if ($temp === false) { - break; - } - $length = $temp['length']; - // end-of-content octets - see paragraph 8.1.5 - if (substr($content, $content_pos + $length, 2) == "\0\0") { - $length += 2; - $start += $length; - $newcontent[] = $temp; - break; - } - $start += $length; - $remainingLength -= $length; - $newcontent[] = $temp; - $content_pos += $length; - } - - return [ - 'type' => $class, - 'constant' => $tag, - // the array encapsulation is for BC with the old format - 'content' => $newcontent, - // the only time when $content['headerlength'] isn't defined is when the length is indefinite. - // the absence of $content['headerlength'] is how we know if something is indefinite or not. - // technically, it could be defined to be 2 and then another indicator could be used but whatever. - 'length' => $start - $current['start'] - ] + $current; - } - - $current += ['type' => $tag]; - - // decode UNIVERSAL tags - switch ($tag) { - case self::TYPE_BOOLEAN: - // "The contents octets shall consist of a single octet." -- paragraph 8.2.1 - if ($constructed || strlen($content) != 1) { - return false; - } - $current['content'] = (bool) ord($content[$content_pos]); - break; - case self::TYPE_INTEGER: - case self::TYPE_ENUMERATED: - if ($constructed) { - return false; - } - $current['content'] = new BigInteger(substr($content, $content_pos), -256); - break; - case self::TYPE_REAL: // not currently supported - return false; - case self::TYPE_BIT_STRING: - // The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, - // the number of unused bits in the final subsequent octet. The number shall be in the range zero to - // seven. - if (!$constructed) { - $current['content'] = substr($content, $content_pos); - } else { - $temp = self::decode_ber($content, $start, $content_pos); - if ($temp === false) { - return false; - } - $length -= (strlen($content) - $content_pos); - $last = count($temp) - 1; - for ($i = 0; $i < $last; $i++) { - // all subtags should be bit strings - if ($temp[$i]['type'] != self::TYPE_BIT_STRING) { - return false; - } - $current['content'] .= substr($temp[$i]['content'], 1); - } - // all subtags should be bit strings - if ($temp[$last]['type'] != self::TYPE_BIT_STRING) { - return false; - } - $current['content'] = $temp[$last]['content'][0] . $current['content'] . substr($temp[$i]['content'], 1); - } - break; - case self::TYPE_OCTET_STRING: - if (!$constructed) { - $current['content'] = substr($content, $content_pos); - } else { - $current['content'] = ''; - $length = 0; - while (substr($content, $content_pos, 2) != "\0\0") { - $temp = self::decode_ber($content, $length + $start, $content_pos); - if ($temp === false) { - return false; - } - $content_pos += $temp['length']; - // all subtags should be octet strings - if ($temp['type'] != self::TYPE_OCTET_STRING) { - return false; - } - $current['content'] .= $temp['content']; - $length += $temp['length']; - } - if (substr($content, $content_pos, 2) == "\0\0") { - $length += 2; // +2 for the EOC - } - } - break; - case self::TYPE_NULL: - // "The contents octets shall not contain any octets." -- paragraph 8.8.2 - if ($constructed || strlen($content)) { - return false; - } - break; - case self::TYPE_SEQUENCE: - case self::TYPE_SET: - if (!$constructed) { - return false; - } - $offset = 0; - $current['content'] = []; - $content_len = strlen($content); - while ($content_pos < $content_len) { - // if indefinite length construction was used and we have an end-of-content string next - // see paragraphs 8.1.1.3, 8.1.3.2, 8.1.3.6, 8.1.5, and (for an example) 8.6.4.2 - if (!isset($current['headerlength']) && substr($content, $content_pos, 2) == "\0\0") { - $length = $offset + 2; // +2 for the EOC - break 2; - } - $temp = self::decode_ber($content, $start + $offset, $content_pos); - if ($temp === false) { - return false; - } - $content_pos += $temp['length']; - $current['content'][] = $temp; - $offset += $temp['length']; - } - break; - case self::TYPE_OBJECT_IDENTIFIER: - if ($constructed) { - return false; - } - $current['content'] = self::decodeOID(substr($content, $content_pos)); - if ($current['content'] === false) { - return false; - } - break; - /* Each character string type shall be encoded as if it had been declared: - [UNIVERSAL x] IMPLICIT OCTET STRING - - -- X.690-0207.pdf#page=23 (paragraph 8.21.3) - - Per that, we're not going to do any validation. If there are any illegal characters in the string, - we don't really care */ - case self::TYPE_NUMERIC_STRING: - // 0,1,2,3,4,5,6,7,8,9, and space - case self::TYPE_PRINTABLE_STRING: - // Upper and lower case letters, digits, space, apostrophe, left/right parenthesis, plus sign, comma, - // hyphen, full stop, solidus, colon, equal sign, question mark - case self::TYPE_TELETEX_STRING: - // The Teletex character set in CCITT's T61, space, and delete - // see http://en.wikipedia.org/wiki/Teletex#Character_sets - case self::TYPE_VIDEOTEX_STRING: - // The Videotex character set in CCITT's T.100 and T.101, space, and delete - case self::TYPE_VISIBLE_STRING: - // Printing character sets of international ASCII, and space - case self::TYPE_IA5_STRING: - // International Alphabet 5 (International ASCII) - case self::TYPE_GRAPHIC_STRING: - // All registered G sets, and space - case self::TYPE_GENERAL_STRING: - // All registered C and G sets, space and delete - case self::TYPE_UTF8_STRING: - // ???? - case self::TYPE_BMP_STRING: - if ($constructed) { - return false; - } - $current['content'] = substr($content, $content_pos); - break; - case self::TYPE_UTC_TIME: - case self::TYPE_GENERALIZED_TIME: - if ($constructed) { - return false; - } - $current['content'] = self::decodeTime(substr($content, $content_pos), $tag); - break; - default: - return false; - } - - $start += $length; - - // ie. length is the length of the full TLV encoding - it's not just the length of the value - return $current + ['length' => $start - $current['start']]; - } - - /** - * ASN.1 Map - * - * Provides an ASN.1 semantic mapping ($mapping) from a parsed BER-encoding to a human readable format. - * - * "Special" mappings may be applied on a per tag-name basis via $special. - * - * @param array $decoded - * @param array $mapping - * @param array $special - * @return array|bool|Element|string|null - */ - public static function asn1map(array $decoded, $mapping, $special = []) - { - if (isset($mapping['explicit']) && is_array($decoded['content'])) { - $decoded = $decoded['content'][0]; - } - - switch (true) { - case $mapping['type'] == self::TYPE_ANY: - $intype = $decoded['type']; - // !isset(self::ANY_MAP[$intype]) produces a fatal error on PHP 5.6 - if (isset($decoded['constant']) || !array_key_exists($intype, self::ANY_MAP) || (ord(self::$encoded[$decoded['start']]) & 0x20)) { - return new Element(substr(self::$encoded, $decoded['start'], $decoded['length'])); - } - $inmap = self::ANY_MAP[$intype]; - if (is_string($inmap)) { - return [$inmap => self::asn1map($decoded, ['type' => $intype] + $mapping, $special)]; - } - break; - case $mapping['type'] == self::TYPE_CHOICE: - foreach ($mapping['children'] as $key => $option) { - switch (true) { - case isset($option['constant']) && $option['constant'] == $decoded['constant']: - case !isset($option['constant']) && $option['type'] == $decoded['type']: - $value = self::asn1map($decoded, $option, $special); - break; - case !isset($option['constant']) && $option['type'] == self::TYPE_CHOICE: - $v = self::asn1map($decoded, $option, $special); - if (isset($v)) { - $value = $v; - } - } - if (isset($value)) { - if (isset($special[$key])) { - $value = $special[$key]($value); - } - return [$key => $value]; - } - } - return null; - case isset($mapping['implicit']): - case isset($mapping['explicit']): - case $decoded['type'] == $mapping['type']: - break; - default: - // if $decoded['type'] and $mapping['type'] are both strings, but different types of strings, - // let it through - switch (true) { - case $decoded['type'] < 18: // self::TYPE_NUMERIC_STRING == 18 - case $decoded['type'] > 30: // self::TYPE_BMP_STRING == 30 - case $mapping['type'] < 18: - case $mapping['type'] > 30: - return null; - } - } - - if (isset($mapping['implicit'])) { - $decoded['type'] = $mapping['type']; - } - - switch ($decoded['type']) { - case self::TYPE_SEQUENCE: - $map = []; - - // ignore the min and max - if (isset($mapping['min']) && isset($mapping['max'])) { - $child = $mapping['children']; - foreach ($decoded['content'] as $content) { - if (($map[] = self::asn1map($content, $child, $special)) === null) { - return null; - } - } - - return $map; - } - - $n = count($decoded['content']); - $i = 0; - - foreach ($mapping['children'] as $key => $child) { - $maymatch = $i < $n; // Match only existing input. - if ($maymatch) { - $temp = $decoded['content'][$i]; - - if ($child['type'] != self::TYPE_CHOICE) { - // Get the mapping and input class & constant. - $childClass = $tempClass = self::CLASS_UNIVERSAL; - $constant = null; - if (isset($temp['constant'])) { - $tempClass = $temp['type']; - } - if (isset($child['class'])) { - $childClass = $child['class']; - $constant = $child['cast']; - } elseif (isset($child['constant'])) { - $childClass = self::CLASS_CONTEXT_SPECIFIC; - $constant = $child['constant']; - } - - if (isset($constant) && isset($temp['constant'])) { - // Can only match if constants and class match. - $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; - } else { - // Can only match if no constant expected and type matches or is generic. - $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; - } - } - } - - if ($maymatch) { - // Attempt submapping. - $candidate = self::asn1map($temp, $child, $special); - $maymatch = $candidate !== null; - } - - if ($maymatch) { - // Got the match: use it. - if (isset($special[$key])) { - $candidate = $special[$key]($candidate); - } - $map[$key] = $candidate; - $i++; - } elseif (isset($child['default'])) { - $map[$key] = $child['default']; - } elseif (!isset($child['optional'])) { - return null; // Syntax error. - } - } - - // Fail mapping if all input items have not been consumed. - return $i < $n ? null : $map; - - // the main diff between sets and sequences is the encapsulation of the foreach in another for loop - case self::TYPE_SET: - $map = []; - - // ignore the min and max - if (isset($mapping['min']) && isset($mapping['max'])) { - $child = $mapping['children']; - foreach ($decoded['content'] as $content) { - if (($map[] = self::asn1map($content, $child, $special)) === null) { - return null; - } - } - - return $map; - } - - for ($i = 0; $i < count($decoded['content']); $i++) { - $temp = $decoded['content'][$i]; - $tempClass = self::CLASS_UNIVERSAL; - if (isset($temp['constant'])) { - $tempClass = $temp['type']; - } - - foreach ($mapping['children'] as $key => $child) { - if (isset($map[$key])) { - continue; - } - $maymatch = true; - if ($child['type'] != self::TYPE_CHOICE) { - $childClass = self::CLASS_UNIVERSAL; - $constant = null; - if (isset($child['class'])) { - $childClass = $child['class']; - $constant = $child['cast']; - } elseif (isset($child['constant'])) { - $childClass = self::CLASS_CONTEXT_SPECIFIC; - $constant = $child['constant']; - } - - if (isset($constant) && isset($temp['constant'])) { - // Can only match if constants and class match. - $maymatch = $constant == $temp['constant'] && $childClass == $tempClass; - } else { - // Can only match if no constant expected and type matches or is generic. - $maymatch = !isset($child['constant']) && array_search($child['type'], [$temp['type'], self::TYPE_ANY, self::TYPE_CHOICE]) !== false; - } - } - - if ($maymatch) { - // Attempt submapping. - $candidate = self::asn1map($temp, $child, $special); - $maymatch = $candidate !== null; - } - - if (!$maymatch) { - break; - } - - // Got the match: use it. - if (isset($special[$key])) { - $candidate = $special[$key]($candidate); - } - $map[$key] = $candidate; - break; - } - } - - foreach ($mapping['children'] as $key => $child) { - if (!isset($map[$key])) { - if (isset($child['default'])) { - $map[$key] = $child['default']; - } elseif (!isset($child['optional'])) { - return null; - } - } - } - return $map; - case self::TYPE_OBJECT_IDENTIFIER: - return isset(self::$oids[$decoded['content']]) ? self::$oids[$decoded['content']] : $decoded['content']; - case self::TYPE_UTC_TIME: - case self::TYPE_GENERALIZED_TIME: - // for explicitly tagged optional stuff - if (is_array($decoded['content'])) { - $decoded['content'] = $decoded['content'][0]['content']; - } - // for implicitly tagged optional stuff - // in theory, doing isset($mapping['implicit']) would work but malformed certs do exist - // in the wild that OpenSSL decodes without issue so we'll support them as well - if (!is_object($decoded['content'])) { - $decoded['content'] = self::decodeTime($decoded['content'], $decoded['type']); - } - return $decoded['content'] ? $decoded['content']->format(self::$format) : false; - case self::TYPE_BIT_STRING: - if (isset($mapping['mapping'])) { - $offset = ord($decoded['content'][0]); - $size = (strlen($decoded['content']) - 1) * 8 - $offset; - /* - From X.680-0207.pdf#page=46 (21.7): - - "When a "NamedBitList" is used in defining a bitstring type ASN.1 encoding rules are free to add (or remove) - arbitrarily any trailing 0 bits to (or from) values that are being encoded or decoded. Application designers should - therefore ensure that different semantics are not associated with such values which differ only in the number of trailing - 0 bits." - */ - $bits = count($mapping['mapping']) == $size ? [] : array_fill(0, count($mapping['mapping']) - $size, false); - for ($i = strlen($decoded['content']) - 1; $i > 0; $i--) { - $current = ord($decoded['content'][$i]); - for ($j = $offset; $j < 8; $j++) { - $bits[] = (bool) ($current & (1 << $j)); - } - $offset = 0; - } - $values = []; - $map = array_reverse($mapping['mapping']); - foreach ($map as $i => $value) { - if ($bits[$i]) { - $values[] = $value; - } - } - return $values; - } - // fall-through - case self::TYPE_OCTET_STRING: - return $decoded['content']; - case self::TYPE_NULL: - return ''; - case self::TYPE_BOOLEAN: - case self::TYPE_NUMERIC_STRING: - case self::TYPE_PRINTABLE_STRING: - case self::TYPE_TELETEX_STRING: - case self::TYPE_VIDEOTEX_STRING: - case self::TYPE_IA5_STRING: - case self::TYPE_GRAPHIC_STRING: - case self::TYPE_VISIBLE_STRING: - case self::TYPE_GENERAL_STRING: - case self::TYPE_UNIVERSAL_STRING: - case self::TYPE_UTF8_STRING: - case self::TYPE_BMP_STRING: - return $decoded['content']; - case self::TYPE_INTEGER: - case self::TYPE_ENUMERATED: - $temp = $decoded['content']; - if (isset($mapping['implicit'])) { - $temp = new BigInteger($decoded['content'], -256); - } - if (isset($mapping['mapping'])) { - $temp = (int) $temp->toString(); - return isset($mapping['mapping'][$temp]) ? - $mapping['mapping'][$temp] : - false; - } - return $temp; - } - } - - /** - * DER-decode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @param string $string - * @return int - */ - public static function decodeLength(&$string) - { - $length = ord(Strings::shift($string)); - if ($length & 0x80) { // definite length, long form - $length &= 0x7F; - $temp = Strings::shift($string, $length); - list(, $length) = unpack('N', substr(str_pad($temp, 4, chr(0), STR_PAD_LEFT), -4)); - } - return $length; - } - - /** - * ASN.1 Encode - * - * DER-encodes an ASN.1 semantic mapping ($mapping). Some libraries would probably call this function - * an ASN.1 compiler. - * - * "Special" mappings can be applied via $special. - * - * @param Element|string|array $source - * @param array $mapping - * @param array $special - * @return string - */ - public static function encodeDER($source, $mapping, $special = []) - { - self::$location = []; - return self::encode_der($source, $mapping, null, $special); - } - - /** - * ASN.1 Encode (Helper function) - * - * @param Element|string|array|null $source - * @param array $mapping - * @param int $idx - * @param array $special - * @return string - */ - private static function encode_der($source, array $mapping, $idx = null, array $special = []) - { - if ($source instanceof Element) { - return $source->element; - } - - // do not encode (implicitly optional) fields with value set to default - if (isset($mapping['default']) && $source === $mapping['default']) { - return ''; - } - - if (isset($idx)) { - if (isset($special[$idx])) { - $source = $special[$idx]($source); - } - self::$location[] = $idx; - } - - $tag = $mapping['type']; - - switch ($tag) { - case self::TYPE_SET: // Children order is not important, thus process in sequence. - case self::TYPE_SEQUENCE: - $tag |= 0x20; // set the constructed bit - - // ignore the min and max - if (isset($mapping['min']) && isset($mapping['max'])) { - $value = []; - $child = $mapping['children']; - - foreach ($source as $content) { - $temp = self::encode_der($content, $child, null, $special); - if ($temp === false) { - return false; - } - $value[] = $temp; - } - /* "The encodings of the component values of a set-of value shall appear in ascending order, the encodings being compared - as octet strings with the shorter components being padded at their trailing end with 0-octets. - NOTE - The padding octets are for comparison purposes only and do not appear in the encodings." - - -- sec 11.6 of http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf */ - if ($mapping['type'] == self::TYPE_SET) { - sort($value); - } - $value = implode('', $value); - break; - } - - $value = ''; - foreach ($mapping['children'] as $key => $child) { - if (!array_key_exists($key, $source)) { - if (!isset($child['optional'])) { - return false; - } - continue; - } - - $temp = self::encode_der($source[$key], $child, $key, $special); - if ($temp === false) { - return false; - } - - // An empty child encoding means it has been optimized out. - // Else we should have at least one tag byte. - if ($temp === '') { - continue; - } - - // if isset($child['constant']) is true then isset($child['optional']) should be true as well - if (isset($child['constant'])) { - /* - From X.680-0207.pdf#page=58 (30.6): - - "The tagging construction specifies explicit tagging if any of the following holds: - ... - c) the "Tag Type" alternative is used and the value of "TagDefault" for the module is IMPLICIT TAGS or - AUTOMATIC TAGS, but the type defined by "Type" is an untagged choice type, an untagged open type, or - an untagged "DummyReference" (see ITU-T Rec. X.683 | ISO/IEC 8824-4, 8.3)." - */ - if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { - $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); - $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; - } else { - $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); - $temp = $subtag . substr($temp, 1); - } - } - $value .= $temp; - } - break; - case self::TYPE_CHOICE: - $temp = false; - - foreach ($mapping['children'] as $key => $child) { - if (!isset($source[$key])) { - continue; - } - - $temp = self::encode_der($source[$key], $child, $key, $special); - if ($temp === false) { - return false; - } - - // An empty child encoding means it has been optimized out. - // Else we should have at least one tag byte. - if ($temp === '') { - continue; - } - - $tag = ord($temp[0]); - - // if isset($child['constant']) is true then isset($child['optional']) should be true as well - if (isset($child['constant'])) { - if (isset($child['explicit']) || $child['type'] == self::TYPE_CHOICE) { - $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | 0x20 | $child['constant']); - $temp = $subtag . self::encodeLength(strlen($temp)) . $temp; - } else { - $subtag = chr((self::CLASS_CONTEXT_SPECIFIC << 6) | (ord($temp[0]) & 0x20) | $child['constant']); - $temp = $subtag . substr($temp, 1); - } - } - } - - if (isset($idx)) { - array_pop(self::$location); - } - - if ($temp && isset($mapping['cast'])) { - $temp[0] = chr(($mapping['class'] << 6) | ($tag & 0x20) | $mapping['cast']); - } - - return $temp; - case self::TYPE_INTEGER: - case self::TYPE_ENUMERATED: - if (!isset($mapping['mapping'])) { - if (is_numeric($source)) { - $source = new BigInteger($source); - } - $value = $source->toBytes(true); - } else { - $value = array_search($source, $mapping['mapping']); - if ($value === false) { - return false; - } - $value = new BigInteger($value); - $value = $value->toBytes(true); - } - if (!strlen($value)) { - $value = chr(0); - } - break; - case self::TYPE_UTC_TIME: - case self::TYPE_GENERALIZED_TIME: - $format = $mapping['type'] == self::TYPE_UTC_TIME ? 'y' : 'Y'; - $format .= 'mdHis'; - // if $source does _not_ include timezone information within it then assume that the timezone is GMT - $date = new \DateTime($source, new \DateTimeZone('GMT')); - // if $source _does_ include timezone information within it then convert the time to GMT - $date->setTimezone(new \DateTimeZone('GMT')); - $value = $date->format($format) . 'Z'; - break; - case self::TYPE_BIT_STRING: - if (isset($mapping['mapping'])) { - $bits = array_fill(0, count($mapping['mapping']), 0); - $size = 0; - for ($i = 0; $i < count($mapping['mapping']); $i++) { - if (in_array($mapping['mapping'][$i], $source)) { - $bits[$i] = 1; - $size = $i; - } - } - - if (isset($mapping['min']) && $mapping['min'] >= 1 && $size < $mapping['min']) { - $size = $mapping['min'] - 1; - } - - $offset = 8 - (($size + 1) & 7); - $offset = $offset !== 8 ? $offset : 0; - - $value = chr($offset); - - for ($i = $size + 1; $i < count($mapping['mapping']); $i++) { - unset($bits[$i]); - } - - $bits = implode('', array_pad($bits, $size + $offset + 1, 0)); - $bytes = explode(' ', rtrim(chunk_split($bits, 8, ' '))); - foreach ($bytes as $byte) { - $value .= chr(bindec($byte)); - } - - break; - } - // fall-through - case self::TYPE_OCTET_STRING: - /* The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, - the number of unused bits in the final subsequent octet. The number shall be in the range zero to seven. - - -- http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=16 */ - $value = $source; - break; - case self::TYPE_OBJECT_IDENTIFIER: - $value = self::encodeOID($source); - break; - case self::TYPE_ANY: - $loc = self::$location; - if (isset($idx)) { - array_pop(self::$location); - } - - switch (true) { - case !isset($source): - return self::encode_der(null, ['type' => self::TYPE_NULL] + $mapping, null, $special); - case is_int($source): - case $source instanceof BigInteger: - return self::encode_der($source, ['type' => self::TYPE_INTEGER] + $mapping, null, $special); - case is_float($source): - return self::encode_der($source, ['type' => self::TYPE_REAL] + $mapping, null, $special); - case is_bool($source): - return self::encode_der($source, ['type' => self::TYPE_BOOLEAN] + $mapping, null, $special); - case is_array($source) && count($source) == 1: - $typename = implode('', array_keys($source)); - $outtype = array_search($typename, self::ANY_MAP, true); - if ($outtype !== false) { - return self::encode_der($source[$typename], ['type' => $outtype] + $mapping, null, $special); - } - } - - $filters = self::$filters; - foreach ($loc as $part) { - if (!isset($filters[$part])) { - $filters = false; - break; - } - $filters = $filters[$part]; - } - if ($filters === false) { - throw new \RuntimeException('No filters defined for ' . implode('/', $loc)); - } - return self::encode_der($source, $filters + $mapping, null, $special); - case self::TYPE_NULL: - $value = ''; - break; - case self::TYPE_NUMERIC_STRING: - case self::TYPE_TELETEX_STRING: - case self::TYPE_PRINTABLE_STRING: - case self::TYPE_UNIVERSAL_STRING: - case self::TYPE_UTF8_STRING: - case self::TYPE_BMP_STRING: - case self::TYPE_IA5_STRING: - case self::TYPE_VISIBLE_STRING: - case self::TYPE_VIDEOTEX_STRING: - case self::TYPE_GRAPHIC_STRING: - case self::TYPE_GENERAL_STRING: - $value = $source; - break; - case self::TYPE_BOOLEAN: - $value = $source ? "\xFF" : "\x00"; - break; - default: - throw new \RuntimeException('Mapping provides no type definition for ' . implode('/', self::$location)); - } - - if (isset($idx)) { - array_pop(self::$location); - } - - if (isset($mapping['cast'])) { - if (isset($mapping['explicit']) || $mapping['type'] == self::TYPE_CHOICE) { - $value = chr($tag) . self::encodeLength(strlen($value)) . $value; - $tag = ($mapping['class'] << 6) | 0x20 | $mapping['cast']; - } else { - $tag = ($mapping['class'] << 6) | (ord($temp[0]) & 0x20) | $mapping['cast']; - } - } - - return chr($tag) . self::encodeLength(strlen($value)) . $value; - } - - /** - * BER-decode the OID - * - * Called by _decode_ber() - * - * @param string $content - * @return string - */ - public static function decodeOID($content) - { - static $eighty; - if (!$eighty) { - $eighty = new BigInteger(80); - } - - $oid = []; - $pos = 0; - $len = strlen($content); - - if (ord($content[$len - 1]) & 0x80) { - return false; - } - - $n = new BigInteger(); - while ($pos < $len) { - $temp = ord($content[$pos++]); - $n = $n->bitwise_leftShift(7); - $n = $n->bitwise_or(new BigInteger($temp & 0x7F)); - if (~$temp & 0x80) { - $oid[] = $n; - $n = new BigInteger(); - } - } - $part1 = array_shift($oid); - $first = floor(ord($content[0]) / 40); - /* - "This packing of the first two object identifier components recognizes that only three values are allocated from the root - node, and at most 39 subsequent values from nodes reached by X = 0 and X = 1." - - -- https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=22 - */ - if ($first <= 2) { // ie. 0 <= ord($content[0]) < 120 (0x78) - array_unshift($oid, ord($content[0]) % 40); - array_unshift($oid, $first); - } else { - array_unshift($oid, $part1->subtract($eighty)); - array_unshift($oid, 2); - } - - return implode('.', $oid); - } - - /** - * DER-encode the OID - * - * Called by _encode_der() - * - * @param string $source - * @return string - */ - public static function encodeOID($source) - { - static $mask, $zero, $forty; - if (!$mask) { - $mask = new BigInteger(0x7F); - $zero = new BigInteger(); - $forty = new BigInteger(40); - } - - if (!preg_match('#(?:\d+\.)+#', $source)) { - $oid = isset(self::$reverseOIDs[$source]) ? self::$reverseOIDs[$source] : false; - } else { - $oid = $source; - } - if ($oid === false) { - throw new \RuntimeException('Invalid OID'); - } - - $parts = explode('.', $oid); - $part1 = array_shift($parts); - $part2 = array_shift($parts); - - $first = new BigInteger($part1); - $first = $first->multiply($forty); - $first = $first->add(new BigInteger($part2)); - - array_unshift($parts, $first->toString()); - - $value = ''; - foreach ($parts as $part) { - if (!$part) { - $temp = "\0"; - } else { - $temp = ''; - $part = new BigInteger($part); - while (!$part->equals($zero)) { - $submask = $part->bitwise_and($mask); - $submask->setPrecision(8); - $temp = (chr(0x80) | $submask->toBytes()) . $temp; - $part = $part->bitwise_rightShift(7); - } - $temp[strlen($temp) - 1] = $temp[strlen($temp) - 1] & chr(0x7F); - } - $value .= $temp; - } - - return $value; - } - - /** - * BER-decode the time - * - * Called by _decode_ber() and in the case of implicit tags asn1map(). - * - * @param string $content - * @param int $tag - * @return \DateTime|false - */ - private static function decodeTime($content, $tag) - { - /* UTCTime: - http://tools.ietf.org/html/rfc5280#section-4.1.2.5.1 - http://www.obj-sys.com/asn1tutorial/node15.html - - GeneralizedTime: - http://tools.ietf.org/html/rfc5280#section-4.1.2.5.2 - http://www.obj-sys.com/asn1tutorial/node14.html */ - - $format = 'YmdHis'; - - if ($tag == self::TYPE_UTC_TIME) { - // https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#page=28 says "the seconds - // element shall always be present" but none-the-less I've seen X509 certs where it isn't and if the - // browsers parse it phpseclib ought to too - if (preg_match('#^(\d{10})(Z|[+-]\d{4})$#', $content, $matches)) { - $content = $matches[1] . '00' . $matches[2]; - } - $prefix = substr($content, 0, 2) >= 50 ? '19' : '20'; - $content = $prefix . $content; - } elseif (strpos($content, '.') !== false) { - $format .= '.u'; - } - - if ($content[strlen($content) - 1] == 'Z') { - $content = substr($content, 0, -1) . '+0000'; - } - - if (strpos($content, '-') !== false || strpos($content, '+') !== false) { - $format .= 'O'; - } - - // error supression isn't necessary as of PHP 7.0: - // http://php.net/manual/en/migration70.other-changes.php - return @\DateTime::createFromFormat($format, $content); - } - - /** - * Set the time format - * - * Sets the time / date format for asn1map(). - * - * @param string $format - */ - public static function setTimeFormat($format) - { - self::$format = $format; - } - - /** - * Load OIDs - * - * Load the relevant OIDs for a particular ASN.1 semantic mapping. - * Previously loaded OIDs are retained. - * - * @param array $oids - */ - public static function loadOIDs(array $oids) - { - self::$reverseOIDs += $oids; - self::$oids = array_flip(self::$reverseOIDs); - } - - /** - * Set filters - * - * See \phpseclib3\File\X509, etc, for an example. - * Previously loaded filters are not retained. - * - * @param array $filters - */ - public static function setFilters(array $filters) - { - self::$filters = $filters; - } - - /** - * String type conversion - * - * This is a lazy conversion, dealing only with character size. - * No real conversion table is used. - * - * @param string $in - * @param int $from - * @param int $to - * @return string - */ - public static function convert($in, $from = self::TYPE_UTF8_STRING, $to = self::TYPE_UTF8_STRING) - { - // isset(self::STRING_TYPE_SIZE[$from] returns a fatal error on PHP 5.6 - if (!array_key_exists($from, self::STRING_TYPE_SIZE) || !array_key_exists($to, self::STRING_TYPE_SIZE)) { - return false; - } - $insize = self::STRING_TYPE_SIZE[$from]; - $outsize = self::STRING_TYPE_SIZE[$to]; - $inlength = strlen($in); - $out = ''; - - for ($i = 0; $i < $inlength;) { - if ($inlength - $i < $insize) { - return false; - } - - // Get an input character as a 32-bit value. - $c = ord($in[$i++]); - switch (true) { - case $insize == 4: - $c = ($c << 8) | ord($in[$i++]); - $c = ($c << 8) | ord($in[$i++]); - // fall-through - case $insize == 2: - $c = ($c << 8) | ord($in[$i++]); - // fall-through - case $insize == 1: - break; - case ($c & 0x80) == 0x00: - break; - case ($c & 0x40) == 0x00: - return false; - default: - $bit = 6; - do { - if ($bit > 25 || $i >= $inlength || (ord($in[$i]) & 0xC0) != 0x80) { - return false; - } - $c = ($c << 6) | (ord($in[$i++]) & 0x3F); - $bit += 5; - $mask = 1 << $bit; - } while ($c & $bit); - $c &= $mask - 1; - break; - } - - // Convert and append the character to output string. - $v = ''; - switch (true) { - case $outsize == 4: - $v .= chr($c & 0xFF); - $c >>= 8; - $v .= chr($c & 0xFF); - $c >>= 8; - // fall-through - case $outsize == 2: - $v .= chr($c & 0xFF); - $c >>= 8; - // fall-through - case $outsize == 1: - $v .= chr($c & 0xFF); - $c >>= 8; - if ($c) { - return false; - } - break; - case ($c & (PHP_INT_SIZE == 8 ? 0x80000000 : (1 << 31))) != 0: - return false; - case $c >= 0x04000000: - $v .= chr(0x80 | ($c & 0x3F)); - $c = ($c >> 6) | 0x04000000; - // fall-through - case $c >= 0x00200000: - $v .= chr(0x80 | ($c & 0x3F)); - $c = ($c >> 6) | 0x00200000; - // fall-through - case $c >= 0x00010000: - $v .= chr(0x80 | ($c & 0x3F)); - $c = ($c >> 6) | 0x00010000; - // fall-through - case $c >= 0x00000800: - $v .= chr(0x80 | ($c & 0x3F)); - $c = ($c >> 6) | 0x00000800; - // fall-through - case $c >= 0x00000080: - $v .= chr(0x80 | ($c & 0x3F)); - $c = ($c >> 6) | 0x000000C0; - // fall-through - default: - $v .= chr($c); - break; - } - $out .= strrev($v); - } - return $out; - } - - /** - * Extract raw BER from Base64 encoding - * - * @param string $str - * @return string - */ - public static function extractBER($str) - { - /* X.509 certs are assumed to be base64 encoded but sometimes they'll have additional things in them - * above and beyond the ceritificate. - * ie. some may have the following preceding the -----BEGIN CERTIFICATE----- line: - * - * Bag Attributes - * localKeyID: 01 00 00 00 - * subject=/O=organization/OU=org unit/CN=common name - * issuer=/O=organization/CN=common name - */ - if (strlen($str) > ini_get('pcre.backtrack_limit')) { - $temp = $str; - } else { - $temp = preg_replace('#.*?^-+[^-]+-+[\r\n ]*$#ms', '', $str, 1); - $temp = preg_replace('#-+END.*[\r\n ]*.*#ms', '', $temp, 1); - } - // remove new lines - $temp = str_replace(["\r", "\n", ' '], '', $temp); - // remove the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- stuff - $temp = preg_replace('#^-+[^-]+-+|-+[^-]+-+$#', '', $temp); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; - return $temp != false ? $temp : $str; - } - - /** - * DER-encode the length - * - * DER supports lengths up to (2**8)**127, however, we'll only support lengths up to (2**8)**4. See - * {@link http://itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf#p=13 X.690 paragraph 8.1.3} for more information. - * - * @param int $length - * @return string - */ - public static function encodeLength($length) - { - if ($length <= 0x7F) { - return chr($length); - } - - $temp = ltrim(pack('N', $length), chr(0)); - return pack('Ca*', 0x80 | strlen($temp), $temp); - } - - /** - * Returns the OID corresponding to a name - * - * What's returned in the associative array returned by loadX509() (or load*()) is either a name or an OID if - * no OID to name mapping is available. The problem with this is that what may be an unmapped OID in one version - * of phpseclib may not be unmapped in the next version, so apps that are looking at this OID may not be able - * to work from version to version. - * - * This method will return the OID if a name is passed to it and if no mapping is avialable it'll assume that - * what's being passed to it already is an OID and return that instead. A few examples. - * - * getOID('2.16.840.1.101.3.4.2.1') == '2.16.840.1.101.3.4.2.1' - * getOID('id-sha256') == '2.16.840.1.101.3.4.2.1' - * getOID('zzz') == 'zzz' - * - * @param string $name - * @return string - */ - public static function getOID($name) - { - return isset(self::$reverseOIDs[$name]) ? self::$reverseOIDs[$name] : $name; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php deleted file mode 100644 index 6540b42..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Element.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2012 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1; - -/** - * ASN.1 Raw Element - * - * An ASN.1 ANY mapping will return an ASN1\Element object. Use of this object - * will also bypass the normal encoding rules in ASN1::encodeDER() - * - * @author Jim Wigginton - */ -class Element -{ - /** - * Raw element value - * - * @var string - */ - public $element; - - /** - * Constructor - * - * @param string $encoded - * @return \phpseclib3\File\ASN1\Element - */ - public function __construct($encoded) - { - $this->element = $encoded; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php deleted file mode 100644 index 1cbc5a5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AccessDescription.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AccessDescription - * - * @author Jim Wigginton - */ -abstract class AccessDescription -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'accessMethod' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'accessLocation' => GeneralName::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php deleted file mode 100644 index 04183a1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AdministrationDomainName.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AdministrationDomainName - * - * @author Jim Wigginton - */ -abstract class AdministrationDomainName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or - // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC - 'class' => ASN1::CLASS_APPLICATION, - 'cast' => 2, - 'children' => [ - 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], - 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php deleted file mode 100644 index 0da7eb1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AlgorithmIdentifier.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AlgorithmIdentifier - * - * @author Jim Wigginton - */ -abstract class AlgorithmIdentifier -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'algorithm' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'parameters' => [ - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php deleted file mode 100644 index d96c170..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AnotherName.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AnotherName - * - * @author Jim Wigginton - */ -abstract class AnotherName -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type-id' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'value' => [ - 'type' => ASN1::TYPE_ANY, - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php deleted file mode 100644 index 38a6aee..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attribute.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Attribute - * - * @author Jim Wigginton - */ -abstract class Attribute -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type' => AttributeType::MAP, - 'value' => [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => AttributeValue::MAP - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php deleted file mode 100644 index 5cbc2bc..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeType.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AttributeType - * - * @author Jim Wigginton - */ -abstract class AttributeType -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php deleted file mode 100644 index fe414f1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeTypeAndValue.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AttributeTypeAndValue - * - * @author Jim Wigginton - */ -abstract class AttributeTypeAndValue -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type' => AttributeType::MAP, - 'value' => AttributeValue::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php deleted file mode 100644 index 3b3b6d2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AttributeValue.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AttributeValue - * - * @author Jim Wigginton - */ -abstract class AttributeValue -{ - const MAP = ['type' => ASN1::TYPE_ANY]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php deleted file mode 100644 index cd53ecf..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Attributes.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Attributes - * - * @author Jim Wigginton - */ -abstract class Attributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => Attribute::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php deleted file mode 100644 index 3e80a55..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityInfoAccessSyntax.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AuthorityInfoAccessSyntax - * - * @author Jim Wigginton - */ -abstract class AuthorityInfoAccessSyntax -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => AccessDescription::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php deleted file mode 100644 index e7ec5b2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/AuthorityKeyIdentifier.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * AuthorityKeyIdentifier - * - * @author Jim Wigginton - */ -abstract class AuthorityKeyIdentifier -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'keyIdentifier' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + KeyIdentifier::MAP, - 'authorityCertIssuer' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + GeneralNames::MAP, - 'authorityCertSerialNumber' => [ - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ] + CertificateSerialNumber::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php deleted file mode 100644 index e59668a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BaseDistance.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BaseDistance - * - * @author Jim Wigginton - */ -abstract class BaseDistance -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php deleted file mode 100644 index 587ef1b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BasicConstraints.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BasicConstraints - * - * @author Jim Wigginton - */ -abstract class BasicConstraints -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'cA' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'optional' => true, - 'default' => false - ], - 'pathLenConstraint' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php deleted file mode 100644 index e81bc78..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttribute.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BuiltInDomainDefinedAttribute - * - * @author Jim Wigginton - */ -abstract class BuiltInDomainDefinedAttribute -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'type' => ['type' => ASN1::TYPE_PRINTABLE_STRING], - 'value' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php deleted file mode 100644 index 471e88f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInDomainDefinedAttributes.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BuiltInDomainDefinedAttributes - * - * @author Jim Wigginton - */ -abstract class BuiltInDomainDefinedAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 4, // ub-domain-defined-attributes - 'children' => BuiltInDomainDefinedAttribute::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php deleted file mode 100644 index 752f400..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/BuiltInStandardAttributes.php +++ /dev/null @@ -1,67 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * BuiltInStandardAttributes - * - * @author Jim Wigginton - */ -abstract class BuiltInStandardAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'country-name' => ['optional' => true] + CountryName::MAP, - 'administration-domain-name' => ['optional' => true] + AdministrationDomainName::MAP, - 'network-address' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + NetworkAddress::MAP, - 'terminal-identifier' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + TerminalIdentifier::MAP, - 'private-domain-name' => [ - 'constant' => 2, - 'optional' => true, - 'explicit' => true - ] + PrivateDomainName::MAP, - 'organization-name' => [ - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] + OrganizationName::MAP, - 'numeric-user-identifier' => [ - 'constant' => 4, - 'optional' => true, - 'implicit' => true - ] + NumericUserIdentifier::MAP, - 'personal-name' => [ - 'constant' => 5, - 'optional' => true, - 'implicit' => true - ] + PersonalName::MAP, - 'organizational-unit-names' => [ - 'constant' => 6, - 'optional' => true, - 'implicit' => true - ] + OrganizationalUnitNames::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php deleted file mode 100644 index 56e5888..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CPSuri.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CPSuri - * - * @author Jim Wigginton - */ -abstract class CPSuri -{ - const MAP = ['type' => ASN1::TYPE_IA5_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php deleted file mode 100644 index 79860b2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLDistributionPoints.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CRLDistributionPoints - * - * @author Jim Wigginton - */ -abstract class CRLDistributionPoints -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => DistributionPoint::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php deleted file mode 100644 index f6cb956..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLNumber.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CRLNumber - * - * @author Jim Wigginton - */ -abstract class CRLNumber -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php deleted file mode 100644 index d373652..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CRLReason.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CRLReason - * - * @author Jim Wigginton - */ -abstract class CRLReason -{ - const MAP = [ - 'type' => ASN1::TYPE_ENUMERATED, - 'mapping' => [ - 'unspecified', - 'keyCompromise', - 'cACompromise', - 'affiliationChanged', - 'superseded', - 'cessationOfOperation', - 'certificateHold', - // Value 7 is not used. - 8 => 'removeFromCRL', - 'privilegeWithdrawn', - 'aACompromise' - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php deleted file mode 100644 index d7e7776..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertPolicyId.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertPolicyId - * - * @author Jim Wigginton - */ -abstract class CertPolicyId -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php deleted file mode 100644 index 01943a0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Certificate.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Certificate - * - * @author Jim Wigginton - */ -abstract class Certificate -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'tbsCertificate' => TBSCertificate::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php deleted file mode 100644 index ccd68dd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateIssuer.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -/** - * CertificateIssuer - * - * @author Jim Wigginton - */ -abstract class CertificateIssuer -{ - const MAP = GeneralNames::MAP; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php deleted file mode 100644 index d54ed6d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateList.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificateList - * - * @author Jim Wigginton - */ -abstract class CertificateList -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'tbsCertList' => TBSCertList::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php deleted file mode 100644 index ec0fa6b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificatePolicies.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificatePolicies - * - * @author Jim Wigginton - */ -abstract class CertificatePolicies -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => PolicyInformation::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php deleted file mode 100644 index 06ec944..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificateSerialNumber.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificateSerialNumber - * - * @author Jim Wigginton - */ -abstract class CertificateSerialNumber -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php deleted file mode 100644 index 2da70ed..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequest.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificationRequest - * - * @author Jim Wigginton - */ -abstract class CertificationRequest -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'certificationRequestInfo' => CertificationRequestInfo::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php deleted file mode 100644 index ce6dc88..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CertificationRequestInfo.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CertificationRequestInfo - * - * @author Jim Wigginton - */ -abstract class CertificationRequestInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1'] - ], - 'subject' => Name::MAP, - 'subjectPKInfo' => SubjectPublicKeyInfo::MAP, - 'attributes' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + Attributes::MAP, - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php deleted file mode 100644 index 5bf59bb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Characteristic_two.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Characteristic_two - * - * @author Jim Wigginton - */ -abstract class Characteristic_two -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'm' => ['type' => ASN1::TYPE_INTEGER], // field size 2**m - 'basis' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'parameters' => [ - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php deleted file mode 100644 index 737d844..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/CountryName.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * CountryName - * - * @author Jim Wigginton - */ -abstract class CountryName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - // if class isn't present it's assumed to be \phpseclib3\File\ASN1::CLASS_UNIVERSAL or - // (if constant is present) \phpseclib3\File\ASN1::CLASS_CONTEXT_SPECIFIC - 'class' => ASN1::CLASS_APPLICATION, - 'cast' => 1, - 'children' => [ - 'x121-dcc-code' => ['type' => ASN1::TYPE_NUMERIC_STRING], - 'iso-3166-alpha2-code' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php deleted file mode 100644 index 621f103..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Curve.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Curve - * - * @author Jim Wigginton - */ -abstract class Curve -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'a' => FieldElement::MAP, - 'b' => FieldElement::MAP, - 'seed' => [ - 'type' => ASN1::TYPE_BIT_STRING, - 'optional' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php deleted file mode 100644 index 26863db..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DHParameter.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DHParameter - * - * @author Jim Wigginton - */ -abstract class DHParameter -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'prime' => ['type' => ASN1::TYPE_INTEGER], - 'base' => ['type' => ASN1::TYPE_INTEGER], - 'privateValueLength' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php deleted file mode 100644 index 7af397b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAParams.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DSAParams - * - * @author Jim Wigginton - */ -abstract class DSAParams -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'p' => ['type' => ASN1::TYPE_INTEGER], - 'q' => ['type' => ASN1::TYPE_INTEGER], - 'g' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php deleted file mode 100644 index d97cd02..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPrivateKey.php +++ /dev/null @@ -1,36 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DSAPrivateKey - * - * @author Jim Wigginton - */ -abstract class DSAPrivateKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => ['type' => ASN1::TYPE_INTEGER], - 'p' => ['type' => ASN1::TYPE_INTEGER], - 'q' => ['type' => ASN1::TYPE_INTEGER], - 'g' => ['type' => ASN1::TYPE_INTEGER], - 'y' => ['type' => ASN1::TYPE_INTEGER], - 'x' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php deleted file mode 100644 index f795747..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DSAPublicKey.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DSAPublicKey - * - * @author Jim Wigginton - */ -abstract class DSAPublicKey -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php deleted file mode 100644 index b38ff3c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DigestInfo.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DigestInfo - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @author Jim Wigginton - */ -abstract class DigestInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'digestAlgorithm' => AlgorithmIdentifier::MAP, - 'digest' => ['type' => ASN1::TYPE_OCTET_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php deleted file mode 100644 index 45218e3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DirectoryString.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DirectoryString - * - * @author Jim Wigginton - */ -abstract class DirectoryString -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'teletexString' => ['type' => ASN1::TYPE_TELETEX_STRING], - 'printableString' => ['type' => ASN1::TYPE_PRINTABLE_STRING], - 'universalString' => ['type' => ASN1::TYPE_UNIVERSAL_STRING], - 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING], - 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php deleted file mode 100644 index a13e6a6..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DisplayText.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DisplayText - * - * @author Jim Wigginton - */ -abstract class DisplayText -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], - 'visibleString' => ['type' => ASN1::TYPE_VISIBLE_STRING], - 'bmpString' => ['type' => ASN1::TYPE_BMP_STRING], - 'utf8String' => ['type' => ASN1::TYPE_UTF8_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php deleted file mode 100644 index 4d9af6b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPoint.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DistributionPoint - * - * @author Jim Wigginton - */ -abstract class DistributionPoint -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'distributionPoint' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + DistributionPointName::MAP, - 'reasons' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + ReasonFlags::MAP, - 'cRLIssuer' => [ - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ] + GeneralNames::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php deleted file mode 100644 index bc0cec8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DistributionPointName.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DistributionPointName - * - * @author Jim Wigginton - */ -abstract class DistributionPointName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'fullName' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + GeneralNames::MAP, - 'nameRelativeToCRLIssuer' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + RelativeDistinguishedName::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php deleted file mode 100644 index 2af7408..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/DssSigValue.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * DssSigValue - * - * @author Jim Wigginton - */ -abstract class DssSigValue -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'r' => ['type' => ASN1::TYPE_INTEGER], - 's' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php deleted file mode 100644 index f25f6fa..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECParameters.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ECParameters - * - * ECParameters ::= CHOICE { - * namedCurve OBJECT IDENTIFIER - * -- implicitCurve NULL - * -- specifiedCurve SpecifiedECDomain - * } - * -- implicitCurve and specifiedCurve MUST NOT be used in PKIX. - * -- Details for SpecifiedECDomain can be found in [X9.62]. - * -- Any future additions to this CHOICE should be coordinated - * -- with ANSI X9. - * - * @author Jim Wigginton - */ -abstract class ECParameters -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'namedCurve' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'implicitCurve' => ['type' => ASN1::TYPE_NULL], - 'specifiedCurve' => SpecifiedECDomain::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php deleted file mode 100644 index fb11db8..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPoint.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ECPoint - * - * @author Jim Wigginton - */ -abstract class ECPoint -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php deleted file mode 100644 index 7454f38..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ECPrivateKey.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ECPrivateKey - * - * @author Jim Wigginton - */ -abstract class ECPrivateKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => [1 => 'ecPrivkeyVer1'] - ], - 'privateKey' => ['type' => ASN1::TYPE_OCTET_STRING], - 'parameters' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + ECParameters::MAP, - 'publicKey' => [ - 'type' => ASN1::TYPE_BIT_STRING, - 'constant' => 1, - 'optional' => true, - 'explicit' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php deleted file mode 100644 index ea7dcf1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EDIPartyName.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EDIPartyName - * - * @author Jim Wigginton - */ -abstract class EDIPartyName -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'nameAssigner' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + DirectoryString::MAP, - // partyName is technically required but \phpseclib3\File\ASN1 doesn't currently support non-optional constants and - // setting it to optional gets the job done in any event. - 'partyName' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + DirectoryString::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php deleted file mode 100644 index 8ab9ff1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EcdsaSigValue.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EcdsaSigValue - * - * @author Jim Wigginton - */ -abstract class EcdsaSigValue -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'r' => ['type' => ASN1::TYPE_INTEGER], - 's' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php deleted file mode 100644 index 8d8739e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedData.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EncryptedData - * - * @author Jim Wigginton - */ -abstract class EncryptedData -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php deleted file mode 100644 index 2c93567..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/EncryptedPrivateKeyInfo.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * EncryptedPrivateKeyInfo - * - * @author Jim Wigginton - */ -abstract class EncryptedPrivateKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'encryptionAlgorithm' => AlgorithmIdentifier::MAP, - 'encryptedData' => EncryptedData::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php deleted file mode 100644 index f9bc5de..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtKeyUsageSyntax.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ExtKeyUsageSyntax - * - * @author Jim Wigginton - */ -abstract class ExtKeyUsageSyntax -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => KeyPurposeId::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php deleted file mode 100644 index e32668f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extension.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Extension - * - * A certificate using system MUST reject the certificate if it encounters - * a critical extension it does not recognize; however, a non-critical - * extension may be ignored if it is not recognized. - * - * http://tools.ietf.org/html/rfc5280#section-4.2 - * - * @author Jim Wigginton - */ -abstract class Extension -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'extnId' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'critical' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'optional' => true, - 'default' => false - ], - 'extnValue' => ['type' => ASN1::TYPE_OCTET_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php deleted file mode 100644 index 565b36d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttribute.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ExtensionAttribute - * - * @author Jim Wigginton - */ -abstract class ExtensionAttribute -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'extension-attribute-type' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ], - 'extension-attribute-value' => [ - 'type' => ASN1::TYPE_ANY, - 'constant' => 1, - 'optional' => true, - 'explicit' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php deleted file mode 100644 index a2e9bfa..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ExtensionAttributes.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ExtensionAttributes - * - * @author Jim Wigginton - */ -abstract class ExtensionAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => 256, // ub-extension-attributes - 'children' => ExtensionAttribute::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php deleted file mode 100644 index 5015c97..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Extensions.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Extensions - * - * @author Jim Wigginton - */ -abstract class Extensions -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - // technically, it's MAX, but we'll assume anything < 0 is MAX - 'max' => -1, - // if 'children' isn't an array then 'min' and 'max' must be defined - 'children' => Extension::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php deleted file mode 100644 index 3173407..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldElement.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * FieldElement - * - * @author Jim Wigginton - */ -abstract class FieldElement -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php deleted file mode 100644 index e32a9c0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/FieldID.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * FieldID - * - * @author Jim Wigginton - */ -abstract class FieldID -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'fieldType' => ['type' => ASN1::TYPE_OBJECT_IDENTIFIER], - 'parameters' => [ - 'type' => ASN1::TYPE_ANY, - 'optional' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php deleted file mode 100644 index 57d86da..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralName.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralName - * - * @author Jim Wigginton - */ -abstract class GeneralName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'otherName' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + AnotherName::MAP, - 'rfc822Name' => [ - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ], - 'dNSName' => [ - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ], - 'x400Address' => [ - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] + ORAddress::MAP, - 'directoryName' => [ - 'constant' => 4, - 'optional' => true, - 'explicit' => true - ] + Name::MAP, - 'ediPartyName' => [ - 'constant' => 5, - 'optional' => true, - 'implicit' => true - ] + EDIPartyName::MAP, - 'uniformResourceIdentifier' => [ - 'type' => ASN1::TYPE_IA5_STRING, - 'constant' => 6, - 'optional' => true, - 'implicit' => true - ], - 'iPAddress' => [ - 'type' => ASN1::TYPE_OCTET_STRING, - 'constant' => 7, - 'optional' => true, - 'implicit' => true - ], - 'registeredID' => [ - 'type' => ASN1::TYPE_OBJECT_IDENTIFIER, - 'constant' => 8, - 'optional' => true, - 'implicit' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php deleted file mode 100644 index 5d93153..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralNames.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralNames - * - * @author Jim Wigginton - */ -abstract class GeneralNames -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => GeneralName::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php deleted file mode 100644 index 5388db5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtree.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralSubtree - * - * @author Jim Wigginton - */ -abstract class GeneralSubtree -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'base' => GeneralName::MAP, - 'minimum' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true, - 'default' => '0' - ] + BaseDistance::MAP, - 'maximum' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true, - ] + BaseDistance::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php deleted file mode 100644 index 27548cf..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/GeneralSubtrees.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * GeneralSubtrees - * - * @author Jim Wigginton - */ -abstract class GeneralSubtrees -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => GeneralSubtree::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php deleted file mode 100644 index deb13ca..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HashAlgorithm.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -/** - * HashAglorithm - * - * @author Jim Wigginton - */ -abstract class HashAlgorithm -{ - const MAP = AlgorithmIdentifier::MAP; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php deleted file mode 100644 index 88d6ff3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/HoldInstructionCode.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * HoldInstructionCode - * - * @author Jim Wigginton - */ -abstract class HoldInstructionCode -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php deleted file mode 100644 index f34b5f7..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/InvalidityDate.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * InvalidityDate - * - * @author Jim Wigginton - */ -abstract class InvalidityDate -{ - const MAP = ['type' => ASN1::TYPE_GENERALIZED_TIME]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php deleted file mode 100644 index e9d0324..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuerAltName.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -/** - * IssuerAltName - * - * @author Jim Wigginton - */ -abstract class IssuerAltName -{ - const MAP = GeneralNames::MAP; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php deleted file mode 100644 index 415996f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/IssuingDistributionPoint.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * IssuingDistributionPoint - * - * @author Jim Wigginton - */ -abstract class IssuingDistributionPoint -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'distributionPoint' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + DistributionPointName::MAP, - 'onlyContainsUserCerts' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 1, - 'optional' => true, - 'default' => false, - 'implicit' => true - ], - 'onlyContainsCACerts' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 2, - 'optional' => true, - 'default' => false, - 'implicit' => true - ], - 'onlySomeReasons' => [ - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] + ReasonFlags::MAP, - 'indirectCRL' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 4, - 'optional' => true, - 'default' => false, - 'implicit' => true - ], - 'onlyContainsAttributeCerts' => [ - 'type' => ASN1::TYPE_BOOLEAN, - 'constant' => 5, - 'optional' => true, - 'default' => false, - 'implicit' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php deleted file mode 100644 index 82a4151..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyIdentifier.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * KeyIdentifier - * - * @author Jim Wigginton - */ -abstract class KeyIdentifier -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php deleted file mode 100644 index b8509f1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyPurposeId.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * KeyPurposeId - * - * @author Jim Wigginton - */ -abstract class KeyPurposeId -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php deleted file mode 100644 index 827ce03..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/KeyUsage.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * KeyUsage - * - * @author Jim Wigginton - */ -abstract class KeyUsage -{ - const MAP = [ - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => [ - 'digitalSignature', - 'nonRepudiation', - 'keyEncipherment', - 'dataEncipherment', - 'keyAgreement', - 'keyCertSign', - 'cRLSign', - 'encipherOnly', - 'decipherOnly' - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php deleted file mode 100644 index ea3f998..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/MaskGenAlgorithm.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -/** - * MaskGenAglorithm - * - * @author Jim Wigginton - */ -abstract class MaskGenAlgorithm -{ - const MAP = AlgorithmIdentifier::MAP; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php deleted file mode 100644 index a6a9009..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Name.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Name - * - * @author Jim Wigginton - */ -abstract class Name -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'rdnSequence' => RDNSequence::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php deleted file mode 100644 index 80486f9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NameConstraints.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NameConstraints - * - * @author Jim Wigginton - */ -abstract class NameConstraints -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'permittedSubtrees' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + GeneralSubtrees::MAP, - 'excludedSubtrees' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + GeneralSubtrees::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php deleted file mode 100644 index 6c68df0..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NetworkAddress.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NetworkAddress - * - * @author Jim Wigginton - */ -abstract class NetworkAddress -{ - const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php deleted file mode 100644 index 9eec123..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NoticeReference.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NoticeReference - * - * @author Jim Wigginton - */ -abstract class NoticeReference -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'organization' => DisplayText::MAP, - 'noticeNumbers' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 200, - 'children' => ['type' => ASN1::TYPE_INTEGER] - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php deleted file mode 100644 index 635a89d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/NumericUserIdentifier.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * NumericUserIdentifier - * - * @author Jim Wigginton - */ -abstract class NumericUserIdentifier -{ - const MAP = ['type' => ASN1::TYPE_NUMERIC_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php deleted file mode 100644 index b853abe..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ORAddress.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ORAddress - * - * @author Jim Wigginton - */ -abstract class ORAddress -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'built-in-standard-attributes' => BuiltInStandardAttributes::MAP, - 'built-in-domain-defined-attributes' => ['optional' => true] + BuiltInDomainDefinedAttributes::MAP, - 'extension-attributes' => ['optional' => true] + ExtensionAttributes::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php deleted file mode 100644 index 5953024..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OneAsymmetricKey.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OneAsymmetricKey - * - * @author Jim Wigginton - */ -abstract class OneAsymmetricKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1', 'v2'] - ], - 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, - 'privateKey' => PrivateKey::MAP, - 'attributes' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + Attributes::MAP, - 'publicKey' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + PublicKey::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php deleted file mode 100644 index b5cc949..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationName.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OrganizationName - * - * @author Jim Wigginton - */ -abstract class OrganizationName -{ - const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php deleted file mode 100644 index b3e5780..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OrganizationalUnitNames.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OrganizationalUnitNames - * - * @author Jim Wigginton - */ -abstract class OrganizationalUnitNames -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => 4, // ub-organizational-units - 'children' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php deleted file mode 100644 index 5d56560..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfo.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OtherPrimeInfo - * - * @author Jim Wigginton - */ -abstract class OtherPrimeInfo -{ - // version must be multi if otherPrimeInfos present - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'prime' => ['type' => ASN1::TYPE_INTEGER], // ri - 'exponent' => ['type' => ASN1::TYPE_INTEGER], // di - 'coefficient' => ['type' => ASN1::TYPE_INTEGER] // ti - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php deleted file mode 100644 index 9802a80..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/OtherPrimeInfos.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * OtherPrimeInfos - * - * @author Jim Wigginton - */ -abstract class OtherPrimeInfos -{ - // version must be multi if otherPrimeInfos present - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => OtherPrimeInfo::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php deleted file mode 100644 index 8eb27cf..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBEParameter.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBEParameter - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @author Jim Wigginton - */ -abstract class PBEParameter -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], - 'iterationCount' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php deleted file mode 100644 index bd31699..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBES2params.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBES2params - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @author Jim Wigginton - */ -abstract class PBES2params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'keyDerivationFunc' => AlgorithmIdentifier::MAP, - 'encryptionScheme' => AlgorithmIdentifier::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php deleted file mode 100644 index 2dafed9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBKDF2params.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBKDF2params - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @author Jim Wigginton - */ -abstract class PBKDF2params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - // technically, this is a CHOICE in RFC2898 but the other "choice" is, currently, more of a placeholder - // in the RFC - 'salt' => ['type' => ASN1::TYPE_OCTET_STRING], - 'iterationCount' => ['type' => ASN1::TYPE_INTEGER], - 'keyLength' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ], - 'prf' => AlgorithmIdentifier::MAP + ['optional' => true] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php deleted file mode 100644 index 91319f5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PBMAC1params.php +++ /dev/null @@ -1,34 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PBMAC1params - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @author Jim Wigginton - */ -abstract class PBMAC1params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'keyDerivationFunc' => AlgorithmIdentifier::MAP, - 'messageAuthScheme' => AlgorithmIdentifier::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php deleted file mode 100644 index 87d0862..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PKCS9String.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PKCS9String - * - * @author Jim Wigginton - */ -abstract class PKCS9String -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'ia5String' => ['type' => ASN1::TYPE_IA5_STRING], - 'directoryString' => DirectoryString::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php deleted file mode 100644 index b8c8c02..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Pentanomial.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Pentanomial - * - * @author Jim Wigginton - */ -abstract class Pentanomial -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'k1' => ['type' => ASN1::TYPE_INTEGER], // k1 > 0 - 'k2' => ['type' => ASN1::TYPE_INTEGER], // k2 > k1 - 'k3' => ['type' => ASN1::TYPE_INTEGER], // k3 > h2 - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php deleted file mode 100644 index 14e2860..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PersonalName.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PersonalName - * - * @author Jim Wigginton - */ -abstract class PersonalName -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'children' => [ - 'surname' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ], - 'given-name' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ], - 'initials' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ], - 'generation-qualifier' => [ - 'type' => ASN1::TYPE_PRINTABLE_STRING, - 'constant' => 3, - 'optional' => true, - 'implicit' => true - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php deleted file mode 100644 index 1625d19..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyInformation.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyInformation - * - * @author Jim Wigginton - */ -abstract class PolicyInformation -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'policyIdentifier' => CertPolicyId::MAP, - 'policyQualifiers' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 0, - 'max' => -1, - 'optional' => true, - 'children' => PolicyQualifierInfo::MAP - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php deleted file mode 100644 index d30b852..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyMappings.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyMappings - * - * @author Jim Wigginton - */ -abstract class PolicyMappings -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'issuerDomainPolicy' => CertPolicyId::MAP, - 'subjectDomainPolicy' => CertPolicyId::MAP - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php deleted file mode 100644 index 7b7cd6a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierId.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyQualifierId - * - * @author Jim Wigginton - */ -abstract class PolicyQualifierId -{ - const MAP = ['type' => ASN1::TYPE_OBJECT_IDENTIFIER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php deleted file mode 100644 index d227702..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PolicyQualifierInfo.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PolicyQualifierInfo - * - * @author Jim Wigginton - */ -abstract class PolicyQualifierInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'policyQualifierId' => PolicyQualifierId::MAP, - 'qualifier' => ['type' => ASN1::TYPE_ANY] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php deleted file mode 100644 index 142b309..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PostalAddress.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PostalAddress - * - * @author Jim Wigginton - */ -abstract class PostalAddress -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'optional' => true, - 'min' => 1, - 'max' => -1, - 'children' => DirectoryString::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php deleted file mode 100644 index 7743034..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Prime_p.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Prime_p - * - * @author Jim Wigginton - */ -abstract class Prime_p -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php deleted file mode 100644 index 195dcaa..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateDomainName.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateDomainName - * - * @author Jim Wigginton - */ -abstract class PrivateDomainName -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'numeric' => ['type' => ASN1::TYPE_NUMERIC_STRING], - 'printable' => ['type' => ASN1::TYPE_PRINTABLE_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php deleted file mode 100644 index 3c89594..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKey.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateKey - * - * @author Jim Wigginton - */ -abstract class PrivateKey -{ - const MAP = ['type' => ASN1::TYPE_OCTET_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php deleted file mode 100644 index b440b78..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyInfo.php +++ /dev/null @@ -1,41 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateKeyInfo - * - * @author Jim Wigginton - */ -abstract class PrivateKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1'] - ], - 'privateKeyAlgorithm' => AlgorithmIdentifier::MAP, - 'privateKey' => PrivateKey::MAP, - 'attributes' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true - ] + Attributes::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php deleted file mode 100644 index 5b87036..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PrivateKeyUsagePeriod.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PrivateKeyUsagePeriod - * - * @author Jim Wigginton - */ -abstract class PrivateKeyUsagePeriod -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'notBefore' => [ - 'constant' => 0, - 'optional' => true, - 'implicit' => true, - 'type' => ASN1::TYPE_GENERALIZED_TIME], - 'notAfter' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true, - 'type' => ASN1::TYPE_GENERALIZED_TIME] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php deleted file mode 100644 index 4840920..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKey.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PublicKey - * - * @author Jim Wigginton - */ -abstract class PublicKey -{ - const MAP = ['type' => ASN1::TYPE_BIT_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php deleted file mode 100644 index 432581e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyAndChallenge.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PublicKeyAndChallenge - * - * @author Jim Wigginton - */ -abstract class PublicKeyAndChallenge -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'spki' => SubjectPublicKeyInfo::MAP, - 'challenge' => ['type' => ASN1::TYPE_IA5_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php deleted file mode 100644 index b39a341..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/PublicKeyInfo.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * PublicKeyInfo - * - * this format is not formally defined anywhere but is none-the-less the form you - * get when you do "openssl rsa -in private.pem -outform PEM -pubout" - * - * @author Jim Wigginton - */ -abstract class PublicKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'publicKeyAlgorithm' => AlgorithmIdentifier::MAP, - 'publicKey' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php deleted file mode 100644 index 48649ab..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RC2CBCParameter.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RC2CBCParameter - * - * from https://tools.ietf.org/html/rfc2898#appendix-A.3 - * - * @author Jim Wigginton - */ -abstract class RC2CBCParameter -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'rc2ParametersVersion' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ], - 'iv' => ['type' => ASN1::TYPE_OCTET_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php deleted file mode 100644 index 04b071c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RDNSequence.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RDNSequence - * - * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, - * but they can be useful at times when either there is no unique attribute in the entry or you - * want to ensure that the entry's DN contains some useful identifying information. - * - * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName - * - * @author Jim Wigginton - */ -abstract class RDNSequence -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - // RDNSequence does not define a min or a max, which means it doesn't have one - 'min' => 0, - 'max' => -1, - 'children' => RelativeDistinguishedName::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php deleted file mode 100644 index 8c19c65..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPrivateKey.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RSAPrivateKey - * - * @author Jim Wigginton - */ -abstract class RSAPrivateKey -{ - // version must be multi if otherPrimeInfos present - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['two-prime', 'multi'] - ], - 'modulus' => ['type' => ASN1::TYPE_INTEGER], // n - 'publicExponent' => ['type' => ASN1::TYPE_INTEGER], // e - 'privateExponent' => ['type' => ASN1::TYPE_INTEGER], // d - 'prime1' => ['type' => ASN1::TYPE_INTEGER], // p - 'prime2' => ['type' => ASN1::TYPE_INTEGER], // q - 'exponent1' => ['type' => ASN1::TYPE_INTEGER], // d mod (p-1) - 'exponent2' => ['type' => ASN1::TYPE_INTEGER], // d mod (q-1) - 'coefficient' => ['type' => ASN1::TYPE_INTEGER], // (inverse of q) mod p - 'otherPrimeInfos' => OtherPrimeInfos::MAP + ['optional' => true] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php deleted file mode 100644 index b14c32c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSAPublicKey.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RSAPublicKey - * - * @author Jim Wigginton - */ -abstract class RSAPublicKey -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'modulus' => ['type' => ASN1::TYPE_INTEGER], - 'publicExponent' => ['type' => ASN1::TYPE_INTEGER] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php deleted file mode 100644 index 1a784bf..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RSASSA_PSS_params.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RSASSA_PSS_params - * - * @author Jim Wigginton - */ -abstract class RSASSA_PSS_params -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'hashAlgorithm' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true, - //'default' => 'sha1Identifier' - ] + HashAlgorithm::MAP, - 'maskGenAlgorithm' => [ - 'constant' => 1, - 'optional' => true, - 'explicit' => true, - //'default' => 'mgf1SHA1Identifier' - ] + MaskGenAlgorithm::MAP, - 'saltLength' => [ - 'type' => ASN1::TYPE_INTEGER, - 'constant' => 2, - 'optional' => true, - 'explicit' => true, - 'default' => 20 - ], - 'trailerField' => [ - 'type' => ASN1::TYPE_INTEGER, - 'constant' => 3, - 'optional' => true, - 'explicit' => true, - 'default' => 1 - ] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php deleted file mode 100644 index 2e62fcd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/ReasonFlags.php +++ /dev/null @@ -1,39 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * ReasonFlags - * - * @author Jim Wigginton - */ -abstract class ReasonFlags -{ - const MAP = [ - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => [ - 'unused', - 'keyCompromise', - 'cACompromise', - 'affiliationChanged', - 'superseded', - 'cessationOfOperation', - 'certificateHold', - 'privilegeWithdrawn', - 'aACompromise' - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php deleted file mode 100644 index a0421f7..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RelativeDistinguishedName.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RelativeDistinguishedName - * - * In practice, RDNs containing multiple name-value pairs (called "multivalued RDNs") are rare, - * but they can be useful at times when either there is no unique attribute in the entry or you - * want to ensure that the entry's DN contains some useful identifying information. - * - * - https://www.opends.org/wiki/page/DefinitionRelativeDistinguishedName - * - * @author Jim Wigginton - */ -abstract class RelativeDistinguishedName -{ - const MAP = [ - 'type' => ASN1::TYPE_SET, - 'min' => 1, - 'max' => -1, - 'children' => AttributeTypeAndValue::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php deleted file mode 100644 index ff759eb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/RevokedCertificate.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * RevokedCertificate - * - * @author Jim Wigginton - */ -abstract class RevokedCertificate -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'userCertificate' => CertificateSerialNumber::MAP, - 'revocationDate' => Time::MAP, - 'crlEntryExtensions' => [ - 'optional' => true - ] + Extensions::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php deleted file mode 100644 index 0f482a2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SignedPublicKeyAndChallenge.php +++ /dev/null @@ -1,33 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SignedPublicKeyAndChallenge - * - * @author Jim Wigginton - */ -abstract class SignedPublicKeyAndChallenge -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'publicKeyAndChallenge' => PublicKeyAndChallenge::MAP, - 'signatureAlgorithm' => AlgorithmIdentifier::MAP, - 'signature' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php deleted file mode 100644 index 7408a56..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SpecifiedECDomain.php +++ /dev/null @@ -1,45 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SpecifiedECDomain - * - * @author Jim Wigginton - */ -abstract class SpecifiedECDomain -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => [1 => 'ecdpVer1', 'ecdpVer2', 'ecdpVer3'] - ], - 'fieldID' => FieldID::MAP, - 'curve' => Curve::MAP, - 'base' => ECPoint::MAP, - 'order' => ['type' => ASN1::TYPE_INTEGER], - 'cofactor' => [ - 'type' => ASN1::TYPE_INTEGER, - 'optional' => true - ], - 'hash' => ['optional' => true] + HashAlgorithm::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php deleted file mode 100644 index 39138a9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectAltName.php +++ /dev/null @@ -1,24 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -/** - * SubjectAltName - * - * @author Jim Wigginton - */ -abstract class SubjectAltName -{ - const MAP = GeneralNames::MAP; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php deleted file mode 100644 index f2e206f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectDirectoryAttributes.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectDirectoryAttributes - * - * @author Jim Wigginton - */ -abstract class SubjectDirectoryAttributes -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => Attribute::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php deleted file mode 100644 index 1ff241f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectInfoAccessSyntax.php +++ /dev/null @@ -1,31 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectInfoAccessSyntax - * - * @author Jim Wigginton - */ -abstract class SubjectInfoAccessSyntax -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'min' => 1, - 'max' => -1, - 'children' => AccessDescription::MAP - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php deleted file mode 100644 index 0d53d54..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/SubjectPublicKeyInfo.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * SubjectPublicKeyInfo - * - * @author Jim Wigginton - */ -abstract class SubjectPublicKeyInfo -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'algorithm' => AlgorithmIdentifier::MAP, - 'subjectPublicKey' => ['type' => ASN1::TYPE_BIT_STRING] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php deleted file mode 100644 index 49b3cfc..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertList.php +++ /dev/null @@ -1,54 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * TBSCertList - * - * @author Jim Wigginton - */ -abstract class TBSCertList -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'mapping' => ['v1', 'v2', 'v3'], - 'optional' => true, - 'default' => 'v2' - ], - 'signature' => AlgorithmIdentifier::MAP, - 'issuer' => Name::MAP, - 'thisUpdate' => Time::MAP, - 'nextUpdate' => [ - 'optional' => true - ] + Time::MAP, - 'revokedCertificates' => [ - 'type' => ASN1::TYPE_SEQUENCE, - 'optional' => true, - 'min' => 0, - 'max' => -1, - 'children' => RevokedCertificate::MAP - ], - 'crlExtensions' => [ - 'constant' => 0, - 'optional' => true, - 'explicit' => true - ] + Extensions::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php deleted file mode 100644 index 007360c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TBSCertificate.php +++ /dev/null @@ -1,65 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * TBSCertificate - * - * @author Jim Wigginton - */ -abstract class TBSCertificate -{ - // assert($TBSCertificate['children']['signature'] == $Certificate['children']['signatureAlgorithm']) - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - // technically, default implies optional, but we'll define it as being optional, none-the-less, just to - // reenforce that fact - 'version' => [ - 'type' => ASN1::TYPE_INTEGER, - 'constant' => 0, - 'optional' => true, - 'explicit' => true, - 'mapping' => ['v1', 'v2', 'v3'], - 'default' => 'v1' - ], - 'serialNumber' => CertificateSerialNumber::MAP, - 'signature' => AlgorithmIdentifier::MAP, - 'issuer' => Name::MAP, - 'validity' => Validity::MAP, - 'subject' => Name::MAP, - 'subjectPublicKeyInfo' => SubjectPublicKeyInfo::MAP, - // implicit means that the T in the TLV structure is to be rewritten, regardless of the type - 'issuerUniqueID' => [ - 'constant' => 1, - 'optional' => true, - 'implicit' => true - ] + UniqueIdentifier::MAP, - 'subjectUniqueID' => [ - 'constant' => 2, - 'optional' => true, - 'implicit' => true - ] + UniqueIdentifier::MAP, - // doesn't use the EXPLICIT keyword but if - // it's not IMPLICIT, it's EXPLICIT - 'extensions' => [ - 'constant' => 3, - 'optional' => true, - 'explicit' => true - ] + Extensions::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php deleted file mode 100644 index 7f6d9d2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/TerminalIdentifier.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * TerminalIdentifier - * - * @author Jim Wigginton - */ -abstract class TerminalIdentifier -{ - const MAP = ['type' => ASN1::TYPE_PRINTABLE_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php deleted file mode 100644 index 744ee70..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Time.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Time - * - * @author Jim Wigginton - */ -abstract class Time -{ - const MAP = [ - 'type' => ASN1::TYPE_CHOICE, - 'children' => [ - 'utcTime' => ['type' => ASN1::TYPE_UTC_TIME], - 'generalTime' => ['type' => ASN1::TYPE_GENERALIZED_TIME] - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php deleted file mode 100644 index 33baa91..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Trinomial.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Trinomial - * - * @author Jim Wigginton - */ -abstract class Trinomial -{ - const MAP = ['type' => ASN1::TYPE_INTEGER]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php deleted file mode 100644 index f4c954b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UniqueIdentifier.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * UniqueIdentifier - * - * @author Jim Wigginton - */ -abstract class UniqueIdentifier -{ - const MAP = ['type' => ASN1::TYPE_BIT_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php deleted file mode 100644 index 98d527b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/UserNotice.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * UserNotice - * - * @author Jim Wigginton - */ -abstract class UserNotice -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'noticeRef' => [ - 'optional' => true, - 'implicit' => true - ] + NoticeReference::MAP, - 'explicitText' => [ - 'optional' => true, - 'implicit' => true - ] + DisplayText::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php deleted file mode 100644 index 8ef64cf..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/Validity.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * Validity - * - * @author Jim Wigginton - */ -abstract class Validity -{ - const MAP = [ - 'type' => ASN1::TYPE_SEQUENCE, - 'children' => [ - 'notBefore' => Time::MAP, - 'notAfter' => Time::MAP - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php deleted file mode 100644 index 2ab1572..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_ca_policy_url.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * netscape_ca_policy_url - * - * @author Jim Wigginton - */ -abstract class netscape_ca_policy_url -{ - const MAP = ['type' => ASN1::TYPE_IA5_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php deleted file mode 100644 index 49e8da4..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_cert_type.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * netscape_cert_type - * - * mapping is from - * - * @author Jim Wigginton - */ -abstract class netscape_cert_type -{ - const MAP = [ - 'type' => ASN1::TYPE_BIT_STRING, - 'mapping' => [ - 'SSLClient', - 'SSLServer', - 'Email', - 'ObjectSigning', - 'Reserved', - 'SSLCA', - 'EmailCA', - 'ObjectSigningCA' - ] - ]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php deleted file mode 100644 index d3ff4dd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/ASN1/Maps/netscape_comment.php +++ /dev/null @@ -1,26 +0,0 @@ - - * @copyright 2016 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File\ASN1\Maps; - -use phpseclib3\File\ASN1; - -/** - * netscape_comment - * - * @author Jim Wigginton - */ -abstract class netscape_comment -{ - const MAP = ['type' => ASN1::TYPE_IA5_STRING]; -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php deleted file mode 100644 index 5e2f073..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/File/X509.php +++ /dev/null @@ -1,4006 +0,0 @@ - - * @copyright 2012 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\File; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Crypt\Common\PublicKey; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\PublicKeyLoader; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\RSA\Formats\Keys\PSS; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\File\ASN1\Element; -use phpseclib3\File\ASN1\Maps; -use phpseclib3\Math\BigInteger; - -/** - * Pure-PHP X.509 Parser - * - * @author Jim Wigginton - */ -class X509 -{ - /** - * Flag to only accept signatures signed by certificate authorities - * - * Not really used anymore but retained all the same to suppress E_NOTICEs from old installs - * - */ - const VALIDATE_SIGNATURE_BY_CA = 1; - - /** - * Return internal array representation - * - * @see \phpseclib3\File\X509::getDN() - */ - const DN_ARRAY = 0; - /** - * Return string - * - * @see \phpseclib3\File\X509::getDN() - */ - const DN_STRING = 1; - /** - * Return ASN.1 name string - * - * @see \phpseclib3\File\X509::getDN() - */ - const DN_ASN1 = 2; - /** - * Return OpenSSL compatible array - * - * @see \phpseclib3\File\X509::getDN() - */ - const DN_OPENSSL = 3; - /** - * Return canonical ASN.1 RDNs string - * - * @see \phpseclib3\File\X509::getDN() - */ - const DN_CANON = 4; - /** - * Return name hash for file indexing - * - * @see \phpseclib3\File\X509::getDN() - */ - const DN_HASH = 5; - - /** - * Save as PEM - * - * ie. a base64-encoded PEM with a header and a footer - * - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() - */ - const FORMAT_PEM = 0; - /** - * Save as DER - * - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() - */ - const FORMAT_DER = 1; - /** - * Save as a SPKAC - * - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() - * - * Only works on CSRs. Not currently supported. - */ - const FORMAT_SPKAC = 2; - /** - * Auto-detect the format - * - * Used only by the load*() functions - * - * @see \phpseclib3\File\X509::saveX509() - * @see \phpseclib3\File\X509::saveCSR() - * @see \phpseclib3\File\X509::saveCRL() - */ - const FORMAT_AUTO_DETECT = 3; - - /** - * Attribute value disposition. - * If disposition is >= 0, this is the index of the target value. - */ - const ATTR_ALL = -1; // All attribute values (array). - const ATTR_APPEND = -2; // Add a value. - const ATTR_REPLACE = -3; // Clear first, then add a value. - - /** - * Distinguished Name - * - * @var array - */ - private $dn; - - /** - * Public key - * - * @var string|PublicKey - */ - private $publicKey; - - /** - * Private key - * - * @var string|PrivateKey - */ - private $privateKey; - - /** - * The certificate authorities - * - * @var array - */ - private $CAs = []; - - /** - * The currently loaded certificate - * - * @var array - */ - private $currentCert; - - /** - * The signature subject - * - * There's no guarantee \phpseclib3\File\X509 is going to re-encode an X.509 cert in the same way it was originally - * encoded so we take save the portion of the original cert that the signature would have made for. - * - * @var string - */ - private $signatureSubject; - - /** - * Certificate Start Date - * - * @var string - */ - private $startDate; - - /** - * Certificate End Date - * - * @var string|Element - */ - private $endDate; - - /** - * Serial Number - * - * @var string - */ - private $serialNumber; - - /** - * Key Identifier - * - * See {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.1 RFC5280#section-4.2.1.1} and - * {@link http://tools.ietf.org/html/rfc5280#section-4.2.1.2 RFC5280#section-4.2.1.2}. - * - * @var string - */ - private $currentKeyIdentifier; - - /** - * CA Flag - * - * @var bool - */ - private $caFlag = false; - - /** - * SPKAC Challenge - * - * @var string - */ - private $challenge; - - /** - * @var array - */ - private $extensionValues = []; - - /** - * OIDs loaded - * - * @var bool - */ - private static $oidsLoaded = false; - - /** - * Recursion Limit - * - * @var int - */ - private static $recur_limit = 5; - - /** - * URL fetch flag - * - * @var bool - */ - private static $disable_url_fetch = false; - - /** - * @var array - */ - private static $extensions = []; - - /** - * @var ?array - */ - private $ipAddresses = null; - - /** - * @var ?array - */ - private $domains = null; - - /** - * Default Constructor. - * - * @return \phpseclib3\File\X509 - */ - public function __construct() - { - // Explicitly Tagged Module, 1988 Syntax - // http://tools.ietf.org/html/rfc5280#appendix-A.1 - - if (!self::$oidsLoaded) { - // OIDs from RFC5280 and those RFCs mentioned in RFC5280#section-4.1.1.2 - ASN1::loadOIDs([ - //'id-pkix' => '1.3.6.1.5.5.7', - //'id-pe' => '1.3.6.1.5.5.7.1', - //'id-qt' => '1.3.6.1.5.5.7.2', - //'id-kp' => '1.3.6.1.5.5.7.3', - //'id-ad' => '1.3.6.1.5.5.7.48', - 'id-qt-cps' => '1.3.6.1.5.5.7.2.1', - 'id-qt-unotice' => '1.3.6.1.5.5.7.2.2', - 'id-ad-ocsp' => '1.3.6.1.5.5.7.48.1', - 'id-ad-caIssuers' => '1.3.6.1.5.5.7.48.2', - 'id-ad-timeStamping' => '1.3.6.1.5.5.7.48.3', - 'id-ad-caRepository' => '1.3.6.1.5.5.7.48.5', - //'id-at' => '2.5.4', - 'id-at-name' => '2.5.4.41', - 'id-at-surname' => '2.5.4.4', - 'id-at-givenName' => '2.5.4.42', - 'id-at-initials' => '2.5.4.43', - 'id-at-generationQualifier' => '2.5.4.44', - 'id-at-commonName' => '2.5.4.3', - 'id-at-localityName' => '2.5.4.7', - 'id-at-stateOrProvinceName' => '2.5.4.8', - 'id-at-organizationName' => '2.5.4.10', - 'id-at-organizationalUnitName' => '2.5.4.11', - 'id-at-title' => '2.5.4.12', - 'id-at-description' => '2.5.4.13', - 'id-at-dnQualifier' => '2.5.4.46', - 'id-at-countryName' => '2.5.4.6', - 'id-at-serialNumber' => '2.5.4.5', - 'id-at-pseudonym' => '2.5.4.65', - 'id-at-postalCode' => '2.5.4.17', - 'id-at-streetAddress' => '2.5.4.9', - 'id-at-uniqueIdentifier' => '2.5.4.45', - 'id-at-role' => '2.5.4.72', - 'id-at-postalAddress' => '2.5.4.16', - 'jurisdictionOfIncorporationCountryName' => '1.3.6.1.4.1.311.60.2.1.3', - 'jurisdictionOfIncorporationStateOrProvinceName' => '1.3.6.1.4.1.311.60.2.1.2', - 'jurisdictionLocalityName' => '1.3.6.1.4.1.311.60.2.1.1', - 'id-at-businessCategory' => '2.5.4.15', - - //'id-domainComponent' => '0.9.2342.19200300.100.1.25', - //'pkcs-9' => '1.2.840.113549.1.9', - 'pkcs-9-at-emailAddress' => '1.2.840.113549.1.9.1', - //'id-ce' => '2.5.29', - 'id-ce-authorityKeyIdentifier' => '2.5.29.35', - 'id-ce-subjectKeyIdentifier' => '2.5.29.14', - 'id-ce-keyUsage' => '2.5.29.15', - 'id-ce-privateKeyUsagePeriod' => '2.5.29.16', - 'id-ce-certificatePolicies' => '2.5.29.32', - //'anyPolicy' => '2.5.29.32.0', - - 'id-ce-policyMappings' => '2.5.29.33', - - 'id-ce-subjectAltName' => '2.5.29.17', - 'id-ce-issuerAltName' => '2.5.29.18', - 'id-ce-subjectDirectoryAttributes' => '2.5.29.9', - 'id-ce-basicConstraints' => '2.5.29.19', - 'id-ce-nameConstraints' => '2.5.29.30', - 'id-ce-policyConstraints' => '2.5.29.36', - 'id-ce-cRLDistributionPoints' => '2.5.29.31', - 'id-ce-extKeyUsage' => '2.5.29.37', - //'anyExtendedKeyUsage' => '2.5.29.37.0', - 'id-kp-serverAuth' => '1.3.6.1.5.5.7.3.1', - 'id-kp-clientAuth' => '1.3.6.1.5.5.7.3.2', - 'id-kp-codeSigning' => '1.3.6.1.5.5.7.3.3', - 'id-kp-emailProtection' => '1.3.6.1.5.5.7.3.4', - 'id-kp-timeStamping' => '1.3.6.1.5.5.7.3.8', - 'id-kp-OCSPSigning' => '1.3.6.1.5.5.7.3.9', - 'id-ce-inhibitAnyPolicy' => '2.5.29.54', - 'id-ce-freshestCRL' => '2.5.29.46', - 'id-pe-authorityInfoAccess' => '1.3.6.1.5.5.7.1.1', - 'id-pe-subjectInfoAccess' => '1.3.6.1.5.5.7.1.11', - 'id-ce-cRLNumber' => '2.5.29.20', - 'id-ce-issuingDistributionPoint' => '2.5.29.28', - 'id-ce-deltaCRLIndicator' => '2.5.29.27', - 'id-ce-cRLReasons' => '2.5.29.21', - 'id-ce-certificateIssuer' => '2.5.29.29', - 'id-ce-holdInstructionCode' => '2.5.29.23', - //'holdInstruction' => '1.2.840.10040.2', - 'id-holdinstruction-none' => '1.2.840.10040.2.1', - 'id-holdinstruction-callissuer' => '1.2.840.10040.2.2', - 'id-holdinstruction-reject' => '1.2.840.10040.2.3', - 'id-ce-invalidityDate' => '2.5.29.24', - - 'rsaEncryption' => '1.2.840.113549.1.1.1', - 'md2WithRSAEncryption' => '1.2.840.113549.1.1.2', - 'md5WithRSAEncryption' => '1.2.840.113549.1.1.4', - 'sha1WithRSAEncryption' => '1.2.840.113549.1.1.5', - 'sha224WithRSAEncryption' => '1.2.840.113549.1.1.14', - 'sha256WithRSAEncryption' => '1.2.840.113549.1.1.11', - 'sha384WithRSAEncryption' => '1.2.840.113549.1.1.12', - 'sha512WithRSAEncryption' => '1.2.840.113549.1.1.13', - - 'id-ecPublicKey' => '1.2.840.10045.2.1', - 'ecdsa-with-SHA1' => '1.2.840.10045.4.1', - // from https://tools.ietf.org/html/rfc5758#section-3.2 - 'ecdsa-with-SHA224' => '1.2.840.10045.4.3.1', - 'ecdsa-with-SHA256' => '1.2.840.10045.4.3.2', - 'ecdsa-with-SHA384' => '1.2.840.10045.4.3.3', - 'ecdsa-with-SHA512' => '1.2.840.10045.4.3.4', - - 'id-dsa' => '1.2.840.10040.4.1', - 'id-dsa-with-sha1' => '1.2.840.10040.4.3', - // from https://tools.ietf.org/html/rfc5758#section-3.1 - 'id-dsa-with-sha224' => '2.16.840.1.101.3.4.3.1', - 'id-dsa-with-sha256' => '2.16.840.1.101.3.4.3.2', - - // from https://tools.ietf.org/html/rfc8410: - 'id-Ed25519' => '1.3.101.112', - 'id-Ed448' => '1.3.101.113', - - 'id-RSASSA-PSS' => '1.2.840.113549.1.1.10', - - //'id-sha224' => '2.16.840.1.101.3.4.2.4', - //'id-sha256' => '2.16.840.1.101.3.4.2.1', - //'id-sha384' => '2.16.840.1.101.3.4.2.2', - //'id-sha512' => '2.16.840.1.101.3.4.2.3', - //'id-GostR3411-94-with-GostR3410-94' => '1.2.643.2.2.4', - //'id-GostR3411-94-with-GostR3410-2001' => '1.2.643.2.2.3', - //'id-GostR3410-2001' => '1.2.643.2.2.20', - //'id-GostR3410-94' => '1.2.643.2.2.19', - // Netscape Object Identifiers from "Netscape Certificate Extensions" - 'netscape' => '2.16.840.1.113730', - 'netscape-cert-extension' => '2.16.840.1.113730.1', - 'netscape-cert-type' => '2.16.840.1.113730.1.1', - 'netscape-comment' => '2.16.840.1.113730.1.13', - 'netscape-ca-policy-url' => '2.16.840.1.113730.1.8', - // the following are X.509 extensions not supported by phpseclib - 'id-pe-logotype' => '1.3.6.1.5.5.7.1.12', - 'entrustVersInfo' => '1.2.840.113533.7.65.0', - 'verisignPrivate' => '2.16.840.1.113733.1.6.9', - // for Certificate Signing Requests - // see http://tools.ietf.org/html/rfc2985 - 'pkcs-9-at-unstructuredName' => '1.2.840.113549.1.9.2', // PKCS #9 unstructured name - 'pkcs-9-at-challengePassword' => '1.2.840.113549.1.9.7', // Challenge password for certificate revocations - 'pkcs-9-at-extensionRequest' => '1.2.840.113549.1.9.14' // Certificate extension request - ]); - } - } - - /** - * Load X.509 certificate - * - * Returns an associative array describing the X.509 cert or a false if the cert failed to load - * - * @param array|string $cert - * @param int $mode - * @return mixed - */ - public function loadX509($cert, $mode = self::FORMAT_AUTO_DETECT) - { - if (is_array($cert) && isset($cert['tbsCertificate'])) { - unset($this->currentCert); - unset($this->currentKeyIdentifier); - $this->dn = $cert['tbsCertificate']['subject']; - if (!isset($this->dn)) { - return false; - } - $this->currentCert = $cert; - - $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); - $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; - - unset($this->signatureSubject); - - return $cert; - } - - if ($mode != self::FORMAT_DER) { - $newcert = ASN1::extractBER($cert); - if ($mode == self::FORMAT_PEM && $cert == $newcert) { - return false; - } - $cert = $newcert; - } - - if ($cert === false) { - $this->currentCert = false; - return false; - } - - $decoded = ASN1::decodeBER($cert); - - if ($decoded) { - $x509 = ASN1::asn1map($decoded[0], Maps\Certificate::MAP); - } - if (!isset($x509) || $x509 === false) { - $this->currentCert = false; - return false; - } - - $this->signatureSubject = substr($cert, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - - if ($this->isSubArrayValid($x509, 'tbsCertificate/extensions')) { - $this->mapInExtensions($x509, 'tbsCertificate/extensions'); - } - $this->mapInDNs($x509, 'tbsCertificate/issuer/rdnSequence'); - $this->mapInDNs($x509, 'tbsCertificate/subject/rdnSequence'); - - $key = $x509['tbsCertificate']['subjectPublicKeyInfo']; - $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); - $x509['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'] = - "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; - - $this->currentCert = $x509; - $this->dn = $x509['tbsCertificate']['subject']; - - $currentKeyIdentifier = $this->getExtension('id-ce-subjectKeyIdentifier'); - $this->currentKeyIdentifier = is_string($currentKeyIdentifier) ? $currentKeyIdentifier : null; - - return $x509; - } - - /** - * Save X.509 certificate - * - * @param array $cert - * @param int $format optional - * @return string - */ - public function saveX509(array $cert, $format = self::FORMAT_PEM) - { - if (!is_array($cert) || !isset($cert['tbsCertificate'])) { - return false; - } - - switch (true) { - // "case !$a: case !$b: break; default: whatever();" is the same thing as "if ($a && $b) whatever()" - case !($algorithm = $this->subArray($cert, 'tbsCertificate/subjectPublicKeyInfo/algorithm/algorithm')): - case is_object($cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): - break; - default: - $cert['tbsCertificate']['subjectPublicKeyInfo'] = new Element( - base64_decode(preg_replace('#-.+-|[\r\n]#', '', $cert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'])) - ); - } - - if ($algorithm == 'rsaEncryption') { - $cert['signatureAlgorithm']['parameters'] = null; - $cert['tbsCertificate']['signature']['parameters'] = null; - } - - $filters = []; - $type_utf8_string = ['type' => ASN1::TYPE_UTF8_STRING]; - $filters['tbsCertificate']['signature']['parameters'] = $type_utf8_string; - $filters['tbsCertificate']['signature']['issuer']['rdnSequence']['value'] = $type_utf8_string; - $filters['tbsCertificate']['issuer']['rdnSequence']['value'] = $type_utf8_string; - $filters['tbsCertificate']['subject']['rdnSequence']['value'] = $type_utf8_string; - $filters['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['parameters'] = $type_utf8_string; - $filters['signatureAlgorithm']['parameters'] = $type_utf8_string; - $filters['authorityCertIssuer']['directoryName']['rdnSequence']['value'] = $type_utf8_string; - //$filters['policyQualifiers']['qualifier'] = $type_utf8_string; - $filters['distributionPoint']['fullName']['directoryName']['rdnSequence']['value'] = $type_utf8_string; - $filters['directoryName']['rdnSequence']['value'] = $type_utf8_string; - - foreach (self::$extensions as $extension) { - $filters['tbsCertificate']['extensions'][] = $extension; - } - - /* in the case of policyQualifiers/qualifier, the type has to be \phpseclib3\File\ASN1::TYPE_IA5_STRING. - \phpseclib3\File\ASN1::TYPE_PRINTABLE_STRING will cause OpenSSL's X.509 parser to spit out random - characters. - */ - $filters['policyQualifiers']['qualifier'] - = ['type' => ASN1::TYPE_IA5_STRING]; - - ASN1::setFilters($filters); - - $this->mapOutExtensions($cert, 'tbsCertificate/extensions'); - $this->mapOutDNs($cert, 'tbsCertificate/issuer/rdnSequence'); - $this->mapOutDNs($cert, 'tbsCertificate/subject/rdnSequence'); - - $cert = ASN1::encodeDER($cert, Maps\Certificate::MAP); - - switch ($format) { - case self::FORMAT_DER: - return $cert; - // case self::FORMAT_PEM: - default: - return "-----BEGIN CERTIFICATE-----\r\n" . chunk_split(Strings::base64_encode($cert), 64) . '-----END CERTIFICATE-----'; - } - } - - /** - * Map extension values from octet string to extension-specific internal - * format. - * - * @param array $root (by reference) - * @param string $path - */ - private function mapInExtensions(array &$root, $path) - { - $extensions = &$this->subArrayUnchecked($root, $path); - - if ($extensions) { - for ($i = 0; $i < count($extensions); $i++) { - $id = $extensions[$i]['extnId']; - $value = &$extensions[$i]['extnValue']; - /* [extnValue] contains the DER encoding of an ASN.1 value - corresponding to the extension type identified by extnID */ - $map = $this->getMapping($id); - if (!is_bool($map)) { - $decoder = $id == 'id-ce-nameConstraints' ? - [static::class, 'decodeNameConstraintIP'] : - [static::class, 'decodeIP']; - $decoded = ASN1::decodeBER($value); - if (!$decoded) { - continue; - } - $mapped = ASN1::asn1map($decoded[0], $map, ['iPAddress' => $decoder]); - $value = $mapped === false ? $decoded[0] : $mapped; - - if ($id == 'id-ce-certificatePolicies') { - for ($j = 0; $j < count($value); $j++) { - if (!isset($value[$j]['policyQualifiers'])) { - continue; - } - for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { - $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; - $map = $this->getMapping($subid); - $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; - if ($map !== false) { - $decoded = ASN1::decodeBER($subvalue); - if (!$decoded) { - continue; - } - $mapped = ASN1::asn1map($decoded[0], $map); - $subvalue = $mapped === false ? $decoded[0] : $mapped; - } - } - } - } - } - } - } - } - - /** - * Map extension values from extension-specific internal format to - * octet string. - * - * @param array $root (by reference) - * @param string $path - */ - private function mapOutExtensions(array &$root, $path) - { - $extensions = &$this->subArray($root, $path, !empty($this->extensionValues)); - - foreach ($this->extensionValues as $id => $data) { - extract($data); - $newext = [ - 'extnId' => $id, - 'extnValue' => $value, - 'critical' => $critical - ]; - if ($replace) { - foreach ($extensions as $key => $value) { - if ($value['extnId'] == $id) { - $extensions[$key] = $newext; - continue 2; - } - } - } - $extensions[] = $newext; - } - - if (is_array($extensions)) { - $size = count($extensions); - for ($i = 0; $i < $size; $i++) { - if ($extensions[$i] instanceof Element) { - continue; - } - - $id = $extensions[$i]['extnId']; - $value = &$extensions[$i]['extnValue']; - - switch ($id) { - case 'id-ce-certificatePolicies': - for ($j = 0; $j < count($value); $j++) { - if (!isset($value[$j]['policyQualifiers'])) { - continue; - } - for ($k = 0; $k < count($value[$j]['policyQualifiers']); $k++) { - $subid = $value[$j]['policyQualifiers'][$k]['policyQualifierId']; - $map = $this->getMapping($subid); - $subvalue = &$value[$j]['policyQualifiers'][$k]['qualifier']; - if ($map !== false) { - // by default \phpseclib3\File\ASN1 will try to render qualifier as a \phpseclib3\File\ASN1::TYPE_IA5_STRING since it's - // actual type is \phpseclib3\File\ASN1::TYPE_ANY - $subvalue = new Element(ASN1::encodeDER($subvalue, $map)); - } - } - } - break; - case 'id-ce-authorityKeyIdentifier': // use 00 as the serial number instead of an empty string - if (isset($value['authorityCertSerialNumber'])) { - if ($value['authorityCertSerialNumber']->toBytes() == '') { - $temp = chr((ASN1::CLASS_CONTEXT_SPECIFIC << 6) | 2) . "\1\0"; - $value['authorityCertSerialNumber'] = new Element($temp); - } - } - } - - /* [extnValue] contains the DER encoding of an ASN.1 value - corresponding to the extension type identified by extnID */ - $map = $this->getMapping($id); - if (is_bool($map)) { - if (!$map) { - //user_error($id . ' is not a currently supported extension'); - unset($extensions[$i]); - } - } else { - $value = ASN1::encodeDER($value, $map, ['iPAddress' => [static::class, 'encodeIP']]); - } - } - } - } - - /** - * Map attribute values from ANY type to attribute-specific internal - * format. - * - * @param array $root (by reference) - * @param string $path - */ - private function mapInAttributes(&$root, $path) - { - $attributes = &$this->subArray($root, $path); - - if (is_array($attributes)) { - for ($i = 0; $i < count($attributes); $i++) { - $id = $attributes[$i]['type']; - /* $value contains the DER encoding of an ASN.1 value - corresponding to the attribute type identified by type */ - $map = $this->getMapping($id); - if (is_array($attributes[$i]['value'])) { - $values = &$attributes[$i]['value']; - for ($j = 0; $j < count($values); $j++) { - $value = ASN1::encodeDER($values[$j], Maps\AttributeValue::MAP); - $decoded = ASN1::decodeBER($value); - if (!is_bool($map)) { - if (!$decoded) { - continue; - } - $mapped = ASN1::asn1map($decoded[0], $map); - if ($mapped !== false) { - $values[$j] = $mapped; - } - if ($id == 'pkcs-9-at-extensionRequest' && $this->isSubArrayValid($values, $j)) { - $this->mapInExtensions($values, $j); - } - } elseif ($map) { - $values[$j] = $value; - } - } - } - } - } - } - - /** - * Map attribute values from attribute-specific internal format to - * ANY type. - * - * @param array $root (by reference) - * @param string $path - */ - private function mapOutAttributes(&$root, $path) - { - $attributes = &$this->subArray($root, $path); - - if (is_array($attributes)) { - $size = count($attributes); - for ($i = 0; $i < $size; $i++) { - /* [value] contains the DER encoding of an ASN.1 value - corresponding to the attribute type identified by type */ - $id = $attributes[$i]['type']; - $map = $this->getMapping($id); - if ($map === false) { - //user_error($id . ' is not a currently supported attribute', E_USER_NOTICE); - unset($attributes[$i]); - } elseif (is_array($attributes[$i]['value'])) { - $values = &$attributes[$i]['value']; - for ($j = 0; $j < count($values); $j++) { - switch ($id) { - case 'pkcs-9-at-extensionRequest': - $this->mapOutExtensions($values, $j); - break; - } - - if (!is_bool($map)) { - $temp = ASN1::encodeDER($values[$j], $map); - $decoded = ASN1::decodeBER($temp); - if (!$decoded) { - continue; - } - $values[$j] = ASN1::asn1map($decoded[0], Maps\AttributeValue::MAP); - } - } - } - } - } - } - - /** - * Map DN values from ANY type to DN-specific internal - * format. - * - * @param array $root (by reference) - * @param string $path - */ - private function mapInDNs(array &$root, $path) - { - $dns = &$this->subArray($root, $path); - - if (is_array($dns)) { - for ($i = 0; $i < count($dns); $i++) { - for ($j = 0; $j < count($dns[$i]); $j++) { - $type = $dns[$i][$j]['type']; - $value = &$dns[$i][$j]['value']; - if (is_object($value) && $value instanceof Element) { - $map = $this->getMapping($type); - if (!is_bool($map)) { - $decoded = ASN1::decodeBER($value); - if (!$decoded) { - continue; - } - $value = ASN1::asn1map($decoded[0], $map); - } - } - } - } - } - } - - /** - * Map DN values from DN-specific internal format to - * ANY type. - * - * @param array $root (by reference) - * @param string $path - */ - private function mapOutDNs(array &$root, $path) - { - $dns = &$this->subArray($root, $path); - - if (is_array($dns)) { - $size = count($dns); - for ($i = 0; $i < $size; $i++) { - for ($j = 0; $j < count($dns[$i]); $j++) { - $type = $dns[$i][$j]['type']; - $value = &$dns[$i][$j]['value']; - if (is_object($value) && $value instanceof Element) { - continue; - } - - $map = $this->getMapping($type); - if (!is_bool($map)) { - $value = new Element(ASN1::encodeDER($value, $map)); - } - } - } - } - } - - /** - * Associate an extension ID to an extension mapping - * - * @param string $extnId - * @return mixed - */ - private function getMapping($extnId) - { - if (!is_string($extnId)) { // eg. if it's a \phpseclib3\File\ASN1\Element object - return true; - } - - if (isset(self::$extensions[$extnId])) { - return self::$extensions[$extnId]; - } - - switch ($extnId) { - case 'id-ce-keyUsage': - return Maps\KeyUsage::MAP; - case 'id-ce-basicConstraints': - return Maps\BasicConstraints::MAP; - case 'id-ce-subjectKeyIdentifier': - return Maps\KeyIdentifier::MAP; - case 'id-ce-cRLDistributionPoints': - return Maps\CRLDistributionPoints::MAP; - case 'id-ce-authorityKeyIdentifier': - return Maps\AuthorityKeyIdentifier::MAP; - case 'id-ce-certificatePolicies': - return Maps\CertificatePolicies::MAP; - case 'id-ce-extKeyUsage': - return Maps\ExtKeyUsageSyntax::MAP; - case 'id-pe-authorityInfoAccess': - return Maps\AuthorityInfoAccessSyntax::MAP; - case 'id-ce-subjectAltName': - return Maps\SubjectAltName::MAP; - case 'id-ce-subjectDirectoryAttributes': - return Maps\SubjectDirectoryAttributes::MAP; - case 'id-ce-privateKeyUsagePeriod': - return Maps\PrivateKeyUsagePeriod::MAP; - case 'id-ce-issuerAltName': - return Maps\IssuerAltName::MAP; - case 'id-ce-policyMappings': - return Maps\PolicyMappings::MAP; - case 'id-ce-nameConstraints': - return Maps\NameConstraints::MAP; - - case 'netscape-cert-type': - return Maps\netscape_cert_type::MAP; - case 'netscape-comment': - return Maps\netscape_comment::MAP; - case 'netscape-ca-policy-url': - return Maps\netscape_ca_policy_url::MAP; - - // since id-qt-cps isn't a constructed type it will have already been decoded as a string by the time it gets - // back around to asn1map() and we don't want it decoded again. - //case 'id-qt-cps': - // return Maps\CPSuri::MAP; - case 'id-qt-unotice': - return Maps\UserNotice::MAP; - - // the following OIDs are unsupported but we don't want them to give notices when calling saveX509(). - case 'id-pe-logotype': // http://www.ietf.org/rfc/rfc3709.txt - case 'entrustVersInfo': - // http://support.microsoft.com/kb/287547 - case '1.3.6.1.4.1.311.20.2': // szOID_ENROLL_CERTTYPE_EXTENSION - case '1.3.6.1.4.1.311.21.1': // szOID_CERTSRV_CA_VERSION - // "SET Secure Electronic Transaction Specification" - // http://www.maithean.com/docs/set_bk3.pdf - case '2.23.42.7.0': // id-set-hashedRootKey - // "Certificate Transparency" - // https://tools.ietf.org/html/rfc6962 - case '1.3.6.1.4.1.11129.2.4.2': - // "Qualified Certificate statements" - // https://tools.ietf.org/html/rfc3739#section-3.2.6 - case '1.3.6.1.5.5.7.1.3': - return true; - - // CSR attributes - case 'pkcs-9-at-unstructuredName': - return Maps\PKCS9String::MAP; - case 'pkcs-9-at-challengePassword': - return Maps\DirectoryString::MAP; - case 'pkcs-9-at-extensionRequest': - return Maps\Extensions::MAP; - - // CRL extensions. - case 'id-ce-cRLNumber': - return Maps\CRLNumber::MAP; - case 'id-ce-deltaCRLIndicator': - return Maps\CRLNumber::MAP; - case 'id-ce-issuingDistributionPoint': - return Maps\IssuingDistributionPoint::MAP; - case 'id-ce-freshestCRL': - return Maps\CRLDistributionPoints::MAP; - case 'id-ce-cRLReasons': - return Maps\CRLReason::MAP; - case 'id-ce-invalidityDate': - return Maps\InvalidityDate::MAP; - case 'id-ce-certificateIssuer': - return Maps\CertificateIssuer::MAP; - case 'id-ce-holdInstructionCode': - return Maps\HoldInstructionCode::MAP; - case 'id-at-postalAddress': - return Maps\PostalAddress::MAP; - } - - return false; - } - - /** - * Load an X.509 certificate as a certificate authority - * - * @param string $cert - * @return bool - */ - public function loadCA($cert) - { - $olddn = $this->dn; - $oldcert = $this->currentCert; - $oldsigsubj = $this->signatureSubject; - $oldkeyid = $this->currentKeyIdentifier; - - $cert = $this->loadX509($cert); - if (!$cert) { - $this->dn = $olddn; - $this->currentCert = $oldcert; - $this->signatureSubject = $oldsigsubj; - $this->currentKeyIdentifier = $oldkeyid; - - return false; - } - - /* From RFC5280 "PKIX Certificate and CRL Profile": - - If the keyUsage extension is present, then the subject public key - MUST NOT be used to verify signatures on certificates or CRLs unless - the corresponding keyCertSign or cRLSign bit is set. */ - //$keyUsage = $this->getExtension('id-ce-keyUsage'); - //if ($keyUsage && !in_array('keyCertSign', $keyUsage)) { - // return false; - //} - - /* From RFC5280 "PKIX Certificate and CRL Profile": - - The cA boolean indicates whether the certified public key may be used - to verify certificate signatures. If the cA boolean is not asserted, - then the keyCertSign bit in the key usage extension MUST NOT be - asserted. If the basic constraints extension is not present in a - version 3 certificate, or the extension is present but the cA boolean - is not asserted, then the certified public key MUST NOT be used to - verify certificate signatures. */ - //$basicConstraints = $this->getExtension('id-ce-basicConstraints'); - //if (!$basicConstraints || !$basicConstraints['cA']) { - // return false; - //} - - $this->CAs[] = $cert; - - $this->dn = $olddn; - $this->currentCert = $oldcert; - $this->signatureSubject = $oldsigsubj; - - return true; - } - - /** - * Validate an X.509 certificate against a URL - * - * From RFC2818 "HTTP over TLS": - * - * Matching is performed using the matching rules specified by - * [RFC2459]. If more than one identity of a given type is present in - * the certificate (e.g., more than one dNSName name, a match in any one - * of the set is considered acceptable.) Names may contain the wildcard - * character * which is considered to match any single domain name - * component or component fragment. E.g., *.a.com matches foo.a.com but - * not bar.foo.a.com. f*.com matches foo.com but not bar.com. - * - * @param string $url - * @return bool - */ - public function validateURL($url) - { - if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { - return false; - } - - $components = parse_url($url); - if (!isset($components['host'])) { - return false; - } - - if ($names = $this->getExtension('id-ce-subjectAltName')) { - foreach ($names as $name) { - foreach ($name as $key => $value) { - $value = preg_quote($value); - $value = str_replace('\*', '[^.]*', $value); - switch ($key) { - case 'dNSName': - /* From RFC2818 "HTTP over TLS": - - If a subjectAltName extension of type dNSName is present, that MUST - be used as the identity. Otherwise, the (most specific) Common Name - field in the Subject field of the certificate MUST be used. Although - the use of the Common Name is existing practice, it is deprecated and - Certification Authorities are encouraged to use the dNSName instead. */ - if (preg_match('#^' . $value . '$#', $components['host'])) { - return true; - } - break; - case 'iPAddress': - /* From RFC2818 "HTTP over TLS": - - In some cases, the URI is specified as an IP address rather than a - hostname. In this case, the iPAddress subjectAltName must be present - in the certificate and must exactly match the IP in the URI. */ - if (preg_match('#(?:\d{1-3}\.){4}#', $components['host'] . '.') && preg_match('#^' . $value . '$#', $components['host'])) { - return true; - } - } - } - } - return false; - } - - if ($value = $this->getDNProp('id-at-commonName')) { - $value = str_replace(['.', '*'], ['\.', '[^.]*'], $value[0]); - return preg_match('#^' . $value . '$#', $components['host']) === 1; - } - - return false; - } - - /** - * Validate a date - * - * If $date isn't defined it is assumed to be the current date. - * - * @param \DateTimeInterface|string $date optional - * @return bool - */ - public function validateDate($date = null) - { - if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { - return false; - } - - if (!isset($date)) { - $date = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); - } - - $notBefore = $this->currentCert['tbsCertificate']['validity']['notBefore']; - $notBefore = isset($notBefore['generalTime']) ? $notBefore['generalTime'] : $notBefore['utcTime']; - - $notAfter = $this->currentCert['tbsCertificate']['validity']['notAfter']; - $notAfter = isset($notAfter['generalTime']) ? $notAfter['generalTime'] : $notAfter['utcTime']; - - if (is_string($date)) { - $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); - } - - $notBefore = new \DateTimeImmutable($notBefore, new \DateTimeZone(@date_default_timezone_get())); - $notAfter = new \DateTimeImmutable($notAfter, new \DateTimeZone(@date_default_timezone_get())); - - return $date >= $notBefore && $date <= $notAfter; - } - - /** - * Fetches a URL - * - * @param string $url - * @return bool|string - */ - private static function fetchURL($url) - { - if (self::$disable_url_fetch) { - return false; - } - - $parts = parse_url($url); - $data = ''; - switch ($parts['scheme']) { - case 'http': - $fsock = @fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80); - if (!$fsock) { - return false; - } - $path = $parts['path']; - if (isset($parts['query'])) { - $path .= '?' . $parts['query']; - } - fputs($fsock, "GET $path HTTP/1.0\r\n"); - fputs($fsock, "Host: $parts[host]\r\n\r\n"); - $line = fgets($fsock, 1024); - if (strlen($line) < 3) { - return false; - } - preg_match('#HTTP/1.\d (\d{3})#', $line, $temp); - if ($temp[1] != '200') { - return false; - } - - // skip the rest of the headers in the http response - while (!feof($fsock) && fgets($fsock, 1024) != "\r\n") { - } - - while (!feof($fsock)) { - $temp = fread($fsock, 1024); - if ($temp === false) { - return false; - } - $data .= $temp; - } - - break; - //case 'ftp': - //case 'ldap': - //default: - } - - return $data; - } - - /** - * Validates an intermediate cert as identified via authority info access extension - * - * See https://tools.ietf.org/html/rfc4325 for more info - * - * @param bool $caonly - * @param int $count - * @return bool - */ - private function testForIntermediate($caonly, $count) - { - $opts = $this->getExtension('id-pe-authorityInfoAccess'); - if (!is_array($opts)) { - return false; - } - foreach ($opts as $opt) { - if ($opt['accessMethod'] == 'id-ad-caIssuers') { - // accessLocation is a GeneralName. GeneralName fields support stuff like email addresses, IP addresses, LDAP, - // etc, but we're only supporting URI's. URI's and LDAP are the only thing https://tools.ietf.org/html/rfc4325 - // discusses - if (isset($opt['accessLocation']['uniformResourceIdentifier'])) { - $url = $opt['accessLocation']['uniformResourceIdentifier']; - break; - } - } - } - - if (!isset($url)) { - return false; - } - - $cert = static::fetchURL($url); - if (!is_string($cert)) { - return false; - } - - $parent = new static(); - $parent->CAs = $this->CAs; - /* - "Conforming applications that support HTTP or FTP for accessing - certificates MUST be able to accept .cer files and SHOULD be able - to accept .p7c files." -- https://tools.ietf.org/html/rfc4325 - - A .p7c file is 'a "certs-only" CMS message as specified in RFC 2797" - - These are currently unsupported - */ - if (!is_array($parent->loadX509($cert))) { - return false; - } - - if (!$parent->validateSignatureCountable($caonly, ++$count)) { - return false; - } - - $this->CAs[] = $parent->currentCert; - //$this->loadCA($cert); - - return true; - } - - /** - * Validate a signature - * - * Works on X.509 certs, CSR's and CRL's. - * Returns true if the signature is verified, false if it is not correct or null on error - * - * By default returns false for self-signed certs. Call validateSignature(false) to make this support - * self-signed. - * - * The behavior of this function is inspired by {@link http://php.net/openssl-verify openssl_verify}. - * - * @param bool $caonly optional - * @return mixed - */ - public function validateSignature($caonly = true) - { - return $this->validateSignatureCountable($caonly, 0); - } - - /** - * Validate a signature - * - * Performs said validation whilst keeping track of how many times validation method is called - * - * @param bool $caonly - * @param int $count - * @return mixed - */ - private function validateSignatureCountable($caonly, $count) - { - if (!is_array($this->currentCert) || !isset($this->signatureSubject)) { - return null; - } - - if ($count == self::$recur_limit) { - return false; - } - - /* TODO: - "emailAddress attribute values are not case-sensitive (e.g., "subscriber@example.com" is the same as "SUBSCRIBER@EXAMPLE.COM")." - -- http://tools.ietf.org/html/rfc5280#section-4.1.2.6 - - implement pathLenConstraint in the id-ce-basicConstraints extension */ - - switch (true) { - case isset($this->currentCert['tbsCertificate']): - // self-signed cert - switch (true) { - case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $this->currentCert['tbsCertificate']['subject']: - case defined('FILE_X509_IGNORE_TYPE') && $this->getIssuerDN(self::DN_STRING) === $this->getDN(self::DN_STRING): - $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); - $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier'); - switch (true) { - case !is_array($authorityKey): - case !$subjectKeyID: - case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: - $signingCert = $this->currentCert; // working cert - } - } - - if (!empty($this->CAs)) { - for ($i = 0; $i < count($this->CAs); $i++) { - // even if the cert is a self-signed one we still want to see if it's a CA; - // if not, we'll conditionally return an error - $ca = $this->CAs[$i]; - switch (true) { - case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']: - case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertificate']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): - $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); - $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); - switch (true) { - case !is_array($authorityKey): - case !$subjectKeyID: - case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: - if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { - break 2; // serial mismatch - check other ca - } - $signingCert = $ca; // working cert - break 3; - } - } - } - if (count($this->CAs) == $i && $caonly) { - return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); - } - } elseif (!isset($signingCert) || $caonly) { - return $this->testForIntermediate($caonly, $count) && $this->validateSignature($caonly); - } - return $this->validateSignatureHelper( - $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], - $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], - $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), - $this->signatureSubject - ); - case isset($this->currentCert['certificationRequestInfo']): - return $this->validateSignatureHelper( - $this->currentCert['certificationRequestInfo']['subjectPKInfo']['algorithm']['algorithm'], - $this->currentCert['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], - $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), - $this->signatureSubject - ); - case isset($this->currentCert['publicKeyAndChallenge']): - return $this->validateSignatureHelper( - $this->currentCert['publicKeyAndChallenge']['spki']['algorithm']['algorithm'], - $this->currentCert['publicKeyAndChallenge']['spki']['subjectPublicKey'], - $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), - $this->signatureSubject - ); - case isset($this->currentCert['tbsCertList']): - if (!empty($this->CAs)) { - for ($i = 0; $i < count($this->CAs); $i++) { - $ca = $this->CAs[$i]; - switch (true) { - case !defined('FILE_X509_IGNORE_TYPE') && $this->currentCert['tbsCertList']['issuer'] === $ca['tbsCertificate']['subject']: - case defined('FILE_X509_IGNORE_TYPE') && $this->getDN(self::DN_STRING, $this->currentCert['tbsCertList']['issuer']) === $this->getDN(self::DN_STRING, $ca['tbsCertificate']['subject']): - $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier'); - $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); - switch (true) { - case !is_array($authorityKey): - case !$subjectKeyID: - case isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: - if (is_array($authorityKey) && isset($authorityKey['authorityCertSerialNumber']) && !$authorityKey['authorityCertSerialNumber']->equals($ca['tbsCertificate']['serialNumber'])) { - break 2; // serial mismatch - check other ca - } - $signingCert = $ca; // working cert - break 3; - } - } - } - } - if (!isset($signingCert)) { - return false; - } - return $this->validateSignatureHelper( - $signingCert['tbsCertificate']['subjectPublicKeyInfo']['algorithm']['algorithm'], - $signingCert['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], - $this->currentCert['signatureAlgorithm']['algorithm'], - substr($this->currentCert['signature'], 1), - $this->signatureSubject - ); - default: - return false; - } - } - - /** - * Validates a signature - * - * Returns true if the signature is verified and false if it is not correct. - * If the algorithms are unsupposed an exception is thrown. - * - * @param string $publicKeyAlgorithm - * @param string $publicKey - * @param string $signatureAlgorithm - * @param string $signature - * @param string $signatureSubject - * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported - * @return bool - */ - private function validateSignatureHelper($publicKeyAlgorithm, $publicKey, $signatureAlgorithm, $signature, $signatureSubject) - { - switch ($publicKeyAlgorithm) { - case 'id-RSASSA-PSS': - $key = RSA::loadFormat('PSS', $publicKey); - break; - case 'rsaEncryption': - $key = RSA::loadFormat('PKCS8', $publicKey); - switch ($signatureAlgorithm) { - case 'id-RSASSA-PSS': - break; - case 'md2WithRSAEncryption': - case 'md5WithRSAEncryption': - case 'sha1WithRSAEncryption': - case 'sha224WithRSAEncryption': - case 'sha256WithRSAEncryption': - case 'sha384WithRSAEncryption': - case 'sha512WithRSAEncryption': - $key = $key - ->withHash(preg_replace('#WithRSAEncryption$#', '', $signatureAlgorithm)) - ->withPadding(RSA::SIGNATURE_PKCS1); - break; - default: - throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); - } - break; - case 'id-Ed25519': - case 'id-Ed448': - $key = EC::loadFormat('PKCS8', $publicKey); - break; - case 'id-ecPublicKey': - $key = EC::loadFormat('PKCS8', $publicKey); - switch ($signatureAlgorithm) { - case 'ecdsa-with-SHA1': - case 'ecdsa-with-SHA224': - case 'ecdsa-with-SHA256': - case 'ecdsa-with-SHA384': - case 'ecdsa-with-SHA512': - $key = $key - ->withHash(preg_replace('#^ecdsa-with-#', '', strtolower($signatureAlgorithm))); - break; - default: - throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); - } - break; - case 'id-dsa': - $key = DSA::loadFormat('PKCS8', $publicKey); - switch ($signatureAlgorithm) { - case 'id-dsa-with-sha1': - case 'id-dsa-with-sha224': - case 'id-dsa-with-sha256': - $key = $key - ->withHash(preg_replace('#^id-dsa-with-#', '', strtolower($signatureAlgorithm))); - break; - default: - throw new UnsupportedAlgorithmException('Signature algorithm unsupported'); - } - break; - default: - throw new UnsupportedAlgorithmException('Public key algorithm unsupported'); - } - - return $key->verify($signatureSubject, $signature); - } - - /** - * Sets the recursion limit - * - * When validating a signature it may be necessary to download intermediate certs from URI's. - * An intermediate cert that linked to itself would result in an infinite loop so to prevent - * that we set a recursion limit. A negative number means that there is no recursion limit. - * - * @param int $count - */ - public static function setRecurLimit($count) - { - self::$recur_limit = $count; - } - - /** - * Prevents URIs from being automatically retrieved - * - */ - public static function disableURLFetch() - { - self::$disable_url_fetch = true; - } - - /** - * Allows URIs to be automatically retrieved - * - */ - public static function enableURLFetch() - { - self::$disable_url_fetch = false; - } - - /** - * Decodes an IP address - * - * Takes in a base64 encoded "blob" and returns a human readable IP address - * - * @param string $ip - * @return string - */ - public static function decodeIP($ip) - { - return inet_ntop($ip); - } - - /** - * Decodes an IP address in a name constraints extension - * - * Takes in a base64 encoded "blob" and returns a human readable IP address / mask - * - * @param string $ip - * @return array - */ - public static function decodeNameConstraintIP($ip) - { - $size = strlen($ip) >> 1; - $mask = substr($ip, $size); - $ip = substr($ip, 0, $size); - return [inet_ntop($ip), inet_ntop($mask)]; - } - - /** - * Encodes an IP address - * - * Takes a human readable IP address into a base64-encoded "blob" - * - * @param string|array $ip - * @return string - */ - public static function encodeIP($ip) - { - return is_string($ip) ? - inet_pton($ip) : - inet_pton($ip[0]) . inet_pton($ip[1]); - } - - /** - * "Normalizes" a Distinguished Name property - * - * @param string $propName - * @return mixed - */ - private function translateDNProp($propName) - { - switch (strtolower($propName)) { - case 'jurisdictionofincorporationcountryname': - case 'jurisdictioncountryname': - case 'jurisdictionc': - return 'jurisdictionOfIncorporationCountryName'; - case 'jurisdictionofincorporationstateorprovincename': - case 'jurisdictionstateorprovincename': - case 'jurisdictionst': - return 'jurisdictionOfIncorporationStateOrProvinceName'; - case 'jurisdictionlocalityname': - case 'jurisdictionl': - return 'jurisdictionLocalityName'; - case 'id-at-businesscategory': - case 'businesscategory': - return 'id-at-businessCategory'; - case 'id-at-countryname': - case 'countryname': - case 'c': - return 'id-at-countryName'; - case 'id-at-organizationname': - case 'organizationname': - case 'o': - return 'id-at-organizationName'; - case 'id-at-dnqualifier': - case 'dnqualifier': - return 'id-at-dnQualifier'; - case 'id-at-commonname': - case 'commonname': - case 'cn': - return 'id-at-commonName'; - case 'id-at-stateorprovincename': - case 'stateorprovincename': - case 'state': - case 'province': - case 'provincename': - case 'st': - return 'id-at-stateOrProvinceName'; - case 'id-at-localityname': - case 'localityname': - case 'l': - return 'id-at-localityName'; - case 'id-emailaddress': - case 'emailaddress': - return 'pkcs-9-at-emailAddress'; - case 'id-at-serialnumber': - case 'serialnumber': - return 'id-at-serialNumber'; - case 'id-at-postalcode': - case 'postalcode': - return 'id-at-postalCode'; - case 'id-at-streetaddress': - case 'streetaddress': - return 'id-at-streetAddress'; - case 'id-at-name': - case 'name': - return 'id-at-name'; - case 'id-at-givenname': - case 'givenname': - return 'id-at-givenName'; - case 'id-at-surname': - case 'surname': - case 'sn': - return 'id-at-surname'; - case 'id-at-initials': - case 'initials': - return 'id-at-initials'; - case 'id-at-generationqualifier': - case 'generationqualifier': - return 'id-at-generationQualifier'; - case 'id-at-organizationalunitname': - case 'organizationalunitname': - case 'ou': - return 'id-at-organizationalUnitName'; - case 'id-at-pseudonym': - case 'pseudonym': - return 'id-at-pseudonym'; - case 'id-at-title': - case 'title': - return 'id-at-title'; - case 'id-at-description': - case 'description': - return 'id-at-description'; - case 'id-at-role': - case 'role': - return 'id-at-role'; - case 'id-at-uniqueidentifier': - case 'uniqueidentifier': - case 'x500uniqueidentifier': - return 'id-at-uniqueIdentifier'; - case 'postaladdress': - case 'id-at-postaladdress': - return 'id-at-postalAddress'; - default: - return false; - } - } - - /** - * Set a Distinguished Name property - * - * @param string $propName - * @param mixed $propValue - * @param string $type optional - * @return bool - */ - public function setDNProp($propName, $propValue, $type = 'utf8String') - { - if (empty($this->dn)) { - $this->dn = ['rdnSequence' => []]; - } - - if (($propName = $this->translateDNProp($propName)) === false) { - return false; - } - - foreach ((array) $propValue as $v) { - if (!is_array($v) && isset($type)) { - $v = [$type => $v]; - } - $this->dn['rdnSequence'][] = [ - [ - 'type' => $propName, - 'value' => $v - ] - ]; - } - - return true; - } - - /** - * Remove Distinguished Name properties - * - * @param string $propName - */ - public function removeDNProp($propName) - { - if (empty($this->dn)) { - return; - } - - if (($propName = $this->translateDNProp($propName)) === false) { - return; - } - - $dn = &$this->dn['rdnSequence']; - $size = count($dn); - for ($i = 0; $i < $size; $i++) { - if ($dn[$i][0]['type'] == $propName) { - unset($dn[$i]); - } - } - - $dn = array_values($dn); - // fix for https://bugs.php.net/75433 affecting PHP 7.2 - if (!isset($dn[0])) { - $dn = array_splice($dn, 0, 0); - } - } - - /** - * Get Distinguished Name properties - * - * @param string $propName - * @param array $dn optional - * @param bool $withType optional - * @return mixed - */ - public function getDNProp($propName, array $dn = null, $withType = false) - { - if (!isset($dn)) { - $dn = $this->dn; - } - - if (empty($dn)) { - return false; - } - - if (($propName = $this->translateDNProp($propName)) === false) { - return false; - } - - $filters = []; - $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $this->mapOutDNs($dn, 'rdnSequence'); - $dn = $dn['rdnSequence']; - $result = []; - for ($i = 0; $i < count($dn); $i++) { - if ($dn[$i][0]['type'] == $propName) { - $v = $dn[$i][0]['value']; - if (!$withType) { - if (is_array($v)) { - foreach ($v as $type => $s) { - $type = array_search($type, ASN1::ANY_MAP); - if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { - $s = ASN1::convert($s, $type); - if ($s !== false) { - $v = $s; - break; - } - } - } - if (is_array($v)) { - $v = array_pop($v); // Always strip data type. - } - } elseif (is_object($v) && $v instanceof Element) { - $map = $this->getMapping($propName); - if (!is_bool($map)) { - $decoded = ASN1::decodeBER($v); - if (!$decoded) { - return false; - } - $v = ASN1::asn1map($decoded[0], $map); - } - } - } - $result[] = $v; - } - } - - return $result; - } - - /** - * Set a Distinguished Name - * - * @param mixed $dn - * @param bool $merge optional - * @param string $type optional - * @return bool - */ - public function setDN($dn, $merge = false, $type = 'utf8String') - { - if (!$merge) { - $this->dn = null; - } - - if (is_array($dn)) { - if (isset($dn['rdnSequence'])) { - $this->dn = $dn; // No merge here. - return true; - } - - // handles stuff generated by openssl_x509_parse() - foreach ($dn as $prop => $value) { - if (!$this->setDNProp($prop, $value, $type)) { - return false; - } - } - return true; - } - - // handles everything else - $results = preg_split('#((?:^|, *|/)(?:C=|O=|OU=|CN=|L=|ST=|SN=|postalCode=|streetAddress=|emailAddress=|serialNumber=|organizationalUnitName=|title=|description=|role=|x500UniqueIdentifier=|postalAddress=))#', $dn, -1, PREG_SPLIT_DELIM_CAPTURE); - for ($i = 1; $i < count($results); $i += 2) { - $prop = trim($results[$i], ', =/'); - $value = $results[$i + 1]; - if (!$this->setDNProp($prop, $value, $type)) { - return false; - } - } - - return true; - } - - /** - * Get the Distinguished Name for a certificates subject - * - * @param mixed $format optional - * @param array $dn optional - * @return array|bool|string - */ - public function getDN($format = self::DN_ARRAY, array $dn = null) - { - if (!isset($dn)) { - $dn = isset($this->currentCert['tbsCertList']) ? $this->currentCert['tbsCertList']['issuer'] : $this->dn; - } - - switch ((int) $format) { - case self::DN_ARRAY: - return $dn; - case self::DN_ASN1: - $filters = []; - $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $this->mapOutDNs($dn, 'rdnSequence'); - return ASN1::encodeDER($dn, Maps\Name::MAP); - case self::DN_CANON: - // No SEQUENCE around RDNs and all string values normalized as - // trimmed lowercase UTF-8 with all spacing as one blank. - // constructed RDNs will not be canonicalized - $filters = []; - $filters['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $result = ''; - $this->mapOutDNs($dn, 'rdnSequence'); - foreach ($dn['rdnSequence'] as $rdn) { - foreach ($rdn as $i => $attr) { - $attr = &$rdn[$i]; - if (is_array($attr['value'])) { - foreach ($attr['value'] as $type => $v) { - $type = array_search($type, ASN1::ANY_MAP, true); - if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { - $v = ASN1::convert($v, $type); - if ($v !== false) { - $v = preg_replace('/\s+/', ' ', $v); - $attr['value'] = strtolower(trim($v)); - break; - } - } - } - } - } - $result .= ASN1::encodeDER($rdn, Maps\RelativeDistinguishedName::MAP); - } - return $result; - case self::DN_HASH: - $dn = $this->getDN(self::DN_CANON, $dn); - $hash = new Hash('sha1'); - $hash = $hash->hash($dn); - extract(unpack('Vhash', $hash)); - return strtolower(Strings::bin2hex(pack('N', $hash))); - } - - // Default is to return a string. - $start = true; - $output = ''; - - $result = []; - $filters = []; - $filters['rdnSequence']['value'] = ['type' => ASN1::TYPE_UTF8_STRING]; - ASN1::setFilters($filters); - $this->mapOutDNs($dn, 'rdnSequence'); - - foreach ($dn['rdnSequence'] as $field) { - $prop = $field[0]['type']; - $value = $field[0]['value']; - - $delim = ', '; - switch ($prop) { - case 'id-at-countryName': - $desc = 'C'; - break; - case 'id-at-stateOrProvinceName': - $desc = 'ST'; - break; - case 'id-at-organizationName': - $desc = 'O'; - break; - case 'id-at-organizationalUnitName': - $desc = 'OU'; - break; - case 'id-at-commonName': - $desc = 'CN'; - break; - case 'id-at-localityName': - $desc = 'L'; - break; - case 'id-at-surname': - $desc = 'SN'; - break; - case 'id-at-uniqueIdentifier': - $delim = '/'; - $desc = 'x500UniqueIdentifier'; - break; - case 'id-at-postalAddress': - $delim = '/'; - $desc = 'postalAddress'; - break; - default: - $delim = '/'; - $desc = preg_replace('#.+-([^-]+)$#', '$1', $prop); - } - - if (!$start) { - $output .= $delim; - } - if (is_array($value)) { - foreach ($value as $type => $v) { - $type = array_search($type, ASN1::ANY_MAP, true); - if ($type !== false && array_key_exists($type, ASN1::STRING_TYPE_SIZE)) { - $v = ASN1::convert($v, $type); - if ($v !== false) { - $value = $v; - break; - } - } - } - if (is_array($value)) { - $value = array_pop($value); // Always strip data type. - } - } elseif (is_object($value) && $value instanceof Element) { - $callback = function ($x) { - return '\x' . bin2hex($x[0]); - }; - $value = strtoupper(preg_replace_callback('#[^\x20-\x7E]#', $callback, $value->element)); - } - $output .= $desc . '=' . $value; - $result[$desc] = isset($result[$desc]) ? - array_merge((array) $result[$desc], [$value]) : - $value; - $start = false; - } - - return $format == self::DN_OPENSSL ? $result : $output; - } - - /** - * Get the Distinguished Name for a certificate/crl issuer - * - * @param int $format optional - * @return mixed - */ - public function getIssuerDN($format = self::DN_ARRAY) - { - switch (true) { - case !isset($this->currentCert) || !is_array($this->currentCert): - break; - case isset($this->currentCert['tbsCertificate']): - return $this->getDN($format, $this->currentCert['tbsCertificate']['issuer']); - case isset($this->currentCert['tbsCertList']): - return $this->getDN($format, $this->currentCert['tbsCertList']['issuer']); - } - - return false; - } - - /** - * Get the Distinguished Name for a certificate/csr subject - * Alias of getDN() - * - * @param int $format optional - * @return mixed - */ - public function getSubjectDN($format = self::DN_ARRAY) - { - switch (true) { - case !empty($this->dn): - return $this->getDN($format); - case !isset($this->currentCert) || !is_array($this->currentCert): - break; - case isset($this->currentCert['tbsCertificate']): - return $this->getDN($format, $this->currentCert['tbsCertificate']['subject']); - case isset($this->currentCert['certificationRequestInfo']): - return $this->getDN($format, $this->currentCert['certificationRequestInfo']['subject']); - } - - return false; - } - - /** - * Get an individual Distinguished Name property for a certificate/crl issuer - * - * @param string $propName - * @param bool $withType optional - * @return mixed - */ - public function getIssuerDNProp($propName, $withType = false) - { - switch (true) { - case !isset($this->currentCert) || !is_array($this->currentCert): - break; - case isset($this->currentCert['tbsCertificate']): - return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['issuer'], $withType); - case isset($this->currentCert['tbsCertList']): - return $this->getDNProp($propName, $this->currentCert['tbsCertList']['issuer'], $withType); - } - - return false; - } - - /** - * Get an individual Distinguished Name property for a certificate/csr subject - * - * @param string $propName - * @param bool $withType optional - * @return mixed - */ - public function getSubjectDNProp($propName, $withType = false) - { - switch (true) { - case !empty($this->dn): - return $this->getDNProp($propName, null, $withType); - case !isset($this->currentCert) || !is_array($this->currentCert): - break; - case isset($this->currentCert['tbsCertificate']): - return $this->getDNProp($propName, $this->currentCert['tbsCertificate']['subject'], $withType); - case isset($this->currentCert['certificationRequestInfo']): - return $this->getDNProp($propName, $this->currentCert['certificationRequestInfo']['subject'], $withType); - } - - return false; - } - - /** - * Get the certificate chain for the current cert - * - * @return mixed - */ - public function getChain() - { - $chain = [$this->currentCert]; - - if (!is_array($this->currentCert) || !isset($this->currentCert['tbsCertificate'])) { - return false; - } - while (true) { - $currentCert = $chain[count($chain) - 1]; - for ($i = 0; $i < count($this->CAs); $i++) { - $ca = $this->CAs[$i]; - if ($currentCert['tbsCertificate']['issuer'] === $ca['tbsCertificate']['subject']) { - $authorityKey = $this->getExtension('id-ce-authorityKeyIdentifier', $currentCert); - $subjectKeyID = $this->getExtension('id-ce-subjectKeyIdentifier', $ca); - switch (true) { - case !is_array($authorityKey): - case is_array($authorityKey) && isset($authorityKey['keyIdentifier']) && $authorityKey['keyIdentifier'] === $subjectKeyID: - if ($currentCert === $ca) { - break 3; - } - $chain[] = $ca; - break 2; - } - } - } - if ($i == count($this->CAs)) { - break; - } - } - foreach ($chain as $key => $value) { - $chain[$key] = new X509(); - $chain[$key]->loadX509($value); - } - return $chain; - } - - /** - * Returns the current cert - * - * @return array|bool - */ - public function &getCurrentCert() - { - return $this->currentCert; - } - - /** - * Set public key - * - * Key needs to be a \phpseclib3\Crypt\RSA object - * - * @param PublicKey $key - * @return void - */ - public function setPublicKey(PublicKey $key) - { - $this->publicKey = $key; - } - - /** - * Set private key - * - * Key needs to be a \phpseclib3\Crypt\RSA object - * - * @param PrivateKey $key - */ - public function setPrivateKey(PrivateKey $key) - { - $this->privateKey = $key; - } - - /** - * Set challenge - * - * Used for SPKAC CSR's - * - * @param string $challenge - */ - public function setChallenge($challenge) - { - $this->challenge = $challenge; - } - - /** - * Gets the public key - * - * Returns a \phpseclib3\Crypt\RSA object or a false. - * - * @return mixed - */ - public function getPublicKey() - { - if (isset($this->publicKey)) { - return $this->publicKey; - } - - if (isset($this->currentCert) && is_array($this->currentCert)) { - $paths = [ - 'tbsCertificate/subjectPublicKeyInfo', - 'certificationRequestInfo/subjectPKInfo', - 'publicKeyAndChallenge/spki' - ]; - foreach ($paths as $path) { - $keyinfo = $this->subArray($this->currentCert, $path); - if (!empty($keyinfo)) { - break; - } - } - } - if (empty($keyinfo)) { - return false; - } - - $key = $keyinfo['subjectPublicKey']; - - switch ($keyinfo['algorithm']['algorithm']) { - case 'id-RSASSA-PSS': - return RSA::loadFormat('PSS', $key); - case 'rsaEncryption': - return RSA::loadFormat('PKCS8', $key)->withPadding(RSA::SIGNATURE_PKCS1); - case 'id-ecPublicKey': - case 'id-Ed25519': - case 'id-Ed448': - return EC::loadFormat('PKCS8', $key); - case 'id-dsa': - return DSA::loadFormat('PKCS8', $key); - } - - return false; - } - - /** - * Load a Certificate Signing Request - * - * @param string $csr - * @param int $mode - * @return mixed - */ - public function loadCSR($csr, $mode = self::FORMAT_AUTO_DETECT) - { - if (is_array($csr) && isset($csr['certificationRequestInfo'])) { - unset($this->currentCert); - unset($this->currentKeyIdentifier); - unset($this->signatureSubject); - $this->dn = $csr['certificationRequestInfo']['subject']; - if (!isset($this->dn)) { - return false; - } - - $this->currentCert = $csr; - return $csr; - } - - // see http://tools.ietf.org/html/rfc2986 - - if ($mode != self::FORMAT_DER) { - $newcsr = ASN1::extractBER($csr); - if ($mode == self::FORMAT_PEM && $csr == $newcsr) { - return false; - } - $csr = $newcsr; - } - $orig = $csr; - - if ($csr === false) { - $this->currentCert = false; - return false; - } - - $decoded = ASN1::decodeBER($csr); - - if (!$decoded) { - $this->currentCert = false; - return false; - } - - $csr = ASN1::asn1map($decoded[0], Maps\CertificationRequest::MAP); - if (!isset($csr) || $csr === false) { - $this->currentCert = false; - return false; - } - - $this->mapInAttributes($csr, 'certificationRequestInfo/attributes'); - $this->mapInDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); - - $this->dn = $csr['certificationRequestInfo']['subject']; - - $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - - $key = $csr['certificationRequestInfo']['subjectPKInfo']; - $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); - $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'] = - "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; - - $this->currentKeyIdentifier = null; - $this->currentCert = $csr; - - $this->publicKey = null; - $this->publicKey = $this->getPublicKey(); - - return $csr; - } - - /** - * Save CSR request - * - * @param array $csr - * @param int $format optional - * @return string - */ - public function saveCSR(array $csr, $format = self::FORMAT_PEM) - { - if (!is_array($csr) || !isset($csr['certificationRequestInfo'])) { - return false; - } - - switch (true) { - case !($algorithm = $this->subArray($csr, 'certificationRequestInfo/subjectPKInfo/algorithm/algorithm')): - case is_object($csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): - break; - default: - $csr['certificationRequestInfo']['subjectPKInfo'] = new Element( - base64_decode(preg_replace('#-.+-|[\r\n]#', '', $csr['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'])) - ); - } - - $filters = []; - $filters['certificationRequestInfo']['subject']['rdnSequence']['value'] - = ['type' => ASN1::TYPE_UTF8_STRING]; - - ASN1::setFilters($filters); - - $this->mapOutDNs($csr, 'certificationRequestInfo/subject/rdnSequence'); - $this->mapOutAttributes($csr, 'certificationRequestInfo/attributes'); - $csr = ASN1::encodeDER($csr, Maps\CertificationRequest::MAP); - - switch ($format) { - case self::FORMAT_DER: - return $csr; - // case self::FORMAT_PEM: - default: - return "-----BEGIN CERTIFICATE REQUEST-----\r\n" . chunk_split(Strings::base64_encode($csr), 64) . '-----END CERTIFICATE REQUEST-----'; - } - } - - /** - * Load a SPKAC CSR - * - * SPKAC's are produced by the HTML5 keygen element: - * - * https://developer.mozilla.org/en-US/docs/HTML/Element/keygen - * - * @param string $spkac - * @return mixed - */ - public function loadSPKAC($spkac) - { - if (is_array($spkac) && isset($spkac['publicKeyAndChallenge'])) { - unset($this->currentCert); - unset($this->currentKeyIdentifier); - unset($this->signatureSubject); - $this->currentCert = $spkac; - return $spkac; - } - - // see http://www.w3.org/html/wg/drafts/html/master/forms.html#signedpublickeyandchallenge - - // OpenSSL produces SPKAC's that are preceded by the string SPKAC= - $temp = preg_replace('#(?:SPKAC=)|[ \r\n\\\]#', '', $spkac); - $temp = preg_match('#^[a-zA-Z\d/+]*={0,2}$#', $temp) ? Strings::base64_decode($temp) : false; - if ($temp != false) { - $spkac = $temp; - } - $orig = $spkac; - - if ($spkac === false) { - $this->currentCert = false; - return false; - } - - $decoded = ASN1::decodeBER($spkac); - - if (!$decoded) { - $this->currentCert = false; - return false; - } - - $spkac = ASN1::asn1map($decoded[0], Maps\SignedPublicKeyAndChallenge::MAP); - - if (!isset($spkac) || !is_array($spkac)) { - $this->currentCert = false; - return false; - } - - $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - - $key = $spkac['publicKeyAndChallenge']['spki']; - $key = ASN1::encodeDER($key, Maps\SubjectPublicKeyInfo::MAP); - $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'] = - "-----BEGIN PUBLIC KEY-----\r\n" . - chunk_split(base64_encode($key), 64) . - "-----END PUBLIC KEY-----"; - - $this->currentKeyIdentifier = null; - $this->currentCert = $spkac; - - $this->publicKey = null; - $this->publicKey = $this->getPublicKey(); - - return $spkac; - } - - /** - * Save a SPKAC CSR request - * - * @param array $spkac - * @param int $format optional - * @return string - */ - public function saveSPKAC(array $spkac, $format = self::FORMAT_PEM) - { - if (!is_array($spkac) || !isset($spkac['publicKeyAndChallenge'])) { - return false; - } - - $algorithm = $this->subArray($spkac, 'publicKeyAndChallenge/spki/algorithm/algorithm'); - switch (true) { - case !$algorithm: - case is_object($spkac['publicKeyAndChallenge']['spki']['subjectPublicKey']): - break; - default: - $spkac['publicKeyAndChallenge']['spki'] = new Element( - base64_decode(preg_replace('#-.+-|[\r\n]#', '', $spkac['publicKeyAndChallenge']['spki']['subjectPublicKey'])) - ); - } - - $spkac = ASN1::encodeDER($spkac, Maps\SignedPublicKeyAndChallenge::MAP); - - switch ($format) { - case self::FORMAT_DER: - return $spkac; - // case self::FORMAT_PEM: - default: - // OpenSSL's implementation of SPKAC requires the SPKAC be preceded by SPKAC= and since there are pretty much - // no other SPKAC decoders phpseclib will use that same format - return 'SPKAC=' . Strings::base64_encode($spkac); - } - } - - /** - * Load a Certificate Revocation List - * - * @param string $crl - * @param int $mode - * @return mixed - */ - public function loadCRL($crl, $mode = self::FORMAT_AUTO_DETECT) - { - if (is_array($crl) && isset($crl['tbsCertList'])) { - $this->currentCert = $crl; - unset($this->signatureSubject); - return $crl; - } - - if ($mode != self::FORMAT_DER) { - $newcrl = ASN1::extractBER($crl); - if ($mode == self::FORMAT_PEM && $crl == $newcrl) { - return false; - } - $crl = $newcrl; - } - $orig = $crl; - - if ($crl === false) { - $this->currentCert = false; - return false; - } - - $decoded = ASN1::decodeBER($crl); - - if (!$decoded) { - $this->currentCert = false; - return false; - } - - $crl = ASN1::asn1map($decoded[0], Maps\CertificateList::MAP); - if (!isset($crl) || $crl === false) { - $this->currentCert = false; - return false; - } - - $this->signatureSubject = substr($orig, $decoded[0]['content'][0]['start'], $decoded[0]['content'][0]['length']); - - $this->mapInDNs($crl, 'tbsCertList/issuer/rdnSequence'); - if ($this->isSubArrayValid($crl, 'tbsCertList/crlExtensions')) { - $this->mapInExtensions($crl, 'tbsCertList/crlExtensions'); - } - if ($this->isSubArrayValid($crl, 'tbsCertList/revokedCertificates')) { - $rclist_ref = &$this->subArrayUnchecked($crl, 'tbsCertList/revokedCertificates'); - if ($rclist_ref) { - $rclist = $crl['tbsCertList']['revokedCertificates']; - foreach ($rclist as $i => $extension) { - if ($this->isSubArrayValid($rclist, "$i/crlEntryExtensions")) { - $this->mapInExtensions($rclist_ref, "$i/crlEntryExtensions"); - } - } - } - } - - $this->currentKeyIdentifier = null; - $this->currentCert = $crl; - - return $crl; - } - - /** - * Save Certificate Revocation List. - * - * @param array $crl - * @param int $format optional - * @return string - */ - public function saveCRL(array $crl, $format = self::FORMAT_PEM) - { - if (!is_array($crl) || !isset($crl['tbsCertList'])) { - return false; - } - - $filters = []; - $filters['tbsCertList']['issuer']['rdnSequence']['value'] - = ['type' => ASN1::TYPE_UTF8_STRING]; - $filters['tbsCertList']['signature']['parameters'] - = ['type' => ASN1::TYPE_UTF8_STRING]; - $filters['signatureAlgorithm']['parameters'] - = ['type' => ASN1::TYPE_UTF8_STRING]; - - if (empty($crl['tbsCertList']['signature']['parameters'])) { - $filters['tbsCertList']['signature']['parameters'] - = ['type' => ASN1::TYPE_NULL]; - } - - if (empty($crl['signatureAlgorithm']['parameters'])) { - $filters['signatureAlgorithm']['parameters'] - = ['type' => ASN1::TYPE_NULL]; - } - - ASN1::setFilters($filters); - - $this->mapOutDNs($crl, 'tbsCertList/issuer/rdnSequence'); - $this->mapOutExtensions($crl, 'tbsCertList/crlExtensions'); - $rclist = &$this->subArray($crl, 'tbsCertList/revokedCertificates'); - if (is_array($rclist)) { - foreach ($rclist as $i => $extension) { - $this->mapOutExtensions($rclist, "$i/crlEntryExtensions"); - } - } - - $crl = ASN1::encodeDER($crl, Maps\CertificateList::MAP); - - switch ($format) { - case self::FORMAT_DER: - return $crl; - // case self::FORMAT_PEM: - default: - return "-----BEGIN X509 CRL-----\r\n" . chunk_split(Strings::base64_encode($crl), 64) . '-----END X509 CRL-----'; - } - } - - /** - * Helper function to build a time field according to RFC 3280 section - * - 4.1.2.5 Validity - * - 5.1.2.4 This Update - * - 5.1.2.5 Next Update - * - 5.1.2.6 Revoked Certificates - * by choosing utcTime iff year of date given is before 2050 and generalTime else. - * - * @param string $date in format date('D, d M Y H:i:s O') - * @return array|Element - */ - private function timeField($date) - { - if ($date instanceof Element) { - return $date; - } - $dateObj = new \DateTimeImmutable($date, new \DateTimeZone('GMT')); - $year = $dateObj->format('Y'); // the same way ASN1.php parses this - if ($year < 2050) { - return ['utcTime' => $date]; - } else { - return ['generalTime' => $date]; - } - } - - /** - * Sign an X.509 certificate - * - * $issuer's private key needs to be loaded. - * $subject can be either an existing X.509 cert (if you want to resign it), - * a CSR or something with the DN and public key explicitly set. - * - * @return mixed - */ - public function sign(X509 $issuer, X509 $subject) - { - if (!is_object($issuer->privateKey) || empty($issuer->dn)) { - return false; - } - - if (isset($subject->publicKey) && !($subjectPublicKey = $subject->formatSubjectPublicKey())) { - return false; - } - - $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); - - if (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertificate'])) { - $this->currentCert = $subject->currentCert; - $this->currentCert['tbsCertificate']['signature'] = $signatureAlgorithm; - $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; - - if (!empty($this->startDate)) { - $this->currentCert['tbsCertificate']['validity']['notBefore'] = $this->timeField($this->startDate); - } - if (!empty($this->endDate)) { - $this->currentCert['tbsCertificate']['validity']['notAfter'] = $this->timeField($this->endDate); - } - if (!empty($this->serialNumber)) { - $this->currentCert['tbsCertificate']['serialNumber'] = $this->serialNumber; - } - if (!empty($subject->dn)) { - $this->currentCert['tbsCertificate']['subject'] = $subject->dn; - } - if (!empty($subject->publicKey)) { - $this->currentCert['tbsCertificate']['subjectPublicKeyInfo'] = $subjectPublicKey; - } - $this->removeExtension('id-ce-authorityKeyIdentifier'); - if (isset($subject->domains)) { - $this->removeExtension('id-ce-subjectAltName'); - } - } elseif (isset($subject->currentCert) && is_array($subject->currentCert) && isset($subject->currentCert['tbsCertList'])) { - return false; - } else { - if (!isset($subject->publicKey)) { - return false; - } - - $startDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); - $startDate = !empty($this->startDate) ? $this->startDate : $startDate->format('D, d M Y H:i:s O'); - - $endDate = new \DateTimeImmutable('+1 year', new \DateTimeZone(@date_default_timezone_get())); - $endDate = !empty($this->endDate) ? $this->endDate : $endDate->format('D, d M Y H:i:s O'); - - /* "The serial number MUST be a positive integer" - "Conforming CAs MUST NOT use serialNumber values longer than 20 octets." - -- https://tools.ietf.org/html/rfc5280#section-4.1.2.2 - - for the integer to be positive the leading bit needs to be 0 hence the - application of a bitmap - */ - $serialNumber = !empty($this->serialNumber) ? - $this->serialNumber : - new BigInteger(Random::string(20) & ("\x7F" . str_repeat("\xFF", 19)), 256); - - $this->currentCert = [ - 'tbsCertificate' => - [ - 'version' => 'v3', - 'serialNumber' => $serialNumber, // $this->setSerialNumber() - 'signature' => $signatureAlgorithm, - 'issuer' => false, // this is going to be overwritten later - 'validity' => [ - 'notBefore' => $this->timeField($startDate), // $this->setStartDate() - 'notAfter' => $this->timeField($endDate) // $this->setEndDate() - ], - 'subject' => $subject->dn, - 'subjectPublicKeyInfo' => $subjectPublicKey - ], - 'signatureAlgorithm' => $signatureAlgorithm, - 'signature' => false // this is going to be overwritten later - ]; - - // Copy extensions from CSR. - $csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0); - - if (!empty($csrexts)) { - $this->currentCert['tbsCertificate']['extensions'] = $csrexts; - } - } - - $this->currentCert['tbsCertificate']['issuer'] = $issuer->dn; - - if (isset($issuer->currentKeyIdentifier)) { - $this->setExtension('id-ce-authorityKeyIdentifier', [ - //'authorityCertIssuer' => array( - // array( - // 'directoryName' => $issuer->dn - // ) - //), - 'keyIdentifier' => $issuer->currentKeyIdentifier - ]); - //$extensions = &$this->currentCert['tbsCertificate']['extensions']; - //if (isset($issuer->serialNumber)) { - // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; - //} - //unset($extensions); - } - - if (isset($subject->currentKeyIdentifier)) { - $this->setExtension('id-ce-subjectKeyIdentifier', $subject->currentKeyIdentifier); - } - - $altName = []; - - if (isset($subject->domains) && count($subject->domains)) { - $altName = array_map(['\phpseclib3\File\X509', 'dnsName'], $subject->domains); - } - - if (isset($subject->ipAddresses) && count($subject->ipAddresses)) { - // should an IP address appear as the CN if no domain name is specified? idk - //$ips = count($subject->domains) ? $subject->ipAddresses : array_slice($subject->ipAddresses, 1); - $ipAddresses = []; - foreach ($subject->ipAddresses as $ipAddress) { - $encoded = $subject->ipAddress($ipAddress); - if ($encoded !== false) { - $ipAddresses[] = $encoded; - } - } - if (count($ipAddresses)) { - $altName = array_merge($altName, $ipAddresses); - } - } - - if (!empty($altName)) { - $this->setExtension('id-ce-subjectAltName', $altName); - } - - if ($this->caFlag) { - $keyUsage = $this->getExtension('id-ce-keyUsage'); - if (!$keyUsage) { - $keyUsage = []; - } - - $this->setExtension( - 'id-ce-keyUsage', - array_values(array_unique(array_merge($keyUsage, ['cRLSign', 'keyCertSign']))) - ); - - $basicConstraints = $this->getExtension('id-ce-basicConstraints'); - if (!$basicConstraints) { - $basicConstraints = []; - } - - $this->setExtension( - 'id-ce-basicConstraints', - array_merge(['cA' => true], $basicConstraints), - true - ); - - if (!isset($subject->currentKeyIdentifier)) { - $this->setExtension('id-ce-subjectKeyIdentifier', $this->computeKeyIdentifier($this->currentCert), false, false); - } - } - - // resync $this->signatureSubject - // save $tbsCertificate in case there are any \phpseclib3\File\ASN1\Element objects in it - $tbsCertificate = $this->currentCert['tbsCertificate']; - $this->loadX509($this->saveX509($this->currentCert)); - - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); - $result['tbsCertificate'] = $tbsCertificate; - - $this->currentCert = $currentCert; - $this->signatureSubject = $signatureSubject; - - return $result; - } - - /** - * Sign a CSR - * - * @return mixed - */ - public function signCSR() - { - if (!is_object($this->privateKey) || empty($this->dn)) { - return false; - } - - $origPublicKey = $this->publicKey; - $this->publicKey = $this->privateKey->getPublicKey(); - $publicKey = $this->formatSubjectPublicKey(); - $this->publicKey = $origPublicKey; - - $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); - - if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['certificationRequestInfo'])) { - $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; - if (!empty($this->dn)) { - $this->currentCert['certificationRequestInfo']['subject'] = $this->dn; - } - $this->currentCert['certificationRequestInfo']['subjectPKInfo'] = $publicKey; - } else { - $this->currentCert = [ - 'certificationRequestInfo' => - [ - 'version' => 'v1', - 'subject' => $this->dn, - 'subjectPKInfo' => $publicKey - ], - 'signatureAlgorithm' => $signatureAlgorithm, - 'signature' => false // this is going to be overwritten later - ]; - } - - // resync $this->signatureSubject - // save $certificationRequestInfo in case there are any \phpseclib3\File\ASN1\Element objects in it - $certificationRequestInfo = $this->currentCert['certificationRequestInfo']; - $this->loadCSR($this->saveCSR($this->currentCert)); - - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); - $result['certificationRequestInfo'] = $certificationRequestInfo; - - $this->currentCert = $currentCert; - $this->signatureSubject = $signatureSubject; - - return $result; - } - - /** - * Sign a SPKAC - * - * @return mixed - */ - public function signSPKAC() - { - if (!is_object($this->privateKey)) { - return false; - } - - $origPublicKey = $this->publicKey; - $this->publicKey = $this->privateKey->getPublicKey(); - $publicKey = $this->formatSubjectPublicKey(); - $this->publicKey = $origPublicKey; - - $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($this->privateKey); - - // re-signing a SPKAC seems silly but since everything else supports re-signing why not? - if (isset($this->currentCert) && is_array($this->currentCert) && isset($this->currentCert['publicKeyAndChallenge'])) { - $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; - $this->currentCert['publicKeyAndChallenge']['spki'] = $publicKey; - if (!empty($this->challenge)) { - // the bitwise AND ensures that the output is a valid IA5String - $this->currentCert['publicKeyAndChallenge']['challenge'] = $this->challenge & str_repeat("\x7F", strlen($this->challenge)); - } - } else { - $this->currentCert = [ - 'publicKeyAndChallenge' => - [ - 'spki' => $publicKey, - // quoting , - // "A challenge string that is submitted along with the public key. Defaults to an empty string if not specified." - // both Firefox and OpenSSL ("openssl spkac -key private.key") behave this way - // we could alternatively do this instead if we ignored the specs: - // Random::string(8) & str_repeat("\x7F", 8) - 'challenge' => !empty($this->challenge) ? $this->challenge : '' - ], - 'signatureAlgorithm' => $signatureAlgorithm, - 'signature' => false // this is going to be overwritten later - ]; - } - - // resync $this->signatureSubject - // save $publicKeyAndChallenge in case there are any \phpseclib3\File\ASN1\Element objects in it - $publicKeyAndChallenge = $this->currentCert['publicKeyAndChallenge']; - $this->loadSPKAC($this->saveSPKAC($this->currentCert)); - - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $this->privateKey->sign($this->signatureSubject); - $result['publicKeyAndChallenge'] = $publicKeyAndChallenge; - - $this->currentCert = $currentCert; - $this->signatureSubject = $signatureSubject; - - return $result; - } - - /** - * Sign a CRL - * - * $issuer's private key needs to be loaded. - * - * @return mixed - */ - public function signCRL(X509 $issuer, X509 $crl) - { - if (!is_object($issuer->privateKey) || empty($issuer->dn)) { - return false; - } - - $currentCert = isset($this->currentCert) ? $this->currentCert : null; - $signatureSubject = isset($this->signatureSubject) ? $this->signatureSubject : null; - $signatureAlgorithm = self::identifySignatureAlgorithm($issuer->privateKey); - - $thisUpdate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); - $thisUpdate = !empty($this->startDate) ? $this->startDate : $thisUpdate->format('D, d M Y H:i:s O'); - - if (isset($crl->currentCert) && is_array($crl->currentCert) && isset($crl->currentCert['tbsCertList'])) { - $this->currentCert = $crl->currentCert; - $this->currentCert['tbsCertList']['signature'] = $signatureAlgorithm; - $this->currentCert['signatureAlgorithm'] = $signatureAlgorithm; - } else { - $this->currentCert = [ - 'tbsCertList' => - [ - 'version' => 'v2', - 'signature' => $signatureAlgorithm, - 'issuer' => false, // this is going to be overwritten later - 'thisUpdate' => $this->timeField($thisUpdate) // $this->setStartDate() - ], - 'signatureAlgorithm' => $signatureAlgorithm, - 'signature' => false // this is going to be overwritten later - ]; - } - - $tbsCertList = &$this->currentCert['tbsCertList']; - $tbsCertList['issuer'] = $issuer->dn; - $tbsCertList['thisUpdate'] = $this->timeField($thisUpdate); - - if (!empty($this->endDate)) { - $tbsCertList['nextUpdate'] = $this->timeField($this->endDate); // $this->setEndDate() - } else { - unset($tbsCertList['nextUpdate']); - } - - if (!empty($this->serialNumber)) { - $crlNumber = $this->serialNumber; - } else { - $crlNumber = $this->getExtension('id-ce-cRLNumber'); - // "The CRL number is a non-critical CRL extension that conveys a - // monotonically increasing sequence number for a given CRL scope and - // CRL issuer. This extension allows users to easily determine when a - // particular CRL supersedes another CRL." - // -- https://tools.ietf.org/html/rfc5280#section-5.2.3 - $crlNumber = $crlNumber !== false ? $crlNumber->add(new BigInteger(1)) : null; - } - - $this->removeExtension('id-ce-authorityKeyIdentifier'); - $this->removeExtension('id-ce-issuerAltName'); - - // Be sure version >= v2 if some extension found. - $version = isset($tbsCertList['version']) ? $tbsCertList['version'] : 0; - if (!$version) { - if (!empty($tbsCertList['crlExtensions'])) { - $version = 1; // v2. - } elseif (!empty($tbsCertList['revokedCertificates'])) { - foreach ($tbsCertList['revokedCertificates'] as $cert) { - if (!empty($cert['crlEntryExtensions'])) { - $version = 1; // v2. - } - } - } - - if ($version) { - $tbsCertList['version'] = $version; - } - } - - // Store additional extensions. - if (!empty($tbsCertList['version'])) { // At least v2. - if (!empty($crlNumber)) { - $this->setExtension('id-ce-cRLNumber', $crlNumber); - } - - if (isset($issuer->currentKeyIdentifier)) { - $this->setExtension('id-ce-authorityKeyIdentifier', [ - //'authorityCertIssuer' => array( - // ] - // 'directoryName' => $issuer->dn - // ] - //), - 'keyIdentifier' => $issuer->currentKeyIdentifier - ]); - //$extensions = &$tbsCertList['crlExtensions']; - //if (isset($issuer->serialNumber)) { - // $extensions[count($extensions) - 1]['authorityCertSerialNumber'] = $issuer->serialNumber; - //} - //unset($extensions); - } - - $issuerAltName = $this->getExtension('id-ce-subjectAltName', $issuer->currentCert); - - if ($issuerAltName !== false) { - $this->setExtension('id-ce-issuerAltName', $issuerAltName); - } - } - - if (empty($tbsCertList['revokedCertificates'])) { - unset($tbsCertList['revokedCertificates']); - } - - unset($tbsCertList); - - // resync $this->signatureSubject - // save $tbsCertList in case there are any \phpseclib3\File\ASN1\Element objects in it - $tbsCertList = $this->currentCert['tbsCertList']; - $this->loadCRL($this->saveCRL($this->currentCert)); - - $result = $this->currentCert; - $this->currentCert['signature'] = $result['signature'] = "\0" . $issuer->privateKey->sign($this->signatureSubject); - $result['tbsCertList'] = $tbsCertList; - - $this->currentCert = $currentCert; - $this->signatureSubject = $signatureSubject; - - return $result; - } - - /** - * Identify signature algorithm from key settings - * - * @param PrivateKey $key - * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported - * @return array - */ - private static function identifySignatureAlgorithm(PrivateKey $key) - { - if ($key instanceof RSA) { - if ($key->getPadding() & RSA::SIGNATURE_PSS) { - $r = PSS::load($key->withPassword()->toString('PSS')); - return [ - 'algorithm' => 'id-RSASSA-PSS', - 'parameters' => PSS::savePSSParams($r) - ]; - } - switch ($key->getHash()) { - case 'md2': - case 'md5': - case 'sha1': - case 'sha224': - case 'sha256': - case 'sha384': - case 'sha512': - return ['algorithm' => $key->getHash() . 'WithRSAEncryption']; - } - throw new UnsupportedAlgorithmException('The only supported hash algorithms for RSA are: md2, md5, sha1, sha224, sha256, sha384, sha512'); - } - - if ($key instanceof DSA) { - switch ($key->getHash()) { - case 'sha1': - case 'sha224': - case 'sha256': - return ['algorithm' => 'id-dsa-with-' . $key->getHash()]; - } - throw new UnsupportedAlgorithmException('The only supported hash algorithms for DSA are: sha1, sha224, sha256'); - } - - if ($key instanceof EC) { - switch ($key->getCurve()) { - case 'Ed25519': - case 'Ed448': - return ['algorithm' => 'id-' . $key->getCurve()]; - } - switch ($key->getHash()) { - case 'sha1': - case 'sha224': - case 'sha256': - case 'sha384': - case 'sha512': - return ['algorithm' => 'ecdsa-with-' . strtoupper($key->getHash())]; - } - throw new UnsupportedAlgorithmException('The only supported hash algorithms for EC are: sha1, sha224, sha256, sha384, sha512'); - } - - throw new UnsupportedAlgorithmException('The only supported public key classes are: RSA, DSA, EC'); - } - - /** - * Set certificate start date - * - * @param \DateTimeInterface|string $date - */ - public function setStartDate($date) - { - if (!is_object($date) || !($date instanceof \DateTimeInterface)) { - $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); - } - - $this->startDate = $date->format('D, d M Y H:i:s O'); - } - - /** - * Set certificate end date - * - * @param \DateTimeInterface|string $date - */ - public function setEndDate($date) - { - /* - To indicate that a certificate has no well-defined expiration date, - the notAfter SHOULD be assigned the GeneralizedTime value of - 99991231235959Z. - - -- http://tools.ietf.org/html/rfc5280#section-4.1.2.5 - */ - if (is_string($date) && strtolower($date) === 'lifetime') { - $temp = '99991231235959Z'; - $temp = chr(ASN1::TYPE_GENERALIZED_TIME) . ASN1::encodeLength(strlen($temp)) . $temp; - $this->endDate = new Element($temp); - } else { - if (!is_object($date) || !($date instanceof \DateTimeInterface)) { - $date = new \DateTimeImmutable($date, new \DateTimeZone(@date_default_timezone_get())); - } - - $this->endDate = $date->format('D, d M Y H:i:s O'); - } - } - - /** - * Set Serial Number - * - * @param string $serial - * @param int $base optional - */ - public function setSerialNumber($serial, $base = -256) - { - $this->serialNumber = new BigInteger($serial, $base); - } - - /** - * Turns the certificate into a certificate authority - * - */ - public function makeCA() - { - $this->caFlag = true; - } - - /** - * Check for validity of subarray - * - * This is intended for use in conjunction with _subArrayUnchecked(), - * implementing the checks included in _subArray() but without copying - * a potentially large array by passing its reference by-value to is_array(). - * - * @param array $root - * @param string $path - * @return boolean - */ - private function isSubArrayValid(array $root, $path) - { - if (!is_array($root)) { - return false; - } - - foreach (explode('/', $path) as $i) { - if (!is_array($root)) { - return false; - } - - if (!isset($root[$i])) { - return true; - } - - $root = $root[$i]; - } - - return true; - } - - /** - * Get a reference to a subarray - * - * This variant of _subArray() does no is_array() checking, - * so $root should be checked with _isSubArrayValid() first. - * - * This is here for performance reasons: - * Passing a reference (i.e. $root) by-value (i.e. to is_array()) - * creates a copy. If $root is an especially large array, this is expensive. - * - * @param array $root - * @param string $path absolute path with / as component separator - * @param bool $create optional - * @return array|false - */ - private function &subArrayUnchecked(array &$root, $path, $create = false) - { - $false = false; - - foreach (explode('/', $path) as $i) { - if (!isset($root[$i])) { - if (!$create) { - return $false; - } - - $root[$i] = []; - } - - $root = &$root[$i]; - } - - return $root; - } - - /** - * Get a reference to a subarray - * - * @param array $root - * @param string $path absolute path with / as component separator - * @param bool $create optional - * @return array|false - */ - private function &subArray(array &$root = null, $path, $create = false) - { - $false = false; - - if (!is_array($root)) { - return $false; - } - - foreach (explode('/', $path) as $i) { - if (!is_array($root)) { - return $false; - } - - if (!isset($root[$i])) { - if (!$create) { - return $false; - } - - $root[$i] = []; - } - - $root = &$root[$i]; - } - - return $root; - } - - /** - * Get a reference to an extension subarray - * - * @param array $root - * @param string $path optional absolute path with / as component separator - * @param bool $create optional - * @return array|false - */ - private function &extensions(array &$root = null, $path = null, $create = false) - { - if (!isset($root)) { - $root = $this->currentCert; - } - - switch (true) { - case !empty($path): - case !is_array($root): - break; - case isset($root['tbsCertificate']): - $path = 'tbsCertificate/extensions'; - break; - case isset($root['tbsCertList']): - $path = 'tbsCertList/crlExtensions'; - break; - case isset($root['certificationRequestInfo']): - $pth = 'certificationRequestInfo/attributes'; - $attributes = &$this->subArray($root, $pth, $create); - - if (is_array($attributes)) { - foreach ($attributes as $key => $value) { - if ($value['type'] == 'pkcs-9-at-extensionRequest') { - $path = "$pth/$key/value/0"; - break 2; - } - } - if ($create) { - $key = count($attributes); - $attributes[] = ['type' => 'pkcs-9-at-extensionRequest', 'value' => []]; - $path = "$pth/$key/value/0"; - } - } - break; - } - - $extensions = &$this->subArray($root, $path, $create); - - if (!is_array($extensions)) { - $false = false; - return $false; - } - - return $extensions; - } - - /** - * Remove an Extension - * - * @param string $id - * @param string $path optional - * @return bool - */ - private function removeExtensionHelper($id, $path = null) - { - $extensions = &$this->extensions($this->currentCert, $path); - - if (!is_array($extensions)) { - return false; - } - - $result = false; - foreach ($extensions as $key => $value) { - if ($value['extnId'] == $id) { - unset($extensions[$key]); - $result = true; - } - } - - $extensions = array_values($extensions); - // fix for https://bugs.php.net/75433 affecting PHP 7.2 - if (!isset($extensions[0])) { - $extensions = array_splice($extensions, 0, 0); - } - return $result; - } - - /** - * Get an Extension - * - * Returns the extension if it exists and false if not - * - * @param string $id - * @param array $cert optional - * @param string $path optional - * @return mixed - */ - private function getExtensionHelper($id, array $cert = null, $path = null) - { - $extensions = $this->extensions($cert, $path); - - if (!is_array($extensions)) { - return false; - } - - foreach ($extensions as $key => $value) { - if ($value['extnId'] == $id) { - return $value['extnValue']; - } - } - - return false; - } - - /** - * Returns a list of all extensions in use - * - * @param array $cert optional - * @param string $path optional - * @return array - */ - private function getExtensionsHelper(array $cert = null, $path = null) - { - $exts = $this->extensions($cert, $path); - $extensions = []; - - if (is_array($exts)) { - foreach ($exts as $extension) { - $extensions[] = $extension['extnId']; - } - } - - return $extensions; - } - - /** - * Set an Extension - * - * @param string $id - * @param mixed $value - * @param bool $critical optional - * @param bool $replace optional - * @param string $path optional - * @return bool - */ - private function setExtensionHelper($id, $value, $critical = false, $replace = true, $path = null) - { - $extensions = &$this->extensions($this->currentCert, $path, true); - - if (!is_array($extensions)) { - return false; - } - - $newext = ['extnId' => $id, 'critical' => $critical, 'extnValue' => $value]; - - foreach ($extensions as $key => $value) { - if ($value['extnId'] == $id) { - if (!$replace) { - return false; - } - - $extensions[$key] = $newext; - return true; - } - } - - $extensions[] = $newext; - return true; - } - - /** - * Remove a certificate, CSR or CRL Extension - * - * @param string $id - * @return bool - */ - public function removeExtension($id) - { - return $this->removeExtensionHelper($id); - } - - /** - * Get a certificate, CSR or CRL Extension - * - * Returns the extension if it exists and false if not - * - * @param string $id - * @param array $cert optional - * @param string $path - * @return mixed - */ - public function getExtension($id, array $cert = null, $path = null) - { - return $this->getExtensionHelper($id, $cert, $path); - } - - /** - * Returns a list of all extensions in use in certificate, CSR or CRL - * - * @param array $cert optional - * @param string $path optional - * @return array - */ - public function getExtensions(array $cert = null, $path = null) - { - return $this->getExtensionsHelper($cert, $path); - } - - /** - * Set a certificate, CSR or CRL Extension - * - * @param string $id - * @param mixed $value - * @param bool $critical optional - * @param bool $replace optional - * @return bool - */ - public function setExtension($id, $value, $critical = false, $replace = true) - { - return $this->setExtensionHelper($id, $value, $critical, $replace); - } - - /** - * Remove a CSR attribute. - * - * @param string $id - * @param int $disposition optional - * @return bool - */ - public function removeAttribute($id, $disposition = self::ATTR_ALL) - { - $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes'); - - if (!is_array($attributes)) { - return false; - } - - $result = false; - foreach ($attributes as $key => $attribute) { - if ($attribute['type'] == $id) { - $n = count($attribute['value']); - switch (true) { - case $disposition == self::ATTR_APPEND: - case $disposition == self::ATTR_REPLACE: - return false; - case $disposition >= $n: - $disposition -= $n; - break; - case $disposition == self::ATTR_ALL: - case $n == 1: - unset($attributes[$key]); - $result = true; - break; - default: - unset($attributes[$key]['value'][$disposition]); - $attributes[$key]['value'] = array_values($attributes[$key]['value']); - $result = true; - break; - } - if ($result && $disposition != self::ATTR_ALL) { - break; - } - } - } - - $attributes = array_values($attributes); - return $result; - } - - /** - * Get a CSR attribute - * - * Returns the attribute if it exists and false if not - * - * @param string $id - * @param int $disposition optional - * @param array $csr optional - * @return mixed - */ - public function getAttribute($id, $disposition = self::ATTR_ALL, array $csr = null) - { - if (empty($csr)) { - $csr = $this->currentCert; - } - - $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); - - if (!is_array($attributes)) { - return false; - } - - foreach ($attributes as $key => $attribute) { - if ($attribute['type'] == $id) { - $n = count($attribute['value']); - switch (true) { - case $disposition == self::ATTR_APPEND: - case $disposition == self::ATTR_REPLACE: - return false; - case $disposition == self::ATTR_ALL: - return $attribute['value']; - case $disposition >= $n: - $disposition -= $n; - break; - default: - return $attribute['value'][$disposition]; - } - } - } - - return false; - } - - /** - * Returns a list of all CSR attributes in use - * - * @param array $csr optional - * @return array - */ - public function getAttributes(array $csr = null) - { - if (empty($csr)) { - $csr = $this->currentCert; - } - - $attributes = $this->subArray($csr, 'certificationRequestInfo/attributes'); - $attrs = []; - - if (is_array($attributes)) { - foreach ($attributes as $attribute) { - $attrs[] = $attribute['type']; - } - } - - return $attrs; - } - - /** - * Set a CSR attribute - * - * @param string $id - * @param mixed $value - * @param int $disposition optional - * @return bool - */ - public function setAttribute($id, $value, $disposition = self::ATTR_ALL) - { - $attributes = &$this->subArray($this->currentCert, 'certificationRequestInfo/attributes', true); - - if (!is_array($attributes)) { - return false; - } - - switch ($disposition) { - case self::ATTR_REPLACE: - $disposition = self::ATTR_APPEND; - // fall-through - case self::ATTR_ALL: - $this->removeAttribute($id); - break; - } - - foreach ($attributes as $key => $attribute) { - if ($attribute['type'] == $id) { - $n = count($attribute['value']); - switch (true) { - case $disposition == self::ATTR_APPEND: - $last = $key; - break; - case $disposition >= $n: - $disposition -= $n; - break; - default: - $attributes[$key]['value'][$disposition] = $value; - return true; - } - } - } - - switch (true) { - case $disposition >= 0: - return false; - case isset($last): - $attributes[$last]['value'][] = $value; - break; - default: - $attributes[] = ['type' => $id, 'value' => $disposition == self::ATTR_ALL ? $value : [$value]]; - break; - } - - return true; - } - - /** - * Sets the subject key identifier - * - * This is used by the id-ce-authorityKeyIdentifier and the id-ce-subjectKeyIdentifier extensions. - * - * @param string $value - */ - public function setKeyIdentifier($value) - { - if (empty($value)) { - unset($this->currentKeyIdentifier); - } else { - $this->currentKeyIdentifier = $value; - } - } - - /** - * Compute a public key identifier. - * - * Although key identifiers may be set to any unique value, this function - * computes key identifiers from public key according to the two - * recommended methods (4.2.1.2 RFC 3280). - * Highly polymorphic: try to accept all possible forms of key: - * - Key object - * - \phpseclib3\File\X509 object with public or private key defined - * - Certificate or CSR array - * - \phpseclib3\File\ASN1\Element object - * - PEM or DER string - * - * @param mixed $key optional - * @param int $method optional - * @return string binary key identifier - */ - public function computeKeyIdentifier($key = null, $method = 1) - { - if (is_null($key)) { - $key = $this; - } - - switch (true) { - case is_string($key): - break; - case is_array($key) && isset($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey']): - return $this->computeKeyIdentifier($key['tbsCertificate']['subjectPublicKeyInfo']['subjectPublicKey'], $method); - case is_array($key) && isset($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey']): - return $this->computeKeyIdentifier($key['certificationRequestInfo']['subjectPKInfo']['subjectPublicKey'], $method); - case !is_object($key): - return false; - case $key instanceof Element: - // Assume the element is a bitstring-packed key. - $decoded = ASN1::decodeBER($key->element); - if (!$decoded) { - return false; - } - $raw = ASN1::asn1map($decoded[0], ['type' => ASN1::TYPE_BIT_STRING]); - if (empty($raw)) { - return false; - } - // If the key is private, compute identifier from its corresponding public key. - $key = PublicKeyLoader::load($raw); - if ($key instanceof PrivateKey) { // If private. - return $this->computeKeyIdentifier($key, $method); - } - $key = $raw; // Is a public key. - break; - case $key instanceof X509: - if (isset($key->publicKey)) { - return $this->computeKeyIdentifier($key->publicKey, $method); - } - if (isset($key->privateKey)) { - return $this->computeKeyIdentifier($key->privateKey, $method); - } - if (isset($key->currentCert['tbsCertificate']) || isset($key->currentCert['certificationRequestInfo'])) { - return $this->computeKeyIdentifier($key->currentCert, $method); - } - return false; - default: // Should be a key object (i.e.: \phpseclib3\Crypt\RSA). - $key = $key->getPublicKey(); - break; - } - - // If in PEM format, convert to binary. - $key = ASN1::extractBER($key); - - // Now we have the key string: compute its sha-1 sum. - $hash = new Hash('sha1'); - $hash = $hash->hash($key); - - if ($method == 2) { - $hash = substr($hash, -8); - $hash[0] = chr((ord($hash[0]) & 0x0F) | 0x40); - } - - return $hash; - } - - /** - * Format a public key as appropriate - * - * @return array|false - */ - private function formatSubjectPublicKey() - { - $format = $this->publicKey instanceof RSA && ($this->publicKey->getPadding() & RSA::SIGNATURE_PSS) ? - 'PSS' : - 'PKCS8'; - - $publicKey = base64_decode(preg_replace('#-.+-|[\r\n]#', '', $this->publicKey->toString($format))); - - $decoded = ASN1::decodeBER($publicKey); - if (!$decoded) { - return false; - } - $mapped = ASN1::asn1map($decoded[0], Maps\SubjectPublicKeyInfo::MAP); - if (!is_array($mapped)) { - return false; - } - - $mapped['subjectPublicKey'] = $this->publicKey->toString($format); - - return $mapped; - } - - /** - * Set the domain name's which the cert is to be valid for - * - * @param mixed ...$domains - * @return void - */ - public function setDomain(...$domains) - { - $this->domains = $domains; - $this->removeDNProp('id-at-commonName'); - $this->setDNProp('id-at-commonName', $this->domains[0]); - } - - /** - * Set the IP Addresses's which the cert is to be valid for - * - * @param mixed[] ...$ipAddresses - */ - public function setIPAddress(...$ipAddresses) - { - $this->ipAddresses = $ipAddresses; - /* - if (!isset($this->domains)) { - $this->removeDNProp('id-at-commonName'); - $this->setDNProp('id-at-commonName', $this->ipAddresses[0]); - } - */ - } - - /** - * Helper function to build domain array - * - * @param string $domain - * @return array - */ - private static function dnsName($domain) - { - return ['dNSName' => $domain]; - } - - /** - * Helper function to build IP Address array - * - * (IPv6 is not currently supported) - * - * @param string $address - * @return array - */ - private function iPAddress($address) - { - return ['iPAddress' => $address]; - } - - /** - * Get the index of a revoked certificate. - * - * @param array $rclist - * @param string $serial - * @param bool $create optional - * @return int|false - */ - private function revokedCertificate(array &$rclist, $serial, $create = false) - { - $serial = new BigInteger($serial); - - foreach ($rclist as $i => $rc) { - if (!($serial->compare($rc['userCertificate']))) { - return $i; - } - } - - if (!$create) { - return false; - } - - $i = count($rclist); - $revocationDate = new \DateTimeImmutable('now', new \DateTimeZone(@date_default_timezone_get())); - $rclist[] = ['userCertificate' => $serial, - 'revocationDate' => $this->timeField($revocationDate->format('D, d M Y H:i:s O'))]; - return $i; - } - - /** - * Revoke a certificate. - * - * @param string $serial - * @param string $date optional - * @return bool - */ - public function revoke($serial, $date = null) - { - if (isset($this->currentCert['tbsCertList'])) { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { - if ($this->revokedCertificate($rclist, $serial) === false) { // If not yet revoked - if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { - if (!empty($date)) { - $rclist[$i]['revocationDate'] = $this->timeField($date); - } - - return true; - } - } - } - } - - return false; - } - - /** - * Unrevoke a certificate. - * - * @param string $serial - * @return bool - */ - public function unrevoke($serial) - { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - unset($rclist[$i]); - $rclist = array_values($rclist); - return true; - } - } - - return false; - } - - /** - * Get a revoked certificate. - * - * @param string $serial - * @return mixed - */ - public function getRevoked($serial) - { - if (is_array($rclist = $this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $rclist[$i]; - } - } - - return false; - } - - /** - * List revoked certificates - * - * @param array $crl optional - * @return array|bool - */ - public function listRevoked(array $crl = null) - { - if (!isset($crl)) { - $crl = $this->currentCert; - } - - if (!isset($crl['tbsCertList'])) { - return false; - } - - $result = []; - - if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { - foreach ($rclist as $rc) { - $result[] = $rc['userCertificate']->toString(); - } - } - - return $result; - } - - /** - * Remove a Revoked Certificate Extension - * - * @param string $serial - * @param string $id - * @return bool - */ - public function removeRevokedCertificateExtension($serial, $id) - { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $this->removeExtensionHelper($id, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); - } - } - - return false; - } - - /** - * Get a Revoked Certificate Extension - * - * Returns the extension if it exists and false if not - * - * @param string $serial - * @param string $id - * @param array $crl optional - * @return mixed - */ - public function getRevokedCertificateExtension($serial, $id, array $crl = null) - { - if (!isset($crl)) { - $crl = $this->currentCert; - } - - if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $this->getExtension($id, $crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); - } - } - - return false; - } - - /** - * Returns a list of all extensions in use for a given revoked certificate - * - * @param string $serial - * @param array $crl optional - * @return array|bool - */ - public function getRevokedCertificateExtensions($serial, array $crl = null) - { - if (!isset($crl)) { - $crl = $this->currentCert; - } - - if (is_array($rclist = $this->subArray($crl, 'tbsCertList/revokedCertificates'))) { - if (($i = $this->revokedCertificate($rclist, $serial)) !== false) { - return $this->getExtensions($crl, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); - } - } - - return false; - } - - /** - * Set a Revoked Certificate Extension - * - * @param string $serial - * @param string $id - * @param mixed $value - * @param bool $critical optional - * @param bool $replace optional - * @return bool - */ - public function setRevokedCertificateExtension($serial, $id, $value, $critical = false, $replace = true) - { - if (isset($this->currentCert['tbsCertList'])) { - if (is_array($rclist = &$this->subArray($this->currentCert, 'tbsCertList/revokedCertificates', true))) { - if (($i = $this->revokedCertificate($rclist, $serial, true)) !== false) { - return $this->setExtensionHelper($id, $value, $critical, $replace, "tbsCertList/revokedCertificates/$i/crlEntryExtensions"); - } - } - } - - return false; - } - - /** - * Register the mapping for a custom/unsupported extension. - * - * @param string $id - * @param array $mapping - */ - public static function registerExtension($id, array $mapping) - { - if (isset(self::$extensions[$id]) && self::$extensions[$id] !== $mapping) { - throw new \RuntimeException( - 'Extension ' . $id . ' has already been defined with a different mapping.' - ); - } - - self::$extensions[$id] = $mapping; - } - - /** - * Register the mapping for a custom/unsupported extension. - * - * @param string $id - * - * @return array|null - */ - public static function getRegisteredExtension($id) - { - return isset(self::$extensions[$id]) ? self::$extensions[$id] : null; - } - - /** - * Register the mapping for a custom/unsupported extension. - * - * @param string $id - * @param mixed $value - * @param bool $critical - * @param bool $replace - */ - public function setExtensionValue($id, $value, $critical = false, $replace = false) - { - $this->extensionValues[$id] = compact('critical', 'replace', 'value'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php deleted file mode 100644 index 67d4788..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger.php +++ /dev/null @@ -1,892 +0,0 @@ - - * add($b); - * - * echo $c->toString(); // outputs 5 - * ?> - * - * - * @author Jim Wigginton - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math; - -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Math\BigInteger\Engines\Engine; - -/** - * Pure-PHP arbitrary precision integer arithmetic library. Supports base-2, base-10, base-16, and base-256 - * numbers. - * - * @author Jim Wigginton - */ -class BigInteger implements \JsonSerializable -{ - /** - * Main Engine - * - * @var class-string - */ - private static $mainEngine; - - /** - * Selected Engines - * - * @var list - */ - private static $engines; - - /** - * The actual BigInteger object - * - * @var object - */ - private $value; - - /** - * Mode independent value used for serialization. - * - * @see self::__sleep() - * @see self::__wakeup() - * @var string - */ - private $hex; - - /** - * Precision (used only for serialization) - * - * @see self::__sleep() - * @see self::__wakeup() - * @var int - */ - private $precision; - - /** - * Sets engine type. - * - * Throws an exception if the type is invalid - * - * @param string $main - * @param list $modexps optional - * @return void - */ - public static function setEngine($main, array $modexps = ['DefaultEngine']) - { - self::$engines = []; - - $fqmain = 'phpseclib3\\Math\\BigInteger\\Engines\\' . $main; - if (!class_exists($fqmain) || !method_exists($fqmain, 'isValidEngine')) { - throw new \InvalidArgumentException("$main is not a valid engine"); - } - if (!$fqmain::isValidEngine()) { - throw new BadConfigurationException("$main is not setup correctly on this system"); - } - /** @var class-string $fqmain */ - self::$mainEngine = $fqmain; - - $found = false; - foreach ($modexps as $modexp) { - try { - $fqmain::setModExpEngine($modexp); - $found = true; - break; - } catch (\Exception $e) { - } - } - - if (!$found) { - throw new BadConfigurationException("No valid modular exponentiation engine found for $main"); - } - - self::$engines = [$main, $modexp]; - } - - /** - * Returns the engine type - * - * @return string[] - */ - public static function getEngine() - { - self::initialize_static_variables(); - - return self::$engines; - } - - /** - * Initialize static variables - */ - private static function initialize_static_variables() - { - if (!isset(self::$mainEngine)) { - $engines = [ - ['GMP', ['DefaultEngine']], - ['PHP64', ['OpenSSL']], - ['BCMath', ['OpenSSL']], - ['PHP32', ['OpenSSL']], - ['PHP64', ['DefaultEngine']], - ['PHP32', ['DefaultEngine']] - ]; - - foreach ($engines as $engine) { - try { - self::setEngine($engine[0], $engine[1]); - return; - } catch (\Exception $e) { - } - } - - throw new \UnexpectedValueException('No valid BigInteger found. This is only possible when JIT is enabled on Windows and neither the GMP or BCMath extensions are available so either disable JIT or install GMP / BCMath'); - } - } - - /** - * Converts base-2, base-10, base-16, and binary strings (base-256) to BigIntegers. - * - * If the second parameter - $base - is negative, then it will be assumed that the number's are encoded using - * two's compliment. The sole exception to this is -10, which is treated the same as 10 is. - * - * @param string|int|BigInteger\Engines\Engine $x Base-10 number or base-$base number if $base set. - * @param int $base - */ - public function __construct($x = 0, $base = 10) - { - self::initialize_static_variables(); - - if ($x instanceof self::$mainEngine) { - $this->value = clone $x; - } elseif ($x instanceof BigInteger\Engines\Engine) { - $this->value = new static("$x"); - $this->value->setPrecision($x->getPrecision()); - } else { - $this->value = new self::$mainEngine($x, $base); - } - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - return $this->value->toString(); - } - - /** - * __toString() magic method - */ - public function __toString() - { - return (string)$this->value; - } - - /** - * __debugInfo() magic method - * - * Will be called, automatically, when print_r() or var_dump() are called - */ - public function __debugInfo() - { - return $this->value->__debugInfo(); - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - public function toBytes($twos_compliment = false) - { - return $this->value->toBytes($twos_compliment); - } - - /** - * Converts a BigInteger to a hex string (eg. base-16). - * - * @param bool $twos_compliment - * @return string - */ - public function toHex($twos_compliment = false) - { - return $this->value->toHex($twos_compliment); - } - - /** - * Converts a BigInteger to a bit string (eg. base-2). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * @param bool $twos_compliment - * @return string - */ - public function toBits($twos_compliment = false) - { - return $this->value->toBits($twos_compliment); - } - - /** - * Adds two BigIntegers. - * - * @param BigInteger $y - * @return BigInteger - */ - public function add(BigInteger $y) - { - return new static($this->value->add($y->value)); - } - - /** - * Subtracts two BigIntegers. - * - * @param BigInteger $y - * @return BigInteger - */ - public function subtract(BigInteger $y) - { - return new static($this->value->subtract($y->value)); - } - - /** - * Multiplies two BigIntegers - * - * @param BigInteger $x - * @return BigInteger - */ - public function multiply(BigInteger $x) - { - return new static($this->value->multiply($x->value)); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * Here's an example: - * - * divide($b); - * - * echo $quotient->toString(); // outputs 0 - * echo "\r\n"; - * echo $remainder->toString(); // outputs 10 - * ?> - * - * - * @param BigInteger $y - * @return BigInteger[] - */ - public function divide(BigInteger $y) - { - list($q, $r) = $this->value->divide($y->value); - return [ - new static($q), - new static($r) - ]; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * @param BigInteger $n - * @return BigInteger - */ - public function modInverse(BigInteger $n) - { - return new static($this->value->modInverse($n->value)); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * @param BigInteger $n - * @return BigInteger[] - */ - public function extendedGCD(BigInteger $n) - { - extract($this->value->extendedGCD($n->value)); - /** - * @var BigInteger $gcd - * @var BigInteger $x - * @var BigInteger $y - */ - return [ - 'gcd' => new static($gcd), - 'x' => new static($x), - 'y' => new static($y) - ]; - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param BigInteger $n - * @return BigInteger - */ - public function gcd(BigInteger $n) - { - return new static($this->value->gcd($n->value)); - } - - /** - * Absolute value. - * - * @return BigInteger - */ - public function abs() - { - return new static($this->value->abs()); - } - - /** - * Set Precision - * - * Some bitwise operations give different results depending on the precision being used. Examples include left - * shift, not, and rotates. - * - * @param int $bits - */ - public function setPrecision($bits) - { - $this->value->setPrecision($bits); - } - - /** - * Get Precision - * - * Returns the precision if it exists, false if it doesn't - * - * @return int|bool - */ - public function getPrecision() - { - return $this->value->getPrecision(); - } - - /** - * Serialize - * - * Will be called, automatically, when serialize() is called on a BigInteger object. - * - * __sleep() / __wakeup() have been around since PHP 4.0 - * - * \Serializable was introduced in PHP 5.1 and deprecated in PHP 8.1: - * https://wiki.php.net/rfc/phase_out_serializable - * - * __serialize() / __unserialize() were introduced in PHP 7.4: - * https://wiki.php.net/rfc/custom_object_serialization - * - * @return array - */ - public function __sleep() - { - $this->hex = $this->toHex(true); - $vars = ['hex']; - if ($this->getPrecision() > 0) { - $vars[] = 'precision'; - } - return $vars; - } - - /** - * Serialize - * - * Will be called, automatically, when unserialize() is called on a BigInteger object. - */ - public function __wakeup() - { - $temp = new static($this->hex, -16); - $this->value = $temp->value; - if ($this->precision > 0) { - // recalculate $this->bitmask - $this->setPrecision($this->precision); - } - } - - /** - * JSON Serialize - * - * Will be called, automatically, when json_encode() is called on a BigInteger object. - * - * @return array{hex: string, precision?: int] - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - $result = ['hex' => $this->toHex(true)]; - if ($this->precision > 0) { - $result['precision'] = $this->getPrecision(); - } - return $result; - } - - /** - * Performs modular exponentiation. - * - * @param BigInteger $e - * @param BigInteger $n - * @return BigInteger - */ - public function powMod(BigInteger $e, BigInteger $n) - { - return new static($this->value->powMod($e->value, $n->value)); - } - - /** - * Performs modular exponentiation. - * - * @param BigInteger $e - * @param BigInteger $n - * @return BigInteger - */ - public function modPow(BigInteger $e, BigInteger $n) - { - return new static($this->value->modPow($e->value, $n->value)); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this - * is demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param BigInteger $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @see self::equals() - */ - public function compare(BigInteger $y) - { - return $this->value->compare($y->value); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param BigInteger $x - * @return bool - */ - public function equals(BigInteger $x) - { - return $this->value->equals($x->value); - } - - /** - * Logical Not - * - * @return BigInteger - */ - public function bitwise_not() - { - return new static($this->value->bitwise_not()); - } - - /** - * Logical And - * - * @param BigInteger $x - * @return BigInteger - */ - public function bitwise_and(BigInteger $x) - { - return new static($this->value->bitwise_and($x->value)); - } - - /** - * Logical Or - * - * @param BigInteger $x - * @return BigInteger - */ - public function bitwise_or(BigInteger $x) - { - return new static($this->value->bitwise_or($x->value)); - } - - /** - * Logical Exclusive Or - * - * @param BigInteger $x - * @return BigInteger - */ - public function bitwise_xor(BigInteger $x) - { - return new static($this->value->bitwise_xor($x->value)); - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return BigInteger - */ - public function bitwise_rightShift($shift) - { - return new static($this->value->bitwise_rightShift($shift)); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return BigInteger - */ - public function bitwise_leftShift($shift) - { - return new static($this->value->bitwise_leftShift($shift)); - } - - /** - * Logical Left Rotate - * - * Instead of the top x bits being dropped they're appended to the shifted bit string. - * - * @param int $shift - * @return BigInteger - */ - public function bitwise_leftRotate($shift) - { - return new static($this->value->bitwise_leftRotate($shift)); - } - - /** - * Logical Right Rotate - * - * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. - * - * @param int $shift - * @return BigInteger - */ - public function bitwise_rightRotate($shift) - { - return new static($this->value->bitwise_rightRotate($shift)); - } - - /** - * Returns the smallest and largest n-bit number - * - * @param int $bits - * @return BigInteger[] - */ - public static function minMaxBits($bits) - { - self::initialize_static_variables(); - - $class = self::$mainEngine; - extract($class::minMaxBits($bits)); - /** @var BigInteger $min - * @var BigInteger $max - */ - return [ - 'min' => new static($min), - 'max' => new static($max) - ]; - } - - /** - * Return the size of a BigInteger in bits - * - * @return int - */ - public function getLength() - { - return $this->value->getLength(); - } - - /** - * Return the size of a BigInteger in bytes - * - * @return int - */ - public function getLengthInBytes() - { - return $this->value->getLengthInBytes(); - } - - /** - * Generates a random number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return BigInteger - */ - public static function random($size) - { - self::initialize_static_variables(); - - $class = self::$mainEngine; - return new static($class::random($size)); - } - - /** - * Generates a random prime number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return BigInteger - */ - public static function randomPrime($size) - { - self::initialize_static_variables(); - - $class = self::$mainEngine; - return new static($class::randomPrime($size)); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param BigInteger $min - * @param BigInteger $max - * @return false|BigInteger - */ - public static function randomRangePrime(BigInteger $min, BigInteger $max) - { - $class = self::$mainEngine; - return new static($class::randomRangePrime($min->value, $max->value)); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param BigInteger $min - * @param BigInteger $max - * @return BigInteger - */ - public static function randomRange(BigInteger $min, BigInteger $max) - { - $class = self::$mainEngine; - return new static($class::randomRange($min->value, $max->value)); - } - - /** - * Checks a numer to see if it's prime - * - * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the - * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads - * on a website instead of just one. - * - * @param int|bool $t - * @return bool - */ - public function isPrime($t = false) - { - return $this->value->isPrime($t); - } - - /** - * Calculates the nth root of a biginteger. - * - * Returns the nth root of a positive biginteger, where n defaults to 2 - * - * @param int $n optional - * @return BigInteger - */ - public function root($n = 2) - { - return new static($this->value->root($n)); - } - - /** - * Performs exponentiation. - * - * @param BigInteger $n - * @return BigInteger - */ - public function pow(BigInteger $n) - { - return new static($this->value->pow($n->value)); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param BigInteger ...$nums - * @return BigInteger - */ - public static function min(BigInteger ...$nums) - { - $class = self::$mainEngine; - $nums = array_map(function ($num) { - return $num->value; - }, $nums); - return new static($class::min(...$nums)); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param BigInteger ...$nums - * @return BigInteger - */ - public static function max(BigInteger ...$nums) - { - $class = self::$mainEngine; - $nums = array_map(function ($num) { - return $num->value; - }, $nums); - return new static($class::max(...$nums)); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param BigInteger $min - * @param BigInteger $max - * @return bool - */ - public function between(BigInteger $min, BigInteger $max) - { - return $this->value->between($min->value, $max->value); - } - - /** - * Clone - */ - public function __clone() - { - $this->value = clone $this->value; - } - - /** - * Is Odd? - * - * @return bool - */ - public function isOdd() - { - return $this->value->isOdd(); - } - - /** - * Tests if a bit is set - * - * @param int $x - * @return bool - */ - public function testBit($x) - { - return $this->value->testBit($x); - } - - /** - * Is Negative? - * - * @return bool - */ - public function isNegative() - { - return $this->value->isNegative(); - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return BigInteger - */ - public function negate() - { - return new static($this->value->negate()); - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @param BigInteger $r - * @return int - */ - public static function scan1divide(BigInteger $r) - { - $class = self::$mainEngine; - return $class::scan1divide($r->value); - } - - /** - * Create Recurring Modulo Function - * - * Sometimes it may be desirable to do repeated modulos with the same number outside of - * modular exponentiation - * - * @return callable - */ - public function createRecurringModuloFunction() - { - $func = $this->value->createRecurringModuloFunction(); - return function (BigInteger $x) use ($func) { - return new static($func($x->value)); - }; - } - - /** - * Bitwise Split - * - * Splits BigInteger's into chunks of $split bits - * - * @param int $split - * @return BigInteger[] - */ - public function bitwise_split($split) - { - return array_map(function ($val) { - return new static($val); - }, $this->value->bitwise_split($split)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php deleted file mode 100644 index 7c5ca9f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath.php +++ /dev/null @@ -1,697 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\BadConfigurationException; - -/** - * BCMath Engine. - * - * @author Jim Wigginton - */ -class BCMath extends Engine -{ - /** - * Can Bitwise operations be done fast? - * - * @see parent::bitwise_leftRotate() - * @see parent::bitwise_rightRotate() - */ - const FAST_BITWISE = false; - - /** - * Engine Directory - * - * @see parent::setModExpEngine - */ - const ENGINE_DIR = 'BCMath'; - - /** - * Test for engine validity - * - * @return bool - * @see parent::__construct() - */ - public static function isValidEngine() - { - return extension_loaded('bcmath'); - } - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - * @see parent::__construct() - */ - public function __construct($x = 0, $base = 10) - { - if (!isset(static::$isValidEngine[static::class])) { - static::$isValidEngine[static::class] = self::isValidEngine(); - } - if (!static::$isValidEngine[static::class]) { - throw new BadConfigurationException('BCMath is not setup correctly on this system'); - } - - $this->value = '0'; - - parent::__construct($x, $base); - } - - /** - * Initialize a BCMath BigInteger Engine instance - * - * @param int $base - * @see parent::__construct() - */ - protected function initialize($base) - { - switch (abs($base)) { - case 256: - // round $len to the nearest 4 - $len = (strlen($this->value) + 3) & ~3; - - $x = str_pad($this->value, $len, chr(0), STR_PAD_LEFT); - - $this->value = '0'; - for ($i = 0; $i < $len; $i += 4) { - $this->value = bcmul($this->value, '4294967296', 0); // 4294967296 == 2**32 - $this->value = bcadd( - $this->value, - 0x1000000 * ord($x[$i]) + ((ord($x[$i + 1]) << 16) | (ord( - $x[$i + 2] - ) << 8) | ord($x[$i + 3])), - 0 - ); - } - - if ($this->is_negative) { - $this->value = '-' . $this->value; - } - break; - case 16: - $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; - $temp = new self(Strings::hex2bin($x), 256); - $this->value = $this->is_negative ? '-' . $temp->value : $temp->value; - $this->is_negative = false; - break; - case 10: - // explicitly casting $x to a string is necessary, here, since doing $x[0] on -1 yields different - // results then doing it on '-1' does (modInverse does $x[0]) - $this->value = $this->value === '-' ? '0' : (string)$this->value; - } - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - if ($this->value === '0') { - return '0'; - } - - return ltrim($this->value, '0'); - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - public function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - return $this->toBytesHelper(); - } - - $value = ''; - $current = $this->value; - - if ($current[0] == '-') { - $current = substr($current, 1); - } - - while (bccomp($current, '0', 0) > 0) { - $temp = bcmod($current, '16777216'); - $value = chr($temp >> 16) . chr($temp >> 8) . chr($temp) . $value; - $current = bcdiv($current, '16777216', 0); - } - - return $this->precision > 0 ? - substr(str_pad($value, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : - ltrim($value, chr(0)); - } - - /** - * Adds two BigIntegers. - * - * @param BCMath $y - * @return BCMath - */ - public function add(BCMath $y) - { - $temp = new self(); - $temp->value = bcadd($this->value, $y->value); - - return $this->normalize($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param BCMath $y - * @return BCMath - */ - public function subtract(BCMath $y) - { - $temp = new self(); - $temp->value = bcsub($this->value, $y->value); - - return $this->normalize($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param BCMath $x - * @return BCMath - */ - public function multiply(BCMath $x) - { - $temp = new self(); - $temp->value = bcmul($this->value, $x->value); - - return $this->normalize($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param BCMath $y - * @return array{static, static} - */ - public function divide(BCMath $y) - { - $quotient = new self(); - $remainder = new self(); - - $quotient->value = bcdiv($this->value, $y->value, 0); - $remainder->value = bcmod($this->value, $y->value); - - if ($remainder->value[0] == '-') { - $remainder->value = bcadd($remainder->value, $y->value[0] == '-' ? substr($y->value, 1) : $y->value, 0); - } - - return [$this->normalize($quotient), $this->normalize($remainder)]; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * @param BCMath $n - * @return false|BCMath - */ - public function modInverse(BCMath $n) - { - return $this->modInverseHelper($n); - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that - * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which - * combination is returned is dependent upon which mode is in use. See - * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. - * - * @param BCMath $n - * @return array{gcd: static, x: static, y: static} - */ - public function extendedGCD(BCMath $n) - { - // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works - // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, - // the basic extended euclidean algorithim is what we're using. - - $u = $this->value; - $v = $n->value; - - $a = '1'; - $b = '0'; - $c = '0'; - $d = '1'; - - while (bccomp($v, '0', 0) != 0) { - $q = bcdiv($u, $v, 0); - - $temp = $u; - $u = $v; - $v = bcsub($temp, bcmul($v, $q, 0), 0); - - $temp = $a; - $a = $c; - $c = bcsub($temp, bcmul($a, $q, 0), 0); - - $temp = $b; - $b = $d; - $d = bcsub($temp, bcmul($b, $q, 0), 0); - } - - return [ - 'gcd' => $this->normalize(new static($u)), - 'x' => $this->normalize(new static($a)), - 'y' => $this->normalize(new static($b)) - ]; - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param BCMath $n - * @return BCMath - */ - public function gcd(BCMath $n) - { - extract($this->extendedGCD($n)); - /** @var BCMath $gcd */ - return $gcd; - } - - /** - * Absolute value. - * - * @return BCMath - */ - public function abs() - { - $temp = new static(); - $temp->value = strlen($this->value) && $this->value[0] == '-' ? - substr($this->value, 1) : - $this->value; - - return $temp; - } - - /** - * Logical And - * - * @param BCMath $x - * @return BCMath - */ - public function bitwise_and(BCMath $x) - { - return $this->bitwiseAndHelper($x); - } - - /** - * Logical Or - * - * @param BCMath $x - * @return BCMath - */ - public function bitwise_or(BCMath $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Logical Exclusive Or - * - * @param BCMath $x - * @return BCMath - */ - public function bitwise_xor(BCMath $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return BCMath - */ - public function bitwise_rightShift($shift) - { - $temp = new static(); - $temp->value = bcdiv($this->value, bcpow('2', $shift, 0), 0); - - return $this->normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return BCMath - */ - public function bitwise_leftShift($shift) - { - $temp = new static(); - $temp->value = bcmul($this->value, bcpow('2', $shift, 0), 0); - - return $this->normalize($temp); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this - * is demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param BCMath $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @see self::equals() - */ - public function compare(BCMath $y) - { - return bccomp($this->value, $y->value, 0); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param BCMath $x - * @return bool - */ - public function equals(BCMath $x) - { - return $this->value == $x->value; - } - - /** - * Performs modular exponentiation. - * - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - public function modPow(BCMath $e, BCMath $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - public function powMod(BCMath $e, BCMath $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - protected function powModInner(BCMath $e, BCMath $n) - { - try { - $class = static::$modexpEngine[static::class]; - return $class::powModHelper($this, $e, $n, static::class); - } catch (\Exception $err) { - return BCMath\DefaultEngine::powModHelper($this, $e, $n, static::class); - } - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param BCMath $result - * @return BCMath - */ - protected function normalize(BCMath $result) - { - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - if ($result->bitmask !== false) { - $result->value = bcmod($result->value, $result->bitmask->value); - } - - return $result; - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param BCMath $min - * @param BCMath $max - * @return false|BCMath - */ - public static function randomRangePrime(BCMath $min, BCMath $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param BCMath $min - * @param BCMath $max - * @return BCMath - */ - public static function randomRange(BCMath $min, BCMath $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - */ - protected function make_odd() - { - if (!$this->isOdd()) { - $this->value = bcadd($this->value, '1'); - } - } - - /** - * Test the number against small primes. - * - * @see self::isPrime() - */ - protected function testSmallPrimes() - { - if ($this->value === '1') { - return false; - } - if ($this->value === '2') { - return true; - } - if ($this->value[strlen($this->value) - 1] % 2 == 0) { - return false; - } - - $value = $this->value; - - foreach (self::PRIMES as $prime) { - $r = bcmod($this->value, $prime); - if ($r == '0') { - return $this->value == $prime; - } - } - - return true; - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @param BCMath $r - * @return int - * @see self::isPrime() - */ - public static function scan1divide(BCMath $r) - { - $r_value = &$r->value; - $s = 0; - // if $n was 1, $r would be 0 and this would be an infinite loop, hence our $this->equals(static::$one[static::class]) check earlier - while ($r_value[strlen($r_value) - 1] % 2 == 0) { - $r_value = bcdiv($r_value, '2', 0); - ++$s; - } - - return $s; - } - - /** - * Performs exponentiation. - * - * @param BCMath $n - * @return BCMath - */ - public function pow(BCMath $n) - { - $temp = new self(); - $temp->value = bcpow($this->value, $n->value); - - return $this->normalize($temp); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param BCMath ...$nums - * @return BCMath - */ - public static function min(BCMath ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param BCMath ...$nums - * @return BCMath - */ - public static function max(BCMath ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param BCMath $min - * @param BCMath $max - * @return bool - */ - public function between(BCMath $min, BCMath $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } - - /** - * Set Bitmask - * - * @param int $bits - * @return Engine - * @see self::setPrecision() - */ - protected static function setBitmask($bits) - { - $temp = parent::setBitmask($bits); - return $temp->add(static::$one[static::class]); - } - - /** - * Is Odd? - * - * @return bool - */ - public function isOdd() - { - return $this->value[strlen($this->value) - 1] % 2 == 1; - } - - /** - * Tests if a bit is set - * - * @return bool - */ - public function testBit($x) - { - return bccomp( - bcmod($this->value, bcpow('2', $x + 1, 0)), - bcpow('2', $x, 0), - 0 - ) >= 0; - } - - /** - * Is Negative? - * - * @return bool - */ - public function isNegative() - { - return strlen($this->value) && $this->value[0] == '-'; - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return BCMath - */ - public function negate() - { - $temp = clone $this; - - if (!strlen($temp->value)) { - return $temp; - } - - $temp->value = $temp->value[0] == '-' ? - substr($this->value, 1) : - '-' . $this->value; - - return $temp; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php deleted file mode 100644 index fe21e04..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Base.php +++ /dev/null @@ -1,110 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\BCMath; - -/** - * Sliding Window Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Base extends BCMath -{ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - * - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - * - */ - const DATA = 1; - - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * @param BCMath $x - * @param BCMath $e - * @param BCMath $n - * @param string $class - * @return BCMath - */ - protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n, $class) - { - if (empty($e->value)) { - $temp = new $class(); - $temp->value = '1'; - return $x->normalize($temp); - } - - return $x->normalize(static::slidingWindow($x, $e, $n, $class)); - } - - /** - * Modular reduction preparation - * - * @param string $x - * @param string $n - * @param string $class - * @see self::slidingWindow() - * @return string - */ - protected static function prepareReduce($x, $n, $class) - { - return static::reduce($x, $n); - } - - /** - * Modular multiply - * - * @param string $x - * @param string $y - * @param string $n - * @param string $class - * @see self::slidingWindow() - * @return string - */ - protected static function multiplyReduce($x, $y, $n, $class) - { - return static::reduce(bcmul($x, $y), $n); - } - - /** - * Modular square - * - * @param string $x - * @param string $n - * @param string $class - * @see self::slidingWindow() - * @return string - */ - protected static function squareReduce($x, $n, $class) - { - return static::reduce(bcmul($x, $x), $n); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php deleted file mode 100644 index b7ca8a2..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/BuiltIn.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\BCMath; - -/** - * Built-In BCMath Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class BuiltIn extends BCMath -{ - /** - * Performs modular exponentiation. - * - * @param BCMath $x - * @param BCMath $e - * @param BCMath $n - * @return BCMath - */ - protected static function powModHelper(BCMath $x, BCMath $e, BCMath $n) - { - $temp = new BCMath(); - $temp->value = bcpowmod($x->value, $e->value, $n->value); - - return $x->normalize($temp); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php deleted file mode 100644 index b2d9fa9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/DefaultEngine.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\BCMath\Reductions\Barrett; - -/** - * PHP Default Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class DefaultEngine extends Barrett -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php deleted file mode 100644 index aed9494..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/OpenSSL.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath; - -use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; - -/** - * OpenSSL Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class OpenSSL extends Progenitor -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php deleted file mode 100644 index 0fb7eae..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/Barrett.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; - -use phpseclib3\Math\BigInteger\Engines\BCMath\Base; - -/** - * PHP Barrett Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Barrett extends Base -{ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - * - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - * - */ - const DATA = 1; - - /** - * Barrett Modular Reduction - * - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, - * so as not to require negative numbers (initially, this script didn't support negative numbers). - * - * Employs "folding", as described at - * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from - * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." - * - * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that - * usable on account of (1) its not using reasonable radix points as discussed in - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable - * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that - * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line - * comments for details. - * - * @param string $n - * @param string $m - * @return string - */ - protected static function reduce($n, $m) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $m_length = strlen($m); - - if (strlen($n) > 2 * $m_length) { - return bcmod($n, $m); - } - - // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced - if ($m_length < 5) { - return self::regularBarrett($n, $m); - } - // n = 2 * m.length - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - - $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); - $u = bcdiv($lhs, $m, 0); - $m1 = bcsub($lhs, bcmul($u, $m)); - - $cache[self::DATA][] = [ - 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) - 'm1' => $m1 // m.length - ]; - } else { - extract($cache[self::DATA][$key]); - } - - $cutoff = $m_length + ($m_length >> 1); - - $lsd = substr($n, -$cutoff); - $msd = substr($n, 0, -$cutoff); - - $temp = bcmul($msd, $m1); // m.length + (m.length >> 1) - $n = bcadd($lsd, $temp); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) - //if ($m_length & 1) { - // return self::regularBarrett($n, $m); - //} - - // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 - $temp = substr($n, 0, -$m_length + 1); - // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 - // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 - $temp = bcmul($temp, $u); - // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 - // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) - $temp = substr($temp, 0, -($m_length >> 1) - 1); - // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 - // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) - $temp = bcmul($temp, $m); - - // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit - // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop - // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). - - $result = bcsub($n, $temp); - - //if (bccomp($result, '0') < 0) { - if ($result[0] == '-') { - $temp = '1' . str_repeat('0', $m_length + 1); - $result = bcadd($result, $temp); - } - - while (bccomp($result, $m) >= 0) { - $result = bcsub($result, $m); - } - - return $result; - } - - /** - * (Regular) Barrett Modular Reduction - * - * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this - * is that this function does not fold the denominator into a smaller form. - * - * @param string $x - * @param string $n - * @return string - */ - private static function regularBarrett($x, $n) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $n_length = strlen($n); - - if (strlen($x) > 2 * $n_length) { - return bcmod($x, $n); - } - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $n; - $lhs = '1' . str_repeat('0', 2 * $n_length); - $cache[self::DATA][] = bcdiv($lhs, $n, 0); - } - - $temp = substr($x, 0, -$n_length + 1); - $temp = bcmul($temp, $cache[self::DATA][$key]); - $temp = substr($temp, 0, -$n_length - 1); - - $r1 = substr($x, -$n_length - 1); - $r2 = substr(bcmul($temp, $n), -$n_length - 1); - $result = bcsub($r1, $r2); - - //if (bccomp($result, '0') < 0) { - if ($result[0] == '-') { - $q = '1' . str_repeat('0', $n_length + 1); - $result = bcadd($result, $q); - } - - while (bccomp($result, $n) >= 0) { - $result = bcsub($result, $n); - } - - return $result; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php deleted file mode 100644 index e033ba5..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/BCMath/Reductions/EvalBarrett.php +++ /dev/null @@ -1,108 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\BCMath\Reductions; - -use phpseclib3\Math\BigInteger\Engines\BCMath; -use phpseclib3\Math\BigInteger\Engines\BCMath\Base; - -/** - * PHP Barrett Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class EvalBarrett extends Base -{ - /** - * Custom Reduction Function - * - * @see self::generateCustomReduction - */ - private static $custom_reduction; - - /** - * Barrett Modular Reduction - * - * This calls a dynamically generated loop unrolled function that's specific to a given modulo. - * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. - * - * @param string $n - * @param string $m - * @return string - */ - protected static function reduce($n, $m) - { - $inline = self::$custom_reduction; - return $inline($n); - } - - /** - * Generate Custom Reduction - * - * @param BCMath $m - * @param string $class - * @return callable|void - */ - protected static function generateCustomReduction(BCMath $m, $class) - { - $m_length = strlen($m); - - if ($m_length < 5) { - $code = 'return bcmod($x, $n);'; - eval('$func = function ($n) { ' . $code . '};'); - self::$custom_reduction = $func; - return; - } - - $lhs = '1' . str_repeat('0', $m_length + ($m_length >> 1)); - $u = bcdiv($lhs, $m, 0); - $m1 = bcsub($lhs, bcmul($u, $m)); - - $cutoff = $m_length + ($m_length >> 1); - - $m = "'$m'"; - $u = "'$u'"; - $m1 = "'$m1'"; - - $code = ' - $lsd = substr($n, -' . $cutoff . '); - $msd = substr($n, 0, -' . $cutoff . '); - - $temp = bcmul($msd, ' . $m1 . '); - $n = bcadd($lsd, $temp); - - $temp = substr($n, 0, ' . (-$m_length + 1) . '); - $temp = bcmul($temp, ' . $u . '); - $temp = substr($temp, 0, ' . (-($m_length >> 1) - 1) . '); - $temp = bcmul($temp, ' . $m . '); - - $result = bcsub($n, $temp); - - if ($result[0] == \'-\') { - $temp = \'1' . str_repeat('0', $m_length + 1) . '\'; - $result = bcadd($result, $temp); - } - - while (bccomp($result, ' . $m . ') >= 0) { - $result = bcsub($result, ' . $m . '); - } - - return $result;'; - - eval('$func = function ($n) { ' . $code . '};'); - - self::$custom_reduction = $func; - - return $func; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php deleted file mode 100644 index abdf3b4..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/Engine.php +++ /dev/null @@ -1,1285 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Random; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Math\BigInteger; - -/** - * Base Engine. - * - * @author Jim Wigginton - */ -abstract class Engine implements \JsonSerializable -{ - /* final protected */ const PRIMES = [ - 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, - 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, - 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, - 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, - 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, - 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, - 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, - 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, - 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, - 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, - 953, 967, 971, 977, 983, 991, 997, - ]; - - /** - * BigInteger(0) - * - * @var array, static> - */ - protected static $zero = []; - - /** - * BigInteger(1) - * - * @var array, static> - */ - protected static $one = []; - - /** - * BigInteger(2) - * - * @var array, static> - */ - protected static $two = []; - - /** - * Modular Exponentiation Engine - * - * @var array, class-string> - */ - protected static $modexpEngine; - - /** - * Engine Validity Flag - * - * @var array, bool> - */ - protected static $isValidEngine; - - /** - * Holds the BigInteger's value - * - * @var \GMP|string|array|int - */ - protected $value; - - /** - * Holds the BigInteger's sign - * - * @var bool - */ - protected $is_negative; - - /** - * Precision - * - * @see static::setPrecision() - * @var int - */ - protected $precision = -1; - - /** - * Precision Bitmask - * - * @see static::setPrecision() - * @var static|false - */ - protected $bitmask = false; - - /** - * Recurring Modulo Function - * - * @var callable - */ - protected $reduce; - - /** - * Mode independent value used for serialization. - * - * @see self::__sleep() - * @see self::__wakeup() - * @var string - */ - protected $hex; - - /** - * Default constructor - * - * @param int|numeric-string $x integer Base-10 number or base-$base number if $base set. - * @param int $base - */ - public function __construct($x = 0, $base = 10) - { - if (!array_key_exists(static::class, static::$zero)) { - static::$zero[static::class] = null; // Placeholder to prevent infinite loop. - static::$zero[static::class] = new static(0); - static::$one[static::class] = new static(1); - static::$two[static::class] = new static(2); - } - - // '0' counts as empty() but when the base is 256 '0' is equal to ord('0') or 48 - // '0' is the only value like this per http://php.net/empty - if (empty($x) && (abs($base) != 256 || $x !== '0')) { - return; - } - - switch ($base) { - case -256: - case 256: - if ($base == -256 && (ord($x[0]) & 0x80)) { - $this->value = ~$x; - $this->is_negative = true; - } else { - $this->value = $x; - $this->is_negative = false; - } - - $this->initialize($base); - - if ($this->is_negative) { - $temp = $this->add(new static('-1')); - $this->value = $temp->value; - } - break; - case -16: - case 16: - if ($base > 0 && $x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = preg_replace('#^(?:0x)?([A-Fa-f0-9]*).*#s', '$1', $x); - - $is_negative = false; - if ($base < 0 && hexdec($x[0]) >= 8) { - $this->is_negative = $is_negative = true; - $x = Strings::bin2hex(~Strings::hex2bin($x)); - } - - $this->value = $x; - $this->initialize($base); - - if ($is_negative) { - $temp = $this->add(new static('-1')); - $this->value = $temp->value; - } - break; - case -10: - case 10: - // (?value = preg_replace('#(?value) || $this->value == '-') { - $this->value = '0'; - } - $this->initialize($base); - break; - case -2: - case 2: - if ($base > 0 && $x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = preg_replace('#^([01]*).*#s', '$1', $x); - - $temp = new static(Strings::bits2bin($x), 128 * $base); // ie. either -16 or +16 - $this->value = $temp->value; - if ($temp->is_negative) { - $this->is_negative = true; - } - - break; - default: - // base not supported, so we'll let $this == 0 - } - } - - /** - * Sets engine type. - * - * Throws an exception if the type is invalid - * - * @param class-string $engine - */ - public static function setModExpEngine($engine) - { - $fqengine = '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\' . $engine; - if (!class_exists($fqengine) || !method_exists($fqengine, 'isValidEngine')) { - throw new \InvalidArgumentException("$engine is not a valid engine"); - } - if (!$fqengine::isValidEngine()) { - throw new BadConfigurationException("$engine is not setup correctly on this system"); - } - static::$modexpEngine[static::class] = $fqengine; - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * @return string - */ - protected function toBytesHelper() - { - $comparison = $this->compare(new static()); - if ($comparison == 0) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $temp = $comparison < 0 ? $this->add(new static(1)) : $this; - $bytes = $temp->toBytes(); - - if (!strlen($bytes)) { // eg. if the number we're trying to convert is -1 - $bytes = chr(0); - } - - if (ord($bytes[0]) & 0x80) { - $bytes = chr(0) . $bytes; - } - - return $comparison < 0 ? ~$bytes : $bytes; - } - - /** - * Converts a BigInteger to a hex string (eg. base-16). - * - * @param bool $twos_compliment - * @return string - */ - public function toHex($twos_compliment = false) - { - return Strings::bin2hex($this->toBytes($twos_compliment)); - } - - /** - * Converts a BigInteger to a bit string (eg. base-2). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * @param bool $twos_compliment - * @return string - */ - public function toBits($twos_compliment = false) - { - $hex = $this->toBytes($twos_compliment); - $bits = Strings::bin2bits($hex); - - $result = $this->precision > 0 ? substr($bits, -$this->precision) : ltrim($bits, '0'); - - if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { - return '0' . $result; - } - - return $result; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * {@internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information.} - * - * @param Engine $n - * @return static|false - */ - protected function modInverseHelper(Engine $n) - { - // $x mod -$n == $x mod $n. - $n = $n->abs(); - - if ($this->compare(static::$zero[static::class]) < 0) { - $temp = $this->abs(); - $temp = $temp->modInverse($n); - return $this->normalize($n->subtract($temp)); - } - - extract($this->extendedGCD($n)); - /** - * @var Engine $gcd - * @var Engine $x - */ - - if (!$gcd->equals(static::$one[static::class])) { - return false; - } - - $x = $x->compare(static::$zero[static::class]) < 0 ? $x->add($n) : $x; - - return $this->compare(static::$zero[static::class]) < 0 ? $this->normalize($n->subtract($x)) : $this->normalize($x); - } - - /** - * Serialize - * - * Will be called, automatically, when serialize() is called on a BigInteger object. - * - * @return array - */ - public function __sleep() - { - $this->hex = $this->toHex(true); - $vars = ['hex']; - if ($this->precision > 0) { - $vars[] = 'precision'; - } - return $vars; - } - - /** - * Serialize - * - * Will be called, automatically, when unserialize() is called on a BigInteger object. - * - * @return void - */ - public function __wakeup() - { - $temp = new static($this->hex, -16); - $this->value = $temp->value; - $this->is_negative = $temp->is_negative; - if ($this->precision > 0) { - // recalculate $this->bitmask - $this->setPrecision($this->precision); - } - } - - /** - * JSON Serialize - * - * Will be called, automatically, when json_encode() is called on a BigInteger object. - * - * @return array{hex: string, precision?: int] - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - $result = ['hex' => $this->toHex(true)]; - if ($this->precision > 0) { - $result['precision'] = $this->precision; - } - return $result; - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * __debugInfo() magic method - * - * Will be called, automatically, when print_r() or var_dump() are called - * - * @return array - */ - public function __debugInfo() - { - $result = [ - 'value' => '0x' . $this->toHex(true), - 'engine' => basename(static::class) - ]; - return $this->precision > 0 ? $result + ['precision' => $this->precision] : $result; - } - - /** - * Set Precision - * - * Some bitwise operations give different results depending on the precision being used. Examples include left - * shift, not, and rotates. - * - * @param int $bits - */ - public function setPrecision($bits) - { - if ($bits < 1) { - $this->precision = -1; - $this->bitmask = false; - - return; - } - $this->precision = $bits; - $this->bitmask = static::setBitmask($bits); - - $temp = $this->normalize($this); - $this->value = $temp->value; - } - - /** - * Get Precision - * - * Returns the precision if it exists, -1 if it doesn't - * - * @return int - */ - public function getPrecision() - { - return $this->precision; - } - - /** - * Set Bitmask - * @return static - * @param int $bits - * @see self::setPrecision() - */ - protected static function setBitmask($bits) - { - return new static(chr((1 << ($bits & 0x7)) - 1) . str_repeat(chr(0xFF), $bits >> 3), 256); - } - - /** - * Logical Not - * - * @return Engine|string - */ - public function bitwise_not() - { - // calculuate "not" without regard to $this->precision - // (will always result in a smaller number. ie. ~1 isn't 1111 1110 - it's 0) - $temp = $this->toBytes(); - if ($temp == '') { - return $this->normalize(static::$zero[static::class]); - } - $pre_msb = decbin(ord($temp[0])); - $temp = ~$temp; - $msb = decbin(ord($temp[0])); - if (strlen($msb) == 8) { - $msb = substr($msb, strpos($msb, '0')); - } - $temp[0] = chr(bindec($msb)); - - // see if we need to add extra leading 1's - $current_bits = strlen($pre_msb) + 8 * strlen($temp) - 8; - $new_bits = $this->precision - $current_bits; - if ($new_bits <= 0) { - return $this->normalize(new static($temp, 256)); - } - - // generate as many leading 1's as we need to. - $leading_ones = chr((1 << ($new_bits & 0x7)) - 1) . str_repeat(chr(0xFF), $new_bits >> 3); - - self::base256_lshift($leading_ones, $current_bits); - - $temp = str_pad($temp, strlen($leading_ones), chr(0), STR_PAD_LEFT); - - return $this->normalize(new static($leading_ones | $temp, 256)); - } - - /** - * Logical Left Shift - * - * Shifts binary strings $shift bits, essentially multiplying by 2**$shift. - * - * @param string $x - * @param int $shift - * @return void - */ - protected static function base256_lshift(&$x, $shift) - { - if ($shift == 0) { - return; - } - - $num_bytes = $shift >> 3; // eg. floor($shift/8) - $shift &= 7; // eg. $shift % 8 - - $carry = 0; - for ($i = strlen($x) - 1; $i >= 0; --$i) { - $temp = ord($x[$i]) << $shift | $carry; - $x[$i] = chr($temp); - $carry = $temp >> 8; - } - $carry = ($carry != 0) ? chr($carry) : ''; - $x = $carry . $x . str_repeat(chr(0), $num_bytes); - } - - /** - * Logical Left Rotate - * - * Instead of the top x bits being dropped they're appended to the shifted bit string. - * - * @param int $shift - * @return Engine - */ - public function bitwise_leftRotate($shift) - { - $bits = $this->toBytes(); - - if ($this->precision > 0) { - $precision = $this->precision; - if (static::FAST_BITWISE) { - $mask = $this->bitmask->toBytes(); - } else { - $mask = $this->bitmask->subtract(new static(1)); - $mask = $mask->toBytes(); - } - } else { - $temp = ord($bits[0]); - for ($i = 0; $temp >> $i; ++$i) { - } - $precision = 8 * strlen($bits) - 8 + $i; - $mask = chr((1 << ($precision & 0x7)) - 1) . str_repeat(chr(0xFF), $precision >> 3); - } - - if ($shift < 0) { - $shift += $precision; - } - $shift %= $precision; - - if (!$shift) { - return clone $this; - } - - $left = $this->bitwise_leftShift($shift); - $left = $left->bitwise_and(new static($mask, 256)); - $right = $this->bitwise_rightShift($precision - $shift); - $result = static::FAST_BITWISE ? $left->bitwise_or($right) : $left->add($right); - return $this->normalize($result); - } - - /** - * Logical Right Rotate - * - * Instead of the bottom x bits being dropped they're prepended to the shifted bit string. - * - * @param int $shift - * @return Engine - */ - public function bitwise_rightRotate($shift) - { - return $this->bitwise_leftRotate(-$shift); - } - - /** - * Returns the smallest and largest n-bit number - * - * @param int $bits - * @return array{min: static, max: static} - */ - public static function minMaxBits($bits) - { - $bytes = $bits >> 3; - $min = str_repeat(chr(0), $bytes); - $max = str_repeat(chr(0xFF), $bytes); - $msb = $bits & 7; - if ($msb) { - $min = chr(1 << ($msb - 1)) . $min; - $max = chr((1 << $msb) - 1) . $max; - } else { - $min[0] = chr(0x80); - } - return [ - 'min' => new static($min, 256), - 'max' => new static($max, 256) - ]; - } - - /** - * Return the size of a BigInteger in bits - * - * @return int - */ - public function getLength() - { - return strlen($this->toBits()); - } - - /** - * Return the size of a BigInteger in bytes - * - * @return int - */ - public function getLengthInBytes() - { - return strlen($this->toBytes()); - } - - /** - * Performs some pre-processing for powMod - * - * @param Engine $e - * @param Engine $n - * @return static|false - */ - protected function powModOuter(Engine $e, Engine $n) - { - $n = $this->bitmask !== false && $this->bitmask->compare($n) < 0 ? $this->bitmask : $n->abs(); - - if ($e->compare(new static()) < 0) { - $e = $e->abs(); - - $temp = $this->modInverse($n); - if ($temp === false) { - return false; - } - - return $this->normalize($temp->powModInner($e, $n)); - } - - if ($this->compare($n) > 0) { - list(, $temp) = $this->divide($n); - return $temp->powModInner($e, $n); - } - - return $this->powModInner($e, $n); - } - - /** - * Sliding Window k-ary Modular Exponentiation - * - * Based on {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=27 HAC 14.85} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=210 MPM 7.7}. In a departure from those algorithims, - * however, this function performs a modular reduction after every multiplication and squaring operation. - * As such, this function has the same preconditions that the reductions being used do. - * - * @template T of Engine - * @param Engine $x - * @param Engine $e - * @param Engine $n - * @param class-string $class - * @return T - */ - protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) - { - static $window_ranges = [7, 25, 81, 241, 673, 1793]; // from BigInteger.java's oddModPow function - //static $window_ranges = [0, 7, 36, 140, 450, 1303, 3529]; // from MPM 7.3.1 - - $e_bits = $e->toBits(); - $e_length = strlen($e_bits); - - // calculate the appropriate window size. - // $window_size == 3 if $window_ranges is between 25 and 81, for example. - for ($i = 0, $window_size = 1; $i < count($window_ranges) && $e_length > $window_ranges[$i]; ++$window_size, ++$i) { - } - - $n_value = $n->value; - - if (method_exists(static::class, 'generateCustomReduction')) { - static::generateCustomReduction($n, $class); - } - - // precompute $this^0 through $this^$window_size - $powers = []; - $powers[1] = static::prepareReduce($x->value, $n_value, $class); - $powers[2] = static::squareReduce($powers[1], $n_value, $class); - - // we do every other number since substr($e_bits, $i, $j+1) (see below) is supposed to end - // in a 1. ie. it's supposed to be odd. - $temp = 1 << ($window_size - 1); - for ($i = 1; $i < $temp; ++$i) { - $i2 = $i << 1; - $powers[$i2 + 1] = static::multiplyReduce($powers[$i2 - 1], $powers[2], $n_value, $class); - } - - $result = new $class(1); - $result = static::prepareReduce($result->value, $n_value, $class); - - for ($i = 0; $i < $e_length;) { - if (!$e_bits[$i]) { - $result = static::squareReduce($result, $n_value, $class); - ++$i; - } else { - for ($j = $window_size - 1; $j > 0; --$j) { - if (!empty($e_bits[$i + $j])) { - break; - } - } - - // eg. the length of substr($e_bits, $i, $j + 1) - for ($k = 0; $k <= $j; ++$k) { - $result = static::squareReduce($result, $n_value, $class); - } - - $result = static::multiplyReduce($result, $powers[bindec(substr($e_bits, $i, $j + 1))], $n_value, $class); - - $i += $j + 1; - } - } - - $temp = new $class(); - $temp->value = static::reduce($result, $n_value, $class); - - return $temp; - } - - /** - * Generates a random number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return Engine - */ - public static function random($size) - { - extract(static::minMaxBits($size)); - /** - * @var BigInteger $min - * @var BigInteger $max - */ - return static::randomRange($min, $max); - } - - /** - * Generates a random prime number of a certain size - * - * Bit length is equal to $size - * - * @param int $size - * @return Engine - */ - public static function randomPrime($size) - { - extract(static::minMaxBits($size)); - /** - * @var static $min - * @var static $max - */ - return static::randomRangePrime($min, $max); - } - - /** - * Performs some pre-processing for randomRangePrime - * - * @param Engine $min - * @param Engine $max - * @return static|false - */ - protected static function randomRangePrimeOuter(Engine $min, Engine $max) - { - $compare = $max->compare($min); - - if (!$compare) { - return $min->isPrime() ? $min : false; - } elseif ($compare < 0) { - // if $min is bigger then $max, swap $min and $max - $temp = $max; - $max = $min; - $min = $temp; - } - - $x = static::randomRange($min, $max); - - return static::randomRangePrimeInner($x, $min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param Engine $min - * @param Engine $max - * @return Engine - */ - protected static function randomRangeHelper(Engine $min, Engine $max) - { - $compare = $max->compare($min); - - if (!$compare) { - return $min; - } elseif ($compare < 0) { - // if $min is bigger then $max, swap $min and $max - $temp = $max; - $max = $min; - $min = $temp; - } - - if (!isset(static::$one[static::class])) { - static::$one[static::class] = new static(1); - } - - $max = $max->subtract($min->subtract(static::$one[static::class])); - - $size = strlen(ltrim($max->toBytes(), chr(0))); - - /* - doing $random % $max doesn't work because some numbers will be more likely to occur than others. - eg. if $max is 140 and $random's max is 255 then that'd mean both $random = 5 and $random = 145 - would produce 5 whereas the only value of random that could produce 139 would be 139. ie. - not all numbers would be equally likely. some would be more likely than others. - - creating a whole new random number until you find one that is within the range doesn't work - because, for sufficiently small ranges, the likelihood that you'd get a number within that range - would be pretty small. eg. with $random's max being 255 and if your $max being 1 the probability - would be pretty high that $random would be greater than $max. - - phpseclib works around this using the technique described here: - - http://crypto.stackexchange.com/questions/5708/creating-a-small-number-from-a-cryptographically-secure-random-string - */ - $random_max = new static(chr(1) . str_repeat("\0", $size), 256); - $random = new static(Random::string($size), 256); - - list($max_multiple) = $random_max->divide($max); - $max_multiple = $max_multiple->multiply($max); - - while ($random->compare($max_multiple) >= 0) { - $random = $random->subtract($max_multiple); - $random_max = $random_max->subtract($max_multiple); - $random = $random->bitwise_leftShift(8); - $random = $random->add(new static(Random::string(1), 256)); - $random_max = $random_max->bitwise_leftShift(8); - list($max_multiple) = $random_max->divide($max); - $max_multiple = $max_multiple->multiply($max); - } - list(, $random) = $random->divide($max); - - return $random->add($min); - } - - /** - * Performs some post-processing for randomRangePrime - * - * @param Engine $x - * @param Engine $min - * @param Engine $max - * @return static|false - */ - protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) - { - if (!isset(static::$two[static::class])) { - static::$two[static::class] = new static('2'); - } - - $x->make_odd(); - if ($x->compare($max) > 0) { - // if $x > $max then $max is even and if $min == $max then no prime number exists between the specified range - if ($min->equals($max)) { - return false; - } - $x = clone $min; - $x->make_odd(); - } - - $initial_x = clone $x; - - while (true) { - if ($x->isPrime()) { - return $x; - } - - $x = $x->add(static::$two[static::class]); - - if ($x->compare($max) > 0) { - $x = clone $min; - if ($x->equals(static::$two[static::class])) { - return $x; - } - $x->make_odd(); - } - - if ($x->equals($initial_x)) { - return false; - } - } - } - - /** - * Sets the $t parameter for primality testing - * - * @return int - */ - protected function setupIsPrime() - { - $length = $this->getLengthInBytes(); - - // see HAC 4.49 "Note (controlling the error probability)" - // @codingStandardsIgnoreStart - if ($length >= 163) { $t = 2; } // floor(1300 / 8) - else if ($length >= 106) { $t = 3; } // floor( 850 / 8) - else if ($length >= 81 ) { $t = 4; } // floor( 650 / 8) - else if ($length >= 68 ) { $t = 5; } // floor( 550 / 8) - else if ($length >= 56 ) { $t = 6; } // floor( 450 / 8) - else if ($length >= 50 ) { $t = 7; } // floor( 400 / 8) - else if ($length >= 43 ) { $t = 8; } // floor( 350 / 8) - else if ($length >= 37 ) { $t = 9; } // floor( 300 / 8) - else if ($length >= 31 ) { $t = 12; } // floor( 250 / 8) - else if ($length >= 25 ) { $t = 15; } // floor( 200 / 8) - else if ($length >= 18 ) { $t = 18; } // floor( 150 / 8) - else { $t = 27; } - // @codingStandardsIgnoreEnd - - return $t; - } - - /** - * Tests Primality - * - * Uses the {@link http://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test Miller-Rabin primality test}. - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap4.pdf#page=8 HAC 4.24} for more info. - * - * @param int $t - * @return bool - */ - protected function testPrimality($t) - { - if (!$this->testSmallPrimes()) { - return false; - } - - $n = clone $this; - $n_1 = $n->subtract(static::$one[static::class]); - $n_2 = $n->subtract(static::$two[static::class]); - - $r = clone $n_1; - $s = static::scan1divide($r); - - for ($i = 0; $i < $t; ++$i) { - $a = static::randomRange(static::$two[static::class], $n_2); - $y = $a->modPow($r, $n); - - if (!$y->equals(static::$one[static::class]) && !$y->equals($n_1)) { - for ($j = 1; $j < $s && !$y->equals($n_1); ++$j) { - $y = $y->modPow(static::$two[static::class], $n); - if ($y->equals(static::$one[static::class])) { - return false; - } - } - - if (!$y->equals($n_1)) { - return false; - } - } - } - - return true; - } - - /** - * Checks a numer to see if it's prime - * - * Assuming the $t parameter is not set, this function has an error rate of 2**-80. The main motivation for the - * $t parameter is distributability. BigInteger::randomPrime() can be distributed across multiple pageloads - * on a website instead of just one. - * - * @param int|bool $t - * @return bool - */ - public function isPrime($t = false) - { - if (!$t) { - $t = $this->setupIsPrime(); - } - return $this->testPrimality($t); - } - - /** - * Performs a few preliminary checks on root - * - * @param int $n - * @return Engine - */ - protected function rootHelper($n) - { - if ($n < 1) { - return clone static::$zero[static::class]; - } // we want positive exponents - if ($this->compare(static::$one[static::class]) < 0) { - return clone static::$zero[static::class]; - } // we want positive numbers - if ($this->compare(static::$two[static::class]) < 0) { - return clone static::$one[static::class]; - } // n-th root of 1 or 2 is 1 - - return $this->rootInner($n); - } - - /** - * Calculates the nth root of a biginteger. - * - * Returns the nth root of a positive biginteger, where n defaults to 2 - * - * {@internal This function is based off of {@link http://mathforum.org/library/drmath/view/52605.html this page} and {@link http://stackoverflow.com/questions/11242920/calculating-nth-root-with-bcmath-in-php this stackoverflow question}.} - * - * @param int $n - * @return Engine - */ - protected function rootInner($n) - { - $n = new static($n); - - // g is our guess number - $g = static::$two[static::class]; - // while (g^n < num) g=g*2 - while ($g->pow($n)->compare($this) < 0) { - $g = $g->multiply(static::$two[static::class]); - } - // if (g^n==num) num is a power of 2, we're lucky, end of job - // == 0 bccomp(bcpow($g, $n), $n->value)==0 - if ($g->pow($n)->equals($this) > 0) { - $root = $g; - return $this->normalize($root); - } - - // if we're here num wasn't a power of 2 :( - $og = $g; // og means original guess and here is our upper bound - $g = $g->divide(static::$two[static::class])[0]; // g is set to be our lower bound - $step = $og->subtract($g)->divide(static::$two[static::class])[0]; // step is the half of upper bound - lower bound - $g = $g->add($step); // we start at lower bound + step , basically in the middle of our interval - - // while step>1 - - while ($step->compare(static::$one[static::class]) == 1) { - $guess = $g->pow($n); - $step = $step->divide(static::$two[static::class])[0]; - $comp = $guess->compare($this); // compare our guess with real number - switch ($comp) { - case -1: // if guess is lower we add the new step - $g = $g->add($step); - break; - case 1: // if guess is higher we sub the new step - $g = $g->subtract($step); - break; - case 0: // if guess is exactly the num we're done, we return the value - $root = $g; - break 2; - } - } - - if ($comp == 1) { - $g = $g->subtract($step); - } - - // whatever happened, g is the closest guess we can make so return it - $root = $g; - - return $this->normalize($root); - } - - /** - * Calculates the nth root of a biginteger. - * - * @param int $n - * @return Engine - */ - public function root($n = 2) - { - return $this->rootHelper($n); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param array $nums - * @return Engine - */ - protected static function minHelper(array $nums) - { - if (count($nums) == 1) { - return $nums[0]; - } - $min = $nums[0]; - for ($i = 1; $i < count($nums); $i++) { - $min = $min->compare($nums[$i]) > 0 ? $nums[$i] : $min; - } - return $min; - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param array $nums - * @return Engine - */ - protected static function maxHelper(array $nums) - { - if (count($nums) == 1) { - return $nums[0]; - } - $max = $nums[0]; - for ($i = 1; $i < count($nums); $i++) { - $max = $max->compare($nums[$i]) < 0 ? $nums[$i] : $max; - } - return $max; - } - - /** - * Create Recurring Modulo Function - * - * Sometimes it may be desirable to do repeated modulos with the same number outside of - * modular exponentiation - * - * @return callable - */ - public function createRecurringModuloFunction() - { - $class = static::class; - - $fqengine = !method_exists(static::$modexpEngine[static::class], 'reduce') ? - '\\phpseclib3\\Math\\BigInteger\\Engines\\' . static::ENGINE_DIR . '\\DefaultEngine' : - static::$modexpEngine[static::class]; - if (method_exists($fqengine, 'generateCustomReduction')) { - $func = $fqengine::generateCustomReduction($this, static::class); - return eval('return function(' . static::class . ' $x) use ($func, $class) { - $r = new $class(); - $r->value = $func($x->value); - return $r; - };'); - } - $n = $this->value; - return eval('return function(' . static::class . ' $x) use ($n, $fqengine, $class) { - $r = new $class(); - $r->value = $fqengine::reduce($x->value, $n, $class); - return $r; - };'); - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * @param Engine $n - * @return array{gcd: Engine, x: Engine, y: Engine} - */ - protected function extendedGCDHelper(Engine $n) - { - $u = clone $this; - $v = clone $n; - - $one = new static(1); - $zero = new static(); - - $a = clone $one; - $b = clone $zero; - $c = clone $zero; - $d = clone $one; - - while (!$v->equals($zero)) { - list($q) = $u->divide($v); - - $temp = $u; - $u = $v; - $v = $temp->subtract($v->multiply($q)); - - $temp = $a; - $a = $c; - $c = $temp->subtract($a->multiply($q)); - - $temp = $b; - $b = $d; - $d = $temp->subtract($b->multiply($q)); - } - - return [ - 'gcd' => $u, - 'x' => $a, - 'y' => $b - ]; - } - - /** - * Bitwise Split - * - * Splits BigInteger's into chunks of $split bits - * - * @param int $split - * @return Engine[] - */ - public function bitwise_split($split) - { - if ($split < 1) { - throw new \RuntimeException('Offset must be greater than 1'); - } - - $mask = static::$one[static::class]->bitwise_leftShift($split)->subtract(static::$one[static::class]); - - $num = clone $this; - - $vals = []; - while (!$num->equals(static::$zero[static::class])) { - $vals[] = $num->bitwise_and($mask); - $num = $num->bitwise_rightShift($split); - } - - return array_reverse($vals); - } - - /** - * Logical And - * - * @param Engine $x - * @return Engine - */ - protected function bitwiseAndHelper(Engine $x) - { - $left = $this->toBytes(true); - $right = $x->toBytes(true); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->normalize(new static($left & $right, -256)); - } - - /** - * Logical Or - * - * @param Engine $x - * @return Engine - */ - protected function bitwiseOrHelper(Engine $x) - { - $left = $this->toBytes(true); - $right = $x->toBytes(true); - - $length = max(strlen($left), strlen($right)); - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - - return $this->normalize(new static($left | $right, -256)); - } - - /** - * Logical Exclusive Or - * - * @param Engine $x - * @return Engine - */ - protected function bitwiseXorHelper(Engine $x) - { - $left = $this->toBytes(true); - $right = $x->toBytes(true); - - $length = max(strlen($left), strlen($right)); - - - $left = str_pad($left, $length, chr(0), STR_PAD_LEFT); - $right = str_pad($right, $length, chr(0), STR_PAD_LEFT); - return $this->normalize(new static($left ^ $right, -256)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php deleted file mode 100644 index f616362..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP.php +++ /dev/null @@ -1,694 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use phpseclib3\Exception\BadConfigurationException; - -/** - * GMP Engine. - * - * @author Jim Wigginton - */ -class GMP extends Engine -{ - /** - * Can Bitwise operations be done fast? - * - * @see parent::bitwise_leftRotate() - * @see parent::bitwise_rightRotate() - */ - const FAST_BITWISE = true; - - /** - * Engine Directory - * - * @see parent::setModExpEngine - */ - const ENGINE_DIR = 'GMP'; - - /** - * Test for engine validity - * - * @return bool - * @see parent::__construct() - */ - public static function isValidEngine() - { - return extension_loaded('gmp'); - } - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - * @see parent::__construct() - */ - public function __construct($x = 0, $base = 10) - { - if (!isset(static::$isValidEngine[static::class])) { - static::$isValidEngine[static::class] = self::isValidEngine(); - } - if (!static::$isValidEngine[static::class]) { - throw new BadConfigurationException('GMP is not setup correctly on this system'); - } - - if ($x instanceof \GMP) { - $this->value = $x; - return; - } - - $this->value = gmp_init(0); - - parent::__construct($x, $base); - } - - /** - * Initialize a GMP BigInteger Engine instance - * - * @param int $base - * @see parent::__construct() - */ - protected function initialize($base) - { - switch (abs($base)) { - case 256: - $this->value = gmp_import($this->value); - if ($this->is_negative) { - $this->value = -$this->value; - } - break; - case 16: - $temp = $this->is_negative ? '-0x' . $this->value : '0x' . $this->value; - $this->value = gmp_init($temp); - break; - case 10: - $this->value = gmp_init(isset($this->value) ? $this->value : '0'); - } - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - return (string)$this->value; - } - - /** - * Converts a BigInteger to a bit string (eg. base-2). - * - * Negative numbers are saved as positive numbers, unless $twos_compliment is set to true, at which point, they're - * saved as two's compliment. - * - * @param bool $twos_compliment - * @return string - */ - public function toBits($twos_compliment = false) - { - $hex = $this->toHex($twos_compliment); - - $bits = gmp_strval(gmp_init($hex, 16), 2); - - if ($this->precision > 0) { - $bits = substr($bits, -$this->precision); - } - - if ($twos_compliment && $this->compare(new static()) > 0 && $this->precision <= 0) { - return '0' . $bits; - } - - return $bits; - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - public function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - return $this->toBytesHelper(); - } - - if (gmp_cmp($this->value, gmp_init(0)) == 0) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $temp = gmp_export($this->value); - - return $this->precision > 0 ? - substr(str_pad($temp, $this->precision >> 3, chr(0), STR_PAD_LEFT), -($this->precision >> 3)) : - ltrim($temp, chr(0)); - } - - /** - * Adds two BigIntegers. - * - * @param GMP $y - * @return GMP - */ - public function add(GMP $y) - { - $temp = new self(); - $temp->value = $this->value + $y->value; - - return $this->normalize($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param GMP $y - * @return GMP - */ - public function subtract(GMP $y) - { - $temp = new self(); - $temp->value = $this->value - $y->value; - - return $this->normalize($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param GMP $x - * @return GMP - */ - public function multiply(GMP $x) - { - $temp = new self(); - $temp->value = $this->value * $x->value; - - return $this->normalize($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param GMP $y - * @return array{GMP, GMP} - */ - public function divide(GMP $y) - { - $quotient = new self(); - $remainder = new self(); - - list($quotient->value, $remainder->value) = gmp_div_qr($this->value, $y->value); - - if (gmp_sign($remainder->value) < 0) { - $remainder->value = $remainder->value + gmp_abs($y->value); - } - - return [$this->normalize($quotient), $this->normalize($remainder)]; - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this - * is demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param GMP $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @see self::equals() - */ - public function compare(GMP $y) - { - $r = gmp_cmp($this->value, $y->value); - if ($r < -1) { - $r = -1; - } - if ($r > 1) { - $r = 1; - } - return $r; - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param GMP $x - * @return bool - */ - public function equals(GMP $x) - { - return $this->value == $x->value; - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * - * @param GMP $n - * @return false|GMP - */ - public function modInverse(GMP $n) - { - $temp = new self(); - $temp->value = gmp_invert($this->value, $n->value); - - return $temp->value === false ? false : $this->normalize($temp); - } - - /** - * Calculates the greatest common divisor and Bezout's identity. - * - * Say you have 693 and 609. The GCD is 21. Bezout's identity states that there exist integers x and y such that - * 693*x + 609*y == 21. In point of fact, there are actually an infinite number of x and y combinations and which - * combination is returned is dependent upon which mode is in use. See - * {@link http://en.wikipedia.org/wiki/B%C3%A9zout%27s_identity Bezout's identity - Wikipedia} for more information. - * - * @param GMP $n - * @return GMP[] - */ - public function extendedGCD(GMP $n) - { - extract(gmp_gcdext($this->value, $n->value)); - - return [ - 'gcd' => $this->normalize(new self($g)), - 'x' => $this->normalize(new self($s)), - 'y' => $this->normalize(new self($t)) - ]; - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param GMP $n - * @return GMP - */ - public function gcd(GMP $n) - { - $r = gmp_gcd($this->value, $n->value); - return $this->normalize(new self($r)); - } - - /** - * Absolute value. - * - * @return GMP - */ - public function abs() - { - $temp = new self(); - $temp->value = gmp_abs($this->value); - - return $temp; - } - - /** - * Logical And - * - * @param GMP $x - * @return GMP - */ - public function bitwise_and(GMP $x) - { - $temp = new self(); - $temp->value = $this->value & $x->value; - - return $this->normalize($temp); - } - - /** - * Logical Or - * - * @param GMP $x - * @return GMP - */ - public function bitwise_or(GMP $x) - { - $temp = new self(); - $temp->value = $this->value | $x->value; - - return $this->normalize($temp); - } - - /** - * Logical Exclusive Or - * - * @param GMP $x - * @return GMP - */ - public function bitwise_xor(GMP $x) - { - $temp = new self(); - $temp->value = $this->value ^ $x->value; - - return $this->normalize($temp); - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return GMP - */ - public function bitwise_rightShift($shift) - { - // 0xFFFFFFFF >> 2 == -1 (on 32-bit systems) - // gmp_init('0xFFFFFFFF') >> 2 == gmp_init('0x3FFFFFFF') - - $temp = new self(); - $temp->value = $this->value >> $shift; - - return $this->normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return GMP - */ - public function bitwise_leftShift($shift) - { - $temp = new self(); - $temp->value = $this->value << $shift; - - return $this->normalize($temp); - } - - /** - * Performs modular exponentiation. - * - * @param GMP $e - * @param GMP $n - * @return GMP - */ - public function modPow(GMP $e, GMP $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param GMP $e - * @param GMP $n - * @return GMP - */ - public function powMod(GMP $e, GMP $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * @param GMP $e - * @param GMP $n - * @return GMP - */ - protected function powModInner(GMP $e, GMP $n) - { - $class = static::$modexpEngine[static::class]; - return $class::powModHelper($this, $e, $n); - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param GMP $result - * @return GMP - */ - protected function normalize(GMP $result) - { - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - if ($result->bitmask !== false) { - $flip = $result->value < 0; - if ($flip) { - $result->value = -$result->value; - } - $result->value = $result->value & $result->bitmask->value; - if ($flip) { - $result->value = -$result->value; - } - } - - return $result; - } - - /** - * Performs some post-processing for randomRangePrime - * - * @param Engine $x - * @param Engine $min - * @param Engine $max - * @return GMP - */ - protected static function randomRangePrimeInner(Engine $x, Engine $min, Engine $max) - { - $p = gmp_nextprime($x->value); - - if ($p <= $max->value) { - return new self($p); - } - - if ($min->value != $x->value) { - $x = new self($x->value - 1); - } - - return self::randomRangePrime($min, $x); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param GMP $min - * @param GMP $max - * @return false|GMP - */ - public static function randomRangePrime(GMP $min, GMP $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param GMP $min - * @param GMP $max - * @return GMP - */ - public static function randomRange(GMP $min, GMP $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - */ - protected function make_odd() - { - gmp_setbit($this->value, 0); - } - - /** - * Tests Primality - * - * @param int $t - * @return bool - */ - protected function testPrimality($t) - { - return gmp_prob_prime($this->value, $t) != 0; - } - - /** - * Calculates the nth root of a biginteger. - * - * Returns the nth root of a positive biginteger, where n defaults to 2 - * - * @param int $n - * @return GMP - */ - protected function rootInner($n) - { - $root = new self(); - $root->value = gmp_root($this->value, $n); - return $this->normalize($root); - } - - /** - * Performs exponentiation. - * - * @param GMP $n - * @return GMP - */ - public function pow(GMP $n) - { - $temp = new self(); - $temp->value = $this->value ** $n->value; - - return $this->normalize($temp); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param GMP ...$nums - * @return GMP - */ - public static function min(GMP ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param GMP ...$nums - * @return GMP - */ - public static function max(GMP ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param GMP $min - * @param GMP $max - * @return bool - */ - public function between(GMP $min, GMP $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } - - /** - * Create Recurring Modulo Function - * - * Sometimes it may be desirable to do repeated modulos with the same number outside of - * modular exponentiation - * - * @return callable - */ - public function createRecurringModuloFunction() - { - $temp = $this->value; - return function (GMP $x) use ($temp) { - return new GMP($x->value % $temp); - }; - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @param GMP $r - * @return int - */ - public static function scan1divide(GMP $r) - { - $s = gmp_scan1($r->value, 0); - $r->value >>= $s; - return $s; - } - - /** - * Is Odd? - * - * @return bool - */ - public function isOdd() - { - return gmp_testbit($this->value, 0); - } - - /** - * Tests if a bit is set - * - * @return bool - */ - public function testBit($x) - { - return gmp_testbit($this->value, $x); - } - - /** - * Is Negative? - * - * @return bool - */ - public function isNegative() - { - return gmp_sign($this->value) == -1; - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return GMP - */ - public function negate() - { - $temp = clone $this; - $temp->value = -$this->value; - - return $temp; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php deleted file mode 100644 index bc219fb..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/GMP/DefaultEngine.php +++ /dev/null @@ -1,40 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\GMP; - -use phpseclib3\Math\BigInteger\Engines\GMP; - -/** - * GMP Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class DefaultEngine extends GMP -{ - /** - * Performs modular exponentiation. - * - * @param GMP $x - * @param GMP $e - * @param GMP $n - * @return GMP - */ - protected static function powModHelper(GMP $x, GMP $e, GMP $n) - { - $temp = new GMP(); - $temp->value = gmp_powm($x->value, $e->value, $n->value); - - return $x->normalize($temp); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php deleted file mode 100644 index e33a9f1..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/OpenSSL.php +++ /dev/null @@ -1,68 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use phpseclib3\Crypt\RSA\Formats\Keys\PKCS8; -use phpseclib3\Math\BigInteger; - -/** - * OpenSSL Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class OpenSSL -{ - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return extension_loaded('openssl') && static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * @param Engine $x - * @param Engine $e - * @param Engine $n - * @return Engine - */ - public static function powModHelper(Engine $x, Engine $e, Engine $n) - { - if ($n->getLengthInBytes() < 31 || $n->getLengthInBytes() > 16384) { - throw new \OutOfRangeException('Only modulo between 31 and 16384 bits are accepted'); - } - - $key = PKCS8::savePublicKey( - new BigInteger($n), - new BigInteger($e) - ); - - $plaintext = str_pad($x->toBytes(), $n->getLengthInBytes(), "\0", STR_PAD_LEFT); - - // this is easily prone to failure. if the modulo is a multiple of 2 or 3 or whatever it - // won't work and you'll get a "failure: error:0906D06C:PEM routines:PEM_read_bio:no start line" - // error. i suppose, for even numbers, we could do what PHP\Montgomery.php does, but then what - // about odd numbers divisible by 3, by 5, etc? - if (!openssl_public_encrypt($plaintext, $result, $key, OPENSSL_NO_PADDING)) { - throw new \UnexpectedValueException(openssl_error_string()); - } - - $class = get_class($x); - return new $class($result, 256); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php deleted file mode 100644 index 7e85783..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP.php +++ /dev/null @@ -1,1344 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\BadConfigurationException; - -/** - * Pure-PHP Engine. - * - * @author Jim Wigginton - */ -abstract class PHP extends Engine -{ - /**#@+ - * Array constants - * - * Rather than create a thousands and thousands of new BigInteger objects in repeated function calls to add() and - * multiply() or whatever, we'll just work directly on arrays, taking them in as parameters and returning them. - * - */ - /** - * $result[self::VALUE] contains the value. - */ - const VALUE = 0; - /** - * $result[self::SIGN] contains the sign. - */ - const SIGN = 1; - /**#@-*/ - - /** - * Karatsuba Cutoff - * - * At what point do we switch between Karatsuba multiplication and schoolbook long multiplication? - * - */ - const KARATSUBA_CUTOFF = 25; - - /** - * Can Bitwise operations be done fast? - * - * @see parent::bitwise_leftRotate() - * @see parent::bitwise_rightRotate() - */ - const FAST_BITWISE = true; - - /** - * Engine Directory - * - * @see parent::setModExpEngine - */ - const ENGINE_DIR = 'PHP'; - - /** - * Default constructor - * - * @param mixed $x integer Base-10 number or base-$base number if $base set. - * @param int $base - * @return PHP - * @see parent::__construct() - */ - public function __construct($x = 0, $base = 10) - { - if (!isset(static::$isValidEngine[static::class])) { - static::$isValidEngine[static::class] = static::isValidEngine(); - } - if (!static::$isValidEngine[static::class]) { - throw new BadConfigurationException(static::class . ' is not setup correctly on this system'); - } - - $this->value = []; - parent::__construct($x, $base); - } - - /** - * Initialize a PHP BigInteger Engine instance - * - * @param int $base - * @see parent::__construct() - */ - protected function initialize($base) - { - switch (abs($base)) { - case 16: - $x = (strlen($this->value) & 1) ? '0' . $this->value : $this->value; - $temp = new static(Strings::hex2bin($x), 256); - $this->value = $temp->value; - break; - case 10: - $temp = new static(); - - $multiplier = new static(); - $multiplier->value = [static::MAX10]; - - $x = $this->value; - - if ($x[0] == '-') { - $this->is_negative = true; - $x = substr($x, 1); - } - - $x = str_pad( - $x, - strlen($x) + ((static::MAX10LEN - 1) * strlen($x)) % static::MAX10LEN, - 0, - STR_PAD_LEFT - ); - while (strlen($x)) { - $temp = $temp->multiply($multiplier); - $temp = $temp->add(new static($this->int2bytes(substr($x, 0, static::MAX10LEN)), 256)); - $x = substr($x, static::MAX10LEN); - } - - $this->value = $temp->value; - } - } - - /** - * Pads strings so that unpack may be used on them - * - * @param string $str - * @return string - */ - protected function pad($str) - { - $length = strlen($str); - - $pad = 4 - (strlen($str) % 4); - - return str_pad($str, $length + $pad, "\0", STR_PAD_LEFT); - } - - /** - * Converts a BigInteger to a base-10 number. - * - * @return string - */ - public function toString() - { - if (!count($this->value)) { - return '0'; - } - - $temp = clone $this; - $temp->bitmask = false; - $temp->is_negative = false; - - $divisor = new static(); - $divisor->value = [static::MAX10]; - $result = ''; - while (count($temp->value)) { - list($temp, $mod) = $temp->divide($divisor); - $result = str_pad( - isset($mod->value[0]) ? $mod->value[0] : '', - static::MAX10LEN, - '0', - STR_PAD_LEFT - ) . $result; - } - $result = ltrim($result, '0'); - if (empty($result)) { - $result = '0'; - } - - if ($this->is_negative) { - $result = '-' . $result; - } - - return $result; - } - - /** - * Converts a BigInteger to a byte string (eg. base-256). - * - * @param bool $twos_compliment - * @return string - */ - public function toBytes($twos_compliment = false) - { - if ($twos_compliment) { - return $this->toBytesHelper(); - } - - if (!count($this->value)) { - return $this->precision > 0 ? str_repeat(chr(0), ($this->precision + 1) >> 3) : ''; - } - - $result = $this->bitwise_small_split(8); - $result = implode('', array_map('chr', $result)); - - return $this->precision > 0 ? - str_pad( - substr($result, -(($this->precision + 7) >> 3)), - ($this->precision + 7) >> 3, - chr(0), - STR_PAD_LEFT - ) : - $result; - } - - /** - * Performs addition. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - */ - protected static function addHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - $x_size = count($x_value); - $y_size = count($y_value); - - if ($x_size == 0) { - return [ - self::VALUE => $y_value, - self::SIGN => $y_negative - ]; - } elseif ($y_size == 0) { - return [ - self::VALUE => $x_value, - self::SIGN => $x_negative - ]; - } - - // subtract, if appropriate - if ($x_negative != $y_negative) { - if ($x_value == $y_value) { - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - $temp = self::subtractHelper($x_value, false, $y_value, false); - $temp[self::SIGN] = self::compareHelper($x_value, false, $y_value, false) > 0 ? - $x_negative : $y_negative; - - return $temp; - } - - if ($x_size < $y_size) { - $size = $x_size; - $value = $y_value; - } else { - $size = $y_size; - $value = $x_value; - } - - $value[count($value)] = 0; // just in case the carry adds an extra digit - - $carry = 0; - for ($i = 0, $j = 1; $j < $size; $i += 2, $j += 2) { - //$sum = $x_value[$j] * static::BASE_FULL + $x_value[$i] + $y_value[$j] * static::BASE_FULL + $y_value[$i] + $carry; - $sum = ($x_value[$j] + $y_value[$j]) * static::BASE_FULL + $x_value[$i] + $y_value[$i] + $carry; - $carry = $sum >= static::MAX_DIGIT2; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 - $sum = $carry ? $sum - static::MAX_DIGIT2 : $sum; - - $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); - - $value[$i] = (int)($sum - static::BASE_FULL * $temp); // eg. a faster alternative to fmod($sum, 0x4000000) - $value[$j] = $temp; - } - - if ($j == $size) { // ie. if $y_size is odd - $sum = $x_value[$i] + $y_value[$i] + $carry; - $carry = $sum >= static::BASE_FULL; - $value[$i] = $carry ? $sum - static::BASE_FULL : $sum; - ++$i; // ie. let $i = $j since we've just done $value[$i] - } - - if ($carry) { - for (; $value[$i] == static::MAX_DIGIT; ++$i) { - $value[$i] = 0; - } - ++$value[$i]; - } - - return [ - self::VALUE => self::trim($value), - self::SIGN => $x_negative - ]; - } - - /** - * Performs subtraction. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - */ - public static function subtractHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - $x_size = count($x_value); - $y_size = count($y_value); - - if ($x_size == 0) { - return [ - self::VALUE => $y_value, - self::SIGN => !$y_negative - ]; - } elseif ($y_size == 0) { - return [ - self::VALUE => $x_value, - self::SIGN => $x_negative - ]; - } - - // add, if appropriate (ie. -$x - +$y or +$x - -$y) - if ($x_negative != $y_negative) { - $temp = self::addHelper($x_value, false, $y_value, false); - $temp[self::SIGN] = $x_negative; - - return $temp; - } - - $diff = self::compareHelper($x_value, $x_negative, $y_value, $y_negative); - - if (!$diff) { - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - // switch $x and $y around, if appropriate. - if ((!$x_negative && $diff < 0) || ($x_negative && $diff > 0)) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_negative = !$x_negative; - - $x_size = count($x_value); - $y_size = count($y_value); - } - - // at this point, $x_value should be at least as big as - if not bigger than - $y_value - - $carry = 0; - for ($i = 0, $j = 1; $j < $y_size; $i += 2, $j += 2) { - $sum = ($x_value[$j] - $y_value[$j]) * static::BASE_FULL + $x_value[$i] - $y_value[$i] - $carry; - - $carry = $sum < 0; // eg. floor($sum / 2**52); only possible values (in any base) are 0 and 1 - $sum = $carry ? $sum + static::MAX_DIGIT2 : $sum; - - $temp = static::BASE === 26 ? intval($sum / 0x4000000) : ($sum >> 31); - - $x_value[$i] = (int)($sum - static::BASE_FULL * $temp); - $x_value[$j] = $temp; - } - - if ($j == $y_size) { // ie. if $y_size is odd - $sum = $x_value[$i] - $y_value[$i] - $carry; - $carry = $sum < 0; - $x_value[$i] = $carry ? $sum + static::BASE_FULL : $sum; - ++$i; - } - - if ($carry) { - for (; !$x_value[$i]; ++$i) { - $x_value[$i] = static::MAX_DIGIT; - } - --$x_value[$i]; - } - - return [ - self::VALUE => self::trim($x_value), - self::SIGN => $x_negative - ]; - } - - /** - * Performs multiplication. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return array - */ - protected static function multiplyHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - //if ( $x_value == $y_value ) { - // return [ - // self::VALUE => self::square($x_value), - // self::SIGN => $x_sign != $y_value - // ]; - //} - - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - return [ - self::VALUE => min($x_length, $y_length) < 2 * self::KARATSUBA_CUTOFF ? - self::trim(self::regularMultiply($x_value, $y_value)) : - self::trim(self::karatsuba($x_value, $y_value)), - self::SIGN => $x_negative != $y_negative - ]; - } - - /** - * Performs Karatsuba multiplication on two BigIntegers - * - * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=120 MPM 5.2.3}. - * - * @param array $x_value - * @param array $y_value - * @return array - */ - private static function karatsuba(array $x_value, array $y_value) - { - $m = min(count($x_value) >> 1, count($y_value) >> 1); - - if ($m < self::KARATSUBA_CUTOFF) { - return self::regularMultiply($x_value, $y_value); - } - - $x1 = array_slice($x_value, $m); - $x0 = array_slice($x_value, 0, $m); - $y1 = array_slice($y_value, $m); - $y0 = array_slice($y_value, 0, $m); - - $z2 = self::karatsuba($x1, $y1); - $z0 = self::karatsuba($x0, $y0); - - $z1 = self::addHelper($x1, false, $x0, false); - $temp = self::addHelper($y1, false, $y0, false); - $z1 = self::karatsuba($z1[self::VALUE], $temp[self::VALUE]); - $temp = self::addHelper($z2, false, $z0, false); - $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); - - $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); - $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - - $xy = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xy = self::addHelper($xy[self::VALUE], $xy[self::SIGN], $z0, false); - - return $xy[self::VALUE]; - } - - /** - * Performs long multiplication on two BigIntegers - * - * Modeled after 'multiply' in MutableBigInteger.java. - * - * @param array $x_value - * @param array $y_value - * @return array - */ - protected static function regularMultiply(array $x_value, array $y_value) - { - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return []; - } - - $product_value = self::array_repeat(0, $x_length + $y_length); - - // the following for loop could be removed if the for loop following it - // (the one with nested for loops) initially set $i to 0, but - // doing so would also make the result in one set of unnecessary adds, - // since on the outermost loops first pass, $product->value[$k] is going - // to always be 0 - - $carry = 0; - for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0 - $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$j] = (int)($temp - static::BASE_FULL * $carry); - } - - $product_value[$j] = $carry; - - // the above for loop is what the previous comment was talking about. the - // following for loop is the "one with nested for loops" - for ($i = 1; $i < $y_length; ++$i) { - $carry = 0; - - for ($j = 0, $k = $i; $j < $x_length; ++$j, ++$k) { - $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$k] = (int)($temp - static::BASE_FULL * $carry); - } - - $product_value[$k] = $carry; - } - - return $product_value; - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @return array{static, static} - * @internal This function is based off of - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=9 HAC 14.20}. - */ - protected function divideHelper(PHP $y) - { - if (count($y->value) == 1) { - list($q, $r) = $this->divide_digit($this->value, $y->value[0]); - $quotient = new static(); - $remainder = new static(); - $quotient->value = $q; - $remainder->value = [$r]; - $quotient->is_negative = $this->is_negative != $y->is_negative; - return [$this->normalize($quotient), $this->normalize($remainder)]; - } - - $x = clone $this; - $y = clone $y; - - $x_sign = $x->is_negative; - $y_sign = $y->is_negative; - - $x->is_negative = $y->is_negative = false; - - $diff = $x->compare($y); - - if (!$diff) { - $temp = new static(); - $temp->value = [1]; - $temp->is_negative = $x_sign != $y_sign; - return [$this->normalize($temp), $this->normalize(static::$zero[static::class])]; - } - - if ($diff < 0) { - // if $x is negative, "add" $y. - if ($x_sign) { - $x = $y->subtract($x); - } - return [$this->normalize(static::$zero[static::class]), $this->normalize($x)]; - } - - // normalize $x and $y as described in HAC 14.23 / 14.24 - $msb = $y->value[count($y->value) - 1]; - for ($shift = 0; !($msb & static::MSB); ++$shift) { - $msb <<= 1; - } - $x->lshift($shift); - $y->lshift($shift); - $y_value = &$y->value; - - $x_max = count($x->value) - 1; - $y_max = count($y->value) - 1; - - $quotient = new static(); - $quotient_value = &$quotient->value; - $quotient_value = self::array_repeat(0, $x_max - $y_max + 1); - - static $temp, $lhs, $rhs; - if (!isset($temp)) { - $temp = new static(); - $lhs = new static(); - $rhs = new static(); - } - if (static::class != get_class($temp)) { - $temp = new static(); - $lhs = new static(); - $rhs = new static(); - } - $temp_value = &$temp->value; - $rhs_value = &$rhs->value; - - // $temp = $y << ($x_max - $y_max-1) in base 2**26 - $temp_value = array_merge(self::array_repeat(0, $x_max - $y_max), $y_value); - - while ($x->compare($temp) >= 0) { - // calculate the "common residue" - ++$quotient_value[$x_max - $y_max]; - $x = $x->subtract($temp); - $x_max = count($x->value) - 1; - } - - for ($i = $x_max; $i >= $y_max + 1; --$i) { - $x_value = &$x->value; - $x_window = [ - isset($x_value[$i]) ? $x_value[$i] : 0, - isset($x_value[$i - 1]) ? $x_value[$i - 1] : 0, - isset($x_value[$i - 2]) ? $x_value[$i - 2] : 0 - ]; - $y_window = [ - $y_value[$y_max], - ($y_max > 0) ? $y_value[$y_max - 1] : 0 - ]; - - $q_index = $i - $y_max - 1; - if ($x_window[0] == $y_window[0]) { - $quotient_value[$q_index] = static::MAX_DIGIT; - } else { - $quotient_value[$q_index] = self::safe_divide( - $x_window[0] * static::BASE_FULL + $x_window[1], - $y_window[0] - ); - } - - $temp_value = [$y_window[1], $y_window[0]]; - - $lhs->value = [$quotient_value[$q_index]]; - $lhs = $lhs->multiply($temp); - - $rhs_value = [$x_window[2], $x_window[1], $x_window[0]]; - - while ($lhs->compare($rhs) > 0) { - --$quotient_value[$q_index]; - - $lhs->value = [$quotient_value[$q_index]]; - $lhs = $lhs->multiply($temp); - } - - $adjust = self::array_repeat(0, $q_index); - $temp_value = [$quotient_value[$q_index]]; - $temp = $temp->multiply($y); - $temp_value = &$temp->value; - if (count($temp_value)) { - $temp_value = array_merge($adjust, $temp_value); - } - - $x = $x->subtract($temp); - - if ($x->compare(static::$zero[static::class]) < 0) { - $temp_value = array_merge($adjust, $y_value); - $x = $x->add($temp); - - --$quotient_value[$q_index]; - } - - $x_max = count($x_value) - 1; - } - - // unnormalize the remainder - $x->rshift($shift); - - $quotient->is_negative = $x_sign != $y_sign; - - // calculate the "common residue", if appropriate - if ($x_sign) { - $y->rshift($shift); - $x = $y->subtract($x); - } - - return [$this->normalize($quotient), $this->normalize($x)]; - } - - /** - * Divides a BigInteger by a regular integer - * - * abc / x = a00 / x + b0 / x + c / x - * - * @param array $dividend - * @param int $divisor - * @return array - */ - private static function divide_digit(array $dividend, $divisor) - { - $carry = 0; - $result = []; - - for ($i = count($dividend) - 1; $i >= 0; --$i) { - $temp = static::BASE_FULL * $carry + $dividend[$i]; - $result[$i] = self::safe_divide($temp, $divisor); - $carry = (int)($temp - $divisor * $result[$i]); - } - - return [$result, $carry]; - } - - /** - * Single digit division - * - * Even if int64 is being used the division operator will return a float64 value - * if the dividend is not evenly divisible by the divisor. Since a float64 doesn't - * have the precision of int64 this is a problem so, when int64 is being used, - * we'll guarantee that the dividend is divisible by first subtracting the remainder. - * - * @param int $x - * @param int $y - * @return int - */ - private static function safe_divide($x, $y) - { - if (static::BASE === 26) { - return (int)($x / $y); - } - - // static::BASE === 31 - /** @var int */ - return ($x - ($x % $y)) / $y; - } - - /** - * Convert an array / boolean to a PHP BigInteger object - * - * @param array $arr - * @return static - */ - protected function convertToObj(array $arr) - { - $result = new static(); - $result->value = $arr[self::VALUE]; - $result->is_negative = $arr[self::SIGN]; - - return $this->normalize($result); - } - - /** - * Normalize - * - * Removes leading zeros and truncates (if necessary) to maintain the appropriate precision - * - * @param PHP $result - * @return static - */ - protected function normalize(PHP $result) - { - $result->precision = $this->precision; - $result->bitmask = $this->bitmask; - - $value = &$result->value; - - if (!count($value)) { - $result->is_negative = false; - return $result; - } - - $value = static::trim($value); - - if (!empty($result->bitmask->value)) { - $length = min(count($value), count($result->bitmask->value)); - $value = array_slice($value, 0, $length); - - for ($i = 0; $i < $length; ++$i) { - $value[$i] = $value[$i] & $result->bitmask->value[$i]; - } - - $value = static::trim($value); - } - - return $result; - } - - /** - * Compares two numbers. - * - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @return int - * @see static::compare() - */ - protected static function compareHelper(array $x_value, $x_negative, array $y_value, $y_negative) - { - if ($x_negative != $y_negative) { - return (!$x_negative && $y_negative) ? 1 : -1; - } - - $result = $x_negative ? -1 : 1; - - if (count($x_value) != count($y_value)) { - return (count($x_value) > count($y_value)) ? $result : -$result; - } - $size = max(count($x_value), count($y_value)); - - $x_value = array_pad($x_value, $size, 0); - $y_value = array_pad($y_value, $size, 0); - - for ($i = count($x_value) - 1; $i >= 0; --$i) { - if ($x_value[$i] != $y_value[$i]) { - return ($x_value[$i] > $y_value[$i]) ? $result : -$result; - } - } - - return 0; - } - - /** - * Absolute value. - * - * @return PHP - */ - public function abs() - { - $temp = new static(); - $temp->value = $this->value; - - return $temp; - } - - /** - * Trim - * - * Removes leading zeros - * - * @param list $value - * @return list - */ - protected static function trim(array $value) - { - for ($i = count($value) - 1; $i >= 0; --$i) { - if ($value[$i]) { - break; - } - unset($value[$i]); - } - - return $value; - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits, effectively dividing by 2**$shift. - * - * @param int $shift - * @return PHP - */ - public function bitwise_rightShift($shift) - { - $temp = new static(); - - // could just replace lshift with this, but then all lshift() calls would need to be rewritten - // and I don't want to do that... - $temp->value = $this->value; - $temp->rshift($shift); - - return $this->normalize($temp); - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits, effectively multiplying by 2**$shift. - * - * @param int $shift - * @return PHP - */ - public function bitwise_leftShift($shift) - { - $temp = new static(); - // could just replace _rshift with this, but then all _lshift() calls would need to be rewritten - // and I don't want to do that... - $temp->value = $this->value; - $temp->lshift($shift); - - return $this->normalize($temp); - } - - /** - * Converts 32-bit integers to bytes. - * - * @param int $x - * @return string - */ - private static function int2bytes($x) - { - return ltrim(pack('N', $x), chr(0)); - } - - /** - * Array Repeat - * - * @param int $input - * @param int $multiplier - * @return array - */ - protected static function array_repeat($input, $multiplier) - { - return $multiplier ? array_fill(0, $multiplier, $input) : []; - } - - /** - * Logical Left Shift - * - * Shifts BigInteger's by $shift bits. - * - * @param int $shift - */ - protected function lshift($shift) - { - if ($shift == 0) { - return; - } - - $num_digits = (int)($shift / static::BASE); - $shift %= static::BASE; - $shift = 1 << $shift; - - $carry = 0; - - for ($i = 0; $i < count($this->value); ++$i) { - $temp = $this->value[$i] * $shift + $carry; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $this->value[$i] = (int)($temp - $carry * static::BASE_FULL); - } - - if ($carry) { - $this->value[count($this->value)] = $carry; - } - - while ($num_digits--) { - array_unshift($this->value, 0); - } - } - - /** - * Logical Right Shift - * - * Shifts BigInteger's by $shift bits. - * - * @param int $shift - */ - protected function rshift($shift) - { - if ($shift == 0) { - return; - } - - $num_digits = (int)($shift / static::BASE); - $shift %= static::BASE; - $carry_shift = static::BASE - $shift; - $carry_mask = (1 << $shift) - 1; - - if ($num_digits) { - $this->value = array_slice($this->value, $num_digits); - } - - $carry = 0; - - for ($i = count($this->value) - 1; $i >= 0; --$i) { - $temp = $this->value[$i] >> $shift | $carry; - $carry = ($this->value[$i] & $carry_mask) << $carry_shift; - $this->value[$i] = $temp; - } - - $this->value = static::trim($this->value); - } - - /** - * Performs modular exponentiation. - * - * @param PHP $e - * @param PHP $n - * @return PHP - */ - protected function powModInner(PHP $e, PHP $n) - { - try { - $class = static::$modexpEngine[static::class]; - return $class::powModHelper($this, $e, $n, static::class); - } catch (\Exception $err) { - return PHP\DefaultEngine::powModHelper($this, $e, $n, static::class); - } - } - - /** - * Performs squaring - * - * @param list $x - * @return list - */ - protected static function square(array $x) - { - return count($x) < 2 * self::KARATSUBA_CUTOFF ? - self::trim(self::baseSquare($x)) : - self::trim(self::karatsubaSquare($x)); - } - - /** - * Performs traditional squaring on two BigIntegers - * - * Squaring can be done faster than multiplying a number by itself can be. See - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=7 HAC 14.2.4} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=141 MPM 5.3} for more information. - * - * @param array $value - * @return array - */ - protected static function baseSquare(array $value) - { - if (empty($value)) { - return []; - } - $square_value = self::array_repeat(0, 2 * count($value)); - - for ($i = 0, $max_index = count($value) - 1; $i <= $max_index; ++$i) { - $i2 = $i << 1; - - $temp = $square_value[$i2] + $value[$i] * $value[$i]; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $square_value[$i2] = (int)($temp - static::BASE_FULL * $carry); - - // note how we start from $i+1 instead of 0 as we do in multiplication. - for ($j = $i + 1, $k = $i2 + 1; $j <= $max_index; ++$j, ++$k) { - $temp = $square_value[$k] + 2 * $value[$j] * $value[$i] + $carry; - $carry = static::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $square_value[$k] = (int)($temp - static::BASE_FULL * $carry); - } - - // the following line can yield values larger 2**15. at this point, PHP should switch - // over to floats. - $square_value[$i + $max_index + 1] = $carry; - } - - return $square_value; - } - - /** - * Performs Karatsuba "squaring" on two BigIntegers - * - * See {@link http://en.wikipedia.org/wiki/Karatsuba_algorithm Karatsuba algorithm} and - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=151 MPM 5.3.4}. - * - * @param array $value - * @return array - */ - protected static function karatsubaSquare(array $value) - { - $m = count($value) >> 1; - - if ($m < self::KARATSUBA_CUTOFF) { - return self::baseSquare($value); - } - - $x1 = array_slice($value, $m); - $x0 = array_slice($value, 0, $m); - - $z2 = self::karatsubaSquare($x1); - $z0 = self::karatsubaSquare($x0); - - $z1 = self::addHelper($x1, false, $x0, false); - $z1 = self::karatsubaSquare($z1[self::VALUE]); - $temp = self::addHelper($z2, false, $z0, false); - $z1 = self::subtractHelper($z1, false, $temp[self::VALUE], false); - - $z2 = array_merge(array_fill(0, 2 * $m, 0), $z2); - $z1[self::VALUE] = array_merge(array_fill(0, $m, 0), $z1[self::VALUE]); - - $xx = self::addHelper($z2, false, $z1[self::VALUE], $z1[self::SIGN]); - $xx = self::addHelper($xx[self::VALUE], $xx[self::SIGN], $z0, false); - - return $xx[self::VALUE]; - } - - /** - * Make the current number odd - * - * If the current number is odd it'll be unchanged. If it's even, one will be added to it. - * - * @see self::randomPrime() - */ - protected function make_odd() - { - $this->value[0] |= 1; - } - - /** - * Test the number against small primes. - * - * @see self::isPrime() - */ - protected function testSmallPrimes() - { - if ($this->value == [1]) { - return false; - } - if ($this->value == [2]) { - return true; - } - if (~$this->value[0] & 1) { - return false; - } - - $value = $this->value; - foreach (static::PRIMES as $prime) { - list(, $r) = self::divide_digit($value, $prime); - if (!$r) { - return count($value) == 1 && $value[0] == $prime; - } - } - - return true; - } - - /** - * Scan for 1 and right shift by that amount - * - * ie. $s = gmp_scan1($n, 0) and $r = gmp_div_q($n, gmp_pow(gmp_init('2'), $s)); - * - * @param PHP $r - * @return int - * @see self::isPrime() - */ - public static function scan1divide(PHP $r) - { - $r_value = &$r->value; - for ($i = 0, $r_length = count($r_value); $i < $r_length; ++$i) { - $temp = ~$r_value[$i] & static::MAX_DIGIT; - for ($j = 1; ($temp >> $j) & 1; ++$j) { - } - if ($j <= static::BASE) { - break; - } - } - $s = static::BASE * $i + $j; - $r->rshift($s); - return $s; - } - - /** - * Performs exponentiation. - * - * @param PHP $n - * @return PHP - */ - protected function powHelper(PHP $n) - { - if ($n->compare(static::$zero[static::class]) == 0) { - return new static(1); - } // n^0 = 1 - - $temp = clone $this; - while (!$n->equals(static::$one[static::class])) { - $temp = $temp->multiply($this); - $n = $n->subtract(static::$one[static::class]); - } - - return $temp; - } - - /** - * Is Odd? - * - * @return bool - */ - public function isOdd() - { - return (bool)($this->value[0] & 1); - } - - /** - * Tests if a bit is set - * - * @return bool - */ - public function testBit($x) - { - $digit = (int) floor($x / static::BASE); - $bit = $x % static::BASE; - - if (!isset($this->value[$digit])) { - return false; - } - - return (bool)($this->value[$digit] & (1 << $bit)); - } - - /** - * Is Negative? - * - * @return bool - */ - public function isNegative() - { - return $this->is_negative; - } - - /** - * Negate - * - * Given $k, returns -$k - * - * @return static - */ - public function negate() - { - $temp = clone $this; - $temp->is_negative = !$temp->is_negative; - - return $temp; - } - - /** - * Bitwise Split - * - * Splits BigInteger's into chunks of $split bits - * - * @param int $split - * @return list - */ - public function bitwise_split($split) - { - if ($split < 1) { - throw new \RuntimeException('Offset must be greater than 1'); - } - - $width = (int)($split / static::BASE); - if (!$width) { - $arr = $this->bitwise_small_split($split); - return array_map(function ($digit) { - $temp = new static(); - $temp->value = $digit != 0 ? [$digit] : []; - return $temp; - }, $arr); - } - - $vals = []; - $val = $this->value; - - $i = $overflow = 0; - $len = count($val); - while ($i < $len) { - $digit = []; - if (!$overflow) { - $digit = array_slice($val, $i, $width); - $i += $width; - $overflow = $split % static::BASE; - if ($overflow) { - $mask = (1 << $overflow) - 1; - $temp = isset($val[$i]) ? $val[$i] : 0; - $digit[] = $temp & $mask; - } - } else { - $remaining = static::BASE - $overflow; - $tempsplit = $split - $remaining; - $tempwidth = (int)($tempsplit / static::BASE + 1); - $digit = array_slice($val, $i, $tempwidth); - $i += $tempwidth; - $tempoverflow = $tempsplit % static::BASE; - if ($tempoverflow) { - $tempmask = (1 << $tempoverflow) - 1; - $temp = isset($val[$i]) ? $val[$i] : 0; - $digit[] = $temp & $tempmask; - } - $newbits = 0; - for ($j = count($digit) - 1; $j >= 0; $j--) { - $temp = $digit[$j] & $mask; - $digit[$j] = ($digit[$j] >> $overflow) | ($newbits << $remaining); - $newbits = $temp; - } - $overflow = $tempoverflow; - $mask = $tempmask; - } - $temp = new static(); - $temp->value = static::trim($digit); - $vals[] = $temp; - } - - return array_reverse($vals); - } - - /** - * Bitwise Split where $split < static::BASE - * - * @param int $split - * @return list - */ - private function bitwise_small_split($split) - { - $vals = []; - $val = $this->value; - - $mask = (1 << $split) - 1; - - $i = $overflow = 0; - $len = count($val); - $val[] = 0; - $remaining = static::BASE; - while ($i != $len) { - $digit = $val[$i] & $mask; - $val[$i] >>= $split; - if (!$overflow) { - $remaining -= $split; - $overflow = $split <= $remaining ? 0 : $split - $remaining; - - if (!$remaining) { - $i++; - $remaining = static::BASE; - $overflow = 0; - } - } elseif (++$i != $len) { - $tempmask = (1 << $overflow) - 1; - $digit |= ($val[$i] & $tempmask) << $remaining; - $val[$i] >>= $overflow; - $remaining = static::BASE - $overflow; - $overflow = $split <= $remaining ? 0 : $split - $remaining; - } - - $vals[] = $digit; - } - - while ($vals[count($vals) - 1] == 0) { - unset($vals[count($vals) - 1]); - } - - return array_reverse($vals); - } - - /** - * @return bool - */ - protected static function testJITOnWindows() - { - // see https://github.com/php/php-src/issues/11917 - if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' && function_exists('opcache_get_status') && PHP_VERSION_ID < 80213 && !defined('PHPSECLIB_ALLOW_JIT')) { - $status = opcache_get_status(); - if ($status && isset($status['jit']) && $status['jit']['enabled'] && $status['jit']['on']) { - return true; - } - } - return false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php deleted file mode 100644 index 40f64bd..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Base.php +++ /dev/null @@ -1,143 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\PHP; - -/** - * PHP Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Base extends PHP -{ - /** - * Cache constants - * - * $cache[self::VARIABLE] tells us whether or not the cached data is still valid. - * - */ - const VARIABLE = 0; - /** - * $cache[self::DATA] contains the cached data. - * - */ - const DATA = 1; - - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * The most naive approach to modular exponentiation has very unreasonable requirements, and - * and although the approach involving repeated squaring does vastly better, it, too, is impractical - * for our purposes. The reason being that division - by far the most complicated and time-consuming - * of the basic operations (eg. +,-,*,/) - occurs multiple times within it. - * - * Modular reductions resolve this issue. Although an individual modular reduction takes more time - * then an individual division, when performed in succession (with the same modulo), they're a lot faster. - * - * The two most commonly used modular reductions are Barrett and Montgomery reduction. Montgomery reduction, - * although faster, only works when the gcd of the modulo and of the base being used is 1. In RSA, when the - * base is a power of two, the modulo - a product of two primes - is always going to have a gcd of 1 (because - * the product of two odd numbers is odd), but what about when RSA isn't used? - * - * In contrast, Barrett reduction has no such constraint. As such, some bigint implementations perform a - * Barrett reduction after every operation in the modpow function. Others perform Barrett reductions when the - * modulo is even and Montgomery reductions when the modulo is odd. BigInteger.java's modPow method, however, - * uses a trick involving the Chinese Remainder Theorem to factor the even modulo into two numbers - one odd and - * the other, a power of two - and recombine them, later. This is the method that this modPow function uses. - * {@link http://islab.oregonstate.edu/papers/j34monex.pdf Montgomery Reduction with Even Modulus} elaborates. - * - * @param PHP $x - * @param PHP $e - * @param PHP $n - * @param string $class - * @return PHP - */ - protected static function powModHelper(PHP $x, PHP $e, PHP $n, $class) - { - if (empty($e->value)) { - $temp = new $class(); - $temp->value = [1]; - return $x->normalize($temp); - } - - if ($e->value == [1]) { - list(, $temp) = $x->divide($n); - return $x->normalize($temp); - } - - if ($e->value == [2]) { - $temp = new $class(); - $temp->value = $class::square($x->value); - list(, $temp) = $temp->divide($n); - return $x->normalize($temp); - } - - return $x->normalize(static::slidingWindow($x, $e, $n, $class)); - } - - /** - * Modular reduction preparation - * - * @param array $x - * @param array $n - * @param string $class - * @see self::slidingWindow() - * @return array - */ - protected static function prepareReduce(array $x, array $n, $class) - { - return static::reduce($x, $n, $class); - } - - /** - * Modular multiply - * - * @param array $x - * @param array $y - * @param array $n - * @param string $class - * @see self::slidingWindow() - * @return array - */ - protected static function multiplyReduce(array $x, array $y, array $n, $class) - { - $temp = $class::multiplyHelper($x, false, $y, false); - return static::reduce($temp[self::VALUE], $n, $class); - } - - /** - * Modular square - * - * @param array $x - * @param array $n - * @param string $class - * @see self::slidingWindow() - * @return array - */ - protected static function squareReduce(array $x, array $n, $class) - { - return static::reduce($class::square($x), $n, $class); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php deleted file mode 100644 index 6d33532..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/DefaultEngine.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\EvalBarrett; - -/** - * PHP Default Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class DefaultEngine extends EvalBarrett -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php deleted file mode 100644 index 09f825f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Montgomery.php +++ /dev/null @@ -1,89 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\Engine; -use phpseclib3\Math\BigInteger\Engines\PHP; -use phpseclib3\Math\BigInteger\Engines\PHP\Reductions\PowerOfTwo; - -/** - * PHP Montgomery Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Montgomery extends Base -{ - /** - * Test for engine validity - * - * @return bool - */ - public static function isValidEngine() - { - return static::class != __CLASS__; - } - - /** - * Performs modular exponentiation. - * - * @template T of Engine - * @param Engine $x - * @param Engine $e - * @param Engine $n - * @param class-string $class - * @return T - */ - protected static function slidingWindow(Engine $x, Engine $e, Engine $n, $class) - { - // is the modulo odd? - if ($n->value[0] & 1) { - return parent::slidingWindow($x, $e, $n, $class); - } - // if it's not, it's even - - // find the lowest set bit (eg. the max pow of 2 that divides $n) - for ($i = 0; $i < count($n->value); ++$i) { - if ($n->value[$i]) { - $temp = decbin($n->value[$i]); - $j = strlen($temp) - strrpos($temp, '1') - 1; - $j += $class::BASE * $i; - break; - } - } - // at this point, 2^$j * $n/(2^$j) == $n - - $mod1 = clone $n; - $mod1->rshift($j); - $mod2 = new $class(); - $mod2->value = [1]; - $mod2->lshift($j); - - $part1 = $mod1->value != [1] ? parent::slidingWindow($x, $e, $mod1, $class) : new $class(); - $part2 = PowerOfTwo::slidingWindow($x, $e, $mod2, $class); - - $y1 = $mod2->modInverse($mod1); - $y2 = $mod1->modInverse($mod2); - - $result = $part1->multiply($mod2); - $result = $result->multiply($y1); - - $temp = $part2->multiply($mod1); - $temp = $temp->multiply($y2); - - $result = $result->add($temp); - list(, $result) = $result->divide($n); - - return $result; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php deleted file mode 100644 index eddd25e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/OpenSSL.php +++ /dev/null @@ -1,25 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP; - -use phpseclib3\Math\BigInteger\Engines\OpenSSL as Progenitor; - -/** - * OpenSSL Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class OpenSSL extends Progenitor -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php deleted file mode 100644 index 3518d76..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Barrett.php +++ /dev/null @@ -1,281 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP; -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Barrett Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Barrett extends Base -{ - /** - * Barrett Modular Reduction - * - * See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=14 HAC 14.3.3} / - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=165 MPM 6.2.5} for more information. Modified slightly, - * so as not to require negative numbers (initially, this script didn't support negative numbers). - * - * Employs "folding", as described at - * {@link http://www.cosic.esat.kuleuven.be/publications/thesis-149.pdf#page=66 thesis-149.pdf#page=66}. To quote from - * it, "the idea [behind folding] is to find a value x' such that x (mod m) = x' (mod m), with x' being smaller than x." - * - * Unfortunately, the "Barrett Reduction with Folding" algorithm described in thesis-149.pdf is not, as written, all that - * usable on account of (1) its not using reasonable radix points as discussed in - * {@link http://math.libtomcrypt.com/files/tommath.pdf#page=162 MPM 6.2.2} and (2) the fact that, even with reasonable - * radix points, it only works when there are an even number of digits in the denominator. The reason for (2) is that - * (x >> 1) + (x >> 1) != x / 2 + x / 2. If x is even, they're the same, but if x is odd, they're not. See the in-line - * comments for details. - * - * @param array $n - * @param array $m - * @param class-string $class - * @return array - */ - protected static function reduce(array $n, array $m, $class) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $m_length = count($m); - - // if (self::compareHelper($n, $static::square($m)) >= 0) { - if (count($n) > 2 * $m_length) { - $lhs = new $class(); - $rhs = new $class(); - $lhs->value = $n; - $rhs->value = $m; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - // if (m.length >> 1) + 2 <= m.length then m is too small and n can't be reduced - if ($m_length < 5) { - return self::regularBarrett($n, $m, $class); - } - // n = 2 * m.length - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - - $lhs = new $class(); - $lhs_value = &$lhs->value; - $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); - $lhs_value[] = 1; - $rhs = new $class(); - $rhs->value = $m; - - list($u, $m1) = $lhs->divide($rhs); - $u = $u->value; - $m1 = $m1->value; - - $cache[self::DATA][] = [ - 'u' => $u, // m.length >> 1 (technically (m.length >> 1) + 1) - 'm1' => $m1 // m.length - ]; - } else { - extract($cache[self::DATA][$key]); - } - - $cutoff = $m_length + ($m_length >> 1); - $lsd = array_slice($n, 0, $cutoff); // m.length + (m.length >> 1) - $msd = array_slice($n, $cutoff); // m.length >> 1 - - $lsd = self::trim($lsd); - $temp = $class::multiplyHelper($msd, false, $m1, false); // m.length + (m.length >> 1) - $n = $class::addHelper($lsd, false, $temp[self::VALUE], false); // m.length + (m.length >> 1) + 1 (so basically we're adding two same length numbers) - //if ($m_length & 1) { - // return self::regularBarrett($n[self::VALUE], $m, $class); - //} - - // (m.length + (m.length >> 1) + 1) - (m.length - 1) == (m.length >> 1) + 2 - $temp = array_slice($n[self::VALUE], $m_length - 1); - // if even: ((m.length >> 1) + 2) + (m.length >> 1) == m.length + 2 - // if odd: ((m.length >> 1) + 2) + (m.length >> 1) == (m.length - 1) + 2 == m.length + 1 - $temp = $class::multiplyHelper($temp, false, $u, false); - // if even: (m.length + 2) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) + 1 - // if odd: (m.length + 1) - ((m.length >> 1) + 1) = m.length - (m.length >> 1) - $temp = array_slice($temp[self::VALUE], ($m_length >> 1) + 1); - // if even: (m.length - (m.length >> 1) + 1) + m.length = 2 * m.length - (m.length >> 1) + 1 - // if odd: (m.length - (m.length >> 1)) + m.length = 2 * m.length - (m.length >> 1) - $temp = $class::multiplyHelper($temp, false, $m, false); - - // at this point, if m had an odd number of digits, we'd be subtracting a 2 * m.length - (m.length >> 1) digit - // number from a m.length + (m.length >> 1) + 1 digit number. ie. there'd be an extra digit and the while loop - // following this comment would loop a lot (hence our calling _regularBarrett() in that situation). - - $result = $class::subtractHelper($n[self::VALUE], false, $temp[self::VALUE], false); - - while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $m, false) >= 0) { - $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $m, false); - } - - return $result[self::VALUE]; - } - - /** - * (Regular) Barrett Modular Reduction - * - * For numbers with more than four digits BigInteger::_barrett() is faster. The difference between that and this - * is that this function does not fold the denominator into a smaller form. - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - private static function regularBarrett(array $x, array $n, $class) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - $n_length = count($n); - - if (count($x) > 2 * $n_length) { - $lhs = new $class(); - $rhs = new $class(); - $lhs->value = $x; - $rhs->value = $n; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $n; - $lhs = new $class(); - $lhs_value = &$lhs->value; - $lhs_value = self::array_repeat(0, 2 * $n_length); - $lhs_value[] = 1; - $rhs = new $class(); - $rhs->value = $n; - list($temp, ) = $lhs->divide($rhs); // m.length - $cache[self::DATA][] = $temp->value; - } - - // 2 * m.length - (m.length - 1) = m.length + 1 - $temp = array_slice($x, $n_length - 1); - // (m.length + 1) + m.length = 2 * m.length + 1 - $temp = $class::multiplyHelper($temp, false, $cache[self::DATA][$key], false); - // (2 * m.length + 1) - (m.length - 1) = m.length + 2 - $temp = array_slice($temp[self::VALUE], $n_length + 1); - - // m.length + 1 - $result = array_slice($x, 0, $n_length + 1); - // m.length + 1 - $temp = self::multiplyLower($temp, false, $n, false, $n_length + 1, $class); - // $temp == array_slice($class::regularMultiply($temp, false, $n, false)->value, 0, $n_length + 1) - - if (self::compareHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]) < 0) { - $corrector_value = self::array_repeat(0, $n_length + 1); - $corrector_value[count($corrector_value)] = 1; - $result = $class::addHelper($result, false, $corrector_value, false); - $result = $result[self::VALUE]; - } - - // at this point, we're subtracting a number with m.length + 1 digits from another number with m.length + 1 digits - $result = $class::subtractHelper($result, false, $temp[self::VALUE], $temp[self::SIGN]); - while (self::compareHelper($result[self::VALUE], $result[self::SIGN], $n, false) > 0) { - $result = $class::subtractHelper($result[self::VALUE], $result[self::SIGN], $n, false); - } - - return $result[self::VALUE]; - } - - /** - * Performs long multiplication up to $stop digits - * - * If you're going to be doing array_slice($product->value, 0, $stop), some cycles can be saved. - * - * @see self::regularBarrett() - * @param array $x_value - * @param bool $x_negative - * @param array $y_value - * @param bool $y_negative - * @param int $stop - * @param string $class - * @return array - */ - private static function multiplyLower(array $x_value, $x_negative, array $y_value, $y_negative, $stop, $class) - { - $x_length = count($x_value); - $y_length = count($y_value); - - if (!$x_length || !$y_length) { // a 0 is being multiplied - return [ - self::VALUE => [], - self::SIGN => false - ]; - } - - if ($x_length < $y_length) { - $temp = $x_value; - $x_value = $y_value; - $y_value = $temp; - - $x_length = count($x_value); - $y_length = count($y_value); - } - - $product_value = self::array_repeat(0, $x_length + $y_length); - - // the following for loop could be removed if the for loop following it - // (the one with nested for loops) initially set $i to 0, but - // doing so would also make the result in one set of unnecessary adds, - // since on the outermost loops first pass, $product->value[$k] is going - // to always be 0 - - $carry = 0; - - for ($j = 0; $j < $x_length; ++$j) { // ie. $i = 0, $k = $i - $temp = $x_value[$j] * $y_value[0] + $carry; // $product_value[$k] == 0 - $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$j] = (int) ($temp - $class::BASE_FULL * $carry); - } - - if ($j < $stop) { - $product_value[$j] = $carry; - } - - // the above for loop is what the previous comment was talking about. the - // following for loop is the "one with nested for loops" - - for ($i = 1; $i < $y_length; ++$i) { - $carry = 0; - - for ($j = 0, $k = $i; $j < $x_length && $k < $stop; ++$j, ++$k) { - $temp = $product_value[$k] + $x_value[$j] * $y_value[$i] + $carry; - $carry = $class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31); - $product_value[$k] = (int) ($temp - $class::BASE_FULL * $carry); - } - - if ($k < $stop) { - $product_value[$k] = $carry; - } - } - - return [ - self::VALUE => self::trim($product_value), - self::SIGN => $x_negative != $y_negative - ]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php deleted file mode 100644 index 54f3b86..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Classic.php +++ /dev/null @@ -1,42 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Classic Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Classic extends Base -{ - /** - * Regular Division - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function reduce(array $x, array $n, $class) - { - $lhs = new $class(); - $lhs->value = $x; - $rhs = new $class(); - $rhs->value = $n; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php deleted file mode 100644 index 2f94331..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/EvalBarrett.php +++ /dev/null @@ -1,484 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP; -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Dynamic Barrett Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class EvalBarrett extends Base -{ - /** - * Custom Reduction Function - * - * @see self::generateCustomReduction - */ - private static $custom_reduction; - - /** - * Barrett Modular Reduction - * - * This calls a dynamically generated loop unrolled function that's specific to a given modulo. - * Array lookups are avoided as are if statements testing for how many bits the host OS supports, etc. - * - * @param array $n - * @param array $m - * @param string $class - * @return array - */ - protected static function reduce(array $n, array $m, $class) - { - $inline = self::$custom_reduction; - return $inline($n); - } - - /** - * Generate Custom Reduction - * - * @param PHP $m - * @param string $class - * @return callable - */ - protected static function generateCustomReduction(PHP $m, $class) - { - $m_length = count($m->value); - - if ($m_length < 5) { - $code = ' - $lhs = new ' . $class . '(); - $lhs->value = $x; - $rhs = new ' . $class . '(); - $rhs->value = [' . - implode(',', array_map(self::class . '::float2string', $m->value)) . ']; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - '; - eval('$func = function ($x) { ' . $code . '};'); - self::$custom_reduction = $func; - //self::$custom_reduction = \Closure::bind($func, $m, $class); - return $func; - } - - $lhs = new $class(); - $lhs_value = &$lhs->value; - - $lhs_value = self::array_repeat(0, $m_length + ($m_length >> 1)); - $lhs_value[] = 1; - $rhs = new $class(); - - list($u, $m1) = $lhs->divide($m); - - if ($class::BASE != 26) { - $u = $u->value; - } else { - $lhs_value = self::array_repeat(0, 2 * $m_length); - $lhs_value[] = 1; - $rhs = new $class(); - - list($u) = $lhs->divide($m); - $u = $u->value; - } - - $m = $m->value; - $m1 = $m1->value; - - $cutoff = count($m) + (count($m) >> 1); - - $code = ' - if (count($n) > ' . (2 * count($m)) . ') { - $lhs = new ' . $class . '(); - $rhs = new ' . $class . '(); - $lhs->value = $n; - $rhs->value = [' . - implode(',', array_map(self::class . '::float2string', $m)) . ']; - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - $lsd = array_slice($n, 0, ' . $cutoff . '); - $msd = array_slice($n, ' . $cutoff . ');'; - - $code .= self::generateInlineTrim('msd'); - $code .= self::generateInlineMultiply('msd', $m1, 'temp', $class); - $code .= self::generateInlineAdd('lsd', 'temp', 'n', $class); - - $code .= '$temp = array_slice($n, ' . (count($m) - 1) . ');'; - $code .= self::generateInlineMultiply('temp', $u, 'temp2', $class); - $code .= self::generateInlineTrim('temp2'); - - $code .= $class::BASE == 26 ? - '$temp = array_slice($temp2, ' . (count($m) + 1) . ');' : - '$temp = array_slice($temp2, ' . ((count($m) >> 1) + 1) . ');'; - $code .= self::generateInlineMultiply('temp', $m, 'temp2', $class); - $code .= self::generateInlineTrim('temp2'); - - /* - if ($class::BASE == 26) { - $code.= '$n = array_slice($n, 0, ' . (count($m) + 1) . '); - $temp2 = array_slice($temp2, 0, ' . (count($m) + 1) . ');'; - } - */ - - $code .= self::generateInlineSubtract2('n', 'temp2', 'temp', $class); - - $subcode = self::generateInlineSubtract1('temp', $m, 'temp2', $class); - $subcode .= '$temp = $temp2;'; - - $code .= self::generateInlineCompare($m, 'temp', $subcode); - - $code .= 'return $temp;'; - - eval('$func = function ($n) { ' . $code . '};'); - - self::$custom_reduction = $func; - - return $func; - - //self::$custom_reduction = \Closure::bind($func, $m, $class); - } - - /** - * Inline Trim - * - * Removes leading zeros - * - * @param string $name - * @return string - */ - private static function generateInlineTrim($name) - { - return ' - for ($i = count($' . $name . ') - 1; $i >= 0; --$i) { - if ($' . $name . '[$i]) { - break; - } - unset($' . $name . '[$i]); - }'; - } - - /** - * Inline Multiply (unknown, known) - * - * @param string $input - * @param array $arr - * @param string $output - * @param string $class - * @return string - */ - private static function generateInlineMultiply($input, array $arr, $output, $class) - { - if (!count($arr)) { - return 'return [];'; - } - - $regular = ' - $length = count($' . $input . '); - if (!$length) { - $' . $output . ' = []; - }else{ - $' . $output . ' = array_fill(0, $length + ' . count($arr) . ', 0); - $carry = 0;'; - - for ($i = 0; $i < count($arr); $i++) { - $regular .= ' - $subtemp = $' . $input . '[0] * ' . $arr[$i]; - $regular .= $i ? ' + $carry;' : ';'; - - $regular .= '$carry = '; - $regular .= $class::BASE === 26 ? - 'intval($subtemp / 0x4000000);' : - '$subtemp >> 31;'; - $regular .= - '$' . $output . '[' . $i . '] = '; - if ($class::BASE === 26) { - $regular .= '(int) ('; - } - $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; - $regular .= $class::BASE === 26 ? ');' : ';'; - } - - $regular .= '$' . $output . '[' . count($arr) . '] = $carry;'; - - $regular .= ' - for ($i = 1; $i < $length; ++$i) {'; - - for ($j = 0; $j < count($arr); $j++) { - $regular .= $j ? '$k++;' : '$k = $i;'; - $regular .= ' - $subtemp = $' . $output . '[$k] + $' . $input . '[$i] * ' . $arr[$j]; - $regular .= $j ? ' + $carry;' : ';'; - - $regular .= '$carry = '; - $regular .= $class::BASE === 26 ? - 'intval($subtemp / 0x4000000);' : - '$subtemp >> 31;'; - $regular .= - '$' . $output . '[$k] = '; - if ($class::BASE === 26) { - $regular .= '(int) ('; - } - $regular .= '$subtemp - ' . $class::BASE_FULL . ' * $carry'; - $regular .= $class::BASE === 26 ? ');' : ';'; - } - - $regular .= '$' . $output . '[++$k] = $carry; $carry = 0;'; - - $regular .= '}}'; - - //if (count($arr) < 2 * self::KARATSUBA_CUTOFF) { - //} - - return $regular; - } - - /** - * Inline Addition - * - * @param string $x - * @param string $y - * @param string $result - * @param string $class - * @return string - */ - private static function generateInlineAdd($x, $y, $result, $class) - { - $code = ' - $length = max(count($' . $x . '), count($' . $y . ')); - $' . $result . ' = array_pad($' . $x . ', $length + 1, 0); - $_' . $y . ' = array_pad($' . $y . ', $length, 0); - $carry = 0; - for ($i = 0, $j = 1; $j < $length; $i+=2, $j+=2) { - $sum = ($' . $result . '[$j] + $_' . $y . '[$j]) * ' . $class::BASE_FULL . ' - + $' . $result . '[$i] + $_' . $y . '[$i] + - $carry; - $carry = $sum >= ' . self::float2string($class::MAX_DIGIT2) . '; - $sum = $carry ? $sum - ' . self::float2string($class::MAX_DIGIT2) . ' : $sum;'; - - $code .= $class::BASE === 26 ? - '$upper = intval($sum / 0x4000000); $' . $result . '[$i] = (int) ($sum - ' . $class::BASE_FULL . ' * $upper);' : - '$upper = $sum >> 31; $' . $result . '[$i] = $sum - ' . $class::BASE_FULL . ' * $upper;'; - $code .= ' - $' . $result . '[$j] = $upper; - } - if ($j == $length) { - $sum = $' . $result . '[$i] + $_' . $y . '[$i] + $carry; - $carry = $sum >= ' . self::float2string($class::BASE_FULL) . '; - $' . $result . '[$i] = $carry ? $sum - ' . self::float2string($class::BASE_FULL) . ' : $sum; - ++$i; - } - if ($carry) { - for (; $' . $result . '[$i] == ' . $class::MAX_DIGIT . '; ++$i) { - $' . $result . '[$i] = 0; - } - ++$' . $result . '[$i]; - }'; - $code .= self::generateInlineTrim($result); - - return $code; - } - - /** - * Inline Subtraction 2 - * - * For when $known is more digits than $unknown. This is the harder use case to optimize for. - * - * @param string $known - * @param string $unknown - * @param string $result - * @param string $class - * @return string - */ - private static function generateInlineSubtract2($known, $unknown, $result, $class) - { - $code = ' - $' . $result . ' = $' . $known . '; - $carry = 0; - $size = count($' . $unknown . '); - for ($i = 0, $j = 1; $j < $size; $i+= 2, $j+= 2) { - $sum = ($' . $known . '[$j] - $' . $unknown . '[$j]) * ' . $class::BASE_FULL . ' + $' . $known . '[$i] - - $' . $unknown . '[$i] - - $carry; - $carry = $sum < 0; - if ($carry) { - $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; - } - $subtemp = '; - $code .= $class::BASE === 26 ? - 'intval($sum / 0x4000000);' : - '$sum >> 31;'; - $code .= '$' . $result . '[$i] = '; - if ($class::BASE === 26) { - $code .= '(int) ('; - } - $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; - if ($class::BASE === 26) { - $code .= ')'; - } - $code .= '; - $' . $result . '[$j] = $subtemp; - } - if ($j == $size) { - $sum = $' . $known . '[$i] - $' . $unknown . '[$i] - $carry; - $carry = $sum < 0; - $' . $result . '[$i] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; - ++$i; - } - - if ($carry) { - for (; !$' . $result . '[$i]; ++$i) { - $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; - } - --$' . $result . '[$i]; - }'; - - $code .= self::generateInlineTrim($result); - - return $code; - } - - /** - * Inline Subtraction 1 - * - * For when $unknown is more digits than $known. This is the easier use case to optimize for. - * - * @param string $unknown - * @param array $known - * @param string $result - * @param string $class - * @return string - */ - private static function generateInlineSubtract1($unknown, array $known, $result, $class) - { - $code = '$' . $result . ' = $' . $unknown . ';'; - for ($i = 0, $j = 1; $j < count($known); $i += 2, $j += 2) { - $code .= '$sum = $' . $unknown . '[' . $j . '] * ' . $class::BASE_FULL . ' + $' . $unknown . '[' . $i . '] - '; - $code .= self::float2string($known[$j] * $class::BASE_FULL + $known[$i]); - if ($i != 0) { - $code .= ' - $carry'; - } - - $code .= '; - if ($carry = $sum < 0) { - $sum+= ' . self::float2string($class::MAX_DIGIT2) . '; - } - $subtemp = '; - $code .= $class::BASE === 26 ? - 'intval($sum / 0x4000000);' : - '$sum >> 31;'; - $code .= ' - $' . $result . '[' . $i . '] = '; - if ($class::BASE === 26) { - $code .= ' (int) ('; - } - $code .= '$sum - ' . $class::BASE_FULL . ' * $subtemp'; - if ($class::BASE === 26) { - $code .= ')'; - } - $code .= '; - $' . $result . '[' . $j . '] = $subtemp;'; - } - - $code .= '$i = ' . $i . ';'; - - if ($j == count($known)) { - $code .= ' - $sum = $' . $unknown . '[' . $i . '] - ' . $known[$i] . ' - $carry; - $carry = $sum < 0; - $' . $result . '[' . $i . '] = $carry ? $sum + ' . $class::BASE_FULL . ' : $sum; - ++$i;'; - } - - $code .= ' - if ($carry) { - for (; !$' . $result . '[$i]; ++$i) { - $' . $result . '[$i] = ' . $class::MAX_DIGIT . '; - } - --$' . $result . '[$i]; - }'; - $code .= self::generateInlineTrim($result); - - return $code; - } - - /** - * Inline Comparison - * - * If $unknown >= $known then loop - * - * @param array $known - * @param string $unknown - * @param string $subcode - * @return string - */ - private static function generateInlineCompare(array $known, $unknown, $subcode) - { - $uniqid = uniqid(); - $code = 'loop_' . $uniqid . ': - $clength = count($' . $unknown . '); - switch (true) { - case $clength < ' . count($known) . ': - goto end_' . $uniqid . '; - case $clength > ' . count($known) . ':'; - for ($i = count($known) - 1; $i >= 0; $i--) { - $code .= ' - case $' . $unknown . '[' . $i . '] > ' . $known[$i] . ': - goto subcode_' . $uniqid . '; - case $' . $unknown . '[' . $i . '] < ' . $known[$i] . ': - goto end_' . $uniqid . ';'; - } - $code .= ' - default: - // do subcode - } - - subcode_' . $uniqid . ':' . $subcode . ' - goto loop_' . $uniqid . '; - - end_' . $uniqid . ':'; - - return $code; - } - - /** - * Convert a float to a string - * - * If you do echo floatval(pow(2, 52)) you'll get 4.6116860184274E+18. It /can/ be displayed without a loss of - * precision but displayed in this way there will be precision loss, hence the need for this method. - * - * @param int|float $num - * @return string - */ - private static function float2string($num) - { - if (!is_float($num)) { - return (string) $num; - } - - if ($num < 0) { - return '-' . self::float2string(abs($num)); - } - - $temp = ''; - while ($num) { - $temp = fmod($num, 10) . $temp; - $num = floor($num / 10); - } - - return $temp; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php deleted file mode 100644 index a34035e..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/Montgomery.php +++ /dev/null @@ -1,126 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Montgomery as Progenitor; - -/** - * PHP Montgomery Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class Montgomery extends Progenitor -{ - /** - * Prepare a number for use in Montgomery Modular Reductions - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function prepareReduce(array $x, array $n, $class) - { - $lhs = new $class(); - $lhs->value = array_merge(self::array_repeat(0, count($n)), $x); - $rhs = new $class(); - $rhs->value = $n; - - list(, $temp) = $lhs->divide($rhs); - return $temp->value; - } - - /** - * Montgomery Multiply - * - * Interleaves the montgomery reduction and long multiplication algorithms together as described in - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function reduce(array $x, array $n, $class) - { - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - if (($key = array_search($n, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $x; - $cache[self::DATA][] = self::modInverse67108864($n, $class); - } - - $k = count($n); - - $result = [self::VALUE => $x]; - - for ($i = 0; $i < $k; ++$i) { - $temp = $result[self::VALUE][$i] * $cache[self::DATA][$key]; - $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $class::regularMultiply([$temp], $n); - $temp = array_merge(self::array_repeat(0, $i), $temp); - $result = $class::addHelper($result[self::VALUE], false, $temp, false); - } - - $result[self::VALUE] = array_slice($result[self::VALUE], $k); - - if (self::compareHelper($result, false, $n, false) >= 0) { - $result = $class::subtractHelper($result[self::VALUE], false, $n, false); - } - - return $result[self::VALUE]; - } - - /** - * Modular Inverse of a number mod 2**26 (eg. 67108864) - * - * Based off of the bnpInvDigit function implemented and justified in the following URL: - * - * {@link http://www-cs-students.stanford.edu/~tjw/jsbn/jsbn.js} - * - * The following URL provides more info: - * - * {@link http://groups.google.com/group/sci.crypt/msg/7a137205c1be7d85} - * - * As for why we do all the bitmasking... strange things can happen when converting from floats to ints. For - * instance, on some computers, var_dump((int) -4294967297) yields int(-1) and on others, it yields - * int(-2147483648). To avoid problems stemming from this, we use bitmasks to guarantee that ints aren't - * auto-converted to floats. The outermost bitmask is present because without it, there's no guarantee that - * the "residue" returned would be the so-called "common residue". We use fmod, in the last step, because the - * maximum possible $x is 26 bits and the maximum $result is 16 bits. Thus, we have to be able to handle up to - * 40 bits, which only 64-bit floating points will support. - * - * Thanks to Pedro Gimeno Fortea for input! - * - * @param array $x - * @param string $class - * @return int - */ - protected static function modInverse67108864(array $x, $class) // 2**26 == 67,108,864 - { - $x = -$x[0]; - $result = $x & 0x3; // x**-1 mod 2**2 - $result = ($result * (2 - $x * $result)) & 0xF; // x**-1 mod 2**4 - $result = ($result * (2 - ($x & 0xFF) * $result)) & 0xFF; // x**-1 mod 2**8 - $result = ($result * ((2 - ($x & 0xFFFF) * $result) & 0xFFFF)) & 0xFFFF; // x**-1 mod 2**16 - $result = $class::BASE == 26 ? - fmod($result * (2 - fmod($x * $result, $class::BASE_FULL)), $class::BASE_FULL) : // x**-1 mod 2**26 - ($result * (2 - ($x * $result) % $class::BASE_FULL)) % $class::BASE_FULL; - return $result & $class::MAX_DIGIT; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php deleted file mode 100644 index 4fed3c3..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/MontgomeryMult.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP; - -/** - * PHP Montgomery Modular Exponentiation Engine with interleaved multiplication - * - * @author Jim Wigginton - */ -abstract class MontgomeryMult extends Montgomery -{ - /** - * Montgomery Multiply - * - * Interleaves the montgomery reduction and long multiplication algorithms together as described in - * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=13 HAC 14.36} - * - * @see self::_prepMontgomery() - * @see self::_montgomery() - * @param array $x - * @param array $y - * @param array $m - * @param class-string $class - * @return array - */ - public static function multiplyReduce(array $x, array $y, array $m, $class) - { - // the following code, although not callable, can be run independently of the above code - // although the above code performed better in my benchmarks the following could might - // perform better under different circumstances. in lieu of deleting it it's just been - // made uncallable - - static $cache = [ - self::VARIABLE => [], - self::DATA => [] - ]; - - if (($key = array_search($m, $cache[self::VARIABLE])) === false) { - $key = count($cache[self::VARIABLE]); - $cache[self::VARIABLE][] = $m; - $cache[self::DATA][] = self::modInverse67108864($m, $class); - } - - $n = max(count($x), count($y), count($m)); - $x = array_pad($x, $n, 0); - $y = array_pad($y, $n, 0); - $m = array_pad($m, $n, 0); - $a = [self::VALUE => self::array_repeat(0, $n + 1)]; - for ($i = 0; $i < $n; ++$i) { - $temp = $a[self::VALUE][0] + $x[$i] * $y[0]; - $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $temp * $cache[self::DATA][$key]; - $temp = $temp - $class::BASE_FULL * ($class::BASE === 26 ? intval($temp / 0x4000000) : ($temp >> 31)); - $temp = $class::addHelper($class::regularMultiply([$x[$i]], $y), false, $class::regularMultiply([$temp], $m), false); - $a = $class::addHelper($a[self::VALUE], false, $temp[self::VALUE], false); - $a[self::VALUE] = array_slice($a[self::VALUE], 1); - } - if (self::compareHelper($a[self::VALUE], false, $m, false) >= 0) { - $a = $class::subtractHelper($a[self::VALUE], false, $m, false); - } - return $a[self::VALUE]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php deleted file mode 100644 index 9da133a..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP/Reductions/PowerOfTwo.php +++ /dev/null @@ -1,59 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines\PHP\Reductions; - -use phpseclib3\Math\BigInteger\Engines\PHP\Base; - -/** - * PHP Power Of Two Modular Exponentiation Engine - * - * @author Jim Wigginton - */ -abstract class PowerOfTwo extends Base -{ - /** - * Prepare a number for use in Montgomery Modular Reductions - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function prepareReduce(array $x, array $n, $class) - { - return self::reduce($x, $n, $class); - } - - /** - * Power Of Two Reduction - * - * @param array $x - * @param array $n - * @param string $class - * @return array - */ - protected static function reduce(array $x, array $n, $class) - { - $lhs = new $class(); - $lhs->value = $x; - $rhs = new $class(); - $rhs->value = $n; - - $temp = new $class(); - $temp->value = [1]; - - $result = $lhs->bitwise_and($rhs->subtract($temp)); - return $result->value; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php deleted file mode 100644 index 3a775e7..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP32.php +++ /dev/null @@ -1,371 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -/** - * Pure-PHP 32-bit Engine. - * - * Uses 64-bit floats if int size is 4 bits - * - * @author Jim Wigginton - */ -class PHP32 extends PHP -{ - // Constants used by PHP.php - const BASE = 26; - const BASE_FULL = 0x4000000; - const MAX_DIGIT = 0x3FFFFFF; - const MSB = 0x2000000; - - /** - * MAX10 in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10 = 10000000; - - /** - * MAX10LEN in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10LEN = 7; - const MAX_DIGIT2 = 4503599627370496; - - /** - * Initialize a PHP32 BigInteger Engine instance - * - * @param int $base - * @see parent::initialize() - */ - protected function initialize($base) - { - if ($base != 256 && $base != -256) { - return parent::initialize($base); - } - - $val = $this->value; - $this->value = []; - $vals = &$this->value; - $i = strlen($val); - if (!$i) { - return; - } - - while (true) { - $i -= 4; - if ($i < 0) { - if ($i == -4) { - break; - } - $val = substr($val, 0, 4 + $i); - $val = str_pad($val, 4, "\0", STR_PAD_LEFT); - if ($val == "\0\0\0\0") { - break; - } - $i = 0; - } - list(, $digit) = unpack('N', substr($val, $i, 4)); - if ($digit < 0) { - $digit += 0xFFFFFFFF + 1; - } - $step = count($vals) & 3; - if ($step) { - $digit = (int) floor($digit / pow(2, 2 * $step)); - } - if ($step != 3) { - $digit = (int) fmod($digit, static::BASE_FULL); - $i++; - } - $vals[] = $digit; - } - while (end($vals) === 0) { - array_pop($vals); - } - reset($vals); - } - - /** - * Test for engine validity - * - * @see parent::__construct() - * @return bool - */ - public static function isValidEngine() - { - return PHP_INT_SIZE >= 4 && !self::testJITOnWindows(); - } - - /** - * Adds two BigIntegers. - * - * @param PHP32 $y - * @return PHP32 - */ - public function add(PHP32 $y) - { - $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param PHP32 $y - * @return PHP32 - */ - public function subtract(PHP32 $y) - { - $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param PHP32 $y - * @return PHP32 - */ - public function multiply(PHP32 $y) - { - $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param PHP32 $y - * @return array{PHP32, PHP32} - */ - public function divide(PHP32 $y) - { - return $this->divideHelper($y); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP32 $n - * @return false|PHP32 - */ - public function modInverse(PHP32 $n) - { - return $this->modInverseHelper($n); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP32 $n - * @return PHP32[] - */ - public function extendedGCD(PHP32 $n) - { - return $this->extendedGCDHelper($n); - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param PHP32 $n - * @return PHP32 - */ - public function gcd(PHP32 $n) - { - return $this->extendedGCD($n)['gcd']; - } - - /** - * Logical And - * - * @param PHP32 $x - * @return PHP32 - */ - public function bitwise_and(PHP32 $x) - { - return $this->bitwiseAndHelper($x); - } - - /** - * Logical Or - * - * @param PHP32 $x - * @return PHP32 - */ - public function bitwise_or(PHP32 $x) - { - return $this->bitwiseOrHelper($x); - } - - /** - * Logical Exclusive Or - * - * @param PHP32 $x - * @return PHP32 - */ - public function bitwise_xor(PHP32 $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param PHP32 $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @see self::equals() - */ - public function compare(PHP32 $y) - { - return $this->compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param PHP32 $x - * @return bool - */ - public function equals(PHP32 $x) - { - return $this->value === $x->value && $this->is_negative == $x->is_negative; - } - - /** - * Performs modular exponentiation. - * - * @param PHP32 $e - * @param PHP32 $n - * @return PHP32 - */ - public function modPow(PHP32 $e, PHP32 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param PHP32 $e - * @param PHP32 $n - * @return PHP32 - */ - public function powMod(PHP32 $e, PHP32 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param PHP32 $min - * @param PHP32 $max - * @return false|PHP32 - */ - public static function randomRangePrime(PHP32 $min, PHP32 $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param PHP32 $min - * @param PHP32 $max - * @return PHP32 - */ - public static function randomRange(PHP32 $min, PHP32 $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Performs exponentiation. - * - * @param PHP32 $n - * @return PHP32 - */ - public function pow(PHP32 $n) - { - return $this->powHelper($n); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP32 ...$nums - * @return PHP32 - */ - public static function min(PHP32 ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP32 ...$nums - * @return PHP32 - */ - public static function max(PHP32 ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param PHP32 $min - * @param PHP32 $max - * @return bool - */ - public function between(PHP32 $min, PHP32 $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php deleted file mode 100644 index 70a2e17..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BigInteger/Engines/PHP64.php +++ /dev/null @@ -1,372 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math\BigInteger\Engines; - -/** - * Pure-PHP 64-bit Engine. - * - * Uses 64-bit integers if int size is 8 bits - * - * @author Jim Wigginton - */ -class PHP64 extends PHP -{ - // Constants used by PHP.php - const BASE = 31; - const BASE_FULL = 0x80000000; - const MAX_DIGIT = 0x7FFFFFFF; - const MSB = 0x40000000; - - /** - * MAX10 in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10 = 1000000000; - - /** - * MAX10LEN in greatest MAX10LEN satisfying - * MAX10 = 10**MAX10LEN <= 2**BASE. - */ - const MAX10LEN = 9; - const MAX_DIGIT2 = 4611686018427387904; - - /** - * Initialize a PHP64 BigInteger Engine instance - * - * @param int $base - * @see parent::initialize() - */ - protected function initialize($base) - { - if ($base != 256 && $base != -256) { - return parent::initialize($base); - } - - $val = $this->value; - $this->value = []; - $vals = &$this->value; - $i = strlen($val); - if (!$i) { - return; - } - - while (true) { - $i -= 4; - if ($i < 0) { - if ($i == -4) { - break; - } - $val = substr($val, 0, 4 + $i); - $val = str_pad($val, 4, "\0", STR_PAD_LEFT); - if ($val == "\0\0\0\0") { - break; - } - $i = 0; - } - list(, $digit) = unpack('N', substr($val, $i, 4)); - $step = count($vals) & 7; - if (!$step) { - $digit &= static::MAX_DIGIT; - $i++; - } else { - $shift = 8 - $step; - $digit >>= $shift; - $shift = 32 - $shift; - $digit &= (1 << $shift) - 1; - $temp = $i > 0 ? ord($val[$i - 1]) : 0; - $digit |= ($temp << $shift) & 0x7F000000; - } - $vals[] = $digit; - } - while (end($vals) === 0) { - array_pop($vals); - } - reset($vals); - } - - /** - * Test for engine validity - * - * @see parent::__construct() - * @return bool - */ - public static function isValidEngine() - { - return PHP_INT_SIZE >= 8 && !self::testJITOnWindows(); - } - - /** - * Adds two BigIntegers. - * - * @param PHP64 $y - * @return PHP64 - */ - public function add(PHP64 $y) - { - $temp = self::addHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Subtracts two BigIntegers. - * - * @param PHP64 $y - * @return PHP64 - */ - public function subtract(PHP64 $y) - { - $temp = self::subtractHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Multiplies two BigIntegers. - * - * @param PHP64 $y - * @return PHP64 - */ - public function multiply(PHP64 $y) - { - $temp = self::multiplyHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - - return $this->convertToObj($temp); - } - - /** - * Divides two BigIntegers. - * - * Returns an array whose first element contains the quotient and whose second element contains the - * "common residue". If the remainder would be positive, the "common residue" and the remainder are the - * same. If the remainder would be negative, the "common residue" is equal to the sum of the remainder - * and the divisor (basically, the "common residue" is the first positive modulo). - * - * @param PHP64 $y - * @return array{PHP64, PHP64} - */ - public function divide(PHP64 $y) - { - return $this->divideHelper($y); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP64 $n - * @return false|PHP64 - */ - public function modInverse(PHP64 $n) - { - return $this->modInverseHelper($n); - } - - /** - * Calculates modular inverses. - * - * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. - * @param PHP64 $n - * @return PHP64[] - */ - public function extendedGCD(PHP64 $n) - { - return $this->extendedGCDHelper($n); - } - - /** - * Calculates the greatest common divisor - * - * Say you have 693 and 609. The GCD is 21. - * - * @param PHP64 $n - * @return PHP64 - */ - public function gcd(PHP64 $n) - { - return $this->extendedGCD($n)['gcd']; - } - - /** - * Logical And - * - * @param PHP64 $x - * @return PHP64 - */ - public function bitwise_and(PHP64 $x) - { - return $this->bitwiseAndHelper($x); - } - - /** - * Logical Or - * - * @param PHP64 $x - * @return PHP64 - */ - public function bitwise_or(PHP64 $x) - { - return $this->bitwiseOrHelper($x); - } - - /** - * Logical Exclusive Or - * - * @param PHP64 $x - * @return PHP64 - */ - public function bitwise_xor(PHP64 $x) - { - return $this->bitwiseXorHelper($x); - } - - /** - * Compares two numbers. - * - * Although one might think !$x->compare($y) means $x != $y, it, in fact, means the opposite. The reason for this is - * demonstrated thusly: - * - * $x > $y: $x->compare($y) > 0 - * $x < $y: $x->compare($y) < 0 - * $x == $y: $x->compare($y) == 0 - * - * Note how the same comparison operator is used. If you want to test for equality, use $x->equals($y). - * - * {@internal Could return $this->subtract($x), but that's not as fast as what we do do.} - * - * @param PHP64 $y - * @return int in case < 0 if $this is less than $y; > 0 if $this is greater than $y, and 0 if they are equal. - * @see self::equals() - */ - public function compare(PHP64 $y) - { - return parent::compareHelper($this->value, $this->is_negative, $y->value, $y->is_negative); - } - - /** - * Tests the equality of two numbers. - * - * If you need to see if one number is greater than or less than another number, use BigInteger::compare() - * - * @param PHP64 $x - * @return bool - */ - public function equals(PHP64 $x) - { - return $this->value === $x->value && $this->is_negative == $x->is_negative; - } - - /** - * Performs modular exponentiation. - * - * @param PHP64 $e - * @param PHP64 $n - * @return PHP64 - */ - public function modPow(PHP64 $e, PHP64 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Performs modular exponentiation. - * - * Alias for modPow(). - * - * @param PHP64 $e - * @param PHP64 $n - * @return PHP64|false - */ - public function powMod(PHP64 $e, PHP64 $n) - { - return $this->powModOuter($e, $n); - } - - /** - * Generate a random prime number between a range - * - * If there's not a prime within the given range, false will be returned. - * - * @param PHP64 $min - * @param PHP64 $max - * @return false|PHP64 - */ - public static function randomRangePrime(PHP64 $min, PHP64 $max) - { - return self::randomRangePrimeOuter($min, $max); - } - - /** - * Generate a random number between a range - * - * Returns a random number between $min and $max where $min and $max - * can be defined using one of the two methods: - * - * BigInteger::randomRange($min, $max) - * BigInteger::randomRange($max, $min) - * - * @param PHP64 $min - * @param PHP64 $max - * @return PHP64 - */ - public static function randomRange(PHP64 $min, PHP64 $max) - { - return self::randomRangeHelper($min, $max); - } - - /** - * Performs exponentiation. - * - * @param PHP64 $n - * @return PHP64 - */ - public function pow(PHP64 $n) - { - return $this->powHelper($n); - } - - /** - * Return the minimum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP64 ...$nums - * @return PHP64 - */ - public static function min(PHP64 ...$nums) - { - return self::minHelper($nums); - } - - /** - * Return the maximum BigInteger between an arbitrary number of BigIntegers. - * - * @param PHP64 ...$nums - * @return PHP64 - */ - public static function max(PHP64 ...$nums) - { - return self::maxHelper($nums); - } - - /** - * Tests BigInteger to see if it is between two integers, inclusive - * - * @param PHP64 $min - * @param PHP64 $max - * @return bool - */ - public function between(PHP64 $min, PHP64 $max) - { - return $this->compare($min) >= 0 && $this->compare($max) <= 0; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php deleted file mode 100644 index 5da8c93..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField.php +++ /dev/null @@ -1,203 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BinaryField\Integer; -use phpseclib3\Math\Common\FiniteField; - -/** - * Binary Finite Fields - * - * @author Jim Wigginton - */ -class BinaryField extends FiniteField -{ - /** - * Instance Counter - * - * @var int - */ - private static $instanceCounter = 0; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** @var BigInteger */ - private $randomMax; - - /** - * Default constructor - */ - public function __construct(...$indices) - { - $m = array_shift($indices); - if ($m > 571) { - /* sect571r1 and sect571k1 are the largest binary curves that https://www.secg.org/sec2-v2.pdf defines - altho theoretically there may be legit reasons to use binary finite fields with larger degrees - imposing a limit on the maximum size is both reasonable and precedented. in particular, - http://tools.ietf.org/html/rfc4253#section-6.1 (The Secure Shell (SSH) Transport Layer Protocol) says - "implementations SHOULD check that the packet length is reasonable in order for the implementation to - avoid denial of service and/or buffer overflow attacks" */ - throw new \OutOfBoundsException('Degrees larger than 571 are not supported'); - } - $val = str_repeat('0', $m) . '1'; - foreach ($indices as $index) { - $val[$index] = '1'; - } - $modulo = static::base2ToBase256(strrev($val)); - - $mStart = 2 * $m - 2; - $t = ceil($m / 8); - $finalMask = chr((1 << ($m % 8)) - 1); - if ($finalMask == "\0") { - $finalMask = "\xFF"; - } - $bitLen = $mStart + 1; - $pad = ceil($bitLen / 8); - $h = $bitLen & 7; - $h = $h ? 8 - $h : 0; - - $r = rtrim(substr($val, 0, -1), '0'); - $u = [static::base2ToBase256(strrev($r))]; - for ($i = 1; $i < 8; $i++) { - $u[] = static::base2ToBase256(strrev(str_repeat('0', $i) . $r)); - } - - // implements algorithm 2.40 (in section 2.3.5) in "Guide to Elliptic Curve Cryptography" - // with W = 8 - $reduce = function ($c) use ($u, $mStart, $m, $t, $finalMask, $pad, $h) { - $c = str_pad($c, $pad, "\0", STR_PAD_LEFT); - for ($i = $mStart; $i >= $m;) { - $g = $h >> 3; - $mask = $h & 7; - $mask = $mask ? 1 << (7 - $mask) : 0x80; - for (; $mask > 0; $mask >>= 1, $i--, $h++) { - if (ord($c[$g]) & $mask) { - $temp = $i - $m; - $j = $temp >> 3; - $k = $temp & 7; - $t1 = $j ? substr($c, 0, -$j) : $c; - $length = strlen($t1); - if ($length) { - $t2 = str_pad($u[$k], $length, "\0", STR_PAD_LEFT); - $temp = $t1 ^ $t2; - $c = $j ? substr_replace($c, $temp, 0, $length) : $temp; - } - } - } - } - $c = substr($c, -$t); - if (strlen($c) == $t) { - $c[0] = $c[0] & $finalMask; - } - return ltrim($c, "\0"); - }; - - $this->instanceID = self::$instanceCounter++; - Integer::setModulo($this->instanceID, $modulo); - Integer::setRecurringModuloFunction($this->instanceID, $reduce); - - $this->randomMax = new BigInteger($modulo, 2); - } - - /** - * Returns an instance of a dynamically generated PrimeFieldInteger class - * - * @param string $num - * @return Integer - */ - public function newInteger($num) - { - return new Integer($this->instanceID, $num instanceof BigInteger ? $num->toBytes() : $num); - } - - /** - * Returns an integer on the finite field between one and the prime modulo - * - * @return Integer - */ - public function randomInteger() - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - return new Integer($this->instanceID, BigInteger::randomRange($one, $this->randomMax)->toBytes()); - } - - /** - * Returns the length of the modulo in bytes - * - * @return int - */ - public function getLengthInBytes() - { - return strlen(Integer::getModulo($this->instanceID)); - } - - /** - * Returns the length of the modulo in bits - * - * @return int - */ - public function getLength() - { - return strlen(Integer::getModulo($this->instanceID)) << 3; - } - - /** - * Converts a base-2 string to a base-256 string - * - * @param string $x - * @param int|null $size - * @return string - */ - public static function base2ToBase256($x, $size = null) - { - $str = Strings::bits2bin($x); - - $pad = strlen($x) >> 3; - if (strlen($x) & 3) { - $pad++; - } - $str = str_pad($str, $pad, "\0", STR_PAD_LEFT); - if (isset($size)) { - $str = str_pad($str, $size, "\0", STR_PAD_LEFT); - } - - return $str; - } - - /** - * Converts a base-256 string to a base-2 string - * - * @param string $x - * @return string - */ - public static function base256ToBase2($x) - { - if (function_exists('gmp_import')) { - return gmp_strval(gmp_import($x), 2); - } - - return Strings::bin2bits($x); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php deleted file mode 100644 index 8e88058..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/BinaryField/Integer.php +++ /dev/null @@ -1,516 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\BinaryField; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\BinaryField; -use phpseclib3\Math\Common\FiniteField\Integer as Base; - -/** - * Binary Finite Fields - * - * @author Jim Wigginton - */ -class Integer extends Base -{ - /** - * Holds the BinaryField's value - * - * @var string - */ - protected $value; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Holds the PrimeField's modulo - * - * @var array - */ - protected static $modulo; - - /** - * Holds a pre-generated function to perform modulo reductions - * - * @var callable[] - */ - protected static $reduce; - - /** - * Default constructor - */ - public function __construct($instanceID, $num = '') - { - $this->instanceID = $instanceID; - if (!strlen($num)) { - $this->value = ''; - } else { - $reduce = static::$reduce[$instanceID]; - $this->value = $reduce($num); - } - } - - /** - * Set the modulo for a given instance - * @param int $instanceID - * @param string $modulo - */ - public static function setModulo($instanceID, $modulo) - { - static::$modulo[$instanceID] = $modulo; - } - - /** - * Set the modulo for a given instance - */ - public static function setRecurringModuloFunction($instanceID, callable $function) - { - static::$reduce[$instanceID] = $function; - } - - /** - * Tests a parameter to see if it's of the right instance - * - * Throws an exception if the incorrect class is being utilized - */ - private static function checkInstance(self $x, self $y) - { - if ($x->instanceID != $y->instanceID) { - throw new \UnexpectedValueException('The instances of the two BinaryField\Integer objects do not match'); - } - } - - /** - * Tests the equality of two numbers. - * - * @return bool - */ - public function equals(self $x) - { - static::checkInstance($this, $x); - - return $this->value == $x->value; - } - - /** - * Compares two numbers. - * - * @return int - */ - public function compare(self $x) - { - static::checkInstance($this, $x); - - $a = $this->value; - $b = $x->value; - - $length = max(strlen($a), strlen($b)); - - $a = str_pad($a, $length, "\0", STR_PAD_LEFT); - $b = str_pad($b, $length, "\0", STR_PAD_LEFT); - - return strcmp($a, $b); - } - - /** - * Returns the degree of the polynomial - * - * @param string $x - * @return int - */ - private static function deg($x) - { - $x = ltrim($x, "\0"); - $xbit = decbin(ord($x[0])); - $xlen = $xbit == '0' ? 0 : strlen($xbit); - $len = strlen($x); - if (!$len) { - return -1; - } - return 8 * strlen($x) - 9 + $xlen; - } - - /** - * Perform polynomial division - * - * @return string[] - * @link https://en.wikipedia.org/wiki/Polynomial_greatest_common_divisor#Euclidean_division - */ - private static function polynomialDivide($x, $y) - { - // in wikipedia's description of the algorithm, lc() is the leading coefficient. over a binary field that's - // always going to be 1. - - $q = chr(0); - $d = static::deg($y); - $r = $x; - while (($degr = static::deg($r)) >= $d) { - $s = '1' . str_repeat('0', $degr - $d); - $s = BinaryField::base2ToBase256($s); - $length = max(strlen($s), strlen($q)); - $q = !isset($q) ? $s : - str_pad($q, $length, "\0", STR_PAD_LEFT) ^ - str_pad($s, $length, "\0", STR_PAD_LEFT); - $s = static::polynomialMultiply($s, $y); - $length = max(strlen($r), strlen($s)); - $r = str_pad($r, $length, "\0", STR_PAD_LEFT) ^ - str_pad($s, $length, "\0", STR_PAD_LEFT); - } - - return [ltrim($q, "\0"), ltrim($r, "\0")]; - } - - /** - * Perform polynomial multiplation in the traditional way - * - * @return string - * @link https://en.wikipedia.org/wiki/Finite_field_arithmetic#Multiplication - */ - private static function regularPolynomialMultiply($x, $y) - { - $precomputed = [ltrim($x, "\0")]; - $x = strrev(BinaryField::base256ToBase2($x)); - $y = strrev(BinaryField::base256ToBase2($y)); - if (strlen($x) == strlen($y)) { - $length = strlen($x); - } else { - $length = max(strlen($x), strlen($y)); - $x = str_pad($x, $length, '0'); - $y = str_pad($y, $length, '0'); - } - $result = str_repeat('0', 2 * $length - 1); - $result = BinaryField::base2ToBase256($result); - $size = strlen($result); - $x = strrev($x); - - // precompute left shift 1 through 7 - for ($i = 1; $i < 8; $i++) { - $precomputed[$i] = BinaryField::base2ToBase256($x . str_repeat('0', $i)); - } - for ($i = 0; $i < strlen($y); $i++) { - if ($y[$i] == '1') { - $temp = $precomputed[$i & 7] . str_repeat("\0", $i >> 3); - $result ^= str_pad($temp, $size, "\0", STR_PAD_LEFT); - } - } - - return $result; - } - - /** - * Perform polynomial multiplation - * - * Uses karatsuba multiplication to reduce x-bit multiplications to a series of 32-bit multiplications - * - * @return string - * @link https://en.wikipedia.org/wiki/Karatsuba_algorithm - */ - private static function polynomialMultiply($x, $y) - { - if (strlen($x) == strlen($y)) { - $length = strlen($x); - } else { - $length = max(strlen($x), strlen($y)); - $x = str_pad($x, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y, $length, "\0", STR_PAD_LEFT); - } - - switch (true) { - case PHP_INT_SIZE == 8 && $length <= 4: - return $length != 4 ? - self::subMultiply(str_pad($x, 4, "\0", STR_PAD_LEFT), str_pad($y, 4, "\0", STR_PAD_LEFT)) : - self::subMultiply($x, $y); - case PHP_INT_SIZE == 4 || $length > 32: - return self::regularPolynomialMultiply($x, $y); - } - - $m = $length >> 1; - - $x1 = substr($x, 0, -$m); - $x0 = substr($x, -$m); - $y1 = substr($y, 0, -$m); - $y0 = substr($y, -$m); - - $z2 = self::polynomialMultiply($x1, $y1); - $z0 = self::polynomialMultiply($x0, $y0); - $z1 = self::polynomialMultiply( - self::subAdd2($x1, $x0), - self::subAdd2($y1, $y0) - ); - - $z1 = self::subAdd3($z1, $z2, $z0); - - $xy = self::subAdd3( - $z2 . str_repeat("\0", 2 * $m), - $z1 . str_repeat("\0", $m), - $z0 - ); - - return ltrim($xy, "\0"); - } - - /** - * Perform polynomial multiplication on 2x 32-bit numbers, returning - * a 64-bit number - * - * @param string $x - * @param string $y - * @return string - * @link https://www.bearssl.org/constanttime.html#ghash-for-gcm - */ - private static function subMultiply($x, $y) - { - $x = unpack('N', $x)[1]; - $y = unpack('N', $y)[1]; - - $x0 = $x & 0x11111111; - $x1 = $x & 0x22222222; - $x2 = $x & 0x44444444; - $x3 = $x & 0x88888888; - - $y0 = $y & 0x11111111; - $y1 = $y & 0x22222222; - $y2 = $y & 0x44444444; - $y3 = $y & 0x88888888; - - $z0 = ($x0 * $y0) ^ ($x1 * $y3) ^ ($x2 * $y2) ^ ($x3 * $y1); - $z1 = ($x0 * $y1) ^ ($x1 * $y0) ^ ($x2 * $y3) ^ ($x3 * $y2); - $z2 = ($x0 * $y2) ^ ($x1 * $y1) ^ ($x2 * $y0) ^ ($x3 * $y3); - $z3 = ($x0 * $y3) ^ ($x1 * $y2) ^ ($x2 * $y1) ^ ($x3 * $y0); - - $z0 &= 0x1111111111111111; - $z1 &= 0x2222222222222222; - $z2 &= 0x4444444444444444; - $z3 &= -8608480567731124088; // 0x8888888888888888 gets interpreted as a float - - $z = $z0 | $z1 | $z2 | $z3; - - return pack('J', $z); - } - - /** - * Adds two numbers - * - * @param string $x - * @param string $y - * @return string - */ - private static function subAdd2($x, $y) - { - $length = max(strlen($x), strlen($y)); - $x = str_pad($x, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y, $length, "\0", STR_PAD_LEFT); - return $x ^ $y; - } - - /** - * Adds three numbers - * - * @param string $x - * @param string $y - * @return string - */ - private static function subAdd3($x, $y, $z) - { - $length = max(strlen($x), strlen($y), strlen($z)); - $x = str_pad($x, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y, $length, "\0", STR_PAD_LEFT); - $z = str_pad($z, $length, "\0", STR_PAD_LEFT); - return $x ^ $y ^ $z; - } - - /** - * Adds two BinaryFieldIntegers. - * - * @return static - */ - public function add(self $y) - { - static::checkInstance($this, $y); - - $length = strlen(static::$modulo[$this->instanceID]); - - $x = str_pad($this->value, $length, "\0", STR_PAD_LEFT); - $y = str_pad($y->value, $length, "\0", STR_PAD_LEFT); - - return new static($this->instanceID, $x ^ $y); - } - - /** - * Subtracts two BinaryFieldIntegers. - * - * @return static - */ - public function subtract(self $x) - { - return $this->add($x); - } - - /** - * Multiplies two BinaryFieldIntegers. - * - * @return static - */ - public function multiply(self $y) - { - static::checkInstance($this, $y); - - return new static($this->instanceID, static::polynomialMultiply($this->value, $y->value)); - } - - /** - * Returns the modular inverse of a BinaryFieldInteger - * - * @return static - */ - public function modInverse() - { - $remainder0 = static::$modulo[$this->instanceID]; - $remainder1 = $this->value; - - if ($remainder1 == '') { - return new static($this->instanceID); - } - - $aux0 = "\0"; - $aux1 = "\1"; - while ($remainder1 != "\1") { - list($q, $r) = static::polynomialDivide($remainder0, $remainder1); - $remainder0 = $remainder1; - $remainder1 = $r; - // the auxiliary in row n is given by the sum of the auxiliary in - // row n-2 and the product of the quotient and the auxiliary in row - // n-1 - $temp = static::polynomialMultiply($aux1, $q); - $aux = str_pad($aux0, strlen($temp), "\0", STR_PAD_LEFT) ^ - str_pad($temp, strlen($aux0), "\0", STR_PAD_LEFT); - $aux0 = $aux1; - $aux1 = $aux; - } - - $temp = new static($this->instanceID); - $temp->value = ltrim($aux1, "\0"); - return $temp; - } - - /** - * Divides two PrimeFieldIntegers. - * - * @return static - */ - public function divide(self $x) - { - static::checkInstance($this, $x); - - $x = $x->modInverse(); - return $this->multiply($x); - } - - /** - * Negate - * - * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo - * so 0-12 is the same thing as modulo-12 - * - * @return object - */ - public function negate() - { - $x = str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); - - return new static($this->instanceID, $x ^ static::$modulo[$this->instanceID]); - } - - /** - * Returns the modulo - * - * @return string - */ - public static function getModulo($instanceID) - { - return static::$modulo[$instanceID]; - } - - /** - * Converts an Integer to a byte string (eg. base-256). - * - * @return string - */ - public function toBytes() - { - return str_pad($this->value, strlen(static::$modulo[$this->instanceID]), "\0", STR_PAD_LEFT); - } - - /** - * Converts an Integer to a hex string (eg. base-16). - * - * @return string - */ - public function toHex() - { - return Strings::bin2hex($this->toBytes()); - } - - /** - * Converts an Integer to a bit string (eg. base-2). - * - * @return string - */ - public function toBits() - { - //return str_pad(BinaryField::base256ToBase2($this->value), strlen(static::$modulo[$this->instanceID]), '0', STR_PAD_LEFT); - return BinaryField::base256ToBase2($this->value); - } - - /** - * Converts an Integer to a BigInteger - * - * @return string - */ - public function toBigInteger() - { - return new BigInteger($this->value, 256); - } - - /** - * __toString() magic method - * - */ - public function __toString() - { - return (string) $this->toBigInteger(); - } - - /** - * __debugInfo() magic method - * - */ - public function __debugInfo() - { - return ['value' => $this->toHex()]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php deleted file mode 100644 index 2ea5f48..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField.php +++ /dev/null @@ -1,22 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\Common; - -/** - * Finite Fields - * - * @author Jim Wigginton - */ -abstract class FiniteField -{ -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php deleted file mode 100644 index 3c959e9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/Common/FiniteField/Integer.php +++ /dev/null @@ -1,44 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\Common\FiniteField; - -/** - * Finite Field Integer - * - * @author Jim Wigginton - */ -abstract class Integer implements \JsonSerializable -{ - /** - * JSON Serialize - * - * Will be called, automatically, when json_encode() is called on a BigInteger object. - * - * PHP Serialize isn't supported because unserializing would require the factory be - * serialized as well and that just sounds like too much - * - * @return array{hex: string} - */ - #[\ReturnTypeWillChange] - public function jsonSerialize() - { - return ['hex' => $this->toHex(true)]; - } - - /** - * Converts an Integer to a hex string (eg. base-16). - * - * @return string - */ - abstract public function toHex(); -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php deleted file mode 100644 index 1a0667f..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField.php +++ /dev/null @@ -1,118 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://pear.php.net/package/Math_BigInteger - */ - -namespace phpseclib3\Math; - -use phpseclib3\Math\Common\FiniteField; -use phpseclib3\Math\PrimeField\Integer; - -/** - * Prime Finite Fields - * - * @author Jim Wigginton - */ -class PrimeField extends FiniteField -{ - /** - * Instance Counter - * - * @var int - */ - private static $instanceCounter = 0; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Default constructor - */ - public function __construct(BigInteger $modulo) - { - if (!$modulo->isPrime()) { - throw new \UnexpectedValueException('PrimeField requires a prime number be passed to the constructor'); - } - - $this->instanceID = self::$instanceCounter++; - Integer::setModulo($this->instanceID, $modulo); - Integer::setRecurringModuloFunction($this->instanceID, $modulo->createRecurringModuloFunction()); - } - - /** - * Use a custom defined modular reduction function - * - * @return void - */ - public function setReduction(\Closure $func) - { - $this->reduce = $func->bindTo($this, $this); - } - - /** - * Returns an instance of a dynamically generated PrimeFieldInteger class - * - * @return Integer - */ - public function newInteger(BigInteger $num) - { - return new Integer($this->instanceID, $num); - } - - /** - * Returns an integer on the finite field between one and the prime modulo - * - * @return Integer - */ - public function randomInteger() - { - static $one; - if (!isset($one)) { - $one = new BigInteger(1); - } - - return new Integer($this->instanceID, BigInteger::randomRange($one, Integer::getModulo($this->instanceID))); - } - - /** - * Returns the length of the modulo in bytes - * - * @return int - */ - public function getLengthInBytes() - { - return Integer::getModulo($this->instanceID)->getLengthInBytes(); - } - - /** - * Returns the length of the modulo in bits - * - * @return int - */ - public function getLength() - { - return Integer::getModulo($this->instanceID)->getLength(); - } - - /** - * Destructor - */ - public function __destruct() - { - Integer::cleanupCache($this->instanceID); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php deleted file mode 100644 index 1bd7aaf..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Math/PrimeField/Integer.php +++ /dev/null @@ -1,419 +0,0 @@ - - * @copyright 2017 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - */ - -namespace phpseclib3\Math\PrimeField; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Math\BigInteger; -use phpseclib3\Math\Common\FiniteField\Integer as Base; - -/** - * Prime Finite Fields - * - * @author Jim Wigginton - */ -class Integer extends Base -{ - /** - * Holds the PrimeField's value - * - * @var BigInteger - */ - protected $value; - - /** - * Keeps track of current instance - * - * @var int - */ - protected $instanceID; - - /** - * Holds the PrimeField's modulo - * - * @var array - */ - protected static $modulo; - - /** - * Holds a pre-generated function to perform modulo reductions - * - * @var array - */ - protected static $reduce; - - /** - * Zero - * - * @var BigInteger - */ - protected static $zero; - - /** - * Default constructor - * - * @param int $instanceID - */ - public function __construct($instanceID, BigInteger $num = null) - { - $this->instanceID = $instanceID; - if (!isset($num)) { - $this->value = clone static::$zero[static::class]; - } else { - $reduce = static::$reduce[$instanceID]; - $this->value = $reduce($num); - } - } - - /** - * Set the modulo for a given instance - * - * @param int $instanceID - * @return void - */ - public static function setModulo($instanceID, BigInteger $modulo) - { - static::$modulo[$instanceID] = $modulo; - } - - /** - * Set the modulo for a given instance - * - * @param int $instanceID - * @return void - */ - public static function setRecurringModuloFunction($instanceID, callable $function) - { - static::$reduce[$instanceID] = $function; - if (!isset(static::$zero[static::class])) { - static::$zero[static::class] = new BigInteger(); - } - } - - /** - * Delete the modulo for a given instance - */ - public static function cleanupCache($instanceID) - { - unset(static::$modulo[$instanceID]); - unset(static::$reduce[$instanceID]); - } - - /** - * Returns the modulo - * - * @param int $instanceID - * @return BigInteger - */ - public static function getModulo($instanceID) - { - return static::$modulo[$instanceID]; - } - - /** - * Tests a parameter to see if it's of the right instance - * - * Throws an exception if the incorrect class is being utilized - * - * @return void - */ - public static function checkInstance(self $x, self $y) - { - if ($x->instanceID != $y->instanceID) { - throw new \UnexpectedValueException('The instances of the two PrimeField\Integer objects do not match'); - } - } - - /** - * Tests the equality of two numbers. - * - * @return bool - */ - public function equals(self $x) - { - static::checkInstance($this, $x); - - return $this->value->equals($x->value); - } - - /** - * Compares two numbers. - * - * @return int - */ - public function compare(self $x) - { - static::checkInstance($this, $x); - - return $this->value->compare($x->value); - } - - /** - * Adds two PrimeFieldIntegers. - * - * @return static - */ - public function add(self $x) - { - static::checkInstance($this, $x); - - $temp = new static($this->instanceID); - $temp->value = $this->value->add($x->value); - if ($temp->value->compare(static::$modulo[$this->instanceID]) >= 0) { - $temp->value = $temp->value->subtract(static::$modulo[$this->instanceID]); - } - - return $temp; - } - - /** - * Subtracts two PrimeFieldIntegers. - * - * @return static - */ - public function subtract(self $x) - { - static::checkInstance($this, $x); - - $temp = new static($this->instanceID); - $temp->value = $this->value->subtract($x->value); - if ($temp->value->isNegative()) { - $temp->value = $temp->value->add(static::$modulo[$this->instanceID]); - } - - return $temp; - } - - /** - * Multiplies two PrimeFieldIntegers. - * - * @return static - */ - public function multiply(self $x) - { - static::checkInstance($this, $x); - - return new static($this->instanceID, $this->value->multiply($x->value)); - } - - /** - * Divides two PrimeFieldIntegers. - * - * @return static - */ - public function divide(self $x) - { - static::checkInstance($this, $x); - - $denominator = $x->value->modInverse(static::$modulo[$this->instanceID]); - return new static($this->instanceID, $this->value->multiply($denominator)); - } - - /** - * Performs power operation on a PrimeFieldInteger. - * - * @return static - */ - public function pow(BigInteger $x) - { - $temp = new static($this->instanceID); - $temp->value = $this->value->powMod($x, static::$modulo[$this->instanceID]); - - return $temp; - } - - /** - * Calculates the square root - * - * @link https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm - * @return static|false - */ - public function squareRoot() - { - static $one, $two; - if (!isset($one)) { - $one = new BigInteger(1); - $two = new BigInteger(2); - } - $reduce = static::$reduce[$this->instanceID]; - $p_1 = static::$modulo[$this->instanceID]->subtract($one); - $q = clone $p_1; - $s = BigInteger::scan1divide($q); - list($pow) = $p_1->divide($two); - for ($z = $one; !$z->equals(static::$modulo[$this->instanceID]); $z = $z->add($one)) { - $temp = $z->powMod($pow, static::$modulo[$this->instanceID]); - if ($temp->equals($p_1)) { - break; - } - } - - $m = new BigInteger($s); - $c = $z->powMod($q, static::$modulo[$this->instanceID]); - $t = $this->value->powMod($q, static::$modulo[$this->instanceID]); - list($temp) = $q->add($one)->divide($two); - $r = $this->value->powMod($temp, static::$modulo[$this->instanceID]); - - while (!$t->equals($one)) { - for ($i = clone $one; $i->compare($m) < 0; $i = $i->add($one)) { - if ($t->powMod($two->pow($i), static::$modulo[$this->instanceID])->equals($one)) { - break; - } - } - - if ($i->compare($m) == 0) { - return false; - } - $b = $c->powMod($two->pow($m->subtract($i)->subtract($one)), static::$modulo[$this->instanceID]); - $m = $i; - $c = $reduce($b->multiply($b)); - $t = $reduce($t->multiply($c)); - $r = $reduce($r->multiply($b)); - } - - return new static($this->instanceID, $r); - } - - /** - * Is Odd? - * - * @return bool - */ - public function isOdd() - { - return $this->value->isOdd(); - } - - /** - * Negate - * - * A negative number can be written as 0-12. With modulos, 0 is the same thing as the modulo - * so 0-12 is the same thing as modulo-12 - * - * @return static - */ - public function negate() - { - return new static($this->instanceID, static::$modulo[$this->instanceID]->subtract($this->value)); - } - - /** - * Converts an Integer to a byte string (eg. base-256). - * - * @return string - */ - public function toBytes() - { - if (isset(static::$modulo[$this->instanceID])) { - $length = static::$modulo[$this->instanceID]->getLengthInBytes(); - return str_pad($this->value->toBytes(), $length, "\0", STR_PAD_LEFT); - } - return $this->value->toBytes(); - } - - /** - * Converts an Integer to a hex string (eg. base-16). - * - * @return string - */ - public function toHex() - { - return Strings::bin2hex($this->toBytes()); - } - - /** - * Converts an Integer to a bit string (eg. base-2). - * - * @return string - */ - public function toBits() - { - // return $this->value->toBits(); - static $length; - if (!isset($length)) { - $length = static::$modulo[$this->instanceID]->getLength(); - } - - return str_pad($this->value->toBits(), $length, '0', STR_PAD_LEFT); - } - - /** - * Returns the w-ary non-adjacent form (wNAF) - * - * @param int $w optional - * @return array - */ - public function getNAF($w = 1) - { - $w++; - - $mask = new BigInteger((1 << $w) - 1); - $sub = new BigInteger(1 << $w); - //$sub = new BigInteger(1 << ($w - 1)); - $d = $this->toBigInteger(); - $d_i = []; - - $i = 0; - while ($d->compare(static::$zero[static::class]) > 0) { - if ($d->isOdd()) { - // start mods - - $bigInteger = $d->testBit($w - 1) ? - $d->bitwise_and($mask)->subtract($sub) : - //$sub->subtract($d->bitwise_and($mask)) : - $d->bitwise_and($mask); - // end mods - $d = $d->subtract($bigInteger); - $d_i[$i] = (int) $bigInteger->toString(); - } else { - $d_i[$i] = 0; - } - $shift = !$d->equals(static::$zero[static::class]) && $d->bitwise_and($mask)->equals(static::$zero[static::class]) ? $w : 1; // $w or $w + 1? - $d = $d->bitwise_rightShift($shift); - while (--$shift > 0) { - $d_i[++$i] = 0; - } - $i++; - } - - return $d_i; - } - - /** - * Converts an Integer to a BigInteger - * - * @return BigInteger - */ - public function toBigInteger() - { - return clone $this->value; - } - - /** - * __toString() magic method - * - * @return string - */ - public function __toString() - { - return (string) $this->value; - } - - /** - * __debugInfo() magic method - * - * @return array - */ - public function __debugInfo() - { - return ['value' => $this->toHex()]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php deleted file mode 100644 index 45f748d..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP.php +++ /dev/null @@ -1,3547 +0,0 @@ - - * login('username', 'password')) { - * exit('Login Failed'); - * } - * - * echo $sftp->pwd() . "\r\n"; - * $sftp->put('filename.ext', 'hello, world!'); - * print_r($sftp->nlist()); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Net; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Exception\FileNotFoundException; - -/** - * Pure-PHP implementations of SFTP. - * - * @author Jim Wigginton - */ -class SFTP extends SSH2 -{ - /** - * SFTP channel constant - * - * \phpseclib3\Net\SSH2::exec() uses 0 and \phpseclib3\Net\SSH2::read() / \phpseclib3\Net\SSH2::write() use 1. - * - * @see \phpseclib3\Net\SSH2::send_channel_packet() - * @see \phpseclib3\Net\SSH2::get_channel_packet() - */ - const CHANNEL = 0x100; - - /** - * Reads data from a local file. - * - * @see \phpseclib3\Net\SFTP::put() - */ - const SOURCE_LOCAL_FILE = 1; - /** - * Reads data from a string. - * - * @see \phpseclib3\Net\SFTP::put() - */ - // this value isn't really used anymore but i'm keeping it reserved for historical reasons - const SOURCE_STRING = 2; - /** - * Reads data from callback: - * function callback($length) returns string to proceed, null for EOF - * - * @see \phpseclib3\Net\SFTP::put() - */ - const SOURCE_CALLBACK = 16; - /** - * Resumes an upload - * - * @see \phpseclib3\Net\SFTP::put() - */ - const RESUME = 4; - /** - * Append a local file to an already existing remote file - * - * @see \phpseclib3\Net\SFTP::put() - */ - const RESUME_START = 8; - - /** - * Packet Types - * - * @see self::__construct() - * @var array - * @access private - */ - private static $packet_types = []; - - /** - * Status Codes - * - * @see self::__construct() - * @var array - * @access private - */ - private static $status_codes = []; - - /** @var array */ - private static $attributes; - - /** @var array */ - private static $open_flags; - - /** @var array */ - private static $open_flags5; - - /** @var array */ - private static $file_types; - - /** - * The Request ID - * - * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support - * concurrent actions, so it's somewhat academic, here. - * - * @var boolean - * @see self::_send_sftp_packet() - */ - private $use_request_id = false; - - /** - * The Packet Type - * - * The request ID exists in the off chance that a packet is sent out-of-order. Of course, this library doesn't support - * concurrent actions, so it's somewhat academic, here. - * - * @var int - * @see self::_get_sftp_packet() - */ - private $packet_type = -1; - - /** - * Packet Buffer - * - * @var string - * @see self::_get_sftp_packet() - */ - private $packet_buffer = ''; - - /** - * Extensions supported by the server - * - * @var array - * @see self::_initChannel() - */ - private $extensions = []; - - /** - * Server SFTP version - * - * @var int - * @see self::_initChannel() - */ - private $version; - - /** - * Default Server SFTP version - * - * @var int - * @see self::_initChannel() - */ - private $defaultVersion; - - /** - * Preferred SFTP version - * - * @var int - * @see self::_initChannel() - */ - private $preferredVersion = 3; - - /** - * Current working directory - * - * @var string|bool - * @see self::realpath() - * @see self::chdir() - */ - private $pwd = false; - - /** - * Packet Type Log - * - * @see self::getLog() - * @var array - */ - private $packet_type_log = []; - - /** - * Packet Log - * - * @see self::getLog() - * @var array - */ - private $packet_log = []; - - /** - * Real-time log file pointer - * - * @see self::_append_log() - * @var resource|closed-resource - */ - private $realtime_log_file; - - /** - * Real-time log file size - * - * @see self::_append_log() - * @var int - */ - private $realtime_log_size; - - /** - * Real-time log file wrap boolean - * - * @see self::_append_log() - * @var bool - */ - private $realtime_log_wrap; - - /** - * Current log size - * - * Should never exceed self::LOG_MAX_SIZE - * - * @var int - */ - private $log_size; - - /** - * Error information - * - * @see self::getSFTPErrors() - * @see self::getLastSFTPError() - * @var array - */ - private $sftp_errors = []; - - /** - * Stat Cache - * - * Rather than always having to open a directory and close it immediately there after to see if a file is a directory - * we'll cache the results. - * - * @see self::_update_stat_cache() - * @see self::_remove_from_stat_cache() - * @see self::_query_stat_cache() - * @var array - */ - private $stat_cache = []; - - /** - * Max SFTP Packet Size - * - * @see self::__construct() - * @see self::get() - * @var int - */ - private $max_sftp_packet; - - /** - * Stat Cache Flag - * - * @see self::disableStatCache() - * @see self::enableStatCache() - * @var bool - */ - private $use_stat_cache = true; - - /** - * Sort Options - * - * @see self::_comparator() - * @see self::setListOrder() - * @var array - */ - protected $sortOptions = []; - - /** - * Canonicalization Flag - * - * Determines whether or not paths should be canonicalized before being - * passed on to the remote server. - * - * @see self::enablePathCanonicalization() - * @see self::disablePathCanonicalization() - * @see self::realpath() - * @var bool - */ - private $canonicalize_paths = true; - - /** - * Request Buffers - * - * @see self::_get_sftp_packet() - * @var array - */ - private $requestBuffer = []; - - /** - * Preserve timestamps on file downloads / uploads - * - * @see self::get() - * @see self::put() - * @var bool - */ - private $preserveTime = false; - - /** - * Arbitrary Length Packets Flag - * - * Determines whether or not packets of any length should be allowed, - * in cases where the server chooses the packet length (such as - * directory listings). By default, packets are only allowed to be - * 256 * 1024 bytes (SFTP_MAX_MSG_LENGTH from OpenSSH's sftp-common.h) - * - * @see self::enableArbitraryLengthPackets() - * @see self::_get_sftp_packet() - * @var bool - */ - private $allow_arbitrary_length_packets = false; - - /** - * Was the last packet due to the channels being closed or not? - * - * @see self::get() - * @see self::get_sftp_packet() - * @var bool - */ - private $channel_close = false; - - /** - * Has the SFTP channel been partially negotiated? - * - * @var bool - */ - private $partial_init = false; - - /** - * Default Constructor. - * - * Connects to an SFTP server - * - * $host can either be a string, representing the host, or a stream resource. - * - * @param mixed $host - * @param int $port - * @param int $timeout - */ - public function __construct($host, $port = 22, $timeout = 10) - { - parent::__construct($host, $port, $timeout); - - $this->max_sftp_packet = 1 << 15; - - if (empty(self::$packet_types)) { - self::$packet_types = [ - 1 => 'NET_SFTP_INIT', - 2 => 'NET_SFTP_VERSION', - 3 => 'NET_SFTP_OPEN', - 4 => 'NET_SFTP_CLOSE', - 5 => 'NET_SFTP_READ', - 6 => 'NET_SFTP_WRITE', - 7 => 'NET_SFTP_LSTAT', - 9 => 'NET_SFTP_SETSTAT', - 10 => 'NET_SFTP_FSETSTAT', - 11 => 'NET_SFTP_OPENDIR', - 12 => 'NET_SFTP_READDIR', - 13 => 'NET_SFTP_REMOVE', - 14 => 'NET_SFTP_MKDIR', - 15 => 'NET_SFTP_RMDIR', - 16 => 'NET_SFTP_REALPATH', - 17 => 'NET_SFTP_STAT', - 18 => 'NET_SFTP_RENAME', - 19 => 'NET_SFTP_READLINK', - 20 => 'NET_SFTP_SYMLINK', - 21 => 'NET_SFTP_LINK', - - 101 => 'NET_SFTP_STATUS', - 102 => 'NET_SFTP_HANDLE', - 103 => 'NET_SFTP_DATA', - 104 => 'NET_SFTP_NAME', - 105 => 'NET_SFTP_ATTRS', - - 200 => 'NET_SFTP_EXTENDED' - ]; - self::$status_codes = [ - 0 => 'NET_SFTP_STATUS_OK', - 1 => 'NET_SFTP_STATUS_EOF', - 2 => 'NET_SFTP_STATUS_NO_SUCH_FILE', - 3 => 'NET_SFTP_STATUS_PERMISSION_DENIED', - 4 => 'NET_SFTP_STATUS_FAILURE', - 5 => 'NET_SFTP_STATUS_BAD_MESSAGE', - 6 => 'NET_SFTP_STATUS_NO_CONNECTION', - 7 => 'NET_SFTP_STATUS_CONNECTION_LOST', - 8 => 'NET_SFTP_STATUS_OP_UNSUPPORTED', - 9 => 'NET_SFTP_STATUS_INVALID_HANDLE', - 10 => 'NET_SFTP_STATUS_NO_SUCH_PATH', - 11 => 'NET_SFTP_STATUS_FILE_ALREADY_EXISTS', - 12 => 'NET_SFTP_STATUS_WRITE_PROTECT', - 13 => 'NET_SFTP_STATUS_NO_MEDIA', - 14 => 'NET_SFTP_STATUS_NO_SPACE_ON_FILESYSTEM', - 15 => 'NET_SFTP_STATUS_QUOTA_EXCEEDED', - 16 => 'NET_SFTP_STATUS_UNKNOWN_PRINCIPAL', - 17 => 'NET_SFTP_STATUS_LOCK_CONFLICT', - 18 => 'NET_SFTP_STATUS_DIR_NOT_EMPTY', - 19 => 'NET_SFTP_STATUS_NOT_A_DIRECTORY', - 20 => 'NET_SFTP_STATUS_INVALID_FILENAME', - 21 => 'NET_SFTP_STATUS_LINK_LOOP', - 22 => 'NET_SFTP_STATUS_CANNOT_DELETE', - 23 => 'NET_SFTP_STATUS_INVALID_PARAMETER', - 24 => 'NET_SFTP_STATUS_FILE_IS_A_DIRECTORY', - 25 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_CONFLICT', - 26 => 'NET_SFTP_STATUS_BYTE_RANGE_LOCK_REFUSED', - 27 => 'NET_SFTP_STATUS_DELETE_PENDING', - 28 => 'NET_SFTP_STATUS_FILE_CORRUPT', - 29 => 'NET_SFTP_STATUS_OWNER_INVALID', - 30 => 'NET_SFTP_STATUS_GROUP_INVALID', - 31 => 'NET_SFTP_STATUS_NO_MATCHING_BYTE_RANGE_LOCK' - ]; - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-7.1 - // the order, in this case, matters quite a lot - see \phpseclib3\Net\SFTP::_parseAttributes() to understand why - self::$attributes = [ - 0x00000001 => 'NET_SFTP_ATTR_SIZE', - 0x00000002 => 'NET_SFTP_ATTR_UIDGID', // defined in SFTPv3, removed in SFTPv4+ - 0x00000080 => 'NET_SFTP_ATTR_OWNERGROUP', // defined in SFTPv4+ - 0x00000004 => 'NET_SFTP_ATTR_PERMISSIONS', - 0x00000008 => 'NET_SFTP_ATTR_ACCESSTIME', - 0x00000010 => 'NET_SFTP_ATTR_CREATETIME', // SFTPv4+ - 0x00000020 => 'NET_SFTP_ATTR_MODIFYTIME', - 0x00000040 => 'NET_SFTP_ATTR_ACL', - 0x00000100 => 'NET_SFTP_ATTR_SUBSECOND_TIMES', - 0x00000200 => 'NET_SFTP_ATTR_BITS', // SFTPv5+ - 0x00000400 => 'NET_SFTP_ATTR_ALLOCATION_SIZE', // SFTPv6+ - 0x00000800 => 'NET_SFTP_ATTR_TEXT_HINT', - 0x00001000 => 'NET_SFTP_ATTR_MIME_TYPE', - 0x00002000 => 'NET_SFTP_ATTR_LINK_COUNT', - 0x00004000 => 'NET_SFTP_ATTR_UNTRANSLATED_NAME', - 0x00008000 => 'NET_SFTP_ATTR_CTIME', - // 0x80000000 will yield a floating point on 32-bit systems and converting floating points to integers - // yields inconsistent behavior depending on how php is compiled. so we left shift -1 (which, in - // two's compliment, consists of all 1 bits) by 31. on 64-bit systems this'll yield 0xFFFFFFFF80000000. - // that's not a problem, however, and 'anded' and a 32-bit number, as all the leading 1 bits are ignored. - (PHP_INT_SIZE == 4 ? (-1 << 31) : 0x80000000) => 'NET_SFTP_ATTR_EXTENDED' - ]; - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-6.3 - // the flag definitions change somewhat in SFTPv5+. if SFTPv5+ support is added to this library, maybe name - // the array for that $this->open5_flags and similarly alter the constant names. - self::$open_flags = [ - 0x00000001 => 'NET_SFTP_OPEN_READ', - 0x00000002 => 'NET_SFTP_OPEN_WRITE', - 0x00000004 => 'NET_SFTP_OPEN_APPEND', - 0x00000008 => 'NET_SFTP_OPEN_CREATE', - 0x00000010 => 'NET_SFTP_OPEN_TRUNCATE', - 0x00000020 => 'NET_SFTP_OPEN_EXCL', - 0x00000040 => 'NET_SFTP_OPEN_TEXT' // defined in SFTPv4 - ]; - // SFTPv5+ changed the flags up: - // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-8.1.1.3 - self::$open_flags5 = [ - // when SSH_FXF_ACCESS_DISPOSITION is a 3 bit field that controls how the file is opened - 0x00000000 => 'NET_SFTP_OPEN_CREATE_NEW', - 0x00000001 => 'NET_SFTP_OPEN_CREATE_TRUNCATE', - 0x00000002 => 'NET_SFTP_OPEN_OPEN_EXISTING', - 0x00000003 => 'NET_SFTP_OPEN_OPEN_OR_CREATE', - 0x00000004 => 'NET_SFTP_OPEN_TRUNCATE_EXISTING', - // the rest of the flags are not supported - 0x00000008 => 'NET_SFTP_OPEN_APPEND_DATA', // "the offset field of SS_FXP_WRITE requests is ignored" - 0x00000010 => 'NET_SFTP_OPEN_APPEND_DATA_ATOMIC', - 0x00000020 => 'NET_SFTP_OPEN_TEXT_MODE', - 0x00000040 => 'NET_SFTP_OPEN_BLOCK_READ', - 0x00000080 => 'NET_SFTP_OPEN_BLOCK_WRITE', - 0x00000100 => 'NET_SFTP_OPEN_BLOCK_DELETE', - 0x00000200 => 'NET_SFTP_OPEN_BLOCK_ADVISORY', - 0x00000400 => 'NET_SFTP_OPEN_NOFOLLOW', - 0x00000800 => 'NET_SFTP_OPEN_DELETE_ON_CLOSE', - 0x00001000 => 'NET_SFTP_OPEN_ACCESS_AUDIT_ALARM_INFO', - 0x00002000 => 'NET_SFTP_OPEN_ACCESS_BACKUP', - 0x00004000 => 'NET_SFTP_OPEN_BACKUP_STREAM', - 0x00008000 => 'NET_SFTP_OPEN_OVERRIDE_OWNER', - ]; - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 - // see \phpseclib3\Net\SFTP::_parseLongname() for an explanation - self::$file_types = [ - 1 => 'NET_SFTP_TYPE_REGULAR', - 2 => 'NET_SFTP_TYPE_DIRECTORY', - 3 => 'NET_SFTP_TYPE_SYMLINK', - 4 => 'NET_SFTP_TYPE_SPECIAL', - 5 => 'NET_SFTP_TYPE_UNKNOWN', - // the following types were first defined for use in SFTPv5+ - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 - 6 => 'NET_SFTP_TYPE_SOCKET', - 7 => 'NET_SFTP_TYPE_CHAR_DEVICE', - 8 => 'NET_SFTP_TYPE_BLOCK_DEVICE', - 9 => 'NET_SFTP_TYPE_FIFO' - ]; - self::define_array( - self::$packet_types, - self::$status_codes, - self::$attributes, - self::$open_flags, - self::$open_flags5, - self::$file_types - ); - } - - if (!defined('NET_SFTP_QUEUE_SIZE')) { - define('NET_SFTP_QUEUE_SIZE', 32); - } - if (!defined('NET_SFTP_UPLOAD_QUEUE_SIZE')) { - define('NET_SFTP_UPLOAD_QUEUE_SIZE', 1024); - } - } - - /** - * Check a few things before SFTP functions are called - * - * @return bool - */ - private function precheck() - { - if (!($this->bitmap & SSH2::MASK_LOGIN)) { - return false; - } - - if ($this->pwd === false) { - return $this->init_sftp_connection(); - } - - return true; - } - - /** - * Partially initialize an SFTP connection - * - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return bool - */ - private function partial_init_sftp_connection() - { - $response = $this->openChannel(self::CHANNEL, true); - if ($response === true && $this->isTimeout()) { - return false; - } - - $packet = Strings::packSSH2( - 'CNsbs', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL], - 'subsystem', - true, - 'sftp' - ); - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $response = $this->get_channel_packet(self::CHANNEL, true); - if ($response === false) { - // from PuTTY's psftp.exe - $command = "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n" . - "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n" . - "exec sftp-server"; - // we don't do $this->exec($command, false) because exec() operates on a different channel and plus the SSH_MSG_CHANNEL_OPEN that exec() does - // is redundant - $packet = Strings::packSSH2( - 'CNsCs', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL], - 'exec', - 1, - $command - ); - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $response = $this->get_channel_packet(self::CHANNEL, true); - if ($response === false) { - return false; - } - } elseif ($response === true && $this->isTimeout()) { - return false; - } - - $this->channel_status[self::CHANNEL] = NET_SSH2_MSG_CHANNEL_DATA; - $this->send_sftp_packet(NET_SFTP_INIT, "\0\0\0\3"); - - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_VERSION) { - throw new \UnexpectedValueException('Expected NET_SFTP_VERSION. ' - . 'Got packet type: ' . $this->packet_type); - } - - $this->use_request_id = true; - - list($this->defaultVersion) = Strings::unpackSSH2('N', $response); - while (!empty($response)) { - list($key, $value) = Strings::unpackSSH2('ss', $response); - $this->extensions[$key] = $value; - } - - $this->partial_init = true; - - return true; - } - - /** - * (Re)initializes the SFTP channel - * - * @return bool - */ - private function init_sftp_connection() - { - if (!$this->partial_init && !$this->partial_init_sftp_connection()) { - return false; - } - - /* - A Note on SFTPv4/5/6 support: - states the following: - - "If the client wishes to interoperate with servers that support noncontiguous version - numbers it SHOULD send '3'" - - Given that the server only sends its version number after the client has already done so, the above - seems to be suggesting that v3 should be the default version. This makes sense given that v3 is the - most popular. - - states the following; - - "If the server did not send the "versions" extension, or the version-from-list was not included, the - server MAY send a status response describing the failure, but MUST then close the channel without - processing any further requests." - - So what do you do if you have a client whose initial SSH_FXP_INIT packet says it implements v3 and - a server whose initial SSH_FXP_VERSION reply says it implements v4 and only v4? If it only implements - v4, the "versions" extension is likely not going to have been sent so version re-negotiation as discussed - in draft-ietf-secsh-filexfer-13 would be quite impossible. As such, what \phpseclib3\Net\SFTP would do is close the - channel and reopen it with a new and updated SSH_FXP_INIT packet. - */ - $this->version = $this->defaultVersion; - if (isset($this->extensions['versions']) && (!$this->preferredVersion || $this->preferredVersion != $this->version)) { - $versions = explode(',', $this->extensions['versions']); - $supported = [6, 5, 4]; - if ($this->preferredVersion) { - $supported = array_diff($supported, [$this->preferredVersion]); - array_unshift($supported, $this->preferredVersion); - } - foreach ($supported as $ver) { - if (in_array($ver, $versions)) { - if ($ver === $this->version) { - break; - } - $this->version = (int) $ver; - $packet = Strings::packSSH2('ss', 'version-select', "$ver"); - $this->send_sftp_packet(NET_SFTP_EXTENDED, $packet); - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS_OK. ' - . ' Got ' . $status); - } - break; - } - } - } - - /* - SFTPv4+ defines a 'newline' extension. SFTPv3 seems to have unofficial support for it via 'newline@vandyke.com', - however, I'm not sure what 'newline@vandyke.com' is supposed to do (the fact that it's unofficial means that it's - not in the official SFTPv3 specs) and 'newline@vandyke.com' / 'newline' are likely not drop-in substitutes for - one another due to the fact that 'newline' comes with a SSH_FXF_TEXT bitmask whereas it seems unlikely that - 'newline@vandyke.com' would. - */ - /* - if (isset($this->extensions['newline@vandyke.com'])) { - $this->extensions['newline'] = $this->extensions['newline@vandyke.com']; - unset($this->extensions['newline@vandyke.com']); - } - */ - if ($this->version < 2 || $this->version > 6) { - return false; - } - - $this->pwd = true; - try { - $this->pwd = $this->realpath('.'); - } catch (\UnexpectedValueException $e) { - if (!$this->canonicalize_paths) { - throw $e; - } - $this->canonicalize_paths = false; - $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); - } - - $this->update_stat_cache($this->pwd, []); - - return true; - } - - /** - * Disable the stat cache - * - */ - public function disableStatCache() - { - $this->use_stat_cache = false; - } - - /** - * Enable the stat cache - * - */ - public function enableStatCache() - { - $this->use_stat_cache = true; - } - - /** - * Clear the stat cache - * - */ - public function clearStatCache() - { - $this->stat_cache = []; - } - - /** - * Enable path canonicalization - * - */ - public function enablePathCanonicalization() - { - $this->canonicalize_paths = true; - } - - /** - * Disable path canonicalization - * - * If this is enabled then $sftp->pwd() will not return the canonicalized absolute path - * - */ - public function disablePathCanonicalization() - { - $this->canonicalize_paths = false; - } - - /** - * Enable arbitrary length packets - * - */ - public function enableArbitraryLengthPackets() - { - $this->allow_arbitrary_length_packets = true; - } - - /** - * Disable arbitrary length packets - * - */ - public function disableArbitraryLengthPackets() - { - $this->allow_arbitrary_length_packets = false; - } - - /** - * Returns the current directory name - * - * @return string|bool - */ - public function pwd() - { - if (!$this->precheck()) { - return false; - } - - return $this->pwd; - } - - /** - * Logs errors - * - * @param string $response - * @param int $status - */ - private function logError($response, $status = -1) - { - if ($status == -1) { - list($status) = Strings::unpackSSH2('N', $response); - } - - $error = self::$status_codes[$status]; - - if ($this->version > 2) { - list($message) = Strings::unpackSSH2('s', $response); - $this->sftp_errors[] = "$error: $message"; - } else { - $this->sftp_errors[] = $error; - } - } - - /** - * Canonicalize the Server-Side Path Name - * - * SFTP doesn't provide a mechanism by which the current working directory can be changed, so we'll emulate it. Returns - * the absolute (canonicalized) path. - * - * If canonicalize_paths has been disabled using disablePathCanonicalization(), $path is returned as-is. - * - * @see self::chdir() - * @see self::disablePathCanonicalization() - * @param string $path - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return mixed - */ - public function realpath($path) - { - if ($this->precheck() === false) { - return false; - } - - if (!$this->canonicalize_paths) { - if ($this->pwd === true) { - return '.'; - } - if (!strlen($path) || $path[0] != '/') { - $path = $this->pwd . '/' . $path; - } - $parts = explode('/', $path); - $afterPWD = $beforePWD = []; - foreach ($parts as $part) { - switch ($part) { - //case '': // some SFTP servers /require/ double /'s. see https://github.com/phpseclib/phpseclib/pull/1137 - case '.': - break; - case '..': - if (!empty($afterPWD)) { - array_pop($afterPWD); - } else { - $beforePWD[] = '..'; - } - break; - default: - $afterPWD[] = $part; - } - } - $beforePWD = count($beforePWD) ? implode('/', $beforePWD) : '.'; - return $beforePWD . '/' . implode('/', $afterPWD); - } - - if ($this->pwd === true) { - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.9 - $this->send_sftp_packet(NET_SFTP_REALPATH, Strings::packSSH2('s', $path)); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_NAME: - // although SSH_FXP_NAME is implemented differently in SFTPv3 than it is in SFTPv4+, the following - // should work on all SFTP versions since the only part of the SSH_FXP_NAME packet the following looks - // at is the first part and that part is defined the same in SFTP versions 3 through 6. - list(, $filename) = Strings::unpackSSH2('Ns', $response); - return $filename; - case NET_SFTP_STATUS: - $this->logError($response); - return false; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - } - - if (!strlen($path) || $path[0] != '/') { - $path = $this->pwd . '/' . $path; - } - - $path = explode('/', $path); - $new = []; - foreach ($path as $dir) { - if (!strlen($dir)) { - continue; - } - switch ($dir) { - case '..': - array_pop($new); - // fall-through - case '.': - break; - default: - $new[] = $dir; - } - } - - return '/' . implode('/', $new); - } - - /** - * Changes the current directory - * - * @param string $dir - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return bool - */ - public function chdir($dir) - { - if (!$this->precheck()) { - return false; - } - - // assume current dir if $dir is empty - if ($dir === '') { - $dir = './'; - // suffix a slash if needed - } elseif ($dir[strlen($dir) - 1] != '/') { - $dir .= '/'; - } - - $dir = $this->realpath($dir); - - // confirm that $dir is, in fact, a valid directory - if ($this->use_stat_cache && is_array($this->query_stat_cache($dir))) { - $this->pwd = $dir; - return true; - } - - // we could do a stat on the alleged $dir to see if it's a directory but that doesn't tell us - // the currently logged in user has the appropriate permissions or not. maybe you could see if - // the file's uid / gid match the currently logged in user's uid / gid but how there's no easy - // way to get those with SFTP - - $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); - - // see \phpseclib3\Net\SFTP::nlist() for a more thorough explanation of the following - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - $handle = substr($response, 4); - break; - case NET_SFTP_STATUS: - $this->logError($response); - return false; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS' . - 'Got packet type: ' . $this->packet_type); - } - - if (!$this->close_handle($handle)) { - return false; - } - - $this->update_stat_cache($dir, []); - - $this->pwd = $dir; - return true; - } - - /** - * Returns a list of files in the given directory - * - * @param string $dir - * @param bool $recursive - * @return array|false - */ - public function nlist($dir = '.', $recursive = false) - { - return $this->nlist_helper($dir, $recursive, ''); - } - - /** - * Helper method for nlist - * - * @param string $dir - * @param bool $recursive - * @param string $relativeDir - * @return array|false - */ - private function nlist_helper($dir, $recursive, $relativeDir) - { - $files = $this->readlist($dir, false); - - // If we get an int back, then that is an "unexpected" status. - // We do not have a file list, so return false. - if (is_int($files)) { - return false; - } - - if (!$recursive || $files === false) { - return $files; - } - - $result = []; - foreach ($files as $value) { - if ($value == '.' || $value == '..') { - $result[] = $relativeDir . $value; - continue; - } - if (is_array($this->query_stat_cache($this->realpath($dir . '/' . $value)))) { - $temp = $this->nlist_helper($dir . '/' . $value, true, $relativeDir . $value . '/'); - $temp = is_array($temp) ? $temp : []; - $result = array_merge($result, $temp); - } else { - $result[] = $relativeDir . $value; - } - } - - return $result; - } - - /** - * Returns a detailed list of files in the given directory - * - * @param string $dir - * @param bool $recursive - * @return array|false - */ - public function rawlist($dir = '.', $recursive = false) - { - $files = $this->readlist($dir, true); - - // If we get an int back, then that is an "unexpected" status. - // We do not have a file list, so return false. - if (is_int($files)) { - return false; - } - - if (!$recursive || $files === false) { - return $files; - } - - static $depth = 0; - - foreach ($files as $key => $value) { - if ($depth != 0 && $key == '..') { - unset($files[$key]); - continue; - } - $is_directory = false; - if ($key != '.' && $key != '..') { - if ($this->use_stat_cache) { - $is_directory = is_array($this->query_stat_cache($this->realpath($dir . '/' . $key))); - } else { - $stat = $this->lstat($dir . '/' . $key); - $is_directory = $stat && $stat['type'] === NET_SFTP_TYPE_DIRECTORY; - } - } - - if ($is_directory) { - $depth++; - $files[$key] = $this->rawlist($dir . '/' . $key, true); - $depth--; - } else { - $files[$key] = (object) $value; - } - } - - return $files; - } - - /** - * Reads a list, be it detailed or not, of files in the given directory - * - * @param string $dir - * @param bool $raw - * @return array|false - * @throws \UnexpectedValueException on receipt of unexpected packets - */ - private function readlist($dir, $raw = true) - { - if (!$this->precheck()) { - return false; - } - - $dir = $this->realpath($dir . '/'); - if ($dir === false) { - return false; - } - - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.2 - $this->send_sftp_packet(NET_SFTP_OPENDIR, Strings::packSSH2('s', $dir)); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-9.2 - // since 'handle' is the last field in the SSH_FXP_HANDLE packet, we'll just remove the first four bytes that - // represent the length of the string and leave it at that - $handle = substr($response, 4); - break; - case NET_SFTP_STATUS: - // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - list($status) = Strings::unpackSSH2('N', $response); - $this->logError($response, $status); - return $status; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - $this->update_stat_cache($dir, []); - - $contents = []; - while (true) { - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.2 - // why multiple SSH_FXP_READDIR packets would be sent when the response to a single one can span arbitrarily many - // SSH_MSG_CHANNEL_DATA messages is not known to me. - $this->send_sftp_packet(NET_SFTP_READDIR, Strings::packSSH2('s', $handle)); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_NAME: - list($count) = Strings::unpackSSH2('N', $response); - for ($i = 0; $i < $count; $i++) { - list($shortname) = Strings::unpackSSH2('s', $response); - // SFTPv4 "removed the long filename from the names structure-- it can now be - // built from information available in the attrs structure." - if ($this->version < 4) { - list($longname) = Strings::unpackSSH2('s', $response); - } - $attributes = $this->parseAttributes($response); - if (!isset($attributes['type']) && $this->version < 4) { - $fileType = $this->parseLongname($longname); - if ($fileType) { - $attributes['type'] = $fileType; - } - } - $contents[$shortname] = $attributes + ['filename' => $shortname]; - - if (isset($attributes['type']) && $attributes['type'] == NET_SFTP_TYPE_DIRECTORY && ($shortname != '.' && $shortname != '..')) { - $this->update_stat_cache($dir . '/' . $shortname, []); - } else { - if ($shortname == '..') { - $temp = $this->realpath($dir . '/..') . '/.'; - } else { - $temp = $dir . '/' . $shortname; - } - $this->update_stat_cache($temp, (object) ['lstat' => $attributes]); - } - // SFTPv6 has an optional boolean end-of-list field, but we'll ignore that, since the - // final SSH_FXP_STATUS packet should tell us that, already. - } - break; - case NET_SFTP_STATUS: - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_EOF) { - $this->logError($response, $status); - return $status; - } - break 2; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - } - - if (!$this->close_handle($handle)) { - return false; - } - - if (count($this->sortOptions)) { - uasort($contents, [&$this, 'comparator']); - } - - return $raw ? $contents : array_map('strval', array_keys($contents)); - } - - /** - * Compares two rawlist entries using parameters set by setListOrder() - * - * Intended for use with uasort() - * - * @param array $a - * @param array $b - * @return int - */ - private function comparator(array $a, array $b) - { - switch (true) { - case $a['filename'] === '.' || $b['filename'] === '.': - if ($a['filename'] === $b['filename']) { - return 0; - } - return $a['filename'] === '.' ? -1 : 1; - case $a['filename'] === '..' || $b['filename'] === '..': - if ($a['filename'] === $b['filename']) { - return 0; - } - return $a['filename'] === '..' ? -1 : 1; - case isset($a['type']) && $a['type'] === NET_SFTP_TYPE_DIRECTORY: - if (!isset($b['type'])) { - return 1; - } - if ($b['type'] !== $a['type']) { - return -1; - } - break; - case isset($b['type']) && $b['type'] === NET_SFTP_TYPE_DIRECTORY: - return 1; - } - foreach ($this->sortOptions as $sort => $order) { - if (!isset($a[$sort]) || !isset($b[$sort])) { - if (isset($a[$sort])) { - return -1; - } - if (isset($b[$sort])) { - return 1; - } - return 0; - } - switch ($sort) { - case 'filename': - $result = strcasecmp($a['filename'], $b['filename']); - if ($result) { - return $order === SORT_DESC ? -$result : $result; - } - break; - case 'mode': - $a[$sort] &= 07777; - $b[$sort] &= 07777; - // fall-through - default: - if ($a[$sort] === $b[$sort]) { - break; - } - return $order === SORT_ASC ? $a[$sort] - $b[$sort] : $b[$sort] - $a[$sort]; - } - } - } - - /** - * Defines how nlist() and rawlist() will be sorted - if at all. - * - * If sorting is enabled directories and files will be sorted independently with - * directories appearing before files in the resultant array that is returned. - * - * Any parameter returned by stat is a valid sort parameter for this function. - * Filename comparisons are case insensitive. - * - * Examples: - * - * $sftp->setListOrder('filename', SORT_ASC); - * $sftp->setListOrder('size', SORT_DESC, 'filename', SORT_ASC); - * $sftp->setListOrder(true); - * Separates directories from files but doesn't do any sorting beyond that - * $sftp->setListOrder(); - * Don't do any sort of sorting - * - * @param string ...$args - */ - public function setListOrder(...$args) - { - $this->sortOptions = []; - if (empty($args)) { - return; - } - $len = count($args) & 0x7FFFFFFE; - for ($i = 0; $i < $len; $i += 2) { - $this->sortOptions[$args[$i]] = $args[$i + 1]; - } - if (!count($this->sortOptions)) { - $this->sortOptions = ['bogus' => true]; - } - } - - /** - * Save files / directories to cache - * - * @param string $path - * @param mixed $value - */ - private function update_stat_cache($path, $value) - { - if ($this->use_stat_cache === false) { - return; - } - - // preg_replace('#^/|/(?=/)|/$#', '', $dir) == str_replace('//', '/', trim($path, '/')) - $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); - - $temp = &$this->stat_cache; - $max = count($dirs) - 1; - foreach ($dirs as $i => $dir) { - // if $temp is an object that means one of two things. - // 1. a file was deleted and changed to a directory behind phpseclib's back - // 2. it's a symlink. when lstat is done it's unclear what it's a symlink to - if (is_object($temp)) { - $temp = []; - } - if (!isset($temp[$dir])) { - $temp[$dir] = []; - } - if ($i === $max) { - if (is_object($temp[$dir]) && is_object($value)) { - if (!isset($value->stat) && isset($temp[$dir]->stat)) { - $value->stat = $temp[$dir]->stat; - } - if (!isset($value->lstat) && isset($temp[$dir]->lstat)) { - $value->lstat = $temp[$dir]->lstat; - } - } - $temp[$dir] = $value; - break; - } - $temp = &$temp[$dir]; - } - } - - /** - * Remove files / directories from cache - * - * @param string $path - * @return bool - */ - private function remove_from_stat_cache($path) - { - $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); - - $temp = &$this->stat_cache; - $max = count($dirs) - 1; - foreach ($dirs as $i => $dir) { - if (!is_array($temp)) { - return false; - } - if ($i === $max) { - unset($temp[$dir]); - return true; - } - if (!isset($temp[$dir])) { - return false; - } - $temp = &$temp[$dir]; - } - } - - /** - * Checks cache for path - * - * Mainly used by file_exists - * - * @param string $path - * @return mixed - */ - private function query_stat_cache($path) - { - $dirs = explode('/', preg_replace('#^/|/(?=/)|/$#', '', $path)); - - $temp = &$this->stat_cache; - foreach ($dirs as $dir) { - if (!is_array($temp)) { - return null; - } - if (!isset($temp[$dir])) { - return null; - } - $temp = &$temp[$dir]; - } - return $temp; - } - - /** - * Returns general information about a file. - * - * Returns an array on success and false otherwise. - * - * @param string $filename - * @return array|false - */ - public function stat($filename) - { - if (!$this->precheck()) { - return false; - } - - $filename = $this->realpath($filename); - if ($filename === false) { - return false; - } - - if ($this->use_stat_cache) { - $result = $this->query_stat_cache($filename); - if (is_array($result) && isset($result['.']) && isset($result['.']->stat)) { - return $result['.']->stat; - } - if (is_object($result) && isset($result->stat)) { - return $result->stat; - } - } - - $stat = $this->stat_helper($filename, NET_SFTP_STAT); - if ($stat === false) { - $this->remove_from_stat_cache($filename); - return false; - } - if (isset($stat['type'])) { - if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename .= '/.'; - } - $this->update_stat_cache($filename, (object) ['stat' => $stat]); - return $stat; - } - - $pwd = $this->pwd; - $stat['type'] = $this->chdir($filename) ? - NET_SFTP_TYPE_DIRECTORY : - NET_SFTP_TYPE_REGULAR; - $this->pwd = $pwd; - - if ($stat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename .= '/.'; - } - $this->update_stat_cache($filename, (object) ['stat' => $stat]); - - return $stat; - } - - /** - * Returns general information about a file or symbolic link. - * - * Returns an array on success and false otherwise. - * - * @param string $filename - * @return array|false - */ - public function lstat($filename) - { - if (!$this->precheck()) { - return false; - } - - $filename = $this->realpath($filename); - if ($filename === false) { - return false; - } - - if ($this->use_stat_cache) { - $result = $this->query_stat_cache($filename); - if (is_array($result) && isset($result['.']) && isset($result['.']->lstat)) { - return $result['.']->lstat; - } - if (is_object($result) && isset($result->lstat)) { - return $result->lstat; - } - } - - $lstat = $this->stat_helper($filename, NET_SFTP_LSTAT); - if ($lstat === false) { - $this->remove_from_stat_cache($filename); - return false; - } - if (isset($lstat['type'])) { - if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename .= '/.'; - } - $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); - return $lstat; - } - - $stat = $this->stat_helper($filename, NET_SFTP_STAT); - - if ($lstat != $stat) { - $lstat = array_merge($lstat, ['type' => NET_SFTP_TYPE_SYMLINK]); - $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); - return $stat; - } - - $pwd = $this->pwd; - $lstat['type'] = $this->chdir($filename) ? - NET_SFTP_TYPE_DIRECTORY : - NET_SFTP_TYPE_REGULAR; - $this->pwd = $pwd; - - if ($lstat['type'] == NET_SFTP_TYPE_DIRECTORY) { - $filename .= '/.'; - } - $this->update_stat_cache($filename, (object) ['lstat' => $lstat]); - - return $lstat; - } - - /** - * Returns general information about a file or symbolic link - * - * Determines information without calling \phpseclib3\Net\SFTP::realpath(). - * The second parameter can be either NET_SFTP_STAT or NET_SFTP_LSTAT. - * - * @param string $filename - * @param int $type - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return array|false - */ - private function stat_helper($filename, $type) - { - // SFTPv4+ adds an additional 32-bit integer field - flags - to the following: - $packet = Strings::packSSH2('s', $filename); - $this->send_sftp_packet($type, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_ATTRS: - return $this->parseAttributes($response); - case NET_SFTP_STATUS: - $this->logError($response); - return false; - } - - throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - /** - * Truncates a file to a given length - * - * @param string $filename - * @param int $new_size - * @return bool - */ - public function truncate($filename, $new_size) - { - $attr = Strings::packSSH2('NQ', NET_SFTP_ATTR_SIZE, $new_size); - - return $this->setstat($filename, $attr, false); - } - - /** - * Sets access and modification time of file. - * - * If the file does not exist, it will be created. - * - * @param string $filename - * @param int $time - * @param int $atime - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return bool - */ - public function touch($filename, $time = null, $atime = null) - { - if (!$this->precheck()) { - return false; - } - - $filename = $this->realpath($filename); - if ($filename === false) { - return false; - } - - if (!isset($time)) { - $time = time(); - } - if (!isset($atime)) { - $atime = $time; - } - - $attr = $this->version < 4 ? - pack('N3', NET_SFTP_ATTR_ACCESSTIME, $atime, $time) : - Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $atime, $time); - - $packet = Strings::packSSH2('s', $filename); - $packet .= $this->version >= 5 ? - pack('N2', 0, NET_SFTP_OPEN_OPEN_EXISTING) : - pack('N', NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE | NET_SFTP_OPEN_EXCL); - $packet .= $attr; - - $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - return $this->close_handle(substr($response, 4)); - case NET_SFTP_STATUS: - $this->logError($response); - break; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - return $this->setstat($filename, $attr, false); - } - - /** - * Changes file or directory owner - * - * $uid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string - * would be of the form "user@dns_domain" but it does not need to be. - * `$sftp->getSupportedVersions()['version']` will return the specific version - * that's being used. - * - * Returns true on success or false on error. - * - * @param string $filename - * @param int|string $uid - * @param bool $recursive - * @return bool - */ - public function chown($filename, $uid, $recursive = false) - { - /* - quoting , - - "To avoid a representation that is tied to a particular underlying - implementation at the client or server, the use of UTF-8 strings has - been chosen. The string should be of the form "user@dns_domain". - This will allow for a client and server that do not use the same - local representation the ability to translate to a common syntax that - can be interpreted by both. In the case where there is no - translation available to the client or server, the attribute value - must be constructed without the "@"." - - phpseclib _could_ auto append the dns_domain to $uid BUT what if it shouldn't - have one? phpseclib would have no way of knowing so rather than guess phpseclib - will just use whatever value the user provided - */ - - $attr = $this->version < 4 ? - // quoting , - // "if the owner or group is specified as -1, then that ID is not changed" - pack('N3', NET_SFTP_ATTR_UIDGID, $uid, -1) : - // quoting , - // "If either the owner or group field is zero length, the field should be - // considered absent, and no change should be made to that specific field - // during a modification operation" - Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, $uid, ''); - - return $this->setstat($filename, $attr, $recursive); - } - - /** - * Changes file or directory group - * - * $gid should be an int for SFTPv3 and a string for SFTPv4+. Ideally the string - * would be of the form "user@dns_domain" but it does not need to be. - * `$sftp->getSupportedVersions()['version']` will return the specific version - * that's being used. - * - * Returns true on success or false on error. - * - * @param string $filename - * @param int|string $gid - * @param bool $recursive - * @return bool - */ - public function chgrp($filename, $gid, $recursive = false) - { - $attr = $this->version < 4 ? - pack('N3', NET_SFTP_ATTR_UIDGID, -1, $gid) : - Strings::packSSH2('Nss', NET_SFTP_ATTR_OWNERGROUP, '', $gid); - - return $this->setstat($filename, $attr, $recursive); - } - - /** - * Set permissions on a file. - * - * Returns the new file permissions on success or false on error. - * If $recursive is true than this just returns true or false. - * - * @param int $mode - * @param string $filename - * @param bool $recursive - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return mixed - */ - public function chmod($mode, $filename, $recursive = false) - { - if (is_string($mode) && is_int($filename)) { - $temp = $mode; - $mode = $filename; - $filename = $temp; - } - - $attr = pack('N2', NET_SFTP_ATTR_PERMISSIONS, $mode & 07777); - if (!$this->setstat($filename, $attr, $recursive)) { - return false; - } - if ($recursive) { - return true; - } - - $filename = $this->realpath($filename); - // rather than return what the permissions *should* be, we'll return what they actually are. this will also - // tell us if the file actually exists. - // incidentally, SFTPv4+ adds an additional 32-bit integer field - flags - to the following: - $packet = pack('Na*', strlen($filename), $filename); - $this->send_sftp_packet(NET_SFTP_STAT, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_ATTRS: - $attrs = $this->parseAttributes($response); - return $attrs['mode']; - case NET_SFTP_STATUS: - $this->logError($response); - return false; - } - - throw new \UnexpectedValueException('Expected NET_SFTP_ATTRS or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - /** - * Sets information about a file - * - * @param string $filename - * @param string $attr - * @param bool $recursive - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return bool - */ - private function setstat($filename, $attr, $recursive) - { - if (!$this->precheck()) { - return false; - } - - $filename = $this->realpath($filename); - if ($filename === false) { - return false; - } - - $this->remove_from_stat_cache($filename); - - if ($recursive) { - $i = 0; - $result = $this->setstat_recursive($filename, $attr, $i); - $this->read_put_responses($i); - return $result; - } - - $packet = Strings::packSSH2('s', $filename); - $packet .= $this->version >= 4 ? - pack('a*Ca*', substr($attr, 0, 4), NET_SFTP_TYPE_UNKNOWN, substr($attr, 4)) : - $attr; - $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); - - /* - "Because some systems must use separate system calls to set various attributes, it is possible that a failure - response will be returned, but yet some of the attributes may be have been successfully modified. If possible, - servers SHOULD avoid this situation; however, clients MUST be aware that this is possible." - - -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.6 - */ - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - return false; - } - - return true; - } - - /** - * Recursively sets information on directories on the SFTP server - * - * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. - * - * @param string $path - * @param string $attr - * @param int $i - * @return bool - */ - private function setstat_recursive($path, $attr, &$i) - { - if (!$this->read_put_responses($i)) { - return false; - } - $i = 0; - $entries = $this->readlist($path, true); - - if ($entries === false || is_int($entries)) { - return $this->setstat($path, $attr, false); - } - - // normally $entries would have at least . and .. but it might not if the directories - // permissions didn't allow reading - if (empty($entries)) { - return false; - } - - unset($entries['.'], $entries['..']); - foreach ($entries as $filename => $props) { - if (!isset($props['type'])) { - return false; - } - - $temp = $path . '/' . $filename; - if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { - if (!$this->setstat_recursive($temp, $attr, $i)) { - return false; - } - } else { - $packet = Strings::packSSH2('s', $temp); - $packet .= $this->version >= 4 ? - pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : - $attr; - $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); - - $i++; - - if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { - return false; - } - $i = 0; - } - } - } - - $packet = Strings::packSSH2('s', $path); - $packet .= $this->version >= 4 ? - pack('Ca*', NET_SFTP_TYPE_UNKNOWN, $attr) : - $attr; - $this->send_sftp_packet(NET_SFTP_SETSTAT, $packet); - - $i++; - - if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { - return false; - } - $i = 0; - } - - return true; - } - - /** - * Return the target of a symbolic link - * - * @param string $link - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return mixed - */ - public function readlink($link) - { - if (!$this->precheck()) { - return false; - } - - $link = $this->realpath($link); - - $this->send_sftp_packet(NET_SFTP_READLINK, Strings::packSSH2('s', $link)); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_NAME: - break; - case NET_SFTP_STATUS: - $this->logError($response); - return false; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_NAME or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($count) = Strings::unpackSSH2('N', $response); - // the file isn't a symlink - if (!$count) { - return false; - } - - list($filename) = Strings::unpackSSH2('s', $response); - - return $filename; - } - - /** - * Create a symlink - * - * symlink() creates a symbolic link to the existing target with the specified name link. - * - * @param string $target - * @param string $link - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return bool - */ - public function symlink($target, $link) - { - if (!$this->precheck()) { - return false; - } - - //$target = $this->realpath($target); - $link = $this->realpath($link); - - /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-09#section-12.1 : - - Changed the SYMLINK packet to be LINK and give it the ability to - create hard links. Also change it's packet number because many - implementation implemented SYMLINK with the arguments reversed. - Hopefully the new argument names make it clear which way is which. - */ - if ($this->version == 6) { - $type = NET_SFTP_LINK; - $packet = Strings::packSSH2('ssC', $link, $target, 1); - } else { - $type = NET_SFTP_SYMLINK; - /* quoting http://bxr.su/OpenBSD/usr.bin/ssh/PROTOCOL#347 : - - 3.1. sftp: Reversal of arguments to SSH_FXP_SYMLINK - - When OpenSSH's sftp-server was implemented, the order of the arguments - to the SSH_FXP_SYMLINK method was inadvertently reversed. Unfortunately, - the reversal was not noticed until the server was widely deployed. Since - fixing this to follow the specification would cause incompatibility, the - current order was retained. For correct operation, clients should send - SSH_FXP_SYMLINK as follows: - - uint32 id - string targetpath - string linkpath */ - $packet = substr($this->server_identifier, 0, 15) == 'SSH-2.0-OpenSSH' ? - Strings::packSSH2('ss', $target, $link) : - Strings::packSSH2('ss', $link, $target); - } - $this->send_sftp_packet($type, $packet); - - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - return false; - } - - return true; - } - - /** - * Creates a directory. - * - * @param string $dir - * @param int $mode - * @param bool $recursive - * @return bool - */ - public function mkdir($dir, $mode = -1, $recursive = false) - { - if (!$this->precheck()) { - return false; - } - - $dir = $this->realpath($dir); - - if ($recursive) { - $dirs = explode('/', preg_replace('#/(?=/)|/$#', '', $dir)); - if (empty($dirs[0])) { - array_shift($dirs); - $dirs[0] = '/' . $dirs[0]; - } - for ($i = 0; $i < count($dirs); $i++) { - $temp = array_slice($dirs, 0, $i + 1); - $temp = implode('/', $temp); - $result = $this->mkdir_helper($temp, $mode); - } - return $result; - } - - return $this->mkdir_helper($dir, $mode); - } - - /** - * Helper function for directory creation - * - * @param string $dir - * @param int $mode - * @return bool - */ - private function mkdir_helper($dir, $mode) - { - // send SSH_FXP_MKDIR without any attributes (that's what the \0\0\0\0 is doing) - $this->send_sftp_packet(NET_SFTP_MKDIR, Strings::packSSH2('s', $dir) . "\0\0\0\0"); - - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - return false; - } - - if ($mode !== -1) { - $this->chmod($mode, $dir); - } - - return true; - } - - /** - * Removes a directory. - * - * @param string $dir - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return bool - */ - public function rmdir($dir) - { - if (!$this->precheck()) { - return false; - } - - $dir = $this->realpath($dir); - if ($dir === false) { - return false; - } - - $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $dir)); - - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED? - $this->logError($response, $status); - return false; - } - - $this->remove_from_stat_cache($dir); - // the following will do a soft delete, which would be useful if you deleted a file - // and then tried to do a stat on the deleted file. the above, in contrast, does - // a hard delete - //$this->update_stat_cache($dir, false); - - return true; - } - - /** - * Uploads a file to the SFTP server. - * - * By default, \phpseclib3\Net\SFTP::put() does not read from the local filesystem. $data is dumped directly into $remote_file. - * So, for example, if you set $data to 'filename.ext' and then do \phpseclib3\Net\SFTP::get(), you will get a file, twelve bytes - * long, containing 'filename.ext' as its contents. - * - * Setting $mode to self::SOURCE_LOCAL_FILE will change the above behavior. With self::SOURCE_LOCAL_FILE, $remote_file will - * contain as many bytes as filename.ext does on your local filesystem. If your filename.ext is 1MB then that is how - * large $remote_file will be, as well. - * - * Setting $mode to self::SOURCE_CALLBACK will use $data as callback function, which gets only one parameter -- number - * of bytes to return, and returns a string if there is some data or null if there is no more data - * - * If $data is a resource then it'll be used as a resource instead. - * - * Currently, only binary mode is supported. As such, if the line endings need to be adjusted, you will need to take - * care of that, yourself. - * - * $mode can take an additional two parameters - self::RESUME and self::RESUME_START. These are bitwise AND'd with - * $mode. So if you want to resume upload of a 300mb file on the local file system you'd set $mode to the following: - * - * self::SOURCE_LOCAL_FILE | self::RESUME - * - * If you wanted to simply append the full contents of a local file to the full contents of a remote file you'd replace - * self::RESUME with self::RESUME_START. - * - * If $mode & (self::RESUME | self::RESUME_START) then self::RESUME_START will be assumed. - * - * $start and $local_start give you more fine grained control over this process and take precident over self::RESUME - * when they're non-negative. ie. $start could let you write at the end of a file (like self::RESUME) or in the middle - * of one. $local_start could let you start your reading from the end of a file (like self::RESUME_START) or in the - * middle of one. - * - * Setting $local_start to > 0 or $mode | self::RESUME_START doesn't do anything unless $mode | self::SOURCE_LOCAL_FILE. - * - * {@internal ASCII mode for SFTPv4/5/6 can be supported by adding a new function - \phpseclib3\Net\SFTP::setMode().} - * - * @param string $remote_file - * @param string|resource $data - * @param int $mode - * @param int $start - * @param int $local_start - * @param callable|null $progressCallback - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \BadFunctionCallException if you're uploading via a callback and the callback function is invalid - * @throws \phpseclib3\Exception\FileNotFoundException if you're uploading via a file and the file doesn't exist - * @return bool - */ - public function put($remote_file, $data, $mode = self::SOURCE_STRING, $start = -1, $local_start = -1, $progressCallback = null) - { - if (!$this->precheck()) { - return false; - } - - $remote_file = $this->realpath($remote_file); - if ($remote_file === false) { - return false; - } - - $this->remove_from_stat_cache($remote_file); - - if ($this->version >= 5) { - $flags = NET_SFTP_OPEN_OPEN_OR_CREATE; - } else { - $flags = NET_SFTP_OPEN_WRITE | NET_SFTP_OPEN_CREATE; - // according to the SFTP specs, NET_SFTP_OPEN_APPEND should "force all writes to append data at the end of the file." - // in practice, it doesn't seem to do that. - //$flags|= ($mode & self::RESUME) ? NET_SFTP_OPEN_APPEND : NET_SFTP_OPEN_TRUNCATE; - } - - if ($start >= 0) { - $offset = $start; - } elseif ($mode & (self::RESUME | self::RESUME_START)) { - // if NET_SFTP_OPEN_APPEND worked as it should _size() wouldn't need to be called - $size = $this->stat($remote_file)['size']; - $offset = $size !== false ? $size : 0; - } else { - $offset = 0; - if ($this->version >= 5) { - $flags = NET_SFTP_OPEN_CREATE_TRUNCATE; - } else { - $flags |= NET_SFTP_OPEN_TRUNCATE; - } - } - - $this->remove_from_stat_cache($remote_file); - - $packet = Strings::packSSH2('s', $remote_file); - $packet .= $this->version >= 5 ? - pack('N3', 0, $flags, 0) : - pack('N2', $flags, 0); - $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - $handle = substr($response, 4); - break; - case NET_SFTP_STATUS: - $this->logError($response); - return false; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.2.3 - $dataCallback = false; - switch (true) { - case $mode & self::SOURCE_CALLBACK: - if (!is_callable($data)) { - throw new \BadFunctionCallException("\$data should be is_callable() if you specify SOURCE_CALLBACK flag"); - } - $dataCallback = $data; - // do nothing - break; - case is_resource($data): - $mode = $mode & ~self::SOURCE_LOCAL_FILE; - $info = stream_get_meta_data($data); - if (isset($info['wrapper_type']) && $info['wrapper_type'] == 'PHP' && $info['stream_type'] == 'Input') { - $fp = fopen('php://memory', 'w+'); - stream_copy_to_stream($data, $fp); - rewind($fp); - } else { - $fp = $data; - } - break; - case $mode & self::SOURCE_LOCAL_FILE: - if (!is_file($data)) { - throw new FileNotFoundException("$data is not a valid file"); - } - $fp = @fopen($data, 'rb'); - if (!$fp) { - return false; - } - } - - if (isset($fp)) { - $stat = fstat($fp); - $size = !empty($stat) ? $stat['size'] : 0; - - if ($local_start >= 0) { - fseek($fp, $local_start); - $size -= $local_start; - } elseif ($mode & self::RESUME) { - fseek($fp, $offset); - $size -= $offset; - } - } elseif ($dataCallback) { - $size = 0; - } else { - $size = strlen($data); - } - - $sent = 0; - $size = $size < 0 ? ($size & 0x7FFFFFFF) + 0x80000000 : $size; - - $sftp_packet_size = $this->max_sftp_packet; - // make the SFTP packet be exactly the SFTP packet size by including the bytes in the NET_SFTP_WRITE packets "header" - $sftp_packet_size -= strlen($handle) + 25; - $i = $j = 0; - while ($dataCallback || ($size === 0 || $sent < $size)) { - if ($dataCallback) { - $temp = $dataCallback($sftp_packet_size); - if (is_null($temp)) { - break; - } - } else { - $temp = isset($fp) ? fread($fp, $sftp_packet_size) : substr($data, $sent, $sftp_packet_size); - if ($temp === false || $temp === '') { - break; - } - } - - $subtemp = $offset + $sent; - $packet = pack('Na*N3a*', strlen($handle), $handle, $subtemp / 4294967296, $subtemp, strlen($temp), $temp); - try { - $this->send_sftp_packet(NET_SFTP_WRITE, $packet, $j); - } catch (\Exception $e) { - if ($mode & self::SOURCE_LOCAL_FILE) { - fclose($fp); - } - throw $e; - } - $sent += strlen($temp); - if (is_callable($progressCallback)) { - $progressCallback($sent); - } - - $i++; - $j++; - if ($i == NET_SFTP_UPLOAD_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { - $i = 0; - break; - } - $i = 0; - } - } - - $result = $this->close_handle($handle); - - if (!$this->read_put_responses($i)) { - if ($mode & self::SOURCE_LOCAL_FILE) { - fclose($fp); - } - $this->close_handle($handle); - return false; - } - - if ($mode & SFTP::SOURCE_LOCAL_FILE) { - if (isset($fp) && is_resource($fp)) { - fclose($fp); - } - - if ($this->preserveTime) { - $stat = stat($data); - $attr = $this->version < 4 ? - pack('N3', NET_SFTP_ATTR_ACCESSTIME, $stat['atime'], $stat['mtime']) : - Strings::packSSH2('NQ2', NET_SFTP_ATTR_ACCESSTIME | NET_SFTP_ATTR_MODIFYTIME, $stat['atime'], $stat['mtime']); - if (!$this->setstat($remote_file, $attr, false)) { - throw new \RuntimeException('Error setting file time'); - } - } - } - - return $result; - } - - /** - * Reads multiple successive SSH_FXP_WRITE responses - * - * Sending an SSH_FXP_WRITE packet and immediately reading its response isn't as efficient as blindly sending out $i - * SSH_FXP_WRITEs, in succession, and then reading $i responses. - * - * @param int $i - * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - */ - private function read_put_responses($i) - { - while ($i--) { - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - break; - } - } - - return $i < 0; - } - - /** - * Close handle - * - * @param string $handle - * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - */ - private function close_handle($handle) - { - $this->send_sftp_packet(NET_SFTP_CLOSE, pack('Na*', strlen($handle), $handle)); - - // "The client MUST release all resources associated with the handle regardless of the status." - // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.1.3 - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - return false; - } - - return true; - } - - /** - * Downloads a file from the SFTP server. - * - * Returns a string containing the contents of $remote_file if $local_file is left undefined or a boolean false if - * the operation was unsuccessful. If $local_file is defined, returns true or false depending on the success of the - * operation. - * - * $offset and $length can be used to download files in chunks. - * - * @param string $remote_file - * @param string|bool|resource|callable $local_file - * @param int $offset - * @param int $length - * @param callable|null $progressCallback - * @throws \UnexpectedValueException on receipt of unexpected packets - * @return string|bool - */ - public function get($remote_file, $local_file = false, $offset = 0, $length = -1, $progressCallback = null) - { - if (!$this->precheck()) { - return false; - } - - $remote_file = $this->realpath($remote_file); - if ($remote_file === false) { - return false; - } - - $packet = Strings::packSSH2('s', $remote_file); - $packet .= $this->version >= 5 ? - pack('N3', 0, NET_SFTP_OPEN_OPEN_EXISTING, 0) : - pack('N2', NET_SFTP_OPEN_READ, 0); - $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - $handle = substr($response, 4); - break; - case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - $this->logError($response); - return false; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - if (is_resource($local_file)) { - $fp = $local_file; - $stat = fstat($fp); - $res_offset = $stat['size']; - } else { - $res_offset = 0; - if ($local_file !== false && !is_callable($local_file)) { - $fp = fopen($local_file, 'wb'); - if (!$fp) { - return false; - } - } else { - $content = ''; - } - } - - $fclose_check = $local_file !== false && !is_callable($local_file) && !is_resource($local_file); - - $start = $offset; - $read = 0; - while (true) { - $i = 0; - - while ($i < NET_SFTP_QUEUE_SIZE && ($length < 0 || $read < $length)) { - $tempoffset = $start + $read; - - $packet_size = $length > 0 ? min($this->max_sftp_packet, $length - $read) : $this->max_sftp_packet; - - $packet = Strings::packSSH2('sN3', $handle, $tempoffset / 4294967296, $tempoffset, $packet_size); - try { - $this->send_sftp_packet(NET_SFTP_READ, $packet, $i); - } catch (\Exception $e) { - if ($fclose_check) { - fclose($fp); - } - throw $e; - } - $packet = null; - $read += $packet_size; - $i++; - } - - if (!$i) { - break; - } - - $packets_sent = $i - 1; - - $clear_responses = false; - while ($i > 0) { - $i--; - - if ($clear_responses) { - $this->get_sftp_packet($packets_sent - $i); - continue; - } else { - $response = $this->get_sftp_packet($packets_sent - $i); - } - - switch ($this->packet_type) { - case NET_SFTP_DATA: - $temp = substr($response, 4); - $offset += strlen($temp); - if ($local_file === false) { - $content .= $temp; - } elseif (is_callable($local_file)) { - $local_file($temp); - } else { - fputs($fp, $temp); - } - if (is_callable($progressCallback)) { - call_user_func($progressCallback, $offset); - } - $temp = null; - break; - case NET_SFTP_STATUS: - // could, in theory, return false if !strlen($content) but we'll hold off for the time being - $this->logError($response); - $clear_responses = true; // don't break out of the loop yet, so we can read the remaining responses - break; - default: - if ($fclose_check) { - fclose($fp); - } - if ($this->channel_close) { - $this->partial_init = false; - $this->init_sftp_connection(); - return false; - } else { - throw new \UnexpectedValueException('Expected NET_SFTP_DATA or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - } - $response = null; - } - - if ($clear_responses) { - break; - } - } - - if ($fclose_check) { - fclose($fp); - - if ($this->preserveTime) { - $stat = $this->stat($remote_file); - touch($local_file, $stat['mtime'], $stat['atime']); - } - } - - if (!$this->close_handle($handle)) { - return false; - } - - // if $content isn't set that means a file was written to - return isset($content) ? $content : true; - } - - /** - * Deletes a file on the SFTP server. - * - * @param string $path - * @param bool $recursive - * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - */ - public function delete($path, $recursive = true) - { - if (!$this->precheck()) { - return false; - } - - if (is_object($path)) { - // It's an object. Cast it as string before we check anything else. - $path = (string) $path; - } - - if (!is_string($path) || $path == '') { - return false; - } - - $path = $this->realpath($path); - if ($path === false) { - return false; - } - - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 - $this->send_sftp_packet(NET_SFTP_REMOVE, pack('Na*', strlen($path), $path)); - - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - if (!$recursive) { - return false; - } - - $i = 0; - $result = $this->delete_recursive($path, $i); - $this->read_put_responses($i); - return $result; - } - - $this->remove_from_stat_cache($path); - - return true; - } - - /** - * Recursively deletes directories on the SFTP server - * - * Minimizes directory lookups and SSH_FXP_STATUS requests for speed. - * - * @param string $path - * @param int $i - * @return bool - */ - private function delete_recursive($path, &$i) - { - if (!$this->read_put_responses($i)) { - return false; - } - $i = 0; - $entries = $this->readlist($path, true); - - // The folder does not exist at all, so we cannot delete it. - if ($entries === NET_SFTP_STATUS_NO_SUCH_FILE) { - return false; - } - - // Normally $entries would have at least . and .. but it might not if the directories - // permissions didn't allow reading. If this happens then default to an empty list of files. - if ($entries === false || is_int($entries)) { - $entries = []; - } - - unset($entries['.'], $entries['..']); - foreach ($entries as $filename => $props) { - if (!isset($props['type'])) { - return false; - } - - $temp = $path . '/' . $filename; - if ($props['type'] == NET_SFTP_TYPE_DIRECTORY) { - if (!$this->delete_recursive($temp, $i)) { - return false; - } - } else { - $this->send_sftp_packet(NET_SFTP_REMOVE, Strings::packSSH2('s', $temp)); - $this->remove_from_stat_cache($temp); - - $i++; - - if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { - return false; - } - $i = 0; - } - } - } - - $this->send_sftp_packet(NET_SFTP_RMDIR, Strings::packSSH2('s', $path)); - $this->remove_from_stat_cache($path); - - $i++; - - if ($i >= NET_SFTP_QUEUE_SIZE) { - if (!$this->read_put_responses($i)) { - return false; - } - $i = 0; - } - - return true; - } - - /** - * Checks whether a file or directory exists - * - * @param string $path - * @return bool - */ - public function file_exists($path) - { - if ($this->use_stat_cache) { - if (!$this->precheck()) { - return false; - } - - $path = $this->realpath($path); - - $result = $this->query_stat_cache($path); - - if (isset($result)) { - // return true if $result is an array or if it's an stdClass object - return $result !== false; - } - } - - return $this->stat($path) !== false; - } - - /** - * Tells whether the filename is a directory - * - * @param string $path - * @return bool - */ - public function is_dir($path) - { - $result = $this->get_stat_cache_prop($path, 'type'); - if ($result === false) { - return false; - } - return $result === NET_SFTP_TYPE_DIRECTORY; - } - - /** - * Tells whether the filename is a regular file - * - * @param string $path - * @return bool - */ - public function is_file($path) - { - $result = $this->get_stat_cache_prop($path, 'type'); - if ($result === false) { - return false; - } - return $result === NET_SFTP_TYPE_REGULAR; - } - - /** - * Tells whether the filename is a symbolic link - * - * @param string $path - * @return bool - */ - public function is_link($path) - { - $result = $this->get_lstat_cache_prop($path, 'type'); - if ($result === false) { - return false; - } - return $result === NET_SFTP_TYPE_SYMLINK; - } - - /** - * Tells whether a file exists and is readable - * - * @param string $path - * @return bool - */ - public function is_readable($path) - { - if (!$this->precheck()) { - return false; - } - - $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_READ, 0); - $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - return true; - case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - return false; - default: - throw new \UnexpectedValueException('Expected NET_SFTP_HANDLE or NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - } - - /** - * Tells whether the filename is writable - * - * @param string $path - * @return bool - */ - public function is_writable($path) - { - if (!$this->precheck()) { - return false; - } - - $packet = Strings::packSSH2('sNN', $this->realpath($path), NET_SFTP_OPEN_WRITE, 0); - $this->send_sftp_packet(NET_SFTP_OPEN, $packet); - - $response = $this->get_sftp_packet(); - switch ($this->packet_type) { - case NET_SFTP_HANDLE: - return true; - case NET_SFTP_STATUS: // presumably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - return false; - default: - throw new \UnexpectedValueException('Expected SSH_FXP_HANDLE or SSH_FXP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - } - - /** - * Tells whether the filename is writeable - * - * Alias of is_writable - * - * @param string $path - * @return bool - */ - public function is_writeable($path) - { - return $this->is_writable($path); - } - - /** - * Gets last access time of file - * - * @param string $path - * @return mixed - */ - public function fileatime($path) - { - return $this->get_stat_cache_prop($path, 'atime'); - } - - /** - * Gets file modification time - * - * @param string $path - * @return mixed - */ - public function filemtime($path) - { - return $this->get_stat_cache_prop($path, 'mtime'); - } - - /** - * Gets file permissions - * - * @param string $path - * @return mixed - */ - public function fileperms($path) - { - return $this->get_stat_cache_prop($path, 'mode'); - } - - /** - * Gets file owner - * - * @param string $path - * @return mixed - */ - public function fileowner($path) - { - return $this->get_stat_cache_prop($path, 'uid'); - } - - /** - * Gets file group - * - * @param string $path - * @return mixed - */ - public function filegroup($path) - { - return $this->get_stat_cache_prop($path, 'gid'); - } - - /** - * Recursively go through rawlist() output to get the total filesize - * - * @return int - */ - private static function recursiveFilesize(array $files) - { - $size = 0; - foreach ($files as $name => $file) { - if ($name == '.' || $name == '..') { - continue; - } - $size += is_array($file) ? - self::recursiveFilesize($file) : - $file->size; - } - return $size; - } - - /** - * Gets file size - * - * @param string $path - * @param bool $recursive - * @return mixed - */ - public function filesize($path, $recursive = false) - { - return !$recursive || $this->filetype($path) != 'dir' ? - $this->get_stat_cache_prop($path, 'size') : - self::recursiveFilesize($this->rawlist($path, true)); - } - - /** - * Gets file type - * - * @param string $path - * @return string|false - */ - public function filetype($path) - { - $type = $this->get_stat_cache_prop($path, 'type'); - if ($type === false) { - return false; - } - - switch ($type) { - case NET_SFTP_TYPE_BLOCK_DEVICE: - return 'block'; - case NET_SFTP_TYPE_CHAR_DEVICE: - return 'char'; - case NET_SFTP_TYPE_DIRECTORY: - return 'dir'; - case NET_SFTP_TYPE_FIFO: - return 'fifo'; - case NET_SFTP_TYPE_REGULAR: - return 'file'; - case NET_SFTP_TYPE_SYMLINK: - return 'link'; - default: - return false; - } - } - - /** - * Return a stat properity - * - * Uses cache if appropriate. - * - * @param string $path - * @param string $prop - * @return mixed - */ - private function get_stat_cache_prop($path, $prop) - { - return $this->get_xstat_cache_prop($path, $prop, 'stat'); - } - - /** - * Return an lstat properity - * - * Uses cache if appropriate. - * - * @param string $path - * @param string $prop - * @return mixed - */ - private function get_lstat_cache_prop($path, $prop) - { - return $this->get_xstat_cache_prop($path, $prop, 'lstat'); - } - - /** - * Return a stat or lstat properity - * - * Uses cache if appropriate. - * - * @param string $path - * @param string $prop - * @param string $type - * @return mixed - */ - private function get_xstat_cache_prop($path, $prop, $type) - { - if (!$this->precheck()) { - return false; - } - - if ($this->use_stat_cache) { - $path = $this->realpath($path); - - $result = $this->query_stat_cache($path); - - if (is_object($result) && isset($result->$type)) { - return $result->{$type}[$prop]; - } - } - - $result = $this->$type($path); - - if ($result === false || !isset($result[$prop])) { - return false; - } - - return $result[$prop]; - } - - /** - * Renames a file or a directory on the SFTP server. - * - * If the file already exists this will return false - * - * @param string $oldname - * @param string $newname - * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - */ - public function rename($oldname, $newname) - { - if (!$this->precheck()) { - return false; - } - - $oldname = $this->realpath($oldname); - $newname = $this->realpath($newname); - if ($oldname === false || $newname === false) { - return false; - } - - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#section-8.3 - $packet = Strings::packSSH2('ss', $oldname, $newname); - if ($this->version >= 5) { - /* quoting https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-6.5 , - - 'flags' is 0 or a combination of: - - SSH_FXP_RENAME_OVERWRITE 0x00000001 - SSH_FXP_RENAME_ATOMIC 0x00000002 - SSH_FXP_RENAME_NATIVE 0x00000004 - - (none of these are currently supported) */ - $packet .= "\0\0\0\0"; - } - $this->send_sftp_packet(NET_SFTP_RENAME, $packet); - - $response = $this->get_sftp_packet(); - if ($this->packet_type != NET_SFTP_STATUS) { - throw new \UnexpectedValueException('Expected NET_SFTP_STATUS. ' - . 'Got packet type: ' . $this->packet_type); - } - - // if $status isn't SSH_FX_OK it's probably SSH_FX_NO_SUCH_FILE or SSH_FX_PERMISSION_DENIED - list($status) = Strings::unpackSSH2('N', $response); - if ($status != NET_SFTP_STATUS_OK) { - $this->logError($response, $status); - return false; - } - - // don't move the stat cache entry over since this operation could very well change the - // atime and mtime attributes - //$this->update_stat_cache($newname, $this->query_stat_cache($oldname)); - $this->remove_from_stat_cache($oldname); - $this->remove_from_stat_cache($newname); - - return true; - } - - /** - * Parse Time - * - * See '7.7. Times' of draft-ietf-secsh-filexfer-13 for more info. - * - * @param string $key - * @param int $flags - * @param string $response - * @return array - */ - private function parseTime($key, $flags, &$response) - { - $attr = []; - list($attr[$key]) = Strings::unpackSSH2('Q', $response); - if ($flags & NET_SFTP_ATTR_SUBSECOND_TIMES) { - list($attr[$key . '-nseconds']) = Strings::unpackSSH2('N', $response); - } - return $attr; - } - - /** - * Parse Attributes - * - * See '7. File Attributes' of draft-ietf-secsh-filexfer-13 for more info. - * - * @param string $response - * @return array - */ - protected function parseAttributes(&$response) - { - if ($this->version >= 4) { - list($flags, $attr['type']) = Strings::unpackSSH2('NC', $response); - } else { - list($flags) = Strings::unpackSSH2('N', $response); - } - - foreach (self::$attributes as $key => $value) { - switch ($flags & $key) { - case NET_SFTP_ATTR_UIDGID: - if ($this->version > 3) { - continue 2; - } - break; - case NET_SFTP_ATTR_CREATETIME: - case NET_SFTP_ATTR_MODIFYTIME: - case NET_SFTP_ATTR_ACL: - case NET_SFTP_ATTR_OWNERGROUP: - case NET_SFTP_ATTR_SUBSECOND_TIMES: - if ($this->version < 4) { - continue 2; - } - break; - case NET_SFTP_ATTR_BITS: - if ($this->version < 5) { - continue 2; - } - break; - case NET_SFTP_ATTR_ALLOCATION_SIZE: - case NET_SFTP_ATTR_TEXT_HINT: - case NET_SFTP_ATTR_MIME_TYPE: - case NET_SFTP_ATTR_LINK_COUNT: - case NET_SFTP_ATTR_UNTRANSLATED_NAME: - case NET_SFTP_ATTR_CTIME: - if ($this->version < 6) { - continue 2; - } - } - switch ($flags & $key) { - case NET_SFTP_ATTR_SIZE: // 0x00000001 - // The size attribute is defined as an unsigned 64-bit integer. - // The following will use floats on 32-bit platforms, if necessary. - // As can be seen in the BigInteger class, floats are generally - // IEEE 754 binary64 "double precision" on such platforms and - // as such can represent integers of at least 2^50 without loss - // of precision. Interpreted in filesize, 2^50 bytes = 1024 TiB. - list($attr['size']) = Strings::unpackSSH2('Q', $response); - break; - case NET_SFTP_ATTR_UIDGID: // 0x00000002 (SFTPv3 only) - list($attr['uid'], $attr['gid']) = Strings::unpackSSH2('NN', $response); - break; - case NET_SFTP_ATTR_PERMISSIONS: // 0x00000004 - list($attr['mode']) = Strings::unpackSSH2('N', $response); - $fileType = $this->parseMode($attr['mode']); - if ($this->version < 4 && $fileType !== false) { - $attr += ['type' => $fileType]; - } - break; - case NET_SFTP_ATTR_ACCESSTIME: // 0x00000008 - if ($this->version >= 4) { - $attr += $this->parseTime('atime', $flags, $response); - break; - } - list($attr['atime'], $attr['mtime']) = Strings::unpackSSH2('NN', $response); - break; - case NET_SFTP_ATTR_CREATETIME: // 0x00000010 (SFTPv4+) - $attr += $this->parseTime('createtime', $flags, $response); - break; - case NET_SFTP_ATTR_MODIFYTIME: // 0x00000020 - $attr += $this->parseTime('mtime', $flags, $response); - break; - case NET_SFTP_ATTR_ACL: // 0x00000040 - // access control list - // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-04#section-5.7 - // currently unsupported - list($count) = Strings::unpackSSH2('N', $response); - for ($i = 0; $i < $count; $i++) { - list($type, $flag, $mask, $who) = Strings::unpackSSH2('N3s', $result); - } - break; - case NET_SFTP_ATTR_OWNERGROUP: // 0x00000080 - list($attr['owner'], $attr['$group']) = Strings::unpackSSH2('ss', $response); - break; - case NET_SFTP_ATTR_SUBSECOND_TIMES: // 0x00000100 - break; - case NET_SFTP_ATTR_BITS: // 0x00000200 (SFTPv5+) - // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-05#section-5.8 - // currently unsupported - // tells if you file is: - // readonly, system, hidden, case inensitive, archive, encrypted, compressed, sparse - // append only, immutable, sync - list($attrib_bits, $attrib_bits_valid) = Strings::unpackSSH2('N2', $response); - // if we were actually gonna implement the above it ought to be - // $attr['attrib-bits'] and $attr['attrib-bits-valid'] - // eg. - instead of _ - break; - case NET_SFTP_ATTR_ALLOCATION_SIZE: // 0x00000400 (SFTPv6+) - // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.4 - // represents the number of bytes that the file consumes on the disk. will - // usually be larger than the 'size' field - list($attr['allocation-size']) = Strings::unpackSSH2('Q', $response); - break; - case NET_SFTP_ATTR_TEXT_HINT: // 0x00000800 - // https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.10 - // currently unsupported - // tells if file is "known text", "guessed text", "known binary", "guessed binary" - list($text_hint) = Strings::unpackSSH2('C', $response); - // the above should be $attr['text-hint'] - break; - case NET_SFTP_ATTR_MIME_TYPE: // 0x00001000 - // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.11 - list($attr['mime-type']) = Strings::unpackSSH2('s', $response); - break; - case NET_SFTP_ATTR_LINK_COUNT: // 0x00002000 - // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.12 - list($attr['link-count']) = Strings::unpackSSH2('N', $response); - break; - case NET_SFTP_ATTR_UNTRANSLATED_NAME:// 0x00004000 - // see https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-13#section-7.13 - list($attr['untranslated-name']) = Strings::unpackSSH2('s', $response); - break; - case NET_SFTP_ATTR_CTIME: // 0x00008000 - // 'ctime' contains the last time the file attributes were changed. The - // exact meaning of this field depends on the server. - $attr += $this->parseTime('ctime', $flags, $response); - break; - case NET_SFTP_ATTR_EXTENDED: // 0x80000000 - list($count) = Strings::unpackSSH2('N', $response); - for ($i = 0; $i < $count; $i++) { - list($key, $value) = Strings::unpackSSH2('ss', $response); - $attr[$key] = $value; - } - } - } - return $attr; - } - - /** - * Attempt to identify the file type - * - * Quoting the SFTP RFC, "Implementations MUST NOT send bits that are not defined" but they seem to anyway - * - * @param int $mode - * @return int - */ - private function parseMode($mode) - { - // values come from http://lxr.free-electrons.com/source/include/uapi/linux/stat.h#L12 - // see, also, http://linux.die.net/man/2/stat - switch ($mode & 0170000) {// ie. 1111 0000 0000 0000 - case 0000000: // no file type specified - figure out the file type using alternative means - return false; - case 0040000: - return NET_SFTP_TYPE_DIRECTORY; - case 0100000: - return NET_SFTP_TYPE_REGULAR; - case 0120000: - return NET_SFTP_TYPE_SYMLINK; - // new types introduced in SFTPv5+ - // http://tools.ietf.org/html/draft-ietf-secsh-filexfer-05#section-5.2 - case 0010000: // named pipe (fifo) - return NET_SFTP_TYPE_FIFO; - case 0020000: // character special - return NET_SFTP_TYPE_CHAR_DEVICE; - case 0060000: // block special - return NET_SFTP_TYPE_BLOCK_DEVICE; - case 0140000: // socket - return NET_SFTP_TYPE_SOCKET; - case 0160000: // whiteout - // "SPECIAL should be used for files that are of - // a known type which cannot be expressed in the protocol" - return NET_SFTP_TYPE_SPECIAL; - default: - return NET_SFTP_TYPE_UNKNOWN; - } - } - - /** - * Parse Longname - * - * SFTPv3 doesn't provide any easy way of identifying a file type. You could try to open - * a file as a directory and see if an error is returned or you could try to parse the - * SFTPv3-specific longname field of the SSH_FXP_NAME packet. That's what this function does. - * The result is returned using the - * {@link http://tools.ietf.org/html/draft-ietf-secsh-filexfer-04#section-5.2 SFTPv4 type constants}. - * - * If the longname is in an unrecognized format bool(false) is returned. - * - * @param string $longname - * @return mixed - */ - private function parseLongname($longname) - { - // http://en.wikipedia.org/wiki/Unix_file_types - // http://en.wikipedia.org/wiki/Filesystem_permissions#Notation_of_traditional_Unix_permissions - if (preg_match('#^[^/]([r-][w-][xstST-]){3}#', $longname)) { - switch ($longname[0]) { - case '-': - return NET_SFTP_TYPE_REGULAR; - case 'd': - return NET_SFTP_TYPE_DIRECTORY; - case 'l': - return NET_SFTP_TYPE_SYMLINK; - default: - return NET_SFTP_TYPE_SPECIAL; - } - } - - return false; - } - - /** - * Sends SFTP Packets - * - * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. - * - * @param int $type - * @param string $data - * @param int $request_id - * @see self::_get_sftp_packet() - * @see self::send_channel_packet() - * @return void - */ - private function send_sftp_packet($type, $data, $request_id = 1) - { - // in SSH2.php the timeout is cumulative per function call. eg. exec() will - // timeout after 10s. but for SFTP.php it's cumulative per packet - $this->curTimeout = $this->timeout; - - $packet = $this->use_request_id ? - pack('NCNa*', strlen($data) + 5, $type, $request_id, $data) : - pack('NCa*', strlen($data) + 1, $type, $data); - - $start = microtime(true); - $this->send_channel_packet(self::CHANNEL, $packet); - $stop = microtime(true); - - if (defined('NET_SFTP_LOGGING')) { - $packet_type = '-> ' . self::$packet_types[$type] . - ' (' . round($stop - $start, 4) . 's)'; - $this->append_log($packet_type, $data); - } - } - - /** - * Resets a connection for re-use - * - * @param int $reason - */ - protected function reset_connection($reason) - { - parent::reset_connection($reason); - $this->use_request_id = false; - $this->pwd = false; - $this->requestBuffer = []; - $this->partial_init = false; - } - - /** - * Receives SFTP Packets - * - * See '6. General Packet Format' of draft-ietf-secsh-filexfer-13 for more info. - * - * Incidentally, the number of SSH_MSG_CHANNEL_DATA messages has no bearing on the number of SFTP packets present. - * There can be one SSH_MSG_CHANNEL_DATA messages containing two SFTP packets or there can be two SSH_MSG_CHANNEL_DATA - * messages containing one SFTP packet. - * - * @see self::_send_sftp_packet() - * @return string - */ - private function get_sftp_packet($request_id = null) - { - $this->channel_close = false; - - if (isset($request_id) && isset($this->requestBuffer[$request_id])) { - $this->packet_type = $this->requestBuffer[$request_id]['packet_type']; - $temp = $this->requestBuffer[$request_id]['packet']; - unset($this->requestBuffer[$request_id]); - return $temp; - } - - // in SSH2.php the timeout is cumulative per function call. eg. exec() will - // timeout after 10s. but for SFTP.php it's cumulative per packet - $this->curTimeout = $this->timeout; - - $start = microtime(true); - - // SFTP packet length - while (strlen($this->packet_buffer) < 4) { - $temp = $this->get_channel_packet(self::CHANNEL, true); - if ($temp === true) { - if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { - $this->channel_close = true; - } - $this->packet_type = false; - $this->packet_buffer = ''; - return false; - } - $this->packet_buffer .= $temp; - } - if (strlen($this->packet_buffer) < 4) { - throw new \RuntimeException('Packet is too small'); - } - extract(unpack('Nlength', Strings::shift($this->packet_buffer, 4))); - /** @var integer $length */ - - $tempLength = $length; - $tempLength -= strlen($this->packet_buffer); - - // 256 * 1024 is what SFTP_MAX_MSG_LENGTH is set to in OpenSSH's sftp-common.h - if (!$this->allow_arbitrary_length_packets && !$this->use_request_id && $tempLength > 256 * 1024) { - throw new \RuntimeException('Invalid Size'); - } - - // SFTP packet type and data payload - while ($tempLength > 0) { - $temp = $this->get_channel_packet(self::CHANNEL, true); - if ($temp === true) { - if ($this->channel_status[self::CHANNEL] === NET_SSH2_MSG_CHANNEL_CLOSE) { - $this->channel_close = true; - } - $this->packet_type = false; - $this->packet_buffer = ''; - return false; - } - $this->packet_buffer .= $temp; - $tempLength -= strlen($temp); - } - - $stop = microtime(true); - - $this->packet_type = ord(Strings::shift($this->packet_buffer)); - - if ($this->use_request_id) { - extract(unpack('Npacket_id', Strings::shift($this->packet_buffer, 4))); // remove the request id - $length -= 5; // account for the request id and the packet type - } else { - $length -= 1; // account for the packet type - } - - $packet = Strings::shift($this->packet_buffer, $length); - - if (defined('NET_SFTP_LOGGING')) { - $packet_type = '<- ' . self::$packet_types[$this->packet_type] . - ' (' . round($stop - $start, 4) . 's)'; - $this->append_log($packet_type, $packet); - } - - if (isset($request_id) && $this->use_request_id && $packet_id != $request_id) { - $this->requestBuffer[$packet_id] = [ - 'packet_type' => $this->packet_type, - 'packet' => $packet - ]; - return $this->get_sftp_packet($request_id); - } - - return $packet; - } - - /** - * Logs data packets - * - * Makes sure that only the last 1MB worth of packets will be logged - * - * @param string $message_number - * @param string $message - */ - private function append_log($message_number, $message) - { - $this->append_log_helper( - NET_SFTP_LOGGING, - $message_number, - $message, - $this->packet_type_log, - $this->packet_log, - $this->log_size, - $this->realtime_log_file, - $this->realtime_log_wrap, - $this->realtime_log_size - ); - } - - /** - * Returns a log of the packets that have been sent and received. - * - * Returns a string if NET_SFTP_LOGGING == self::LOG_COMPLEX, an array if NET_SFTP_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SFTP_LOGGING') - * - * @return array|string|false - */ - public function getSFTPLog() - { - if (!defined('NET_SFTP_LOGGING')) { - return false; - } - - switch (NET_SFTP_LOGGING) { - case self::LOG_COMPLEX: - return $this->format_log($this->packet_log, $this->packet_type_log); - break; - //case self::LOG_SIMPLE: - default: - return $this->packet_type_log; - } - } - - /** - * Returns all errors - * - * @return array - */ - public function getSFTPErrors() - { - return $this->sftp_errors; - } - - /** - * Returns the last error - * - * @return string - */ - public function getLastSFTPError() - { - return count($this->sftp_errors) ? $this->sftp_errors[count($this->sftp_errors) - 1] : ''; - } - - /** - * Get supported SFTP versions - * - * @return array - */ - public function getSupportedVersions() - { - if (!($this->bitmap & SSH2::MASK_LOGIN)) { - return false; - } - - if (!$this->partial_init) { - $this->partial_init_sftp_connection(); - } - - $temp = ['version' => $this->defaultVersion]; - if (isset($this->extensions['versions'])) { - $temp['extensions'] = $this->extensions['versions']; - } - return $temp; - } - - /** - * Get supported SFTP versions - * - * @return int|false - */ - public function getNegotiatedVersion() - { - if (!$this->precheck()) { - return false; - } - - return $this->version; - } - - /** - * Set preferred version - * - * If you're preferred version isn't supported then the highest supported - * version of SFTP will be utilized. Set to null or false or int(0) to - * unset the preferred version - * - * @param int $version - */ - public function setPreferredVersion($version) - { - $this->preferredVersion = $version; - } - - /** - * Disconnect - * - * @param int $reason - * @return false - */ - protected function disconnect_helper($reason) - { - $this->pwd = false; - return parent::disconnect_helper($reason); - } - - /** - * Enable Date Preservation - * - */ - public function enableDatePreservation() - { - $this->preserveTime = true; - } - - /** - * Disable Date Preservation - * - */ - public function disableDatePreservation() - { - $this->preserveTime = false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php deleted file mode 100644 index 24047b4..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SFTP/Stream.php +++ /dev/null @@ -1,756 +0,0 @@ - - * @copyright 2013 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Net\SFTP; - -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Net\SFTP; -use phpseclib3\Net\SSH2; - -/** - * SFTP Stream Wrapper - * - * @author Jim Wigginton - */ -class Stream -{ - /** - * SFTP instances - * - * Rather than re-create the connection we re-use instances if possible - * - * @var array - */ - public static $instances; - - /** - * SFTP instance - * - * @var object - */ - private $sftp; - - /** - * Path - * - * @var string - */ - private $path; - - /** - * Mode - * - * @var string - */ - private $mode; - - /** - * Position - * - * @var int - */ - private $pos; - - /** - * Size - * - * @var int - */ - private $size; - - /** - * Directory entries - * - * @var array - */ - private $entries; - - /** - * EOF flag - * - * @var bool - */ - private $eof; - - /** - * Context resource - * - * Technically this needs to be publicly accessible so PHP can set it directly - * - * @var resource - */ - public $context; - - /** - * Notification callback function - * - * @var callable - */ - private $notification; - - /** - * Registers this class as a URL wrapper. - * - * @param string $protocol The wrapper name to be registered. - * @return bool True on success, false otherwise. - */ - public static function register($protocol = 'sftp') - { - if (in_array($protocol, stream_get_wrappers(), true)) { - return false; - } - return stream_wrapper_register($protocol, get_called_class()); - } - - /** - * The Constructor - * - */ - public function __construct() - { - if (defined('NET_SFTP_STREAM_LOGGING')) { - echo "__construct()\r\n"; - } - } - - /** - * Path Parser - * - * Extract a path from a URI and actually connect to an SSH server if appropriate - * - * If "notification" is set as a context parameter the message code for successful login is - * NET_SSH2_MSG_USERAUTH_SUCCESS. For a failed login it's NET_SSH2_MSG_USERAUTH_FAILURE. - * - * @param string $path - * @return string - */ - protected function parse_path($path) - { - $orig = $path; - extract(parse_url($path) + ['port' => 22]); - if (isset($query)) { - $path .= '?' . $query; - } elseif (preg_match('/(\?|\?#)$/', $orig)) { - $path .= '?'; - } - if (isset($fragment)) { - $path .= '#' . $fragment; - } elseif ($orig[strlen($orig) - 1] == '#') { - $path .= '#'; - } - - if (!isset($host)) { - return false; - } - - if (isset($this->context)) { - $context = stream_context_get_params($this->context); - if (isset($context['notification'])) { - $this->notification = $context['notification']; - } - } - - if (preg_match('/^{[a-z0-9]+}$/i', $host)) { - $host = SSH2::getConnectionByResourceId($host); - if ($host === false) { - return false; - } - $this->sftp = $host; - } else { - if (isset($this->context)) { - $context = stream_context_get_options($this->context); - } - if (isset($context[$scheme]['session'])) { - $sftp = $context[$scheme]['session']; - } - if (isset($context[$scheme]['sftp'])) { - $sftp = $context[$scheme]['sftp']; - } - if (isset($sftp) && $sftp instanceof SFTP) { - $this->sftp = $sftp; - return $path; - } - if (isset($context[$scheme]['username'])) { - $user = $context[$scheme]['username']; - } - if (isset($context[$scheme]['password'])) { - $pass = $context[$scheme]['password']; - } - if (isset($context[$scheme]['privkey']) && $context[$scheme]['privkey'] instanceof PrivateKey) { - $pass = $context[$scheme]['privkey']; - } - - if (!isset($user) || !isset($pass)) { - return false; - } - - // casting $pass to a string is necessary in the event that it's a \phpseclib3\Crypt\RSA object - if (isset(self::$instances[$host][$port][$user][(string) $pass])) { - $this->sftp = self::$instances[$host][$port][$user][(string) $pass]; - } else { - $this->sftp = new SFTP($host, $port); - $this->sftp->disableStatCache(); - if (isset($this->notification) && is_callable($this->notification)) { - /* if !is_callable($this->notification) we could do this: - - user_error('fopen(): failed to call user notifier', E_USER_WARNING); - - the ftp wrapper gives errors like that when the notifier isn't callable. - i've opted not to do that, however, since the ftp wrapper gives the line - on which the fopen occurred as the line number - not the line that the - user_error is on. - */ - call_user_func($this->notification, STREAM_NOTIFY_CONNECT, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); - call_user_func($this->notification, STREAM_NOTIFY_AUTH_REQUIRED, STREAM_NOTIFY_SEVERITY_INFO, '', 0, 0, 0); - if (!$this->sftp->login($user, $pass)) { - call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_ERR, 'Login Failure', NET_SSH2_MSG_USERAUTH_FAILURE, 0, 0); - return false; - } - call_user_func($this->notification, STREAM_NOTIFY_AUTH_RESULT, STREAM_NOTIFY_SEVERITY_INFO, 'Login Success', NET_SSH2_MSG_USERAUTH_SUCCESS, 0, 0); - } else { - if (!$this->sftp->login($user, $pass)) { - return false; - } - } - self::$instances[$host][$port][$user][(string) $pass] = $this->sftp; - } - } - - return $path; - } - - /** - * Opens file or URL - * - * @param string $path - * @param string $mode - * @param int $options - * @param string $opened_path - * @return bool - */ - private function _stream_open($path, $mode, $options, &$opened_path) - { - $path = $this->parse_path($path); - - if ($path === false) { - return false; - } - $this->path = $path; - - $this->size = $this->sftp->filesize($path); - $this->mode = preg_replace('#[bt]$#', '', $mode); - $this->eof = false; - - if ($this->size === false) { - if ($this->mode[0] == 'r') { - return false; - } else { - $this->sftp->touch($path); - $this->size = 0; - } - } else { - switch ($this->mode[0]) { - case 'x': - return false; - case 'w': - $this->sftp->truncate($path, 0); - $this->size = 0; - } - } - - $this->pos = $this->mode[0] != 'a' ? 0 : $this->size; - - return true; - } - - /** - * Read from stream - * - * @param int $count - * @return mixed - */ - private function _stream_read($count) - { - switch ($this->mode) { - case 'w': - case 'a': - case 'x': - case 'c': - return false; - } - - // commented out because some files - eg. /dev/urandom - will say their size is 0 when in fact it's kinda infinite - //if ($this->pos >= $this->size) { - // $this->eof = true; - // return false; - //} - - $result = $this->sftp->get($this->path, false, $this->pos, $count); - if (isset($this->notification) && is_callable($this->notification)) { - if ($result === false) { - call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); - return 0; - } - // seems that PHP calls stream_read in 8k chunks - call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($result), $this->size); - } - - if (empty($result)) { // ie. false or empty string - $this->eof = true; - return false; - } - $this->pos += strlen($result); - - return $result; - } - - /** - * Write to stream - * - * @param string $data - * @return int|false - */ - private function _stream_write($data) - { - switch ($this->mode) { - case 'r': - return false; - } - - $result = $this->sftp->put($this->path, $data, SFTP::SOURCE_STRING, $this->pos); - if (isset($this->notification) && is_callable($this->notification)) { - if (!$result) { - call_user_func($this->notification, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_SEVERITY_ERR, $this->sftp->getLastSFTPError(), NET_SFTP_OPEN, 0, 0); - return 0; - } - // seems that PHP splits up strings into 8k blocks before calling stream_write - call_user_func($this->notification, STREAM_NOTIFY_PROGRESS, STREAM_NOTIFY_SEVERITY_INFO, '', 0, strlen($data), strlen($data)); - } - - if ($result === false) { - return false; - } - $this->pos += strlen($data); - if ($this->pos > $this->size) { - $this->size = $this->pos; - } - $this->eof = false; - return strlen($data); - } - - /** - * Retrieve the current position of a stream - * - * @return int - */ - private function _stream_tell() - { - return $this->pos; - } - - /** - * Tests for end-of-file on a file pointer - * - * In my testing there are four classes functions that normally effect the pointer: - * fseek, fputs / fwrite, fgets / fread and ftruncate. - * - * Only fgets / fread, however, results in feof() returning true. do fputs($fp, 'aaa') on a blank file and feof() - * will return false. do fread($fp, 1) and feof() will then return true. do fseek($fp, 10) on ablank file and feof() - * will return false. do fread($fp, 1) and feof() will then return true. - * - * @return bool - */ - private function _stream_eof() - { - return $this->eof; - } - - /** - * Seeks to specific location in a stream - * - * @param int $offset - * @param int $whence - * @return bool - */ - private function _stream_seek($offset, $whence) - { - switch ($whence) { - case SEEK_SET: - if ($offset < 0) { - return false; - } - break; - case SEEK_CUR: - $offset += $this->pos; - break; - case SEEK_END: - $offset += $this->size; - } - - $this->pos = $offset; - $this->eof = false; - return true; - } - - /** - * Change stream options - * - * @param string $path - * @param int $option - * @param mixed $var - * @return bool - */ - private function _stream_metadata($path, $option, $var) - { - $path = $this->parse_path($path); - if ($path === false) { - return false; - } - - // stream_metadata was introduced in PHP 5.4.0 but as of 5.4.11 the constants haven't been defined - // see http://www.php.net/streamwrapper.stream-metadata and https://bugs.php.net/64246 - // and https://github.com/php/php-src/blob/master/main/php_streams.h#L592 - switch ($option) { - case 1: // PHP_STREAM_META_TOUCH - $time = isset($var[0]) ? $var[0] : null; - $atime = isset($var[1]) ? $var[1] : null; - return $this->sftp->touch($path, $time, $atime); - case 2: // PHP_STREAM_OWNER_NAME - case 3: // PHP_STREAM_GROUP_NAME - return false; - case 4: // PHP_STREAM_META_OWNER - return $this->sftp->chown($path, $var); - case 5: // PHP_STREAM_META_GROUP - return $this->sftp->chgrp($path, $var); - case 6: // PHP_STREAM_META_ACCESS - return $this->sftp->chmod($path, $var) !== false; - } - } - - /** - * Retrieve the underlaying resource - * - * @param int $cast_as - * @return resource - */ - private function _stream_cast($cast_as) - { - return $this->sftp->fsock; - } - - /** - * Advisory file locking - * - * @param int $operation - * @return bool - */ - private function _stream_lock($operation) - { - return false; - } - - /** - * Renames a file or directory - * - * Attempts to rename oldname to newname, moving it between directories if necessary. - * If newname exists, it will be overwritten. This is a departure from what \phpseclib3\Net\SFTP - * does. - * - * @param string $path_from - * @param string $path_to - * @return bool - */ - private function _rename($path_from, $path_to) - { - $path1 = parse_url($path_from); - $path2 = parse_url($path_to); - unset($path1['path'], $path2['path']); - if ($path1 != $path2) { - return false; - } - - $path_from = $this->parse_path($path_from); - $path_to = parse_url($path_to); - if ($path_from === false) { - return false; - } - - $path_to = $path_to['path']; // the $component part of parse_url() was added in PHP 5.1.2 - // "It is an error if there already exists a file with the name specified by newpath." - // -- http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02#section-6.5 - if (!$this->sftp->rename($path_from, $path_to)) { - if ($this->sftp->stat($path_to)) { - return $this->sftp->delete($path_to, true) && $this->sftp->rename($path_from, $path_to); - } - return false; - } - - return true; - } - - /** - * Open directory handle - * - * The only $options is "whether or not to enforce safe_mode (0x04)". Since safe mode was deprecated in 5.3 and - * removed in 5.4 I'm just going to ignore it. - * - * Also, nlist() is the best that this function is realistically going to be able to do. When an SFTP client - * sends a SSH_FXP_READDIR packet you don't generally get info on just one file but on multiple files. Quoting - * the SFTP specs: - * - * The SSH_FXP_NAME response has the following format: - * - * uint32 id - * uint32 count - * repeats count times: - * string filename - * string longname - * ATTRS attrs - * - * @param string $path - * @param int $options - * @return bool - */ - private function _dir_opendir($path, $options) - { - $path = $this->parse_path($path); - if ($path === false) { - return false; - } - $this->pos = 0; - $this->entries = $this->sftp->nlist($path); - return $this->entries !== false; - } - - /** - * Read entry from directory handle - * - * @return mixed - */ - private function _dir_readdir() - { - if (isset($this->entries[$this->pos])) { - return $this->entries[$this->pos++]; - } - return false; - } - - /** - * Rewind directory handle - * - * @return bool - */ - private function _dir_rewinddir() - { - $this->pos = 0; - return true; - } - - /** - * Close directory handle - * - * @return bool - */ - private function _dir_closedir() - { - return true; - } - - /** - * Create a directory - * - * Only valid $options is STREAM_MKDIR_RECURSIVE - * - * @param string $path - * @param int $mode - * @param int $options - * @return bool - */ - private function _mkdir($path, $mode, $options) - { - $path = $this->parse_path($path); - if ($path === false) { - return false; - } - - return $this->sftp->mkdir($path, $mode, $options & STREAM_MKDIR_RECURSIVE); - } - - /** - * Removes a directory - * - * Only valid $options is STREAM_MKDIR_RECURSIVE per , however, - * does not have a $recursive parameter as mkdir() does so I don't know how - * STREAM_MKDIR_RECURSIVE is supposed to be set. Also, when I try it out with rmdir() I get 8 as - * $options. What does 8 correspond to? - * - * @param string $path - * @param int $options - * @return bool - */ - private function _rmdir($path, $options) - { - $path = $this->parse_path($path); - if ($path === false) { - return false; - } - - return $this->sftp->rmdir($path); - } - - /** - * Flushes the output - * - * See . Always returns true because \phpseclib3\Net\SFTP doesn't cache stuff before writing - * - * @return bool - */ - private function _stream_flush() - { - return true; - } - - /** - * Retrieve information about a file resource - * - * @return mixed - */ - private function _stream_stat() - { - $results = $this->sftp->stat($this->path); - if ($results === false) { - return false; - } - return $results; - } - - /** - * Delete a file - * - * @param string $path - * @return bool - */ - private function _unlink($path) - { - $path = $this->parse_path($path); - if ($path === false) { - return false; - } - - return $this->sftp->delete($path, false); - } - - /** - * Retrieve information about a file - * - * Ignores the STREAM_URL_STAT_QUIET flag because the entirety of \phpseclib3\Net\SFTP\Stream is quiet by default - * might be worthwhile to reconstruct bits 12-16 (ie. the file type) if mode doesn't have them but we'll - * cross that bridge when and if it's reached - * - * @param string $path - * @param int $flags - * @return mixed - */ - private function _url_stat($path, $flags) - { - $path = $this->parse_path($path); - if ($path === false) { - return false; - } - - $results = $flags & STREAM_URL_STAT_LINK ? $this->sftp->lstat($path) : $this->sftp->stat($path); - if ($results === false) { - return false; - } - - return $results; - } - - /** - * Truncate stream - * - * @param int $new_size - * @return bool - */ - private function _stream_truncate($new_size) - { - if (!$this->sftp->truncate($this->path, $new_size)) { - return false; - } - - $this->eof = false; - $this->size = $new_size; - - return true; - } - - /** - * Change stream options - * - * STREAM_OPTION_WRITE_BUFFER isn't supported for the same reason stream_flush isn't. - * The other two aren't supported because of limitations in \phpseclib3\Net\SFTP. - * - * @param int $option - * @param int $arg1 - * @param int $arg2 - * @return bool - */ - private function _stream_set_option($option, $arg1, $arg2) - { - return false; - } - - /** - * Close an resource - * - */ - private function _stream_close() - { - } - - /** - * __call Magic Method - * - * When you're utilizing an SFTP stream you're not calling the methods in this class directly - PHP is calling them for you. - * Which kinda begs the question... what methods is PHP calling and what parameters is it passing to them? This function - * lets you figure that out. - * - * If NET_SFTP_STREAM_LOGGING is defined all calls will be output on the screen and then (regardless of whether or not - * NET_SFTP_STREAM_LOGGING is enabled) the parameters will be passed through to the appropriate method. - * - * @param string $name - * @param array $arguments - * @return mixed - */ - public function __call($name, array $arguments) - { - if (defined('NET_SFTP_STREAM_LOGGING')) { - echo $name . '('; - $last = count($arguments) - 1; - foreach ($arguments as $i => $argument) { - var_export($argument); - if ($i != $last) { - echo ','; - } - } - echo ")\r\n"; - } - $name = '_' . $name; - if (!method_exists($this, $name)) { - return false; - } - return $this->$name(...$arguments); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php deleted file mode 100644 index ac70af9..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/Net/SSH2.php +++ /dev/null @@ -1,5397 +0,0 @@ - - * login('username', 'password')) { - * exit('Login Failed'); - * } - * - * echo $ssh->exec('pwd'); - * echo $ssh->exec('ls -la'); - * ?> - * - * - * - * login('username', $key)) { - * exit('Login Failed'); - * } - * - * echo $ssh->read('username@username:~$'); - * $ssh->write("ls -la\n"); - * echo $ssh->read('username@username:~$'); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2007 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\Net; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Blowfish; -use phpseclib3\Crypt\ChaCha20; -use phpseclib3\Crypt\Common\AsymmetricKey; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Crypt\Common\PublicKey; -use phpseclib3\Crypt\Common\SymmetricKey; -use phpseclib3\Crypt\DH; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\Hash; -use phpseclib3\Crypt\Random; -use phpseclib3\Crypt\RC4; -use phpseclib3\Crypt\Rijndael; -use phpseclib3\Crypt\RSA; -use phpseclib3\Crypt\TripleDES; // Used to do Diffie-Hellman key exchange and DSA/RSA signature verification. -use phpseclib3\Crypt\Twofish; -use phpseclib3\Exception\ConnectionClosedException; -use phpseclib3\Exception\InsufficientSetupException; -use phpseclib3\Exception\NoSupportedAlgorithmsException; -use phpseclib3\Exception\UnableToConnectException; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\Exception\UnsupportedCurveException; -use phpseclib3\Math\BigInteger; -use phpseclib3\System\SSH\Agent; - -/** - * Pure-PHP implementation of SSHv2. - * - * @author Jim Wigginton - */ -class SSH2 -{ - /**#@+ - * Compression Types - * - */ - /** - * No compression - */ - const NET_SSH2_COMPRESSION_NONE = 1; - /** - * zlib compression - */ - const NET_SSH2_COMPRESSION_ZLIB = 2; - /** - * zlib@openssh.com - */ - const NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH = 3; - /**#@-*/ - - // Execution Bitmap Masks - const MASK_CONSTRUCTOR = 0x00000001; - const MASK_CONNECTED = 0x00000002; - const MASK_LOGIN_REQ = 0x00000004; - const MASK_LOGIN = 0x00000008; - const MASK_SHELL = 0x00000010; - const MASK_WINDOW_ADJUST = 0x00000020; - - /* - * Channel constants - * - * RFC4254 refers not to client and server channels but rather to sender and recipient channels. we don't refer - * to them in that way because RFC4254 toggles the meaning. the client sends a SSH_MSG_CHANNEL_OPEN message with - * a sender channel and the server sends a SSH_MSG_CHANNEL_OPEN_CONFIRMATION in response, with a sender and a - * recipient channel. at first glance, you might conclude that SSH_MSG_CHANNEL_OPEN_CONFIRMATION's sender channel - * would be the same thing as SSH_MSG_CHANNEL_OPEN's sender channel, but it's not, per this snippet: - * The 'recipient channel' is the channel number given in the original - * open request, and 'sender channel' is the channel number allocated by - * the other side. - * - * @see \phpseclib3\Net\SSH2::send_channel_packet() - * @see \phpseclib3\Net\SSH2::get_channel_packet() - */ - const CHANNEL_EXEC = 1; // PuTTy uses 0x100 - const CHANNEL_SHELL = 2; - const CHANNEL_SUBSYSTEM = 3; - const CHANNEL_AGENT_FORWARD = 4; - const CHANNEL_KEEP_ALIVE = 5; - - /** - * Returns the message numbers - * - * @see \phpseclib3\Net\SSH2::getLog() - */ - const LOG_SIMPLE = 1; - /** - * Returns the message content - * - * @see \phpseclib3\Net\SSH2::getLog() - */ - const LOG_COMPLEX = 2; - /** - * Outputs the content real-time - */ - const LOG_REALTIME = 3; - /** - * Dumps the content real-time to a file - */ - const LOG_REALTIME_FILE = 4; - /** - * Outputs the message numbers real-time - */ - const LOG_SIMPLE_REALTIME = 5; - /** - * Make sure that the log never gets larger than this - * - * @see \phpseclib3\Net\SSH2::getLog() - */ - const LOG_MAX_SIZE = 1048576; // 1024 * 1024 - - /** - * Returns when a string matching $expect exactly is found - * - * @see \phpseclib3\Net\SSH2::read() - */ - const READ_SIMPLE = 1; - /** - * Returns when a string matching the regular expression $expect is found - * - * @see \phpseclib3\Net\SSH2::read() - */ - const READ_REGEX = 2; - /** - * Returns whenever a data packet is received. - * - * Some data packets may only contain a single character so it may be necessary - * to call read() multiple times when using this option - * - * @see \phpseclib3\Net\SSH2::read() - */ - const READ_NEXT = 3; - - /** - * The SSH identifier - * - * @var string - */ - private $identifier; - - /** - * The Socket Object - * - * @var resource|closed-resource|null - */ - public $fsock; - - /** - * Execution Bitmap - * - * The bits that are set represent functions that have been called already. This is used to determine - * if a requisite function has been successfully executed. If not, an error should be thrown. - * - * @var int - */ - protected $bitmap = 0; - - /** - * Error information - * - * @see self::getErrors() - * @see self::getLastError() - * @var array - */ - private $errors = []; - - /** - * Server Identifier - * - * @see self::getServerIdentification() - * @var string|false - */ - protected $server_identifier = false; - - /** - * Key Exchange Algorithms - * - * @see self::getKexAlgorithims() - * @var array|false - */ - private $kex_algorithms = false; - - /** - * Key Exchange Algorithm - * - * @see self::getMethodsNegotiated() - * @var string|false - */ - private $kex_algorithm = false; - - /** - * Minimum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods - * - * @see self::_key_exchange() - * @var int - */ - private $kex_dh_group_size_min = 1536; - - /** - * Preferred Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods - * - * @see self::_key_exchange() - * @var int - */ - private $kex_dh_group_size_preferred = 2048; - - /** - * Maximum Diffie-Hellman Group Bit Size in RFC 4419 Key Exchange Methods - * - * @see self::_key_exchange() - * @var int - */ - private $kex_dh_group_size_max = 4096; - - /** - * Server Host Key Algorithms - * - * @see self::getServerHostKeyAlgorithms() - * @var array|false - */ - private $server_host_key_algorithms = false; - - /** - * Supported Private Key Algorithms - * - * In theory this should be the same as the Server Host Key Algorithms but, in practice, - * some servers (eg. Azure) will support rsa-sha2-512 as a server host key algorithm but - * not a private key algorithm - * - * @see self::privatekey_login() - * @var array|false - */ - private $supported_private_key_algorithms = false; - - /** - * Encryption Algorithms: Client to Server - * - * @see self::getEncryptionAlgorithmsClient2Server() - * @var array|false - */ - private $encryption_algorithms_client_to_server = false; - - /** - * Encryption Algorithms: Server to Client - * - * @see self::getEncryptionAlgorithmsServer2Client() - * @var array|false - */ - private $encryption_algorithms_server_to_client = false; - - /** - * MAC Algorithms: Client to Server - * - * @see self::getMACAlgorithmsClient2Server() - * @var array|false - */ - private $mac_algorithms_client_to_server = false; - - /** - * MAC Algorithms: Server to Client - * - * @see self::getMACAlgorithmsServer2Client() - * @var array|false - */ - private $mac_algorithms_server_to_client = false; - - /** - * Compression Algorithms: Client to Server - * - * @see self::getCompressionAlgorithmsClient2Server() - * @var array|false - */ - private $compression_algorithms_client_to_server = false; - - /** - * Compression Algorithms: Server to Client - * - * @see self::getCompressionAlgorithmsServer2Client() - * @var array|false - */ - private $compression_algorithms_server_to_client = false; - - /** - * Languages: Server to Client - * - * @see self::getLanguagesServer2Client() - * @var array|false - */ - private $languages_server_to_client = false; - - /** - * Languages: Client to Server - * - * @see self::getLanguagesClient2Server() - * @var array|false - */ - private $languages_client_to_server = false; - - /** - * Preferred Algorithms - * - * @see self::setPreferredAlgorithms() - * @var array - */ - private $preferred = []; - - /** - * Block Size for Server to Client Encryption - * - * "Note that the length of the concatenation of 'packet_length', - * 'padding_length', 'payload', and 'random padding' MUST be a multiple - * of the cipher block size or 8, whichever is larger. This constraint - * MUST be enforced, even when using stream ciphers." - * - * -- http://tools.ietf.org/html/rfc4253#section-6 - * - * @see self::__construct() - * @see self::_send_binary_packet() - * @var int - */ - private $encrypt_block_size = 8; - - /** - * Block Size for Client to Server Encryption - * - * @see self::__construct() - * @see self::_get_binary_packet() - * @var int - */ - private $decrypt_block_size = 8; - - /** - * Server to Client Encryption Object - * - * @see self::_get_binary_packet() - * @var SymmetricKey|false - */ - private $decrypt = false; - - /** - * Decryption Algorithm Name - * - * @var string|null - */ - private $decryptName; - - /** - * Decryption Invocation Counter - * - * Used by GCM - * - * @var string|null - */ - private $decryptInvocationCounter; - - /** - * Fixed Part of Nonce - * - * Used by GCM - * - * @var string|null - */ - private $decryptFixedPart; - - /** - * Server to Client Length Encryption Object - * - * @see self::_get_binary_packet() - * @var object - */ - private $lengthDecrypt = false; - - /** - * Client to Server Encryption Object - * - * @see self::_send_binary_packet() - * @var SymmetricKey|false - */ - private $encrypt = false; - - /** - * Encryption Algorithm Name - * - * @var string|null - */ - private $encryptName; - - /** - * Encryption Invocation Counter - * - * Used by GCM - * - * @var string|null - */ - private $encryptInvocationCounter; - - /** - * Fixed Part of Nonce - * - * Used by GCM - * - * @var string|null - */ - private $encryptFixedPart; - - /** - * Client to Server Length Encryption Object - * - * @see self::_send_binary_packet() - * @var object - */ - private $lengthEncrypt = false; - - /** - * Client to Server HMAC Object - * - * @see self::_send_binary_packet() - * @var object - */ - private $hmac_create = false; - - /** - * Client to Server HMAC Name - * - * @var string|false - */ - private $hmac_create_name; - - /** - * Client to Server ETM - * - * @var int|false - */ - private $hmac_create_etm; - - /** - * Server to Client HMAC Object - * - * @see self::_get_binary_packet() - * @var object - */ - private $hmac_check = false; - - /** - * Server to Client HMAC Name - * - * @var string|false - */ - private $hmac_check_name; - - /** - * Server to Client ETM - * - * @var int|false - */ - private $hmac_check_etm; - - /** - * Size of server to client HMAC - * - * We need to know how big the HMAC will be for the server to client direction so that we know how many bytes to read. - * For the client to server side, the HMAC object will make the HMAC as long as it needs to be. All we need to do is - * append it. - * - * @see self::_get_binary_packet() - * @var int - */ - private $hmac_size = false; - - /** - * Server Public Host Key - * - * @see self::getServerPublicHostKey() - * @var string - */ - private $server_public_host_key; - - /** - * Session identifier - * - * "The exchange hash H from the first key exchange is additionally - * used as the session identifier, which is a unique identifier for - * this connection." - * - * -- http://tools.ietf.org/html/rfc4253#section-7.2 - * - * @see self::_key_exchange() - * @var string - */ - private $session_id = false; - - /** - * Exchange hash - * - * The current exchange hash - * - * @see self::_key_exchange() - * @var string - */ - private $exchange_hash = false; - - /** - * Message Numbers - * - * @see self::__construct() - * @var array - * @access private - */ - private static $message_numbers = []; - - /** - * Disconnection Message 'reason codes' defined in RFC4253 - * - * @see self::__construct() - * @var array - * @access private - */ - private static $disconnect_reasons = []; - - /** - * SSH_MSG_CHANNEL_OPEN_FAILURE 'reason codes', defined in RFC4254 - * - * @see self::__construct() - * @var array - * @access private - */ - private static $channel_open_failure_reasons = []; - - /** - * Terminal Modes - * - * @link http://tools.ietf.org/html/rfc4254#section-8 - * @see self::__construct() - * @var array - * @access private - */ - private static $terminal_modes = []; - - /** - * SSH_MSG_CHANNEL_EXTENDED_DATA's data_type_codes - * - * @link http://tools.ietf.org/html/rfc4254#section-5.2 - * @see self::__construct() - * @var array - * @access private - */ - private static $channel_extended_data_type_codes = []; - - /** - * Send Sequence Number - * - * See 'Section 6.4. Data Integrity' of rfc4253 for more info. - * - * @see self::_send_binary_packet() - * @var int - */ - private $send_seq_no = 0; - - /** - * Get Sequence Number - * - * See 'Section 6.4. Data Integrity' of rfc4253 for more info. - * - * @see self::_get_binary_packet() - * @var int - */ - private $get_seq_no = 0; - - /** - * Server Channels - * - * Maps client channels to server channels - * - * @see self::get_channel_packet() - * @see self::exec() - * @var array - */ - protected $server_channels = []; - - /** - * Channel Buffers - * - * If a client requests a packet from one channel but receives two packets from another those packets should - * be placed in a buffer - * - * @see self::get_channel_packet() - * @see self::exec() - * @var array - */ - private $channel_buffers = []; - - /** - * Channel Status - * - * Contains the type of the last sent message - * - * @see self::get_channel_packet() - * @var array - */ - protected $channel_status = []; - - /** - * The identifier of the interactive channel which was opened most recently - * - * @see self::getInteractiveChannelId() - * @var int - */ - private $channel_id_last_interactive = 0; - - /** - * Packet Size - * - * Maximum packet size indexed by channel - * - * @see self::send_channel_packet() - * @var array - */ - private $packet_size_client_to_server = []; - - /** - * Message Number Log - * - * @see self::getLog() - * @var array - */ - private $message_number_log = []; - - /** - * Message Log - * - * @see self::getLog() - * @var array - */ - private $message_log = []; - - /** - * The Window Size - * - * Bytes the other party can send before it must wait for the window to be adjusted (0x7FFFFFFF = 2GB) - * - * @var int - * @see self::send_channel_packet() - * @see self::exec() - */ - protected $window_size = 0x7FFFFFFF; - - /** - * What we resize the window to - * - * When PuTTY resizes the window it doesn't add an additional 0x7FFFFFFF bytes - it adds 0x40000000 bytes. - * Some SFTP clients (GoAnywhere) don't support adding 0x7FFFFFFF to the window size after the fact so - * we'll just do what PuTTY does - * - * @var int - * @see self::_send_channel_packet() - * @see self::exec() - */ - private $window_resize = 0x40000000; - - /** - * Window size, server to client - * - * Window size indexed by channel - * - * @see self::send_channel_packet() - * @var array - */ - protected $window_size_server_to_client = []; - - /** - * Window size, client to server - * - * Window size indexed by channel - * - * @see self::get_channel_packet() - * @var array - */ - private $window_size_client_to_server = []; - - /** - * Server signature - * - * Verified against $this->session_id - * - * @see self::getServerPublicHostKey() - * @var string - */ - private $signature = ''; - - /** - * Server signature format - * - * ssh-rsa or ssh-dss. - * - * @see self::getServerPublicHostKey() - * @var string - */ - private $signature_format = ''; - - /** - * Interactive Buffer - * - * @see self::read() - * @var string - */ - private $interactiveBuffer = ''; - - /** - * Current log size - * - * Should never exceed self::LOG_MAX_SIZE - * - * @see self::_send_binary_packet() - * @see self::_get_binary_packet() - * @var int - */ - private $log_size; - - /** - * Timeout - * - * @see self::setTimeout() - */ - protected $timeout; - - /** - * Current Timeout - * - * @see self::get_channel_packet() - */ - protected $curTimeout; - - /** - * Keep Alive Interval - * - * @see self::setKeepAlive() - */ - private $keepAlive; - - /** - * Real-time log file pointer - * - * @see self::_append_log() - * @var resource|closed-resource - */ - private $realtime_log_file; - - /** - * Real-time log file size - * - * @see self::_append_log() - * @var int - */ - private $realtime_log_size; - - /** - * Has the signature been validated? - * - * @see self::getServerPublicHostKey() - * @var bool - */ - private $signature_validated = false; - - /** - * Real-time log file wrap boolean - * - * @see self::_append_log() - * @var bool - */ - private $realtime_log_wrap; - - /** - * Flag to suppress stderr from output - * - * @see self::enableQuietMode() - */ - private $quiet_mode = false; - - /** - * Time of first network activity - * - * @var float - */ - private $last_packet; - - /** - * Exit status returned from ssh if any - * - * @var int - */ - private $exit_status; - - /** - * Flag to request a PTY when using exec() - * - * @var bool - * @see self::enablePTY() - */ - private $request_pty = false; - - /** - * Contents of stdError - * - * @var string - */ - private $stdErrorLog; - - /** - * The Last Interactive Response - * - * @see self::_keyboard_interactive_process() - * @var string - */ - private $last_interactive_response = ''; - - /** - * Keyboard Interactive Request / Responses - * - * @see self::_keyboard_interactive_process() - * @var array - */ - private $keyboard_requests_responses = []; - - /** - * Banner Message - * - * Quoting from the RFC, "in some jurisdictions, sending a warning message before - * authentication may be relevant for getting legal protection." - * - * @see self::_filter() - * @see self::getBannerMessage() - * @var string - */ - private $banner_message = ''; - - /** - * Did read() timeout or return normally? - * - * @see self::isTimeout() - * @var bool - */ - private $is_timeout = false; - - /** - * Log Boundary - * - * @see self::_format_log() - * @var string - */ - private $log_boundary = ':'; - - /** - * Log Long Width - * - * @see self::_format_log() - * @var int - */ - private $log_long_width = 65; - - /** - * Log Short Width - * - * @see self::_format_log() - * @var int - */ - private $log_short_width = 16; - - /** - * Hostname - * - * @see self::__construct() - * @see self::_connect() - * @var string - */ - private $host; - - /** - * Port Number - * - * @see self::__construct() - * @see self::_connect() - * @var int - */ - private $port; - - /** - * Number of columns for terminal window size - * - * @see self::getWindowColumns() - * @see self::setWindowColumns() - * @see self::setWindowSize() - * @var int - */ - private $windowColumns = 80; - - /** - * Number of columns for terminal window size - * - * @see self::getWindowRows() - * @see self::setWindowRows() - * @see self::setWindowSize() - * @var int - */ - private $windowRows = 24; - - /** - * Crypto Engine - * - * @see self::setCryptoEngine() - * @see self::_key_exchange() - * @var int - */ - private static $crypto_engine = false; - - /** - * A System_SSH_Agent for use in the SSH2 Agent Forwarding scenario - * - * @var Agent - */ - private $agent; - - /** - * Connection storage to replicates ssh2 extension functionality: - * {@link http://php.net/manual/en/wrappers.ssh2.php#refsect1-wrappers.ssh2-examples} - * - * @var array> - */ - private static $connections; - - /** - * Send the identification string first? - * - * @var bool - */ - private $send_id_string_first = true; - - /** - * Send the key exchange initiation packet first? - * - * @var bool - */ - private $send_kex_first = true; - - /** - * Some versions of OpenSSH incorrectly calculate the key size - * - * @var bool - */ - private $bad_key_size_fix = false; - - /** - * Should we try to re-connect to re-establish keys? - * - * @var bool - */ - private $retry_connect = false; - - /** - * Binary Packet Buffer - * - * @var string|false - */ - private $binary_packet_buffer = false; - - /** - * Preferred Signature Format - * - * @var string|false - */ - protected $preferred_signature_format = false; - - /** - * Authentication Credentials - * - * @var array - */ - protected $auth = []; - - /** - * Terminal - * - * @var string - */ - private $term = 'vt100'; - - /** - * The authentication methods that may productively continue authentication. - * - * @see https://tools.ietf.org/html/rfc4252#section-5.1 - * @var array|null - */ - private $auth_methods_to_continue = null; - - /** - * Compression method - * - * @var int - */ - private $compress = self::NET_SSH2_COMPRESSION_NONE; - - /** - * Decompression method - * - * @var int - */ - private $decompress = self::NET_SSH2_COMPRESSION_NONE; - - /** - * Compression context - * - * @var resource|false|null - */ - private $compress_context; - - /** - * Decompression context - * - * @var resource|object - */ - private $decompress_context; - - /** - * Regenerate Compression Context - * - * @var bool - */ - private $regenerate_compression_context = false; - - /** - * Regenerate Decompression Context - * - * @var bool - */ - private $regenerate_decompression_context = false; - - /** - * Smart multi-factor authentication flag - * - * @var bool - */ - private $smartMFA = true; - - /** - * How many channels are currently opened - * - * @var int - */ - private $channelCount = 0; - - /** - * Does the server support multiple channels? If not then error out - * when multiple channels are attempted to be opened - * - * @var bool - */ - private $errorOnMultipleChannels; - - /** - * Terrapin Countermeasure - * - * "During initial KEX, terminate the connection if any unexpected or out-of-sequence packet is received" - * -- https://github.com/openssh/openssh-portable/commit/1edb00c58f8a6875fad6a497aa2bacf37f9e6cd5 - * - * @var int - */ - private $extra_packets; - - /** - * Default Constructor. - * - * $host can either be a string, representing the host, or a stream resource. - * - * @param mixed $host - * @param int $port - * @param int $timeout - * @see self::login() - */ - public function __construct($host, $port = 22, $timeout = 10) - { - if (empty(self::$message_numbers)) { - self::$message_numbers = [ - 1 => 'NET_SSH2_MSG_DISCONNECT', - 2 => 'NET_SSH2_MSG_IGNORE', - 3 => 'NET_SSH2_MSG_UNIMPLEMENTED', - 4 => 'NET_SSH2_MSG_DEBUG', - 5 => 'NET_SSH2_MSG_SERVICE_REQUEST', - 6 => 'NET_SSH2_MSG_SERVICE_ACCEPT', - 7 => 'NET_SSH2_MSG_EXT_INFO', // RFC 8308 - 20 => 'NET_SSH2_MSG_KEXINIT', - 21 => 'NET_SSH2_MSG_NEWKEYS', - 30 => 'NET_SSH2_MSG_KEXDH_INIT', - 31 => 'NET_SSH2_MSG_KEXDH_REPLY', - 50 => 'NET_SSH2_MSG_USERAUTH_REQUEST', - 51 => 'NET_SSH2_MSG_USERAUTH_FAILURE', - 52 => 'NET_SSH2_MSG_USERAUTH_SUCCESS', - 53 => 'NET_SSH2_MSG_USERAUTH_BANNER', - - 80 => 'NET_SSH2_MSG_GLOBAL_REQUEST', - 81 => 'NET_SSH2_MSG_REQUEST_SUCCESS', - 82 => 'NET_SSH2_MSG_REQUEST_FAILURE', - 90 => 'NET_SSH2_MSG_CHANNEL_OPEN', - 91 => 'NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION', - 92 => 'NET_SSH2_MSG_CHANNEL_OPEN_FAILURE', - 93 => 'NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST', - 94 => 'NET_SSH2_MSG_CHANNEL_DATA', - 95 => 'NET_SSH2_MSG_CHANNEL_EXTENDED_DATA', - 96 => 'NET_SSH2_MSG_CHANNEL_EOF', - 97 => 'NET_SSH2_MSG_CHANNEL_CLOSE', - 98 => 'NET_SSH2_MSG_CHANNEL_REQUEST', - 99 => 'NET_SSH2_MSG_CHANNEL_SUCCESS', - 100 => 'NET_SSH2_MSG_CHANNEL_FAILURE' - ]; - self::$disconnect_reasons = [ - 1 => 'NET_SSH2_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT', - 2 => 'NET_SSH2_DISCONNECT_PROTOCOL_ERROR', - 3 => 'NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED', - 4 => 'NET_SSH2_DISCONNECT_RESERVED', - 5 => 'NET_SSH2_DISCONNECT_MAC_ERROR', - 6 => 'NET_SSH2_DISCONNECT_COMPRESSION_ERROR', - 7 => 'NET_SSH2_DISCONNECT_SERVICE_NOT_AVAILABLE', - 8 => 'NET_SSH2_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED', - 9 => 'NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE', - 10 => 'NET_SSH2_DISCONNECT_CONNECTION_LOST', - 11 => 'NET_SSH2_DISCONNECT_BY_APPLICATION', - 12 => 'NET_SSH2_DISCONNECT_TOO_MANY_CONNECTIONS', - 13 => 'NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER', - 14 => 'NET_SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE', - 15 => 'NET_SSH2_DISCONNECT_ILLEGAL_USER_NAME' - ]; - self::$channel_open_failure_reasons = [ - 1 => 'NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED' - ]; - self::$terminal_modes = [ - 0 => 'NET_SSH2_TTY_OP_END' - ]; - self::$channel_extended_data_type_codes = [ - 1 => 'NET_SSH2_EXTENDED_DATA_STDERR' - ]; - - self::define_array( - self::$message_numbers, - self::$disconnect_reasons, - self::$channel_open_failure_reasons, - self::$terminal_modes, - self::$channel_extended_data_type_codes, - [60 => 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'], - [60 => 'NET_SSH2_MSG_USERAUTH_PK_OK'], - [60 => 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST', - 61 => 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'], - // RFC 4419 - diffie-hellman-group-exchange-sha{1,256} - [30 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST_OLD', - 31 => 'NET_SSH2_MSG_KEXDH_GEX_GROUP', - 32 => 'NET_SSH2_MSG_KEXDH_GEX_INIT', - 33 => 'NET_SSH2_MSG_KEXDH_GEX_REPLY', - 34 => 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'], - // RFC 5656 - Elliptic Curves (for curve25519-sha256@libssh.org) - [30 => 'NET_SSH2_MSG_KEX_ECDH_INIT', - 31 => 'NET_SSH2_MSG_KEX_ECDH_REPLY'] - ); - } - - /** - * Typehint is required due to a bug in Psalm: https://github.com/vimeo/psalm/issues/7508 - * @var \WeakReference|SSH2 - */ - self::$connections[$this->getResourceId()] = class_exists('WeakReference') - ? \WeakReference::create($this) - : $this; - - if (is_resource($host)) { - $this->fsock = $host; - return; - } - - if (Strings::is_stringable($host)) { - $this->host = $host; - $this->port = $port; - $this->timeout = $timeout; - } - } - - /** - * Set Crypto Engine Mode - * - * Possible $engine values: - * OpenSSL, mcrypt, Eval, PHP - * - * @param int $engine - */ - public static function setCryptoEngine($engine) - { - self::$crypto_engine = $engine; - } - - /** - * Send Identification String First - * - * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, - * both sides MUST send an identification string". It does not say which side sends it first. In - * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - */ - public function sendIdentificationStringFirst() - { - $this->send_id_string_first = true; - } - - /** - * Send Identification String Last - * - * https://tools.ietf.org/html/rfc4253#section-4.2 says "when the connection has been established, - * both sides MUST send an identification string". It does not say which side sends it first. In - * theory it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - */ - public function sendIdentificationStringLast() - { - $this->send_id_string_first = false; - } - - /** - * Send SSH_MSG_KEXINIT First - * - * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending - * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory - * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - */ - public function sendKEXINITFirst() - { - $this->send_kex_first = true; - } - - /** - * Send SSH_MSG_KEXINIT Last - * - * https://tools.ietf.org/html/rfc4253#section-7.1 says "key exchange begins by each sending - * sending the [SSH_MSG_KEXINIT] packet". It does not say which side sends it first. In theory - * it shouldn't matter but it is a fact of life that some SSH servers are simply buggy - * - */ - public function sendKEXINITLast() - { - $this->send_kex_first = false; - } - - /** - * stream_select wrapper - * - * Quoting https://stackoverflow.com/a/14262151/569976, - * "The general approach to `EINTR` is to simply handle the error and retry the operation again" - * - * This wrapper does that loop - */ - private static function stream_select(&$read, &$write, &$except, $seconds, $microseconds = null) - { - $remaining = $seconds + $microseconds / 1000000; - $start = microtime(true); - while (true) { - $result = @stream_select($read, $write, $except, $seconds, $microseconds); - if ($result !== false) { - return $result; - } - $elapsed = microtime(true) - $start; - $seconds = (int) ($remaining - floor($elapsed)); - $microseconds = (int) (1000000 * ($remaining - $seconds)); - if ($elapsed >= $remaining) { - return false; - } - } - } - - /** - * Connect to an SSHv2 server - * - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors - */ - private function connect() - { - if ($this->bitmap & self::MASK_CONSTRUCTOR) { - return; - } - - $this->bitmap |= self::MASK_CONSTRUCTOR; - - $this->curTimeout = $this->timeout; - - $this->last_packet = microtime(true); - - if (!is_resource($this->fsock)) { - $start = microtime(true); - // with stream_select a timeout of 0 means that no timeout takes place; - // with fsockopen a timeout of 0 means that you instantly timeout - // to resolve this incompatibility a timeout of 100,000 will be used for fsockopen if timeout is 0 - $this->fsock = @fsockopen($this->host, $this->port, $errno, $errstr, $this->curTimeout == 0 ? 100000 : $this->curTimeout); - if (!$this->fsock) { - $host = $this->host . ':' . $this->port; - throw new UnableToConnectException(rtrim("Cannot connect to $host. Error $errno. $errstr")); - } - $elapsed = microtime(true) - $start; - - if ($this->curTimeout) { - $this->curTimeout -= $elapsed; - if ($this->curTimeout < 0) { - throw new \RuntimeException('Connection timed out whilst attempting to open socket connection'); - } - } - } - - $this->identifier = $this->generate_identifier(); - - if ($this->send_id_string_first) { - fputs($this->fsock, $this->identifier . "\r\n"); - } - - /* According to the SSH2 specs, - - "The server MAY send other lines of data before sending the version - string. Each line SHOULD be terminated by a Carriage Return and Line - Feed. Such lines MUST NOT begin with "SSH-", and SHOULD be encoded - in ISO-10646 UTF-8 [RFC3629] (language is not specified). Clients - MUST be able to process such lines." */ - $data = ''; - while (!feof($this->fsock) && !preg_match('#(.*)^(SSH-(\d\.\d+).*)#ms', $data, $matches)) { - $line = ''; - while (true) { - if ($this->curTimeout) { - if ($this->curTimeout < 0) { - throw new \RuntimeException('Connection timed out whilst receiving server identification string'); - } - $read = [$this->fsock]; - $write = $except = null; - $start = microtime(true); - $sec = (int) floor($this->curTimeout); - $usec = (int) (1000000 * ($this->curTimeout - $sec)); - if (static::stream_select($read, $write, $except, $sec, $usec) === false) { - throw new \RuntimeException('Connection timed out whilst receiving server identification string'); - } - $elapsed = microtime(true) - $start; - $this->curTimeout -= $elapsed; - } - - $temp = stream_get_line($this->fsock, 255, "\n"); - if ($temp === false) { - throw new \RuntimeException('Error reading from socket'); - } - if (strlen($temp) == 255) { - continue; - } - - $line .= "$temp\n"; - - // quoting RFC4253, "Implementers who wish to maintain - // compatibility with older, undocumented versions of this protocol may - // want to process the identification string without expecting the - // presence of the carriage return character for reasons described in - // Section 5 of this document." - - //if (substr($line, -2) == "\r\n") { - // break; - //} - - break; - } - - $data .= $line; - } - - if (feof($this->fsock)) { - $this->bitmap = 0; - throw new ConnectionClosedException('Connection closed by server'); - } - - $extra = $matches[1]; - - if (defined('NET_SSH2_LOGGING')) { - $this->append_log('<-', $matches[0]); - $this->append_log('->', $this->identifier . "\r\n"); - } - - $this->server_identifier = trim($temp, "\r\n"); - if (strlen($extra)) { - $this->errors[] = $data; - } - - if (version_compare($matches[3], '1.99', '<')) { - $this->bitmap = 0; - throw new UnableToConnectException("Cannot connect to SSH $matches[3] servers"); - } - - // Ubuntu's OpenSSH from 5.8 to 6.9 didn't work with multiple channels. see - // https://bugs.launchpad.net/ubuntu/+source/openssh/+bug/1334916 for more info. - // https://lists.ubuntu.com/archives/oneiric-changes/2011-July/005772.html discusses - // when consolekit was incorporated. - // https://marc.info/?l=openssh-unix-dev&m=163409903417589&w=2 discusses some of the - // issues with how Ubuntu incorporated consolekit - $pattern = '#^SSH-2\.0-OpenSSH_([\d.]+)[^ ]* Ubuntu-.*$#'; - $match = preg_match($pattern, $this->server_identifier, $matches); - $match = $match && version_compare('5.8', $matches[1], '<='); - $match = $match && version_compare('6.9', $matches[1], '>='); - $this->errorOnMultipleChannels = $match; - - if (!$this->send_id_string_first) { - fputs($this->fsock, $this->identifier . "\r\n"); - } - - if (!$this->send_kex_first) { - $response = $this->get_binary_packet(); - - if (is_bool($response) || !strlen($response) || ord($response[0]) != NET_SSH2_MSG_KEXINIT) { - $this->bitmap = 0; - throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); - } - - $this->key_exchange($response); - } - - if ($this->send_kex_first) { - $this->key_exchange(); - } - - $this->bitmap |= self::MASK_CONNECTED; - - return true; - } - - /** - * Generates the SSH identifier - * - * You should overwrite this method in your own class if you want to use another identifier - * - * @return string - */ - private function generate_identifier() - { - $identifier = 'SSH-2.0-phpseclib_3.0'; - - $ext = []; - if (extension_loaded('sodium')) { - $ext[] = 'libsodium'; - } - - if (extension_loaded('openssl')) { - $ext[] = 'openssl'; - } elseif (extension_loaded('mcrypt')) { - $ext[] = 'mcrypt'; - } - - if (extension_loaded('gmp')) { - $ext[] = 'gmp'; - } elseif (extension_loaded('bcmath')) { - $ext[] = 'bcmath'; - } - - if (!empty($ext)) { - $identifier .= ' (' . implode(', ', $ext) . ')'; - } - - return $identifier; - } - - /** - * Key Exchange - * - * @return bool - * @param string|bool $kexinit_payload_server optional - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors - * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when none of the algorithms phpseclib has loaded are compatible - */ - private function key_exchange($kexinit_payload_server = false) - { - $preferred = $this->preferred; - $send_kex = true; - - $kex_algorithms = isset($preferred['kex']) ? - $preferred['kex'] : - SSH2::getSupportedKEXAlgorithms(); - $server_host_key_algorithms = isset($preferred['hostkey']) ? - $preferred['hostkey'] : - SSH2::getSupportedHostKeyAlgorithms(); - $s2c_encryption_algorithms = isset($preferred['server_to_client']['crypt']) ? - $preferred['server_to_client']['crypt'] : - SSH2::getSupportedEncryptionAlgorithms(); - $c2s_encryption_algorithms = isset($preferred['client_to_server']['crypt']) ? - $preferred['client_to_server']['crypt'] : - SSH2::getSupportedEncryptionAlgorithms(); - $s2c_mac_algorithms = isset($preferred['server_to_client']['mac']) ? - $preferred['server_to_client']['mac'] : - SSH2::getSupportedMACAlgorithms(); - $c2s_mac_algorithms = isset($preferred['client_to_server']['mac']) ? - $preferred['client_to_server']['mac'] : - SSH2::getSupportedMACAlgorithms(); - $s2c_compression_algorithms = isset($preferred['server_to_client']['comp']) ? - $preferred['server_to_client']['comp'] : - SSH2::getSupportedCompressionAlgorithms(); - $c2s_compression_algorithms = isset($preferred['client_to_server']['comp']) ? - $preferred['client_to_server']['comp'] : - SSH2::getSupportedCompressionAlgorithms(); - - $kex_algorithms = array_merge($kex_algorithms, ['ext-info-c', 'kex-strict-c-v00@openssh.com']); - - // some SSH servers have buggy implementations of some of the above algorithms - switch (true) { - case $this->server_identifier == 'SSH-2.0-SSHD': - case substr($this->server_identifier, 0, 13) == 'SSH-2.0-DLINK': - if (!isset($preferred['server_to_client']['mac'])) { - $s2c_mac_algorithms = array_values(array_diff( - $s2c_mac_algorithms, - ['hmac-sha1-96', 'hmac-md5-96'] - )); - } - if (!isset($preferred['client_to_server']['mac'])) { - $c2s_mac_algorithms = array_values(array_diff( - $c2s_mac_algorithms, - ['hmac-sha1-96', 'hmac-md5-96'] - )); - } - break; - case substr($this->server_identifier, 0, 24) == 'SSH-2.0-TurboFTP_SERVER_': - if (!isset($preferred['server_to_client']['crypt'])) { - $s2c_encryption_algorithms = array_values(array_diff( - $s2c_encryption_algorithms, - ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] - )); - } - if (!isset($preferred['client_to_server']['crypt'])) { - $c2s_encryption_algorithms = array_values(array_diff( - $c2s_encryption_algorithms, - ['aes128-gcm@openssh.com', 'aes256-gcm@openssh.com'] - )); - } - } - - $client_cookie = Random::string(16); - - $kexinit_payload_client = pack('Ca*', NET_SSH2_MSG_KEXINIT, $client_cookie); - $kexinit_payload_client .= Strings::packSSH2( - 'L10bN', - $kex_algorithms, - $server_host_key_algorithms, - $c2s_encryption_algorithms, - $s2c_encryption_algorithms, - $c2s_mac_algorithms, - $s2c_mac_algorithms, - $c2s_compression_algorithms, - $s2c_compression_algorithms, - [], // language, client to server - [], // language, server to client - false, // first_kex_packet_follows - 0 // reserved for future extension - ); - - if ($kexinit_payload_server === false) { - $this->send_binary_packet($kexinit_payload_client); - - $this->extra_packets = 0; - $kexinit_payload_server = $this->get_binary_packet(); - - if ( - is_bool($kexinit_payload_server) - || !strlen($kexinit_payload_server) - || ord($kexinit_payload_server[0]) != NET_SSH2_MSG_KEXINIT - ) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_KEXINIT'); - } - - $send_kex = false; - } - - $response = $kexinit_payload_server; - Strings::shift($response, 1); // skip past the message number (it should be SSH_MSG_KEXINIT) - $server_cookie = Strings::shift($response, 16); - - list( - $this->kex_algorithms, - $this->server_host_key_algorithms, - $this->encryption_algorithms_client_to_server, - $this->encryption_algorithms_server_to_client, - $this->mac_algorithms_client_to_server, - $this->mac_algorithms_server_to_client, - $this->compression_algorithms_client_to_server, - $this->compression_algorithms_server_to_client, - $this->languages_client_to_server, - $this->languages_server_to_client, - $first_kex_packet_follows - ) = Strings::unpackSSH2('L10C', $response); - if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { - if ($this->session_id === false && $this->extra_packets) { - throw new \UnexpectedValueException('Possible Terrapin Attack detected'); - } - } - - $this->supported_private_key_algorithms = $this->server_host_key_algorithms; - - if ($send_kex) { - $this->send_binary_packet($kexinit_payload_client); - } - - // we need to decide upon the symmetric encryption algorithms before we do the diffie-hellman key exchange - - // we don't initialize any crypto-objects, yet - we do that, later. for now, we need the lengths to make the - // diffie-hellman key exchange as fast as possible - $decrypt = self::array_intersect_first($s2c_encryption_algorithms, $this->encryption_algorithms_server_to_client); - $decryptKeyLength = $this->encryption_algorithm_to_key_size($decrypt); - if ($decryptKeyLength === null) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server to client encryption algorithms found'); - } - - $encrypt = self::array_intersect_first($c2s_encryption_algorithms, $this->encryption_algorithms_client_to_server); - $encryptKeyLength = $this->encryption_algorithm_to_key_size($encrypt); - if ($encryptKeyLength === null) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible client to server encryption algorithms found'); - } - - // through diffie-hellman key exchange a symmetric key is obtained - $this->kex_algorithm = self::array_intersect_first($kex_algorithms, $this->kex_algorithms); - if ($this->kex_algorithm === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible key exchange algorithms found'); - } - - $server_host_key_algorithm = self::array_intersect_first($server_host_key_algorithms, $this->server_host_key_algorithms); - if ($server_host_key_algorithm === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server host key algorithms found'); - } - - $mac_algorithm_out = self::array_intersect_first($c2s_mac_algorithms, $this->mac_algorithms_client_to_server); - if ($mac_algorithm_out === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible client to server message authentication algorithms found'); - } - - $mac_algorithm_in = self::array_intersect_first($s2c_mac_algorithms, $this->mac_algorithms_server_to_client); - if ($mac_algorithm_in === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server to client message authentication algorithms found'); - } - - $compression_map = [ - 'none' => self::NET_SSH2_COMPRESSION_NONE, - 'zlib' => self::NET_SSH2_COMPRESSION_ZLIB, - 'zlib@openssh.com' => self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH - ]; - - $compression_algorithm_in = self::array_intersect_first($s2c_compression_algorithms, $this->compression_algorithms_server_to_client); - if ($compression_algorithm_in === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible server to client compression algorithms found'); - } - $this->decompress = $compression_map[$compression_algorithm_in]; - - $compression_algorithm_out = self::array_intersect_first($c2s_compression_algorithms, $this->compression_algorithms_client_to_server); - if ($compression_algorithm_out === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - throw new NoSupportedAlgorithmsException('No compatible client to server compression algorithms found'); - } - $this->compress = $compression_map[$compression_algorithm_out]; - - switch ($this->kex_algorithm) { - case 'diffie-hellman-group15-sha512': - case 'diffie-hellman-group16-sha512': - case 'diffie-hellman-group17-sha512': - case 'diffie-hellman-group18-sha512': - case 'ecdh-sha2-nistp521': - $kexHash = new Hash('sha512'); - break; - case 'ecdh-sha2-nistp384': - $kexHash = new Hash('sha384'); - break; - case 'diffie-hellman-group-exchange-sha256': - case 'diffie-hellman-group14-sha256': - case 'ecdh-sha2-nistp256': - case 'curve25519-sha256@libssh.org': - case 'curve25519-sha256': - $kexHash = new Hash('sha256'); - break; - default: - $kexHash = new Hash('sha1'); - } - - // Only relevant in diffie-hellman-group-exchange-sha{1,256}, otherwise empty. - - $exchange_hash_rfc4419 = ''; - - if (strpos($this->kex_algorithm, 'curve25519-sha256') === 0 || strpos($this->kex_algorithm, 'ecdh-sha2-nistp') === 0) { - $curve = strpos($this->kex_algorithm, 'curve25519-sha256') === 0 ? - 'Curve25519' : - substr($this->kex_algorithm, 10); - $ourPrivate = EC::createKey($curve); - $ourPublicBytes = $ourPrivate->getPublicKey()->getEncodedCoordinates(); - $clientKexInitMessage = 'NET_SSH2_MSG_KEX_ECDH_INIT'; - $serverKexReplyMessage = 'NET_SSH2_MSG_KEX_ECDH_REPLY'; - } else { - if (strpos($this->kex_algorithm, 'diffie-hellman-group-exchange') === 0) { - $dh_group_sizes_packed = pack( - 'NNN', - $this->kex_dh_group_size_min, - $this->kex_dh_group_size_preferred, - $this->kex_dh_group_size_max - ); - $packet = pack( - 'Ca*', - NET_SSH2_MSG_KEXDH_GEX_REQUEST, - $dh_group_sizes_packed - ); - $this->send_binary_packet($packet); - $this->updateLogHistory('UNKNOWN (34)', 'NET_SSH2_MSG_KEXDH_GEX_REQUEST'); - - $response = $this->get_binary_packet(); - - list($type, $primeBytes, $gBytes) = Strings::unpackSSH2('Css', $response); - if ($type != NET_SSH2_MSG_KEXDH_GEX_GROUP) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_KEX_DH_GEX_GROUP'); - } - $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEXDH_GEX_GROUP'); - $prime = new BigInteger($primeBytes, -256); - $g = new BigInteger($gBytes, -256); - - $exchange_hash_rfc4419 = $dh_group_sizes_packed . Strings::packSSH2( - 'ss', - $primeBytes, - $gBytes - ); - - $params = DH::createParameters($prime, $g); - $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_GEX_INIT'; - $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_GEX_REPLY'; - } else { - $params = DH::createParameters($this->kex_algorithm); - $clientKexInitMessage = 'NET_SSH2_MSG_KEXDH_INIT'; - $serverKexReplyMessage = 'NET_SSH2_MSG_KEXDH_REPLY'; - } - - $keyLength = min($kexHash->getLengthInBytes(), max($encryptKeyLength, $decryptKeyLength)); - - $ourPrivate = DH::createKey($params, 16 * $keyLength); // 2 * 8 * $keyLength - $ourPublic = $ourPrivate->getPublicKey()->toBigInteger(); - $ourPublicBytes = $ourPublic->toBytes(true); - } - - $data = pack('CNa*', constant($clientKexInitMessage), strlen($ourPublicBytes), $ourPublicBytes); - - $this->send_binary_packet($data); - - switch ($clientKexInitMessage) { - case 'NET_SSH2_MSG_KEX_ECDH_INIT': - $this->updateLogHistory('NET_SSH2_MSG_KEXDH_INIT', 'NET_SSH2_MSG_KEX_ECDH_INIT'); - break; - case 'NET_SSH2_MSG_KEXDH_GEX_INIT': - $this->updateLogHistory('UNKNOWN (32)', 'NET_SSH2_MSG_KEXDH_GEX_INIT'); - } - - $response = $this->get_binary_packet(); - - list( - $type, - $server_public_host_key, - $theirPublicBytes, - $this->signature - ) = Strings::unpackSSH2('Csss', $response); - - if ($type != constant($serverKexReplyMessage)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException("Expected $serverKexReplyMessage"); - } - switch ($serverKexReplyMessage) { - case 'NET_SSH2_MSG_KEX_ECDH_REPLY': - $this->updateLogHistory('NET_SSH2_MSG_KEXDH_REPLY', 'NET_SSH2_MSG_KEX_ECDH_REPLY'); - break; - case 'NET_SSH2_MSG_KEXDH_GEX_REPLY': - $this->updateLogHistory('UNKNOWN (33)', 'NET_SSH2_MSG_KEXDH_GEX_REPLY'); - } - - $this->server_public_host_key = $server_public_host_key; - list($public_key_format) = Strings::unpackSSH2('s', $server_public_host_key); - if (strlen($this->signature) < 4) { - throw new \LengthException('The signature needs at least four bytes'); - } - $temp = unpack('Nlength', substr($this->signature, 0, 4)); - $this->signature_format = substr($this->signature, 4, $temp['length']); - - $keyBytes = DH::computeSecret($ourPrivate, $theirPublicBytes); - if (($keyBytes & "\xFF\x80") === "\x00\x00") { - $keyBytes = substr($keyBytes, 1); - } elseif (($keyBytes[0] & "\x80") === "\x80") { - $keyBytes = "\0$keyBytes"; - } - - $this->exchange_hash = Strings::packSSH2( - 's5', - $this->identifier, - $this->server_identifier, - $kexinit_payload_client, - $kexinit_payload_server, - $this->server_public_host_key - ); - $this->exchange_hash .= $exchange_hash_rfc4419; - $this->exchange_hash .= Strings::packSSH2( - 's3', - $ourPublicBytes, - $theirPublicBytes, - $keyBytes - ); - - $this->exchange_hash = $kexHash->hash($this->exchange_hash); - - if ($this->session_id === false) { - $this->session_id = $this->exchange_hash; - } - - switch ($server_host_key_algorithm) { - case 'rsa-sha2-256': - case 'rsa-sha2-512': - //case 'ssh-rsa': - $expected_key_format = 'ssh-rsa'; - break; - default: - $expected_key_format = $server_host_key_algorithm; - } - if ($public_key_format != $expected_key_format || $this->signature_format != $server_host_key_algorithm) { - switch (true) { - case $this->signature_format == $server_host_key_algorithm: - case $server_host_key_algorithm != 'rsa-sha2-256' && $server_host_key_algorithm != 'rsa-sha2-512': - case $this->signature_format != 'ssh-rsa': - $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - throw new \RuntimeException('Server Host Key Algorithm Mismatch (' . $this->signature_format . ' vs ' . $server_host_key_algorithm . ')'); - } - } - - $packet = pack('C', NET_SSH2_MSG_NEWKEYS); - $this->send_binary_packet($packet); - - $response = $this->get_binary_packet(); - - if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); - } - - list($type) = Strings::unpackSSH2('C', $response); - if ($type != NET_SSH2_MSG_NEWKEYS) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_NEWKEYS'); - } - - if (in_array('kex-strict-s-v00@openssh.com', $this->kex_algorithms)) { - $this->get_seq_no = $this->send_seq_no = 0; - } - - $keyBytes = pack('Na*', strlen($keyBytes), $keyBytes); - - $this->encrypt = self::encryption_algorithm_to_crypt_instance($encrypt); - if ($this->encrypt) { - if (self::$crypto_engine) { - $this->encrypt->setPreferredEngine(self::$crypto_engine); - } - if ($this->encrypt->getBlockLengthInBytes()) { - $this->encrypt_block_size = $this->encrypt->getBlockLengthInBytes(); - } - $this->encrypt->disablePadding(); - - if ($this->encrypt->usesIV()) { - $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); - while ($this->encrypt_block_size > strlen($iv)) { - $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); - } - $this->encrypt->setIV(substr($iv, 0, $this->encrypt_block_size)); - } - - switch ($encrypt) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'A' . $this->session_id); - $this->encryptFixedPart = substr($nonce, 0, 4); - $this->encryptInvocationCounter = substr($nonce, 4, 8); - // fall-through - case 'chacha20-poly1305@openssh.com': - break; - default: - $this->encrypt->enableContinuousBuffer(); - } - - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'C' . $this->session_id); - while ($encryptKeyLength > strlen($key)) { - $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - switch ($encrypt) { - case 'chacha20-poly1305@openssh.com': - $encryptKeyLength = 32; - $this->lengthEncrypt = self::encryption_algorithm_to_crypt_instance($encrypt); - $this->lengthEncrypt->setKey(substr($key, 32, 32)); - } - $this->encrypt->setKey(substr($key, 0, $encryptKeyLength)); - $this->encryptName = $encrypt; - } - - $this->decrypt = self::encryption_algorithm_to_crypt_instance($decrypt); - if ($this->decrypt) { - if (self::$crypto_engine) { - $this->decrypt->setPreferredEngine(self::$crypto_engine); - } - if ($this->decrypt->getBlockLengthInBytes()) { - $this->decrypt_block_size = $this->decrypt->getBlockLengthInBytes(); - } - $this->decrypt->disablePadding(); - - if ($this->decrypt->usesIV()) { - $iv = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); - while ($this->decrypt_block_size > strlen($iv)) { - $iv .= $kexHash->hash($keyBytes . $this->exchange_hash . $iv); - } - $this->decrypt->setIV(substr($iv, 0, $this->decrypt_block_size)); - } - - switch ($decrypt) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - // see https://tools.ietf.org/html/rfc5647#section-7.1 - $nonce = $kexHash->hash($keyBytes . $this->exchange_hash . 'B' . $this->session_id); - $this->decryptFixedPart = substr($nonce, 0, 4); - $this->decryptInvocationCounter = substr($nonce, 4, 8); - // fall-through - case 'chacha20-poly1305@openssh.com': - break; - default: - $this->decrypt->enableContinuousBuffer(); - } - - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'D' . $this->session_id); - while ($decryptKeyLength > strlen($key)) { - $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - switch ($decrypt) { - case 'chacha20-poly1305@openssh.com': - $decryptKeyLength = 32; - $this->lengthDecrypt = self::encryption_algorithm_to_crypt_instance($decrypt); - $this->lengthDecrypt->setKey(substr($key, 32, 32)); - } - $this->decrypt->setKey(substr($key, 0, $decryptKeyLength)); - $this->decryptName = $decrypt; - } - - /* The "arcfour128" algorithm is the RC4 cipher, as described in - [SCHNEIER], using a 128-bit key. The first 1536 bytes of keystream - generated by the cipher MUST be discarded, and the first byte of the - first encrypted packet MUST be encrypted using the 1537th byte of - keystream. - - -- http://tools.ietf.org/html/rfc4345#section-4 */ - if ($encrypt == 'arcfour128' || $encrypt == 'arcfour256') { - $this->encrypt->encrypt(str_repeat("\0", 1536)); - } - if ($decrypt == 'arcfour128' || $decrypt == 'arcfour256') { - $this->decrypt->decrypt(str_repeat("\0", 1536)); - } - - if (!$this->encrypt->usesNonce()) { - list($this->hmac_create, $createKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_out); - } else { - $this->hmac_create = new \stdClass(); - $this->hmac_create_name = $mac_algorithm_out; - //$mac_algorithm_out = 'none'; - $createKeyLength = 0; - } - - if ($this->hmac_create instanceof Hash) { - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'E' . $this->session_id); - while ($createKeyLength > strlen($key)) { - $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->hmac_create->setKey(substr($key, 0, $createKeyLength)); - $this->hmac_create_name = $mac_algorithm_out; - $this->hmac_create_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_out); - } - - if (!$this->decrypt->usesNonce()) { - list($this->hmac_check, $checkKeyLength) = self::mac_algorithm_to_hash_instance($mac_algorithm_in); - $this->hmac_size = $this->hmac_check->getLengthInBytes(); - } else { - $this->hmac_check = new \stdClass(); - $this->hmac_check_name = $mac_algorithm_in; - //$mac_algorithm_in = 'none'; - $checkKeyLength = 0; - $this->hmac_size = 0; - } - - if ($this->hmac_check instanceof Hash) { - $key = $kexHash->hash($keyBytes . $this->exchange_hash . 'F' . $this->session_id); - while ($checkKeyLength > strlen($key)) { - $key .= $kexHash->hash($keyBytes . $this->exchange_hash . $key); - } - $this->hmac_check->setKey(substr($key, 0, $checkKeyLength)); - $this->hmac_check_name = $mac_algorithm_in; - $this->hmac_check_etm = preg_match('#-etm@openssh\.com$#', $mac_algorithm_in); - } - - $this->regenerate_compression_context = $this->regenerate_decompression_context = true; - - return true; - } - - /** - * Maps an encryption algorithm name to the number of key bytes. - * - * @param string $algorithm Name of the encryption algorithm - * @return int|null Number of bytes as an integer or null for unknown - */ - private function encryption_algorithm_to_key_size($algorithm) - { - if ($this->bad_key_size_fix && self::bad_algorithm_candidate($algorithm)) { - return 16; - } - - switch ($algorithm) { - case 'none': - return 0; - case 'aes128-gcm@openssh.com': - case 'aes128-cbc': - case 'aes128-ctr': - case 'arcfour': - case 'arcfour128': - case 'blowfish-cbc': - case 'blowfish-ctr': - case 'twofish128-cbc': - case 'twofish128-ctr': - return 16; - case '3des-cbc': - case '3des-ctr': - case 'aes192-cbc': - case 'aes192-ctr': - case 'twofish192-cbc': - case 'twofish192-ctr': - return 24; - case 'aes256-gcm@openssh.com': - case 'aes256-cbc': - case 'aes256-ctr': - case 'arcfour256': - case 'twofish-cbc': - case 'twofish256-cbc': - case 'twofish256-ctr': - return 32; - case 'chacha20-poly1305@openssh.com': - return 64; - } - return null; - } - - /** - * Maps an encryption algorithm name to an instance of a subclass of - * \phpseclib3\Crypt\Common\SymmetricKey. - * - * @param string $algorithm Name of the encryption algorithm - * @return SymmetricKey|null - */ - private static function encryption_algorithm_to_crypt_instance($algorithm) - { - switch ($algorithm) { - case '3des-cbc': - return new TripleDES('cbc'); - case '3des-ctr': - return new TripleDES('ctr'); - case 'aes256-cbc': - case 'aes192-cbc': - case 'aes128-cbc': - return new Rijndael('cbc'); - case 'aes256-ctr': - case 'aes192-ctr': - case 'aes128-ctr': - return new Rijndael('ctr'); - case 'blowfish-cbc': - return new Blowfish('cbc'); - case 'blowfish-ctr': - return new Blowfish('ctr'); - case 'twofish128-cbc': - case 'twofish192-cbc': - case 'twofish256-cbc': - case 'twofish-cbc': - return new Twofish('cbc'); - case 'twofish128-ctr': - case 'twofish192-ctr': - case 'twofish256-ctr': - return new Twofish('ctr'); - case 'arcfour': - case 'arcfour128': - case 'arcfour256': - return new RC4(); - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - return new Rijndael('gcm'); - case 'chacha20-poly1305@openssh.com': - return new ChaCha20(); - } - return null; - } - - /** - * Maps an encryption algorithm name to an instance of a subclass of - * \phpseclib3\Crypt\Hash. - * - * @param string $algorithm Name of the encryption algorithm - * @return array{Hash, int}|null - */ - private static function mac_algorithm_to_hash_instance($algorithm) - { - switch ($algorithm) { - case 'umac-64@openssh.com': - case 'umac-64-etm@openssh.com': - return [new Hash('umac-64'), 16]; - case 'umac-128@openssh.com': - case 'umac-128-etm@openssh.com': - return [new Hash('umac-128'), 16]; - case 'hmac-sha2-512': - case 'hmac-sha2-512-etm@openssh.com': - return [new Hash('sha512'), 64]; - case 'hmac-sha2-256': - case 'hmac-sha2-256-etm@openssh.com': - return [new Hash('sha256'), 32]; - case 'hmac-sha1': - case 'hmac-sha1-etm@openssh.com': - return [new Hash('sha1'), 20]; - case 'hmac-sha1-96': - return [new Hash('sha1-96'), 20]; - case 'hmac-md5': - return [new Hash('md5'), 16]; - case 'hmac-md5-96': - return [new Hash('md5-96'), 16]; - } - } - - /* - * Tests whether or not proposed algorithm has a potential for issues - * - * @link https://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/ssh2-aesctr-openssh.html - * @link https://bugzilla.mindrot.org/show_bug.cgi?id=1291 - * @param string $algorithm Name of the encryption algorithm - * @return bool - */ - private static function bad_algorithm_candidate($algorithm) - { - switch ($algorithm) { - case 'arcfour256': - case 'aes192-ctr': - case 'aes256-ctr': - return true; - } - - return false; - } - - /** - * Login - * - * The $password parameter can be a plaintext password, a \phpseclib3\Crypt\RSA|EC|DSA object, a \phpseclib3\System\SSH\Agent object or an array - * - * @param string $username - * @param string|PrivateKey|array[]|Agent|null ...$args - * @return bool - * @see self::_login() - */ - public function login($username, ...$args) - { - if (!$this->retry_connect) { - $this->auth[] = func_get_args(); - } - - // try logging with 'none' as an authentication method first since that's what - // PuTTY does - if (substr($this->server_identifier, 0, 15) != 'SSH-2.0-CoreFTP' && $this->auth_methods_to_continue === null) { - if ($this->sublogin($username)) { - return true; - } - if (!count($args)) { - return false; - } - } - return $this->sublogin($username, ...$args); - } - - /** - * Login Helper - * - * @param string $username - * @param string|PrivateKey|array[]|Agent|null ...$args - * @return bool - * @see self::_login_helper() - */ - protected function sublogin($username, ...$args) - { - if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - $this->connect(); - } - - if (empty($args)) { - return $this->login_helper($username); - } - - foreach ($args as $arg) { - switch (true) { - case $arg instanceof PublicKey: - throw new \UnexpectedValueException('A PublicKey object was passed to the login method instead of a PrivateKey object'); - case $arg instanceof PrivateKey: - case $arg instanceof Agent: - case is_array($arg): - case Strings::is_stringable($arg): - break; - default: - throw new \UnexpectedValueException('$password needs to either be an instance of \phpseclib3\Crypt\Common\PrivateKey, \System\SSH\Agent, an array or a string'); - } - } - - while (count($args)) { - if (!$this->auth_methods_to_continue || !$this->smartMFA) { - $newargs = $args; - $args = []; - } else { - $newargs = []; - foreach ($this->auth_methods_to_continue as $method) { - switch ($method) { - case 'publickey': - foreach ($args as $key => $arg) { - if ($arg instanceof PrivateKey || $arg instanceof Agent) { - $newargs[] = $arg; - unset($args[$key]); - break; - } - } - break; - case 'keyboard-interactive': - $hasArray = $hasString = false; - foreach ($args as $arg) { - if ($hasArray || is_array($arg)) { - $hasArray = true; - break; - } - if ($hasString || Strings::is_stringable($arg)) { - $hasString = true; - break; - } - } - if ($hasArray && $hasString) { - foreach ($args as $key => $arg) { - if (is_array($arg)) { - $newargs[] = $arg; - break 2; - } - } - } - // fall-through - case 'password': - foreach ($args as $key => $arg) { - $newargs[] = $arg; - unset($args[$key]); - break; - } - } - } - } - - if (!count($newargs)) { - return false; - } - - foreach ($newargs as $arg) { - if ($this->login_helper($username, $arg)) { - return true; - } - } - } - return false; - } - - /** - * Login Helper - * - * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} - * by sending dummy SSH_MSG_IGNORE messages.} - * - * @param string $username - * @param string|AsymmetricKey|array[]|Agent|null ...$args - * @return bool - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors - */ - private function login_helper($username, $password = null) - { - if (!($this->bitmap & self::MASK_CONNECTED)) { - return false; - } - - if (!($this->bitmap & self::MASK_LOGIN_REQ)) { - $packet = Strings::packSSH2('Cs', NET_SSH2_MSG_SERVICE_REQUEST, 'ssh-userauth'); - $this->send_binary_packet($packet); - - try { - $response = $this->get_binary_packet(); - } catch (\Exception $e) { - if ($this->retry_connect) { - $this->retry_connect = false; - $this->connect(); - return $this->login_helper($username, $password); - } - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw $e; - } - - list($type) = Strings::unpackSSH2('C', $response); - - if ($type == NET_SSH2_MSG_EXT_INFO) { - list($nr_extensions) = Strings::unpackSSH2('N', $response); - for ($i = 0; $i < $nr_extensions; $i++) { - list($extension_name, $extension_value) = Strings::unpackSSH2('ss', $response); - if ($extension_name == 'server-sig-algs') { - $this->supported_private_key_algorithms = explode(',', $extension_value); - } - } - - $response = $this->get_binary_packet(); - list($type) = Strings::unpackSSH2('C', $response); - } - - list($service) = Strings::unpackSSH2('s', $response); - - if ($type != NET_SSH2_MSG_SERVICE_ACCEPT || $service != 'ssh-userauth') { - $this->disconnect_helper(NET_SSH2_DISCONNECT_PROTOCOL_ERROR); - throw new \UnexpectedValueException('Expected SSH_MSG_SERVICE_ACCEPT'); - } - $this->bitmap |= self::MASK_LOGIN_REQ; - } - - if (strlen($this->last_interactive_response)) { - return !Strings::is_stringable($password) && !is_array($password) ? false : $this->keyboard_interactive_process($password); - } - - if ($password instanceof PrivateKey) { - return $this->privatekey_login($username, $password); - } - - if ($password instanceof Agent) { - return $this->ssh_agent_login($username, $password); - } - - if (is_array($password)) { - if ($this->keyboard_interactive_login($username, $password)) { - $this->bitmap |= self::MASK_LOGIN; - return true; - } - return false; - } - - if (!isset($password)) { - $packet = Strings::packSSH2( - 'Cs3', - NET_SSH2_MSG_USERAUTH_REQUEST, - $username, - 'ssh-connection', - 'none' - ); - - $this->send_binary_packet($packet); - - $response = $this->get_binary_packet(); - - list($type) = Strings::unpackSSH2('C', $response); - switch ($type) { - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - case NET_SSH2_MSG_USERAUTH_FAILURE: - list($auth_methods) = Strings::unpackSSH2('L', $response); - $this->auth_methods_to_continue = $auth_methods; - // fall-through - default: - return false; - } - } - - $packet = Strings::packSSH2( - 'Cs3bs', - NET_SSH2_MSG_USERAUTH_REQUEST, - $username, - 'ssh-connection', - 'password', - false, - $password - ); - - // remove the username and password from the logged packet - if (!defined('NET_SSH2_LOGGING')) { - $logged = null; - } else { - $logged = Strings::packSSH2( - 'Cs3bs', - NET_SSH2_MSG_USERAUTH_REQUEST, - $username, - 'ssh-connection', - 'password', - false, - 'password' - ); - } - - $this->send_binary_packet($packet, $logged); - - $response = $this->get_binary_packet(); - if ($response === false) { - return false; - } - list($type) = Strings::unpackSSH2('C', $response); - switch ($type) { - case NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ: // in theory, the password can be changed - $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ'); - - list($message) = Strings::unpackSSH2('s', $response); - $this->errors[] = 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ: ' . $message; - - return $this->disconnect_helper(NET_SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER); - case NET_SSH2_MSG_USERAUTH_FAILURE: - // can we use keyboard-interactive authentication? if not then either the login is bad or the server employees - // multi-factor authentication - list($auth_methods, $partial_success) = Strings::unpackSSH2('Lb', $response); - $this->auth_methods_to_continue = $auth_methods; - if (!$partial_success && in_array('keyboard-interactive', $auth_methods)) { - if ($this->keyboard_interactive_login($username, $password)) { - $this->bitmap |= self::MASK_LOGIN; - return true; - } - return false; - } - return false; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - } - - return false; - } - - /** - * Login via keyboard-interactive authentication - * - * See {@link http://tools.ietf.org/html/rfc4256 RFC4256} for details. This is not a full-featured keyboard-interactive authenticator. - * - * @param string $username - * @param string|array $password - * @return bool - */ - private function keyboard_interactive_login($username, $password) - { - $packet = Strings::packSSH2( - 'Cs5', - NET_SSH2_MSG_USERAUTH_REQUEST, - $username, - 'ssh-connection', - 'keyboard-interactive', - '', // language tag - '' // submethods - ); - $this->send_binary_packet($packet); - - return $this->keyboard_interactive_process($password); - } - - /** - * Handle the keyboard-interactive requests / responses. - * - * @param string|array ...$responses - * @return bool - * @throws \RuntimeException on connection error - */ - private function keyboard_interactive_process(...$responses) - { - if (strlen($this->last_interactive_response)) { - $response = $this->last_interactive_response; - } else { - $orig = $response = $this->get_binary_packet(); - } - - list($type) = Strings::unpackSSH2('C', $response); - switch ($type) { - case NET_SSH2_MSG_USERAUTH_INFO_REQUEST: - list( - , // name; may be empty - , // instruction; may be empty - , // language tag; may be empty - $num_prompts - ) = Strings::unpackSSH2('s3N', $response); - - for ($i = 0; $i < count($responses); $i++) { - if (is_array($responses[$i])) { - foreach ($responses[$i] as $key => $value) { - $this->keyboard_requests_responses[$key] = $value; - } - unset($responses[$i]); - } - } - $responses = array_values($responses); - - if (isset($this->keyboard_requests_responses)) { - for ($i = 0; $i < $num_prompts; $i++) { - list( - $prompt, // prompt - ie. "Password: "; must not be empty - // echo - ) = Strings::unpackSSH2('sC', $response); - foreach ($this->keyboard_requests_responses as $key => $value) { - if (substr($prompt, 0, strlen($key)) == $key) { - $responses[] = $value; - break; - } - } - } - } - - // see http://tools.ietf.org/html/rfc4256#section-3.2 - if (strlen($this->last_interactive_response)) { - $this->last_interactive_response = ''; - } else { - $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_INFO_REQUEST'); - } - - if (!count($responses) && $num_prompts) { - $this->last_interactive_response = $orig; - return false; - } - - /* - After obtaining the requested information from the user, the client - MUST respond with an SSH_MSG_USERAUTH_INFO_RESPONSE message. - */ - // see http://tools.ietf.org/html/rfc4256#section-3.4 - $packet = $logged = pack('CN', NET_SSH2_MSG_USERAUTH_INFO_RESPONSE, count($responses)); - for ($i = 0; $i < count($responses); $i++) { - $packet .= Strings::packSSH2('s', $responses[$i]); - $logged .= Strings::packSSH2('s', 'dummy-answer'); - } - - $this->send_binary_packet($packet, $logged); - - $this->updateLogHistory('UNKNOWN (61)', 'NET_SSH2_MSG_USERAUTH_INFO_RESPONSE'); - - /* - After receiving the response, the server MUST send either an - SSH_MSG_USERAUTH_SUCCESS, SSH_MSG_USERAUTH_FAILURE, or another - SSH_MSG_USERAUTH_INFO_REQUEST message. - */ - // maybe phpseclib should force close the connection after x request / responses? unless something like that is done - // there could be an infinite loop of request / responses. - return $this->keyboard_interactive_process(); - case NET_SSH2_MSG_USERAUTH_SUCCESS: - return true; - case NET_SSH2_MSG_USERAUTH_FAILURE: - list($auth_methods) = Strings::unpackSSH2('L', $response); - $this->auth_methods_to_continue = $auth_methods; - return false; - } - - return false; - } - - /** - * Login with an ssh-agent provided key - * - * @param string $username - * @param \phpseclib3\System\SSH\Agent $agent - * @return bool - */ - private function ssh_agent_login($username, Agent $agent) - { - $this->agent = $agent; - $keys = $agent->requestIdentities(); - foreach ($keys as $key) { - if ($this->privatekey_login($username, $key)) { - return true; - } - } - - return false; - } - - /** - * Login with an RSA private key - * - * {@internal It might be worthwhile, at some point, to protect against {@link http://tools.ietf.org/html/rfc4251#section-9.3.9 traffic analysis} - * by sending dummy SSH_MSG_IGNORE messages.} - * - * @param string $username - * @param \phpseclib3\Crypt\Common\PrivateKey $privatekey - * @return bool - * @throws \RuntimeException on connection error - */ - private function privatekey_login($username, PrivateKey $privatekey) - { - $publickey = $privatekey->getPublicKey(); - - if ($publickey instanceof RSA) { - $privatekey = $privatekey->withPadding(RSA::SIGNATURE_PKCS1); - $algos = ['rsa-sha2-256', 'rsa-sha2-512', 'ssh-rsa']; - if (isset($this->preferred['hostkey'])) { - $algos = array_intersect($algos, $this->preferred['hostkey']); - } - $algo = self::array_intersect_first($algos, $this->supported_private_key_algorithms); - switch ($algo) { - case 'rsa-sha2-512': - $hash = 'sha512'; - $signatureType = 'rsa-sha2-512'; - break; - case 'rsa-sha2-256': - $hash = 'sha256'; - $signatureType = 'rsa-sha2-256'; - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - $signatureType = 'ssh-rsa'; - } - } elseif ($publickey instanceof EC) { - $privatekey = $privatekey->withSignatureFormat('SSH2'); - $curveName = $privatekey->getCurve(); - switch ($curveName) { - case 'Ed25519': - $hash = 'sha512'; - $signatureType = 'ssh-ed25519'; - break; - case 'secp256r1': // nistp256 - $hash = 'sha256'; - $signatureType = 'ecdsa-sha2-nistp256'; - break; - case 'secp384r1': // nistp384 - $hash = 'sha384'; - $signatureType = 'ecdsa-sha2-nistp384'; - break; - case 'secp521r1': // nistp521 - $hash = 'sha512'; - $signatureType = 'ecdsa-sha2-nistp521'; - break; - default: - if (is_array($curveName)) { - throw new UnsupportedCurveException('Specified Curves are not supported by SSH2'); - } - throw new UnsupportedCurveException('Named Curve of ' . $curveName . ' is not supported by phpseclib3\'s SSH2 implementation'); - } - } elseif ($publickey instanceof DSA) { - $privatekey = $privatekey->withSignatureFormat('SSH2'); - $hash = 'sha1'; - $signatureType = 'ssh-dss'; - } else { - throw new UnsupportedAlgorithmException('Please use either an RSA key, an EC one or a DSA key'); - } - - $publickeyStr = $publickey->toString('OpenSSH', ['binary' => true]); - - $part1 = Strings::packSSH2( - 'Csss', - NET_SSH2_MSG_USERAUTH_REQUEST, - $username, - 'ssh-connection', - 'publickey' - ); - $part2 = Strings::packSSH2('ss', $signatureType, $publickeyStr); - - $packet = $part1 . chr(0) . $part2; - $this->send_binary_packet($packet); - - $response = $this->get_binary_packet(); - - list($type) = Strings::unpackSSH2('C', $response); - switch ($type) { - case NET_SSH2_MSG_USERAUTH_FAILURE: - list($auth_methods) = Strings::unpackSSH2('L', $response); - if (in_array('publickey', $auth_methods) && substr($signatureType, 0, 9) == 'rsa-sha2-') { - $this->supported_private_key_algorithms = array_diff($this->supported_private_key_algorithms, ['rsa-sha2-256', 'rsa-sha2-512']); - return $this->privatekey_login($username, $privatekey); - } - $this->auth_methods_to_continue = $auth_methods; - $this->errors[] = 'SSH_MSG_USERAUTH_FAILURE'; - return false; - case NET_SSH2_MSG_USERAUTH_PK_OK: - // we'll just take it on faith that the public key blob and the public key algorithm name are as - // they should be - $this->updateLogHistory('UNKNOWN (60)', 'NET_SSH2_MSG_USERAUTH_PK_OK'); - break; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new ConnectionClosedException('Unexpected response to publickey authentication pt 1'); - } - - $packet = $part1 . chr(1) . $part2; - $privatekey = $privatekey->withHash($hash); - $signature = $privatekey->sign(Strings::packSSH2('s', $this->session_id) . $packet); - if ($publickey instanceof RSA) { - $signature = Strings::packSSH2('ss', $signatureType, $signature); - } - $packet .= Strings::packSSH2('s', $signature); - - $this->send_binary_packet($packet); - - $response = $this->get_binary_packet(); - - list($type) = Strings::unpackSSH2('C', $response); - switch ($type) { - case NET_SSH2_MSG_USERAUTH_FAILURE: - // either the login is bad or the server employs multi-factor authentication - list($auth_methods) = Strings::unpackSSH2('L', $response); - $this->auth_methods_to_continue = $auth_methods; - return false; - case NET_SSH2_MSG_USERAUTH_SUCCESS: - $this->bitmap |= self::MASK_LOGIN; - return true; - } - - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new ConnectionClosedException('Unexpected response to publickey authentication pt 2'); - } - - /** - * Return the currently configured timeout - * - * @return int - */ - public function getTimeout() - { - return $this->timeout; - } - - /** - * Set Timeout - * - * $ssh->exec('ping 127.0.0.1'); on a Linux host will never return and will run indefinitely. setTimeout() makes it so it'll timeout. - * Setting $timeout to false or 0 will mean there is no timeout. - * - * @param mixed $timeout - */ - public function setTimeout($timeout) - { - $this->timeout = $this->curTimeout = $timeout; - } - - /** - * Set Keep Alive - * - * Sends an SSH2_MSG_IGNORE message every x seconds, if x is a positive non-zero number. - * - * @param int $interval - */ - public function setKeepAlive($interval) - { - $this->keepAlive = $interval; - } - - /** - * Get the output from stdError - * - */ - public function getStdError() - { - return $this->stdErrorLog; - } - - /** - * Execute Command - * - * If $callback is set to false then \phpseclib3\Net\SSH2::get_channel_packet(self::CHANNEL_EXEC) will need to be called manually. - * In all likelihood, this is not a feature you want to be taking advantage of. - * - * @param string $command - * @return string|bool - * @psalm-return ($callback is callable ? bool : string|bool) - * @throws \RuntimeException on connection error - */ - public function exec($command, callable $callback = null) - { - $this->curTimeout = $this->timeout; - $this->is_timeout = false; - $this->stdErrorLog = ''; - - if (!$this->isAuthenticated()) { - return false; - } - - //if ($this->isPTYOpen()) { - // throw new \RuntimeException('If you want to run multiple exec()\'s you will need to disable (and re-enable if appropriate) a PTY for each one.'); - //} - - $this->openChannel(self::CHANNEL_EXEC); - - if ($this->request_pty === true) { - $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); - $packet = Strings::packSSH2( - 'CNsCsN4s', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_EXEC], - 'pty-req', - 1, - $this->term, - $this->windowColumns, - $this->windowRows, - 0, - 0, - $terminal_modes - ); - - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; - if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unable to request pseudo-terminal'); - } - } - - // sending a pty-req SSH_MSG_CHANNEL_REQUEST message is unnecessary and, in fact, in most cases, slows things - // down. the one place where it might be desirable is if you're doing something like \phpseclib3\Net\SSH2::exec('ping localhost &'). - // with a pty-req SSH_MSG_CHANNEL_REQUEST, exec() will return immediately and the ping process will then - // then immediately terminate. without such a request exec() will loop indefinitely. the ping process won't end but - // neither will your script. - - // although, in theory, the size of SSH_MSG_CHANNEL_REQUEST could exceed the maximum packet size established by - // SSH_MSG_CHANNEL_OPEN_CONFIRMATION, RFC4254#section-5.1 states that the "maximum packet size" refers to the - // "maximum size of an individual data packet". ie. SSH_MSG_CHANNEL_DATA. RFC4254#section-5.2 corroborates. - $packet = Strings::packSSH2( - 'CNsCs', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_EXEC], - 'exec', - 1, - $command - ); - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_REQUEST; - - if (!$this->get_channel_packet(self::CHANNEL_EXEC)) { - return false; - } - - $this->channel_status[self::CHANNEL_EXEC] = NET_SSH2_MSG_CHANNEL_DATA; - - if ($this->request_pty === true) { - $this->channel_id_last_interactive = self::CHANNEL_EXEC; - return true; - } - - $output = ''; - while (true) { - $temp = $this->get_channel_packet(self::CHANNEL_EXEC); - switch (true) { - case $temp === true: - return is_callable($callback) ? true : $output; - case $temp === false: - return false; - default: - if (is_callable($callback)) { - if ($callback($temp) === true) { - $this->close_channel(self::CHANNEL_EXEC); - return true; - } - } else { - $output .= $temp; - } - } - } - } - - /** - * How many channels are currently open? - * - * @return int - */ - public function getOpenChannelCount() - { - return $this->channelCount; - } - - /** - * Opens a channel - * - * @param string $channel - * @param bool $skip_extended - * @return bool - */ - protected function openChannel($channel, $skip_extended = false) - { - if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_CLOSE) { - throw new \RuntimeException('Please close the channel (' . $channel . ') before trying to open it again'); - } - - $this->channelCount++; - - if ($this->channelCount > 1 && $this->errorOnMultipleChannels) { - throw new \RuntimeException("Ubuntu's OpenSSH from 5.8 to 6.9 doesn't work with multiple channels"); - } - - // RFC4254 defines the (client) window size as "bytes the other party can send before it must wait for the window to - // be adjusted". 0x7FFFFFFF is, at 2GB, the max size. technically, it should probably be decremented, but, - // honestly, if you're transferring more than 2GB, you probably shouldn't be using phpseclib, anyway. - // see http://tools.ietf.org/html/rfc4254#section-5.2 for more info - $this->window_size_server_to_client[$channel] = $this->window_size; - // 0x8000 is the maximum max packet size, per http://tools.ietf.org/html/rfc4253#section-6.1, although since PuTTy - // uses 0x4000, that's what will be used here, as well. - $packet_size = 0x4000; - - $packet = Strings::packSSH2( - 'CsN3', - NET_SSH2_MSG_CHANNEL_OPEN, - 'session', - $channel, - $this->window_size_server_to_client[$channel], - $packet_size - ); - - $this->send_binary_packet($packet); - - $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_OPEN; - - return $this->get_channel_packet($channel, $skip_extended); - } - - /** - * Creates an interactive shell - * - * Returns bool(true) if the shell was opened. - * Returns bool(false) if the shell was already open. - * - * @see self::isShellOpen() - * @see self::read() - * @see self::write() - * @return bool - * @throws InsufficientSetupException if not authenticated - * @throws \UnexpectedValueException on receipt of unexpected packets - * @throws \RuntimeException on other errors - */ - public function openShell() - { - if (!$this->isAuthenticated()) { - throw new InsufficientSetupException('Operation disallowed prior to login()'); - } - - $this->openChannel(self::CHANNEL_SHELL); - - $terminal_modes = pack('C', NET_SSH2_TTY_OP_END); - $packet = Strings::packSSH2( - 'CNsbsN4s', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_SHELL], - 'pty-req', - true, // want reply - $this->term, - $this->windowColumns, - $this->windowRows, - 0, - 0, - $terminal_modes - ); - - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_REQUEST; - - if (!$this->get_channel_packet(self::CHANNEL_SHELL)) { - throw new \RuntimeException('Unable to request pty'); - } - - $packet = Strings::packSSH2( - 'CNsb', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_SHELL], - 'shell', - true // want reply - ); - $this->send_binary_packet($packet); - - $response = $this->get_channel_packet(self::CHANNEL_SHELL); - if ($response === false) { - throw new \RuntimeException('Unable to request shell'); - } - - $this->channel_status[self::CHANNEL_SHELL] = NET_SSH2_MSG_CHANNEL_DATA; - - $this->channel_id_last_interactive = self::CHANNEL_SHELL; - - $this->bitmap |= self::MASK_SHELL; - - return true; - } - - /** - * Return the channel to be used with read(), write(), and reset(), if none were specified - * @deprecated for lack of transparency in intended channel target, to be potentially replaced - * with method which guarantees open-ness of all yielded channels and throws - * error for multiple open channels - * @see self::read() - * @see self::write() - * @return int - */ - private function get_interactive_channel() - { - switch (true) { - case $this->is_channel_status_data(self::CHANNEL_SUBSYSTEM): - return self::CHANNEL_SUBSYSTEM; - case $this->is_channel_status_data(self::CHANNEL_EXEC): - return self::CHANNEL_EXEC; - default: - return self::CHANNEL_SHELL; - } - } - - /** - * Indicates the DATA status on the given channel - * - * @param int $channel The channel number to evaluate - * @return bool - */ - private function is_channel_status_data($channel) - { - return isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA; - } - - /** - * Return an available open channel - * - * @return int - */ - private function get_open_channel() - { - $channel = self::CHANNEL_EXEC; - do { - if (isset($this->channel_status[$channel]) && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_OPEN) { - return $channel; - } - } while ($channel++ < self::CHANNEL_SUBSYSTEM); - - return false; - } - - /** - * Request agent forwarding of remote server - * - * @return bool - */ - public function requestAgentForwarding() - { - $request_channel = $this->get_open_channel(); - if ($request_channel === false) { - return false; - } - - $packet = Strings::packSSH2( - 'CNsC', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[$request_channel], - 'auth-agent-req@openssh.com', - 1 - ); - - $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_REQUEST; - - $this->send_binary_packet($packet); - - if (!$this->get_channel_packet($request_channel)) { - return false; - } - - $this->channel_status[$request_channel] = NET_SSH2_MSG_CHANNEL_OPEN; - - return true; - } - - /** - * Returns the output of an interactive shell - * - * Returns when there's a match for $expect, which can take the form of a string literal or, - * if $mode == self::READ_REGEX, a regular expression. - * - * If not specifying a channel, an open interactive channel will be selected, or, if there are - * no open channels, an interactive shell will be created. If there are multiple open - * interactive channels, a legacy behavior will apply in which channel selection prioritizes - * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive - * channels, callers are discouraged from relying on this legacy behavior and should specify - * the intended channel. - * - * @see self::write() - * @param string $expect - * @param int $mode One of the self::READ_* constants - * @param int|null $channel Channel id returned by self::getInteractiveChannelId() - * @return string|bool|null - * @throws \RuntimeException on connection error - * @throws InsufficientSetupException on unexpected channel status, possibly due to closure - */ - public function read($expect = '', $mode = self::READ_SIMPLE, $channel = null) - { - if (!$this->isAuthenticated()) { - throw new InsufficientSetupException('Operation disallowed prior to login()'); - } - - $this->curTimeout = $this->timeout; - $this->is_timeout = false; - - if ($channel === null) { - $channel = $this->get_interactive_channel(); - } - - if (!$this->is_channel_status_data($channel) && empty($this->channel_buffers[$channel])) { - if ($channel != self::CHANNEL_SHELL) { - throw new InsufficientSetupException('Data is not available on channel'); - } elseif (!$this->openShell()) { - throw new \RuntimeException('Unable to initiate an interactive shell session'); - } - } - - if ($mode == self::READ_NEXT) { - return $this->get_channel_packet($channel); - } - - $match = $expect; - while (true) { - if ($mode == self::READ_REGEX) { - preg_match($expect, substr($this->interactiveBuffer, -1024), $matches); - $match = isset($matches[0]) ? $matches[0] : ''; - } - $pos = strlen($match) ? strpos($this->interactiveBuffer, $match) : false; - if ($pos !== false) { - return Strings::shift($this->interactiveBuffer, $pos + strlen($match)); - } - $response = $this->get_channel_packet($channel); - if ($response === true) { - return Strings::shift($this->interactiveBuffer, strlen($this->interactiveBuffer)); - } - - $this->interactiveBuffer .= $response; - } - } - - /** - * Inputs a command into an interactive shell. - * - * If not specifying a channel, an open interactive channel will be selected, or, if there are - * no open channels, an interactive shell will be created. If there are multiple open - * interactive channels, a legacy behavior will apply in which channel selection prioritizes - * an active subsystem, the exec pty, and, lastly, the shell. If using multiple interactive - * channels, callers are discouraged from relying on this legacy behavior and should specify - * the intended channel. - * - * @see SSH2::read() - * @param string $cmd - * @param int|null $channel Channel id returned by self::getInteractiveChannelId() - * @return void - * @throws \RuntimeException on connection error - * @throws InsufficientSetupException on unexpected channel status, possibly due to closure - */ - public function write($cmd, $channel = null) - { - if (!$this->isAuthenticated()) { - throw new InsufficientSetupException('Operation disallowed prior to login()'); - } - - if ($channel === null) { - $channel = $this->get_interactive_channel(); - } - - if (!$this->is_channel_status_data($channel)) { - if ($channel != self::CHANNEL_SHELL) { - throw new InsufficientSetupException('Data is not available on channel'); - } elseif (!$this->openShell()) { - throw new \RuntimeException('Unable to initiate an interactive shell session'); - } - } - - $this->send_channel_packet($channel, $cmd); - } - - /** - * Start a subsystem. - * - * Right now only one subsystem at a time is supported. To support multiple subsystem's stopSubsystem() could accept - * a string that contained the name of the subsystem, but at that point, only one subsystem of each type could be opened. - * To support multiple subsystem's of the same name maybe it'd be best if startSubsystem() generated a new channel id and - * returns that and then that that was passed into stopSubsystem() but that'll be saved for a future date and implemented - * if there's sufficient demand for such a feature. - * - * @see self::stopSubsystem() - * @param string $subsystem - * @return bool - */ - public function startSubsystem($subsystem) - { - $this->openChannel(self::CHANNEL_SUBSYSTEM); - - $packet = Strings::packSSH2( - 'CNsCs', - NET_SSH2_MSG_CHANNEL_REQUEST, - $this->server_channels[self::CHANNEL_SUBSYSTEM], - 'subsystem', - 1, - $subsystem - ); - $this->send_binary_packet($packet); - - $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_REQUEST; - - if (!$this->get_channel_packet(self::CHANNEL_SUBSYSTEM)) { - return false; - } - - $this->channel_status[self::CHANNEL_SUBSYSTEM] = NET_SSH2_MSG_CHANNEL_DATA; - - $this->channel_id_last_interactive = self::CHANNEL_SUBSYSTEM; - - return true; - } - - /** - * Stops a subsystem. - * - * @see self::startSubsystem() - * @return bool - */ - public function stopSubsystem() - { - if ($this->isInteractiveChannelOpen(self::CHANNEL_SUBSYSTEM)) { - $this->close_channel(self::CHANNEL_SUBSYSTEM); - } - return true; - } - - /** - * Closes a channel - * - * If read() timed out you might want to just close the channel and have it auto-restart on the next read() call - * - * If not specifying a channel, an open interactive channel will be selected. If there are - * multiple open interactive channels, a legacy behavior will apply in which channel selection - * prioritizes an active subsystem, the exec pty, and, lastly, the shell. If using multiple - * interactive channels, callers are discouraged from relying on this legacy behavior and - * should specify the intended channel. - * - * @param int|null $channel Channel id returned by self::getInteractiveChannelId() - * @return void - */ - public function reset($channel = null) - { - if ($channel === null) { - $channel = $this->get_interactive_channel(); - } - if ($this->isInteractiveChannelOpen($channel)) { - $this->close_channel($channel); - } - } - - /** - * Is timeout? - * - * Did exec() or read() return because they timed out or because they encountered the end? - * - */ - public function isTimeout() - { - return $this->is_timeout; - } - - /** - * Disconnect - * - */ - public function disconnect() - { - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - if (isset($this->realtime_log_file) && is_resource($this->realtime_log_file)) { - fclose($this->realtime_log_file); - } - unset(self::$connections[$this->getResourceId()]); - } - - /** - * Destructor. - * - * Will be called, automatically, if you're supporting just PHP5. If you're supporting PHP4, you'll need to call - * disconnect(). - * - */ - public function __destruct() - { - $this->disconnect(); - } - - /** - * Is the connection still active? - * - * @return bool - */ - public function isConnected() - { - return ($this->bitmap & self::MASK_CONNECTED) && is_resource($this->fsock) && !feof($this->fsock); - } - - /** - * Have you successfully been logged in? - * - * @return bool - */ - public function isAuthenticated() - { - return (bool) ($this->bitmap & self::MASK_LOGIN); - } - - /** - * Is the interactive shell active? - * - * @return bool - */ - public function isShellOpen() - { - return $this->isInteractiveChannelOpen(self::CHANNEL_SHELL); - } - - /** - * Is the exec pty active? - * - * @return bool - */ - public function isPTYOpen() - { - return $this->isInteractiveChannelOpen(self::CHANNEL_EXEC); - } - - /** - * Is the given interactive channel active? - * - * @param int $channel Channel id returned by self::getInteractiveChannelId() - * @return bool - */ - public function isInteractiveChannelOpen($channel) - { - return $this->isAuthenticated() && $this->is_channel_status_data($channel); - } - - /** - * Returns a channel identifier, presently of the last interactive channel opened, regardless of current status. - * Returns 0 if no interactive channel has been opened. - * - * @see self::isInteractiveChannelOpen() - * @return int - */ - public function getInteractiveChannelId() - { - return $this->channel_id_last_interactive; - } - - /** - * Pings a server connection, or tries to reconnect if the connection has gone down - * - * Inspired by http://php.net/manual/en/mysqli.ping.php - * - * @return bool - */ - public function ping() - { - if (!$this->isAuthenticated()) { - if (!empty($this->auth)) { - return $this->reconnect(); - } - return false; - } - - try { - $this->openChannel(self::CHANNEL_KEEP_ALIVE); - } catch (\RuntimeException $e) { - return $this->reconnect(); - } - - $this->close_channel(self::CHANNEL_KEEP_ALIVE); - return true; - } - - /** - * In situ reconnect method - * - * @return boolean - */ - private function reconnect() - { - $this->reset_connection(NET_SSH2_DISCONNECT_CONNECTION_LOST); - $this->retry_connect = true; - $this->connect(); - foreach ($this->auth as $auth) { - $result = $this->login(...$auth); - } - return $result; - } - - /** - * Resets a connection for re-use - * - * @param int $reason - */ - protected function reset_connection($reason) - { - $this->disconnect_helper($reason); - $this->decrypt = $this->encrypt = false; - $this->decrypt_block_size = $this->encrypt_block_size = 8; - $this->hmac_check = $this->hmac_create = false; - $this->hmac_size = false; - $this->session_id = false; - $this->retry_connect = true; - $this->get_seq_no = $this->send_seq_no = 0; - $this->channel_status = []; - $this->channel_id_last_interactive = 0; - } - - /** - * Gets Binary Packets - * - * See '6. Binary Packet Protocol' of rfc4253 for more info. - * - * @see self::_send_binary_packet() - * @param bool $skip_channel_filter - * @return bool|string - */ - private function get_binary_packet($skip_channel_filter = false) - { - if ($skip_channel_filter) { - if (!is_resource($this->fsock)) { - throw new \InvalidArgumentException('fsock is not a resource.'); - } - $read = [$this->fsock]; - $write = $except = null; - - if (!$this->curTimeout) { - if ($this->keepAlive <= 0) { - static::stream_select($read, $write, $except, null); - } else { - if (!static::stream_select($read, $write, $except, $this->keepAlive)) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - return $this->get_binary_packet(true); - } - } - } else { - if ($this->curTimeout < 0) { - $this->is_timeout = true; - return true; - } - - $start = microtime(true); - - if ($this->keepAlive > 0 && $this->keepAlive < $this->curTimeout) { - if (!static::stream_select($read, $write, $except, $this->keepAlive)) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_IGNORE, 0)); - $elapsed = microtime(true) - $start; - $this->curTimeout -= $elapsed; - return $this->get_binary_packet(true); - } - $elapsed = microtime(true) - $start; - $this->curTimeout -= $elapsed; - } - - $sec = (int) floor($this->curTimeout); - $usec = (int) (1000000 * ($this->curTimeout - $sec)); - - // this can return a "stream_select(): unable to select [4]: Interrupted system call" error - if (!static::stream_select($read, $write, $except, $sec, $usec)) { - $this->is_timeout = true; - return true; - } - $elapsed = microtime(true) - $start; - $this->curTimeout -= $elapsed; - } - } - - if (!is_resource($this->fsock) || feof($this->fsock)) { - $this->bitmap = 0; - $str = 'Connection closed (by server) prematurely'; - if (isset($elapsed)) { - $str .= ' ' . $elapsed . 's'; - } - throw new ConnectionClosedException($str); - } - - $start = microtime(true); - $raw = stream_get_contents($this->fsock, $this->decrypt_block_size); - - if (!strlen($raw)) { - $this->bitmap = 0; - throw new ConnectionClosedException('No data received from server'); - } - - if ($this->decrypt) { - switch ($this->decryptName) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - $this->decrypt->setNonce( - $this->decryptFixedPart . - $this->decryptInvocationCounter - ); - Strings::increment_str($this->decryptInvocationCounter); - $this->decrypt->setAAD($temp = Strings::shift($raw, 4)); - extract(unpack('Npacket_length', $temp)); - /** - * @var integer $packet_length - */ - - $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); - $stop = microtime(true); - $tag = stream_get_contents($this->fsock, $this->decrypt_block_size); - $this->decrypt->setTag($tag); - $raw = $this->decrypt->decrypt($raw); - $raw = $temp . $raw; - $remaining_length = 0; - break; - case 'chacha20-poly1305@openssh.com': - // This should be impossible, but we are checking anyway to narrow the type for Psalm. - if (!($this->decrypt instanceof ChaCha20)) { - throw new \LogicException('$this->decrypt is not a ' . ChaCha20::class); - } - - $nonce = pack('N2', 0, $this->get_seq_no); - - $this->lengthDecrypt->setNonce($nonce); - $temp = $this->lengthDecrypt->decrypt($aad = Strings::shift($raw, 4)); - extract(unpack('Npacket_length', $temp)); - /** - * @var integer $packet_length - */ - - $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); - $stop = microtime(true); - $tag = stream_get_contents($this->fsock, 16); - - $this->decrypt->setNonce($nonce); - $this->decrypt->setCounter(0); - // this is the same approach that's implemented in Salsa20::createPoly1305Key() - // but we don't want to use the same AEAD construction that RFC8439 describes - // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) - $this->decrypt->setPoly1305Key( - $this->decrypt->encrypt(str_repeat("\0", 32)) - ); - $this->decrypt->setAAD($aad); - $this->decrypt->setCounter(1); - $this->decrypt->setTag($tag); - $raw = $this->decrypt->decrypt($raw); - $raw = $temp . $raw; - $remaining_length = 0; - break; - default: - if (!$this->hmac_check instanceof Hash || !$this->hmac_check_etm) { - $raw = $this->decrypt->decrypt($raw); - break; - } - extract(unpack('Npacket_length', $temp = Strings::shift($raw, 4))); - /** - * @var integer $packet_length - */ - $raw .= $this->read_remaining_bytes($packet_length - $this->decrypt_block_size + 4); - $stop = microtime(true); - $encrypted = $temp . $raw; - $raw = $temp . $this->decrypt->decrypt($raw); - $remaining_length = 0; - } - } - - if (strlen($raw) < 5) { - $this->bitmap = 0; - throw new \RuntimeException('Plaintext is too short'); - } - extract(unpack('Npacket_length/Cpadding_length', Strings::shift($raw, 5))); - /** - * @var integer $packet_length - * @var integer $padding_length - */ - - if (!isset($remaining_length)) { - $remaining_length = $packet_length + 4 - $this->decrypt_block_size; - } - - $buffer = $this->read_remaining_bytes($remaining_length); - - if (!isset($stop)) { - $stop = microtime(true); - } - if (strlen($buffer)) { - $raw .= $this->decrypt ? $this->decrypt->decrypt($buffer) : $buffer; - } - - $payload = Strings::shift($raw, $packet_length - $padding_length - 1); - $padding = Strings::shift($raw, $padding_length); // should leave $raw empty - - if ($this->hmac_check instanceof Hash) { - $hmac = stream_get_contents($this->fsock, $this->hmac_size); - if ($hmac === false || strlen($hmac) != $this->hmac_size) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); - throw new \RuntimeException('Error reading socket'); - } - - $reconstructed = !$this->hmac_check_etm ? - pack('NCa*', $packet_length, $padding_length, $payload . $padding) : - $encrypted; - if (($this->hmac_check->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { - $this->hmac_check->setNonce("\0\0\0\0" . pack('N', $this->get_seq_no)); - if ($hmac != $this->hmac_check->hash($reconstructed)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); - throw new \RuntimeException('Invalid UMAC'); - } - } else { - if ($hmac != $this->hmac_check->hash(pack('Na*', $this->get_seq_no, $reconstructed))) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_MAC_ERROR); - throw new \RuntimeException('Invalid HMAC'); - } - } - } - - switch ($this->decompress) { - case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: - if (!$this->isAuthenticated()) { - break; - } - // fall-through - case self::NET_SSH2_COMPRESSION_ZLIB: - if ($this->regenerate_decompression_context) { - $this->regenerate_decompression_context = false; - - $cmf = ord($payload[0]); - $cm = $cmf & 0x0F; - if ($cm != 8) { // deflate - user_error("Only CM = 8 ('deflate') is supported ($cm)"); - } - $cinfo = ($cmf & 0xF0) >> 4; - if ($cinfo > 7) { - user_error("CINFO above 7 is not allowed ($cinfo)"); - } - $windowSize = 1 << ($cinfo + 8); - - $flg = ord($payload[1]); - //$fcheck = $flg && 0x0F; - if ((($cmf << 8) | $flg) % 31) { - user_error('fcheck failed'); - } - $fdict = boolval($flg & 0x20); - $flevel = ($flg & 0xC0) >> 6; - - $this->decompress_context = inflate_init(ZLIB_ENCODING_RAW, ['window' => $cinfo + 8]); - $payload = substr($payload, 2); - } - if ($this->decompress_context) { - $payload = inflate_add($this->decompress_context, $payload, ZLIB_PARTIAL_FLUSH); - } - } - - $this->get_seq_no++; - - if (defined('NET_SSH2_LOGGING')) { - $current = microtime(true); - $message_number = isset(self::$message_numbers[ord($payload[0])]) ? self::$message_numbers[ord($payload[0])] : 'UNKNOWN (' . ord($payload[0]) . ')'; - $message_number = '<- ' . $message_number . - ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; - $this->append_log($message_number, $payload); - $this->last_packet = $current; - } - - return $this->filter($payload, $skip_channel_filter); - } - - /** - * Read Remaining Bytes - * - * @see self::get_binary_packet() - * @param int $remaining_length - * @return string - */ - private function read_remaining_bytes($remaining_length) - { - if (!$remaining_length) { - return ''; - } - - $adjustLength = false; - if ($this->decrypt) { - switch (true) { - case $this->decryptName == 'aes128-gcm@openssh.com': - case $this->decryptName == 'aes256-gcm@openssh.com': - case $this->decryptName == 'chacha20-poly1305@openssh.com': - case $this->hmac_check instanceof Hash && $this->hmac_check_etm: - $remaining_length += $this->decrypt_block_size - 4; - $adjustLength = true; - } - } - - // quoting , - // "implementations SHOULD check that the packet length is reasonable" - // PuTTY uses 0x9000 as the actual max packet size and so to shall we - // don't do this when GCM mode is used since GCM mode doesn't encrypt the length - if ($remaining_length < -$this->decrypt_block_size || $remaining_length > 0x9000 || $remaining_length % $this->decrypt_block_size != 0) { - if (!$this->bad_key_size_fix && self::bad_algorithm_candidate($this->decrypt ? $this->decryptName : '') && !($this->bitmap & SSH2::MASK_LOGIN)) { - $this->bad_key_size_fix = true; - $this->reset_connection(NET_SSH2_DISCONNECT_KEY_EXCHANGE_FAILED); - return false; - } - throw new \RuntimeException('Invalid size'); - } - - if ($adjustLength) { - $remaining_length -= $this->decrypt_block_size - 4; - } - - $buffer = ''; - while ($remaining_length > 0) { - $temp = stream_get_contents($this->fsock, $remaining_length); - if ($temp === false || feof($this->fsock)) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new \RuntimeException('Error reading from socket'); - } - $buffer .= $temp; - $remaining_length -= strlen($temp); - } - - return $buffer; - } - - /** - * Filter Binary Packets - * - * Because some binary packets need to be ignored... - * - * @see self::_get_binary_packet() - * @param string $payload - * @param bool $skip_channel_filter - * @return string|bool - */ - private function filter($payload, $skip_channel_filter) - { - switch (ord($payload[0])) { - case NET_SSH2_MSG_DISCONNECT: - Strings::shift($payload, 1); - list($reason_code, $message) = Strings::unpackSSH2('Ns', $payload); - $this->errors[] = 'SSH_MSG_DISCONNECT: ' . self::$disconnect_reasons[$reason_code] . "\r\n$message"; - $this->bitmap = 0; - return false; - case NET_SSH2_MSG_IGNORE: - $this->extra_packets++; - $payload = $this->get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_DEBUG: - $this->extra_packets++; - Strings::shift($payload, 2); // second byte is "always_display" - list($message) = Strings::unpackSSH2('s', $payload); - $this->errors[] = "SSH_MSG_DEBUG: $message"; - $payload = $this->get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_UNIMPLEMENTED: - return false; - case NET_SSH2_MSG_KEXINIT: - // this is here for key re-exchanges after the initial key exchange - if ($this->session_id !== false) { - if (!$this->key_exchange($payload)) { - $this->bitmap = 0; - return false; - } - $payload = $this->get_binary_packet($skip_channel_filter); - } - } - - // see http://tools.ietf.org/html/rfc4252#section-5.4; only called when the encryption has been activated and when we haven't already logged in - if (($this->bitmap & self::MASK_CONNECTED) && !$this->isAuthenticated() && !is_bool($payload) && ord($payload[0]) == NET_SSH2_MSG_USERAUTH_BANNER) { - Strings::shift($payload, 1); - list($this->banner_message) = Strings::unpackSSH2('s', $payload); - $payload = $this->get_binary_packet(); - } - - // only called when we've already logged in - if (($this->bitmap & self::MASK_CONNECTED) && $this->isAuthenticated()) { - if (is_bool($payload)) { - return $payload; - } - - switch (ord($payload[0])) { - case NET_SSH2_MSG_CHANNEL_REQUEST: - if (strlen($payload) == 31) { - extract(unpack('cpacket_type/Nchannel/Nlength', $payload)); - if (substr($payload, 9, $length) == 'keepalive@openssh.com' && isset($this->server_channels[$channel])) { - if (ord(substr($payload, 9 + $length))) { // want reply - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_SUCCESS, $this->server_channels[$channel])); - } - $payload = $this->get_binary_packet($skip_channel_filter); - } - } - break; - case NET_SSH2_MSG_CHANNEL_DATA: - case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: - case NET_SSH2_MSG_CHANNEL_CLOSE: - case NET_SSH2_MSG_CHANNEL_EOF: - if (!$skip_channel_filter && !empty($this->server_channels)) { - $this->binary_packet_buffer = $payload; - $this->get_channel_packet(true); - $payload = $this->get_binary_packet(); - } - break; - case NET_SSH2_MSG_GLOBAL_REQUEST: // see http://tools.ietf.org/html/rfc4254#section-4 - Strings::shift($payload, 1); - list($request_name) = Strings::unpackSSH2('s', $payload); - $this->errors[] = "SSH_MSG_GLOBAL_REQUEST: $request_name"; - - try { - $this->send_binary_packet(pack('C', NET_SSH2_MSG_REQUEST_FAILURE)); - } catch (\RuntimeException $e) { - return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - - $payload = $this->get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_CHANNEL_OPEN: // see http://tools.ietf.org/html/rfc4254#section-5.1 - Strings::shift($payload, 1); - list($data, $server_channel) = Strings::unpackSSH2('sN', $payload); - switch ($data) { - case 'auth-agent': - case 'auth-agent@openssh.com': - if (isset($this->agent)) { - $new_channel = self::CHANNEL_AGENT_FORWARD; - - list( - $remote_window_size, - $remote_maximum_packet_size - ) = Strings::unpackSSH2('NN', $payload); - - $this->packet_size_client_to_server[$new_channel] = $remote_window_size; - $this->window_size_server_to_client[$new_channel] = $remote_maximum_packet_size; - $this->window_size_client_to_server[$new_channel] = $this->window_size; - - $packet_size = 0x4000; - - $packet = pack( - 'CN4', - NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, - $server_channel, - $new_channel, - $packet_size, - $packet_size - ); - - $this->server_channels[$new_channel] = $server_channel; - $this->channel_status[$new_channel] = NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION; - $this->send_binary_packet($packet); - } - break; - default: - $packet = Strings::packSSH2( - 'CN2ss', - NET_SSH2_MSG_CHANNEL_OPEN_FAILURE, - $server_channel, - NET_SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED, - '', // description - '' // language tag - ); - - try { - $this->send_binary_packet($packet); - } catch (\RuntimeException $e) { - return $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - } - } - - $payload = $this->get_binary_packet($skip_channel_filter); - break; - case NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST: - Strings::shift($payload, 1); - list($channel, $window_size) = Strings::unpackSSH2('NN', $payload); - - $this->window_size_client_to_server[$channel] += $window_size; - - $payload = ($this->bitmap & self::MASK_WINDOW_ADJUST) ? true : $this->get_binary_packet($skip_channel_filter); - } - } - - return $payload; - } - - /** - * Enable Quiet Mode - * - * Suppress stderr from output - * - */ - public function enableQuietMode() - { - $this->quiet_mode = true; - } - - /** - * Disable Quiet Mode - * - * Show stderr in output - * - */ - public function disableQuietMode() - { - $this->quiet_mode = false; - } - - /** - * Returns whether Quiet Mode is enabled or not - * - * @see self::enableQuietMode() - * @see self::disableQuietMode() - * @return bool - */ - public function isQuietModeEnabled() - { - return $this->quiet_mode; - } - - /** - * Enable request-pty when using exec() - * - */ - public function enablePTY() - { - $this->request_pty = true; - } - - /** - * Disable request-pty when using exec() - * - */ - public function disablePTY() - { - if ($this->isPTYOpen()) { - $this->close_channel(self::CHANNEL_EXEC); - } - $this->request_pty = false; - } - - /** - * Returns whether request-pty is enabled or not - * - * @see self::enablePTY() - * @see self::disablePTY() - * @return bool - */ - public function isPTYEnabled() - { - return $this->request_pty; - } - - /** - * Gets channel data - * - * Returns the data as a string. bool(true) is returned if: - * - * - the server closes the channel - * - if the connection times out - * - if the channel status is CHANNEL_OPEN and the response was CHANNEL_OPEN_CONFIRMATION - * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_SUCCESS - * - if the channel status is CHANNEL_CLOSE and the response was CHANNEL_CLOSE - * - * bool(false) is returned if: - * - * - if the channel status is CHANNEL_REQUEST and the response was CHANNEL_FAILURE - * - * @param int $client_channel - * @param bool $skip_extended - * @return mixed - * @throws \RuntimeException on connection error - */ - protected function get_channel_packet($client_channel, $skip_extended = false) - { - if (!empty($this->channel_buffers[$client_channel])) { - switch ($this->channel_status[$client_channel]) { - case NET_SSH2_MSG_CHANNEL_REQUEST: - foreach ($this->channel_buffers[$client_channel] as $i => $packet) { - switch (ord($packet[0])) { - case NET_SSH2_MSG_CHANNEL_SUCCESS: - case NET_SSH2_MSG_CHANNEL_FAILURE: - unset($this->channel_buffers[$client_channel][$i]); - return substr($packet, 1); - } - } - break; - default: - return substr(array_shift($this->channel_buffers[$client_channel]), 1); - } - } - - while (true) { - if ($this->binary_packet_buffer !== false) { - $response = $this->binary_packet_buffer; - $this->binary_packet_buffer = false; - } else { - $response = $this->get_binary_packet(true); - if ($response === true && $this->is_timeout) { - if ($client_channel == self::CHANNEL_EXEC && !$this->request_pty) { - $this->close_channel($client_channel); - } - return true; - } - if ($response === false) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_CONNECTION_LOST); - throw new ConnectionClosedException('Connection closed by server'); - } - } - - if ($client_channel == -1 && $response === true) { - return true; - } - list($type, $channel) = Strings::unpackSSH2('CN', $response); - - // will not be setup yet on incoming channel open request - if (isset($channel) && isset($this->channel_status[$channel]) && isset($this->window_size_server_to_client[$channel])) { - $this->window_size_server_to_client[$channel] -= strlen($response); - - // resize the window, if appropriate - if ($this->window_size_server_to_client[$channel] < 0) { - // PuTTY does something more analogous to the following: - //if ($this->window_size_server_to_client[$channel] < 0x3FFFFFFF) { - $packet = pack('CNN', NET_SSH2_MSG_CHANNEL_WINDOW_ADJUST, $this->server_channels[$channel], $this->window_resize); - $this->send_binary_packet($packet); - $this->window_size_server_to_client[$channel] += $this->window_resize; - } - - switch ($type) { - case NET_SSH2_MSG_CHANNEL_EXTENDED_DATA: - /* - if ($client_channel == self::CHANNEL_EXEC) { - $this->send_channel_packet($client_channel, chr(0)); - } - */ - // currently, there's only one possible value for $data_type_code: NET_SSH2_EXTENDED_DATA_STDERR - list($data_type_code, $data) = Strings::unpackSSH2('Ns', $response); - $this->stdErrorLog .= $data; - if ($skip_extended || $this->quiet_mode) { - continue 2; - } - if ($client_channel == $channel && $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA) { - return $data; - } - $this->channel_buffers[$channel][] = chr($type) . $data; - - continue 2; - case NET_SSH2_MSG_CHANNEL_REQUEST: - if ($this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_CLOSE) { - continue 2; - } - list($value) = Strings::unpackSSH2('s', $response); - switch ($value) { - case 'exit-signal': - list( - , // FALSE - $signal_name, - , // core dumped - $error_message - ) = Strings::unpackSSH2('bsbs', $response); - - $this->errors[] = "SSH_MSG_CHANNEL_REQUEST (exit-signal): $signal_name"; - if (strlen($error_message)) { - $this->errors[count($this->errors) - 1] .= "\r\n$error_message"; - } - - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); - - $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_EOF; - - continue 3; - case 'exit-status': - list(, $this->exit_status) = Strings::unpackSSH2('CN', $response); - - // "The client MAY ignore these messages." - // -- http://tools.ietf.org/html/rfc4254#section-6.10 - - continue 3; - default: - // "Some systems may not implement signals, in which case they SHOULD ignore this message." - // -- http://tools.ietf.org/html/rfc4254#section-6.9 - continue 3; - } - } - - switch ($this->channel_status[$channel]) { - case NET_SSH2_MSG_CHANNEL_OPEN: - switch ($type) { - case NET_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION: - list( - $this->server_channels[$channel], - $window_size, - $this->packet_size_client_to_server[$channel] - ) = Strings::unpackSSH2('NNN', $response); - - if ($window_size < 0) { - $window_size &= 0x7FFFFFFF; - $window_size += 0x80000000; - } - $this->window_size_client_to_server[$channel] = $window_size; - $result = $client_channel == $channel ? true : $this->get_channel_packet($client_channel, $skip_extended); - $this->on_channel_open(); - return $result; - case NET_SSH2_MSG_CHANNEL_OPEN_FAILURE: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unable to open channel'); - default: - if ($client_channel == $channel) { - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unexpected response to open request'); - } - return $this->get_channel_packet($client_channel, $skip_extended); - } - break; - case NET_SSH2_MSG_CHANNEL_REQUEST: - switch ($type) { - case NET_SSH2_MSG_CHANNEL_SUCCESS: - return true; - case NET_SSH2_MSG_CHANNEL_FAILURE: - return false; - case NET_SSH2_MSG_CHANNEL_DATA: - list($data) = Strings::unpackSSH2('s', $response); - $this->channel_buffers[$channel][] = chr($type) . $data; - return $this->get_channel_packet($client_channel, $skip_extended); - default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException('Unable to fulfill channel request'); - } - case NET_SSH2_MSG_CHANNEL_CLOSE: - if ($client_channel == $channel && $type == NET_SSH2_MSG_CHANNEL_CLOSE) { - return true; - } - return $this->get_channel_packet($client_channel, $skip_extended); - } - } - - // ie. $this->channel_status[$channel] == NET_SSH2_MSG_CHANNEL_DATA - - switch ($type) { - case NET_SSH2_MSG_CHANNEL_DATA: - /* - if ($channel == self::CHANNEL_EXEC) { - // SCP requires null packets, such as this, be sent. further, in the case of the ssh.com SSH server - // this actually seems to make things twice as fast. more to the point, the message right after - // SSH_MSG_CHANNEL_DATA (usually SSH_MSG_IGNORE) won't block for as long as it would have otherwise. - // in OpenSSH it slows things down but only by a couple thousandths of a second. - $this->send_channel_packet($channel, chr(0)); - } - */ - list($data) = Strings::unpackSSH2('s', $response); - - if ($channel == self::CHANNEL_AGENT_FORWARD) { - $agent_response = $this->agent->forwardData($data); - if (!is_bool($agent_response)) { - $this->send_channel_packet($channel, $agent_response); - } - break; - } - - if ($client_channel == $channel) { - return $data; - } - $this->channel_buffers[$channel][] = chr($type) . $data; - break; - case NET_SSH2_MSG_CHANNEL_CLOSE: - $this->curTimeout = 5; - - $this->close_channel_bitmap($channel); - - if ($this->channel_status[$channel] != NET_SSH2_MSG_CHANNEL_EOF) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$channel])); - } - - $this->channel_status[$channel] = NET_SSH2_MSG_CHANNEL_CLOSE; - $this->channelCount--; - - if ($client_channel == $channel) { - return true; - } - // fall-through - case NET_SSH2_MSG_CHANNEL_EOF: - break; - default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_BY_APPLICATION); - throw new \RuntimeException("Error reading channel data ($type)"); - } - } - } - - /** - * Sends Binary Packets - * - * See '6. Binary Packet Protocol' of rfc4253 for more info. - * - * @param string $data - * @param string $logged - * @see self::_get_binary_packet() - * @return void - */ - protected function send_binary_packet($data, $logged = null) - { - if (!is_resource($this->fsock) || feof($this->fsock)) { - $this->bitmap = 0; - throw new ConnectionClosedException('Connection closed prematurely'); - } - - if (!isset($logged)) { - $logged = $data; - } - - switch ($this->compress) { - case self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH: - if (!$this->isAuthenticated()) { - break; - } - // fall-through - case self::NET_SSH2_COMPRESSION_ZLIB: - if (!$this->regenerate_compression_context) { - $header = ''; - } else { - $this->regenerate_compression_context = false; - $this->compress_context = deflate_init(ZLIB_ENCODING_RAW, ['window' => 15]); - $header = "\x78\x9C"; - } - if ($this->compress_context) { - $data = $header . deflate_add($this->compress_context, $data, ZLIB_PARTIAL_FLUSH); - } - } - - // 4 (packet length) + 1 (padding length) + 4 (minimal padding amount) == 9 - $packet_length = strlen($data) + 9; - if ($this->encrypt && $this->encrypt->usesNonce()) { - $packet_length -= 4; - } - // round up to the nearest $this->encrypt_block_size - $packet_length += (($this->encrypt_block_size - 1) * $packet_length) % $this->encrypt_block_size; - // subtracting strlen($data) is obvious - subtracting 5 is necessary because of packet_length and padding_length - $padding_length = $packet_length - strlen($data) - 5; - switch (true) { - case $this->encrypt && $this->encrypt->usesNonce(): - case $this->hmac_create instanceof Hash && $this->hmac_create_etm: - $padding_length += 4; - $packet_length += 4; - } - - $padding = Random::string($padding_length); - - // we subtract 4 from packet_length because the packet_length field isn't supposed to include itself - $packet = pack('NCa*', $packet_length - 4, $padding_length, $data . $padding); - - $hmac = ''; - if ($this->hmac_create instanceof Hash && !$this->hmac_create_etm) { - if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { - $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); - $hmac = $this->hmac_create->hash($packet); - } else { - $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); - } - } - - if ($this->encrypt) { - switch ($this->encryptName) { - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - $this->encrypt->setNonce( - $this->encryptFixedPart . - $this->encryptInvocationCounter - ); - Strings::increment_str($this->encryptInvocationCounter); - $this->encrypt->setAAD($temp = ($packet & "\xFF\xFF\xFF\xFF")); - $packet = $temp . $this->encrypt->encrypt(substr($packet, 4)); - break; - case 'chacha20-poly1305@openssh.com': - // This should be impossible, but we are checking anyway to narrow the type for Psalm. - if (!($this->encrypt instanceof ChaCha20)) { - throw new \LogicException('$this->encrypt is not a ' . ChaCha20::class); - } - - $nonce = pack('N2', 0, $this->send_seq_no); - - $this->encrypt->setNonce($nonce); - $this->lengthEncrypt->setNonce($nonce); - - $length = $this->lengthEncrypt->encrypt($packet & "\xFF\xFF\xFF\xFF"); - - $this->encrypt->setCounter(0); - // this is the same approach that's implemented in Salsa20::createPoly1305Key() - // but we don't want to use the same AEAD construction that RFC8439 describes - // for ChaCha20-Poly1305 so we won't rely on it (see Salsa20::poly1305()) - $this->encrypt->setPoly1305Key( - $this->encrypt->encrypt(str_repeat("\0", 32)) - ); - $this->encrypt->setAAD($length); - $this->encrypt->setCounter(1); - $packet = $length . $this->encrypt->encrypt(substr($packet, 4)); - break; - default: - $packet = $this->hmac_create instanceof Hash && $this->hmac_create_etm ? - ($packet & "\xFF\xFF\xFF\xFF") . $this->encrypt->encrypt(substr($packet, 4)) : - $this->encrypt->encrypt($packet); - } - } - - if ($this->hmac_create instanceof Hash && $this->hmac_create_etm) { - if (($this->hmac_create->getHash() & "\xFF\xFF\xFF\xFF") == 'umac') { - $this->hmac_create->setNonce("\0\0\0\0" . pack('N', $this->send_seq_no)); - $hmac = $this->hmac_create->hash($packet); - } else { - $hmac = $this->hmac_create->hash(pack('Na*', $this->send_seq_no, $packet)); - } - } - - $this->send_seq_no++; - - $packet .= $this->encrypt && $this->encrypt->usesNonce() ? $this->encrypt->getTag() : $hmac; - - $start = microtime(true); - $sent = @fputs($this->fsock, $packet); - $stop = microtime(true); - - if (defined('NET_SSH2_LOGGING')) { - $current = microtime(true); - $message_number = isset(self::$message_numbers[ord($logged[0])]) ? self::$message_numbers[ord($logged[0])] : 'UNKNOWN (' . ord($logged[0]) . ')'; - $message_number = '-> ' . $message_number . - ' (since last: ' . round($current - $this->last_packet, 4) . ', network: ' . round($stop - $start, 4) . 's)'; - $this->append_log($message_number, $logged); - $this->last_packet = $current; - } - - if (strlen($packet) != $sent) { - $this->bitmap = 0; - $message = $sent === false ? - 'Unable to write ' . strlen($packet) . ' bytes' : - "Only $sent of " . strlen($packet) . " bytes were sent"; - throw new \RuntimeException($message); - } - } - - /** - * Logs data packets - * - * Makes sure that only the last 1MB worth of packets will be logged - * - * @param string $message_number - * @param string $message - */ - private function append_log($message_number, $message) - { - $this->append_log_helper( - NET_SSH2_LOGGING, - $message_number, - $message, - $this->message_number_log, - $this->message_log, - $this->log_size, - $this->realtime_log_file, - $this->realtime_log_wrap, - $this->realtime_log_size - ); - } - - /** - * Logs data packet helper - * - * @param int $constant - * @param string $message_number - * @param string $message - * @param array &$message_number_log - * @param array &$message_log - * @param int &$log_size - * @param resource &$realtime_log_file - * @param bool &$realtime_log_wrap - * @param int &$realtime_log_size - */ - protected function append_log_helper($constant, $message_number, $message, array &$message_number_log, array &$message_log, &$log_size, &$realtime_log_file, &$realtime_log_wrap, &$realtime_log_size) - { - // remove the byte identifying the message type from all but the first two messages (ie. the identification strings) - if (strlen($message_number) > 2) { - Strings::shift($message); - } - - switch ($constant) { - // useful for benchmarks - case self::LOG_SIMPLE: - $message_number_log[] = $message_number; - break; - case self::LOG_SIMPLE_REALTIME: - echo $message_number; - echo PHP_SAPI == 'cli' ? "\r\n" : '
          '; - @flush(); - @ob_flush(); - break; - // the most useful log for SSH2 - case self::LOG_COMPLEX: - $message_number_log[] = $message_number; - $log_size += strlen($message); - $message_log[] = $message; - while ($log_size > self::LOG_MAX_SIZE) { - $log_size -= strlen(array_shift($message_log)); - array_shift($message_number_log); - } - break; - // dump the output out realtime; packets may be interspersed with non packets, - // passwords won't be filtered out and select other packets may not be correctly - // identified - case self::LOG_REALTIME: - switch (PHP_SAPI) { - case 'cli': - $start = $stop = "\r\n"; - break; - default: - $start = '
          ';
          -                        $stop = '
          '; - } - echo $start . $this->format_log([$message], [$message_number]) . $stop; - @flush(); - @ob_flush(); - break; - // basically the same thing as self::LOG_REALTIME with the caveat that NET_SSH2_LOG_REALTIME_FILENAME - // needs to be defined and that the resultant log file will be capped out at self::LOG_MAX_SIZE. - // the earliest part of the log file is denoted by the first <<< START >>> and is not going to necessarily - // at the beginning of the file - case self::LOG_REALTIME_FILE: - if (!isset($realtime_log_file)) { - // PHP doesn't seem to like using constants in fopen() - $filename = NET_SSH2_LOG_REALTIME_FILENAME; - $fp = fopen($filename, 'w'); - $realtime_log_file = $fp; - } - if (!is_resource($realtime_log_file)) { - break; - } - $entry = $this->format_log([$message], [$message_number]); - if ($realtime_log_wrap) { - $temp = "<<< START >>>\r\n"; - $entry .= $temp; - fseek($realtime_log_file, ftell($realtime_log_file) - strlen($temp)); - } - $realtime_log_size += strlen($entry); - if ($realtime_log_size > self::LOG_MAX_SIZE) { - fseek($realtime_log_file, 0); - $realtime_log_size = strlen($entry); - $realtime_log_wrap = true; - } - fputs($realtime_log_file, $entry); - } - } - - /** - * Sends channel data - * - * Spans multiple SSH_MSG_CHANNEL_DATAs if appropriate - * - * @param int $client_channel - * @param string $data - * @return void - */ - protected function send_channel_packet($client_channel, $data) - { - while (strlen($data)) { - if (!$this->window_size_client_to_server[$client_channel]) { - $this->bitmap ^= self::MASK_WINDOW_ADJUST; - // using an invalid channel will let the buffers be built up for the valid channels - $this->get_channel_packet(-1); - $this->bitmap ^= self::MASK_WINDOW_ADJUST; - } - - /* The maximum amount of data allowed is determined by the maximum - packet size for the channel, and the current window size, whichever - is smaller. - -- http://tools.ietf.org/html/rfc4254#section-5.2 */ - $max_size = min( - $this->packet_size_client_to_server[$client_channel], - $this->window_size_client_to_server[$client_channel] - ); - - $temp = Strings::shift($data, $max_size); - $packet = Strings::packSSH2( - 'CNs', - NET_SSH2_MSG_CHANNEL_DATA, - $this->server_channels[$client_channel], - $temp - ); - $this->window_size_client_to_server[$client_channel] -= strlen($temp); - $this->send_binary_packet($packet); - } - } - - /** - * Closes and flushes a channel - * - * \phpseclib3\Net\SSH2 doesn't properly close most channels. For exec() channels are normally closed by the server - * and for SFTP channels are presumably closed when the client disconnects. This functions is intended - * for SCP more than anything. - * - * @param int $client_channel - * @param bool $want_reply - * @return void - */ - private function close_channel($client_channel, $want_reply = false) - { - // see http://tools.ietf.org/html/rfc4254#section-5.3 - - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_EOF, $this->server_channels[$client_channel])); - - if (!$want_reply) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); - } - - $this->channel_status[$client_channel] = NET_SSH2_MSG_CHANNEL_CLOSE; - $this->channelCount--; - - $this->curTimeout = 5; - - while (!is_bool($this->get_channel_packet($client_channel))) { - } - - if ($want_reply) { - $this->send_binary_packet(pack('CN', NET_SSH2_MSG_CHANNEL_CLOSE, $this->server_channels[$client_channel])); - } - - $this->close_channel_bitmap($client_channel); - } - - /** - * Maintains execution state bitmap in response to channel closure - * - * @param int $client_channel The channel number to maintain closure status of - * @return void - */ - private function close_channel_bitmap($client_channel) - { - switch ($client_channel) { - case self::CHANNEL_SHELL: - // Shell status has been maintained in the bitmap for backwards - // compatibility sake, but can be removed going forward - if ($this->bitmap & self::MASK_SHELL) { - $this->bitmap &= ~self::MASK_SHELL; - } - break; - } - } - - /** - * Disconnect - * - * @param int $reason - * @return false - */ - protected function disconnect_helper($reason) - { - if ($this->bitmap & self::MASK_CONNECTED) { - $data = Strings::packSSH2('CNss', NET_SSH2_MSG_DISCONNECT, $reason, '', ''); - try { - $this->send_binary_packet($data); - } catch (\Exception $e) { - } - } - - $this->bitmap = 0; - if (is_resource($this->fsock) && get_resource_type($this->fsock) === 'stream') { - fclose($this->fsock); - } - - return false; - } - - /** - * Define Array - * - * Takes any number of arrays whose indices are integers and whose values are strings and defines a bunch of - * named constants from it, using the value as the name of the constant and the index as the value of the constant. - * If any of the constants that would be defined already exists, none of the constants will be defined. - * - * @param mixed[] ...$args - * @access protected - */ - protected static function define_array(...$args) - { - foreach ($args as $arg) { - foreach ($arg as $key => $value) { - if (!defined($value)) { - define($value, $key); - } else { - break 2; - } - } - } - } - - /** - * Returns a log of the packets that have been sent and received. - * - * Returns a string if NET_SSH2_LOGGING == self::LOG_COMPLEX, an array if NET_SSH2_LOGGING == self::LOG_SIMPLE and false if !defined('NET_SSH2_LOGGING') - * - * @return array|false|string - */ - public function getLog() - { - if (!defined('NET_SSH2_LOGGING')) { - return false; - } - - switch (NET_SSH2_LOGGING) { - case self::LOG_SIMPLE: - return $this->message_number_log; - case self::LOG_COMPLEX: - $log = $this->format_log($this->message_log, $this->message_number_log); - return PHP_SAPI == 'cli' ? $log : '
          ' . $log . '
          '; - default: - return false; - } - } - - /** - * Formats a log for printing - * - * @param array $message_log - * @param array $message_number_log - * @return string - */ - protected function format_log(array $message_log, array $message_number_log) - { - $output = ''; - for ($i = 0; $i < count($message_log); $i++) { - $output .= $message_number_log[$i] . "\r\n"; - $current_log = $message_log[$i]; - $j = 0; - do { - if (strlen($current_log)) { - $output .= str_pad(dechex($j), 7, '0', STR_PAD_LEFT) . '0 '; - } - $fragment = Strings::shift($current_log, $this->log_short_width); - $hex = substr(preg_replace_callback('#.#s', function ($matches) { - return $this->log_boundary . str_pad(dechex(ord($matches[0])), 2, '0', STR_PAD_LEFT); - }, $fragment), strlen($this->log_boundary)); - // replace non ASCII printable characters with dots - // http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters - // also replace < with a . since < messes up the output on web browsers - $raw = preg_replace('#[^\x20-\x7E]|<#', '.', $fragment); - $output .= str_pad($hex, $this->log_long_width - $this->log_short_width, ' ') . $raw . "\r\n"; - $j++; - } while (strlen($current_log)); - $output .= "\r\n"; - } - - return $output; - } - - /** - * Helper function for agent->on_channel_open() - * - * Used when channels are created to inform agent - * of said channel opening. Must be called after - * channel open confirmation received - * - */ - private function on_channel_open() - { - if (isset($this->agent)) { - $this->agent->registerChannelOpen($this); - } - } - - /** - * Returns the first value of the intersection of two arrays or false if - * the intersection is empty. The order is defined by the first parameter. - * - * @param array $array1 - * @param array $array2 - * @return mixed False if intersection is empty, else intersected value. - */ - private static function array_intersect_first(array $array1, array $array2) - { - foreach ($array1 as $value) { - if (in_array($value, $array2)) { - return $value; - } - } - return false; - } - - /** - * Returns all errors - * - * @return string[] - */ - public function getErrors() - { - return $this->errors; - } - - /** - * Returns the last error - * - * @return string - */ - public function getLastError() - { - $count = count($this->errors); - - if ($count > 0) { - return $this->errors[$count - 1]; - } - } - - /** - * Return the server identification. - * - * @return string|false - */ - public function getServerIdentification() - { - $this->connect(); - - return $this->server_identifier; - } - - /** - * Returns a list of algorithms the server supports - * - * @return array - */ - public function getServerAlgorithms() - { - $this->connect(); - - return [ - 'kex' => $this->kex_algorithms, - 'hostkey' => $this->server_host_key_algorithms, - 'client_to_server' => [ - 'crypt' => $this->encryption_algorithms_client_to_server, - 'mac' => $this->mac_algorithms_client_to_server, - 'comp' => $this->compression_algorithms_client_to_server, - 'lang' => $this->languages_client_to_server - ], - 'server_to_client' => [ - 'crypt' => $this->encryption_algorithms_server_to_client, - 'mac' => $this->mac_algorithms_server_to_client, - 'comp' => $this->compression_algorithms_server_to_client, - 'lang' => $this->languages_server_to_client - ] - ]; - } - - /** - * Returns a list of KEX algorithms that phpseclib supports - * - * @return array - */ - public static function getSupportedKEXAlgorithms() - { - $kex_algorithms = [ - // Elliptic Curve Diffie-Hellman Key Agreement (ECDH) using - // Curve25519. See doc/curve25519-sha256@libssh.org.txt in the - // libssh repository for more information. - 'curve25519-sha256', - 'curve25519-sha256@libssh.org', - - 'ecdh-sha2-nistp256', // RFC 5656 - 'ecdh-sha2-nistp384', // RFC 5656 - 'ecdh-sha2-nistp521', // RFC 5656 - - 'diffie-hellman-group-exchange-sha256',// RFC 4419 - 'diffie-hellman-group-exchange-sha1', // RFC 4419 - - // Diffie-Hellman Key Agreement (DH) using integer modulo prime - // groups. - 'diffie-hellman-group14-sha256', - 'diffie-hellman-group14-sha1', // REQUIRED - 'diffie-hellman-group15-sha512', - 'diffie-hellman-group16-sha512', - 'diffie-hellman-group17-sha512', - 'diffie-hellman-group18-sha512', - - 'diffie-hellman-group1-sha1', // REQUIRED - ]; - - return $kex_algorithms; - } - - /** - * Returns a list of host key algorithms that phpseclib supports - * - * @return array - */ - public static function getSupportedHostKeyAlgorithms() - { - return [ - 'ssh-ed25519', // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-02 - 'ecdsa-sha2-nistp256', // RFC 5656 - 'ecdsa-sha2-nistp384', // RFC 5656 - 'ecdsa-sha2-nistp521', // RFC 5656 - 'rsa-sha2-256', // RFC 8332 - 'rsa-sha2-512', // RFC 8332 - 'ssh-rsa', // RECOMMENDED sign Raw RSA Key - 'ssh-dss' // REQUIRED sign Raw DSS Key - ]; - } - - /** - * Returns a list of symmetric key algorithms that phpseclib supports - * - * @return array - */ - public static function getSupportedEncryptionAlgorithms() - { - $algos = [ - // from : - 'aes128-gcm@openssh.com', - 'aes256-gcm@openssh.com', - - // from : - 'arcfour256', - 'arcfour128', - - //'arcfour', // OPTIONAL the ARCFOUR stream cipher with a 128-bit key - - // CTR modes from : - 'aes128-ctr', // RECOMMENDED AES (Rijndael) in SDCTR mode, with 128-bit key - 'aes192-ctr', // RECOMMENDED AES with 192-bit key - 'aes256-ctr', // RECOMMENDED AES with 256-bit key - - // from : - // one of the big benefits of chacha20-poly1305 is speed. the problem is... - // libsodium doesn't generate the poly1305 keys in the way ssh does and openssl's PHP bindings don't even - // seem to support poly1305 currently. so even if libsodium or openssl are being used for the chacha20 - // part, pure-PHP has to be used for the poly1305 part and that's gonna cause a big slow down. - // speed-wise it winds up being faster to use AES (when openssl or mcrypt are available) and some HMAC - // (which is always gonna be super fast to compute thanks to the hash extension, which - // "is bundled and compiled into PHP by default") - 'chacha20-poly1305@openssh.com', - - 'twofish128-ctr', // OPTIONAL Twofish in SDCTR mode, with 128-bit key - 'twofish192-ctr', // OPTIONAL Twofish with 192-bit key - 'twofish256-ctr', // OPTIONAL Twofish with 256-bit key - - 'aes128-cbc', // RECOMMENDED AES with a 128-bit key - 'aes192-cbc', // OPTIONAL AES with a 192-bit key - 'aes256-cbc', // OPTIONAL AES in CBC mode, with a 256-bit key - - 'twofish128-cbc', // OPTIONAL Twofish with a 128-bit key - 'twofish192-cbc', // OPTIONAL Twofish with a 192-bit key - 'twofish256-cbc', - 'twofish-cbc', // OPTIONAL alias for "twofish256-cbc" - // (this is being retained for historical reasons) - - 'blowfish-ctr', // OPTIONAL Blowfish in SDCTR mode - - 'blowfish-cbc', // OPTIONAL Blowfish in CBC mode - - '3des-ctr', // RECOMMENDED Three-key 3DES in SDCTR mode - - '3des-cbc', // REQUIRED three-key 3DES in CBC mode - - //'none' // OPTIONAL no encryption; NOT RECOMMENDED - ]; - - if (self::$crypto_engine) { - $engines = [self::$crypto_engine]; - } else { - $engines = [ - 'libsodium', - 'OpenSSL (GCM)', - 'OpenSSL', - 'mcrypt', - 'Eval', - 'PHP' - ]; - } - - $ciphers = []; - - foreach ($engines as $engine) { - foreach ($algos as $algo) { - $obj = self::encryption_algorithm_to_crypt_instance($algo); - if ($obj instanceof Rijndael) { - $obj->setKeyLength(preg_replace('#[^\d]#', '', $algo)); - } - switch ($algo) { - case 'chacha20-poly1305@openssh.com': - case 'arcfour128': - case 'arcfour256': - if ($engine != 'Eval') { - continue 2; - } - break; - case 'aes128-gcm@openssh.com': - case 'aes256-gcm@openssh.com': - if ($engine == 'OpenSSL') { - continue 2; - } - $obj->setNonce('dummydummydu'); - } - if ($obj->isValidEngine($engine)) { - $algos = array_diff($algos, [$algo]); - $ciphers[] = $algo; - } - } - } - - return $ciphers; - } - - /** - * Returns a list of MAC algorithms that phpseclib supports - * - * @return array - */ - public static function getSupportedMACAlgorithms() - { - return [ - 'hmac-sha2-256-etm@openssh.com', - 'hmac-sha2-512-etm@openssh.com', - 'umac-64-etm@openssh.com', - 'umac-128-etm@openssh.com', - 'hmac-sha1-etm@openssh.com', - - // from : - 'hmac-sha2-256',// RECOMMENDED HMAC-SHA256 (digest length = key length = 32) - 'hmac-sha2-512',// OPTIONAL HMAC-SHA512 (digest length = key length = 64) - - // from : - 'umac-64@openssh.com', - 'umac-128@openssh.com', - - 'hmac-sha1-96', // RECOMMENDED first 96 bits of HMAC-SHA1 (digest length = 12, key length = 20) - 'hmac-sha1', // REQUIRED HMAC-SHA1 (digest length = key length = 20) - 'hmac-md5-96', // OPTIONAL first 96 bits of HMAC-MD5 (digest length = 12, key length = 16) - 'hmac-md5', // OPTIONAL HMAC-MD5 (digest length = key length = 16) - //'none' // OPTIONAL no MAC; NOT RECOMMENDED - ]; - } - - /** - * Returns a list of compression algorithms that phpseclib supports - * - * @return array - */ - public static function getSupportedCompressionAlgorithms() - { - $algos = ['none']; // REQUIRED no compression - if (function_exists('deflate_init')) { - $algos[] = 'zlib@openssh.com'; // https://datatracker.ietf.org/doc/html/draft-miller-secsh-compression-delayed - $algos[] = 'zlib'; - } - return $algos; - } - - /** - * Return list of negotiated algorithms - * - * Uses the same format as https://www.php.net/ssh2-methods-negotiated - * - * @return array - */ - public function getAlgorithmsNegotiated() - { - $this->connect(); - - $compression_map = [ - self::NET_SSH2_COMPRESSION_NONE => 'none', - self::NET_SSH2_COMPRESSION_ZLIB => 'zlib', - self::NET_SSH2_COMPRESSION_ZLIB_AT_OPENSSH => 'zlib@openssh.com' - ]; - - return [ - 'kex' => $this->kex_algorithm, - 'hostkey' => $this->signature_format, - 'client_to_server' => [ - 'crypt' => $this->encryptName, - 'mac' => $this->hmac_create_name, - 'comp' => $compression_map[$this->compress], - ], - 'server_to_client' => [ - 'crypt' => $this->decryptName, - 'mac' => $this->hmac_check_name, - 'comp' => $compression_map[$this->decompress], - ] - ]; - } - - /** - * Force multiple channels (even if phpseclib has decided to disable them) - */ - public function forceMultipleChannels() - { - $this->errorOnMultipleChannels = false; - } - - /** - * Allows you to set the terminal - * - * @param string $term - */ - public function setTerminal($term) - { - $this->term = $term; - } - - /** - * Accepts an associative array with up to four parameters as described at - * - * - * @param array $methods - */ - public function setPreferredAlgorithms(array $methods) - { - $preferred = $methods; - - if (isset($preferred['kex'])) { - $preferred['kex'] = array_intersect( - $preferred['kex'], - static::getSupportedKEXAlgorithms() - ); - } - - if (isset($preferred['hostkey'])) { - $preferred['hostkey'] = array_intersect( - $preferred['hostkey'], - static::getSupportedHostKeyAlgorithms() - ); - } - - $keys = ['client_to_server', 'server_to_client']; - foreach ($keys as $key) { - if (isset($preferred[$key])) { - $a = &$preferred[$key]; - if (isset($a['crypt'])) { - $a['crypt'] = array_intersect( - $a['crypt'], - static::getSupportedEncryptionAlgorithms() - ); - } - if (isset($a['comp'])) { - $a['comp'] = array_intersect( - $a['comp'], - static::getSupportedCompressionAlgorithms() - ); - } - if (isset($a['mac'])) { - $a['mac'] = array_intersect( - $a['mac'], - static::getSupportedMACAlgorithms() - ); - } - } - } - - $keys = [ - 'kex', - 'hostkey', - 'client_to_server/crypt', - 'client_to_server/comp', - 'client_to_server/mac', - 'server_to_client/crypt', - 'server_to_client/comp', - 'server_to_client/mac', - ]; - foreach ($keys as $key) { - $p = $preferred; - $m = $methods; - - $subkeys = explode('/', $key); - foreach ($subkeys as $subkey) { - if (!isset($p[$subkey])) { - continue 2; - } - $p = $p[$subkey]; - $m = $m[$subkey]; - } - - if (count($p) != count($m)) { - $diff = array_diff($m, $p); - $msg = count($diff) == 1 ? - ' is not a supported algorithm' : - ' are not supported algorithms'; - throw new UnsupportedAlgorithmException(implode(', ', $diff) . $msg); - } - } - - $this->preferred = $preferred; - } - - /** - * Returns the banner message. - * - * Quoting from the RFC, "in some jurisdictions, sending a warning message before - * authentication may be relevant for getting legal protection." - * - * @return string - */ - public function getBannerMessage() - { - return $this->banner_message; - } - - /** - * Returns the server public host key. - * - * Caching this the first time you connect to a server and checking the result on subsequent connections - * is recommended. Returns false if the server signature is not signed correctly with the public host key. - * - * @return string|false - * @throws \RuntimeException on badly formatted keys - * @throws \phpseclib3\Exception\NoSupportedAlgorithmsException when the key isn't in a supported format - */ - public function getServerPublicHostKey() - { - if (!($this->bitmap & self::MASK_CONSTRUCTOR)) { - $this->connect(); - } - - $signature = $this->signature; - $server_public_host_key = base64_encode($this->server_public_host_key); - - if ($this->signature_validated) { - return $this->bitmap ? - $this->signature_format . ' ' . $server_public_host_key : - false; - } - - $this->signature_validated = true; - - switch ($this->signature_format) { - case 'ssh-ed25519': - case 'ecdsa-sha2-nistp256': - case 'ecdsa-sha2-nistp384': - case 'ecdsa-sha2-nistp521': - $key = EC::loadFormat('OpenSSH', $server_public_host_key) - ->withSignatureFormat('SSH2'); - switch ($this->signature_format) { - case 'ssh-ed25519': - $hash = 'sha512'; - break; - case 'ecdsa-sha2-nistp256': - $hash = 'sha256'; - break; - case 'ecdsa-sha2-nistp384': - $hash = 'sha384'; - break; - case 'ecdsa-sha2-nistp521': - $hash = 'sha512'; - } - $key = $key->withHash($hash); - break; - case 'ssh-dss': - $key = DSA::loadFormat('OpenSSH', $server_public_host_key) - ->withSignatureFormat('SSH2') - ->withHash('sha1'); - break; - case 'ssh-rsa': - case 'rsa-sha2-256': - case 'rsa-sha2-512': - // could be ssh-rsa, rsa-sha2-256, rsa-sha2-512 - // we don't check here because we already checked in key_exchange - // some signatures have the type embedded within the message and some don't - list(, $signature) = Strings::unpackSSH2('ss', $signature); - - $key = RSA::loadFormat('OpenSSH', $server_public_host_key) - ->withPadding(RSA::SIGNATURE_PKCS1); - switch ($this->signature_format) { - case 'rsa-sha2-512': - $hash = 'sha512'; - break; - case 'rsa-sha2-256': - $hash = 'sha256'; - break; - //case 'ssh-rsa': - default: - $hash = 'sha1'; - } - $key = $key->withHash($hash); - break; - default: - $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - throw new NoSupportedAlgorithmsException('Unsupported signature format'); - } - - if (!$key->verify($this->exchange_hash, $signature)) { - return $this->disconnect_helper(NET_SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE); - }; - - return $this->signature_format . ' ' . $server_public_host_key; - } - - /** - * Returns the exit status of an SSH command or false. - * - * @return false|int - */ - public function getExitStatus() - { - if (is_null($this->exit_status)) { - return false; - } - return $this->exit_status; - } - - /** - * Returns the number of columns for the terminal window size. - * - * @return int - */ - public function getWindowColumns() - { - return $this->windowColumns; - } - - /** - * Returns the number of rows for the terminal window size. - * - * @return int - */ - public function getWindowRows() - { - return $this->windowRows; - } - - /** - * Sets the number of columns for the terminal window size. - * - * @param int $value - */ - public function setWindowColumns($value) - { - $this->windowColumns = $value; - } - - /** - * Sets the number of rows for the terminal window size. - * - * @param int $value - */ - public function setWindowRows($value) - { - $this->windowRows = $value; - } - - /** - * Sets the number of columns and rows for the terminal window size. - * - * @param int $columns - * @param int $rows - */ - public function setWindowSize($columns = 80, $rows = 24) - { - $this->windowColumns = $columns; - $this->windowRows = $rows; - } - - /** - * To String Magic Method - * - * @return string - */ - #[\ReturnTypeWillChange] - public function __toString() - { - return $this->getResourceId(); - } - - /** - * Get Resource ID - * - * We use {} because that symbols should not be in URL according to - * {@link http://tools.ietf.org/html/rfc3986#section-2 RFC}. - * It will safe us from any conflicts, because otherwise regexp will - * match all alphanumeric domains. - * - * @return string - */ - public function getResourceId() - { - return '{' . spl_object_hash($this) . '}'; - } - - /** - * Return existing connection - * - * @param string $id - * - * @return bool|SSH2 will return false if no such connection - */ - public static function getConnectionByResourceId($id) - { - if (isset(self::$connections[$id])) { - return self::$connections[$id] instanceof \WeakReference ? self::$connections[$id]->get() : self::$connections[$id]; - } - return false; - } - - /** - * Return all excising connections - * - * @return array - */ - public static function getConnections() - { - if (!class_exists('WeakReference')) { - /** @var array */ - return self::$connections; - } - $temp = []; - foreach (self::$connections as $key => $ref) { - $temp[$key] = $ref->get(); - } - return $temp; - } - - /* - * Update packet types in log history - * - * @param string $old - * @param string $new - */ - private function updateLogHistory($old, $new) - { - if (defined('NET_SSH2_LOGGING') && NET_SSH2_LOGGING == self::LOG_COMPLEX) { - $this->message_number_log[count($this->message_number_log) - 1] = str_replace( - $old, - $new, - $this->message_number_log[count($this->message_number_log) - 1] - ); - } - } - - /** - * Return the list of authentication methods that may productively continue authentication. - * - * @see https://tools.ietf.org/html/rfc4252#section-5.1 - * @return array|null - */ - public function getAuthMethodsToContinue() - { - return $this->auth_methods_to_continue; - } - - /** - * Enables "smart" multi-factor authentication (MFA) - */ - public function enableSmartMFA() - { - $this->smartMFA = true; - } - - /** - * Disables "smart" multi-factor authentication (MFA) - */ - public function disableSmartMFA() - { - $this->smartMFA = false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php deleted file mode 100644 index 26ca322..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent.php +++ /dev/null @@ -1,286 +0,0 @@ - - * login('username', $agent)) { - * exit('Login Failed'); - * } - * - * echo $ssh->exec('pwd'); - * echo $ssh->exec('ls -la'); - * ?> - * - * - * @author Jim Wigginton - * @copyright 2014 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\System\SSH; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\PublicKeyLoader; -use phpseclib3\Crypt\RSA; -use phpseclib3\Exception\BadConfigurationException; -use phpseclib3\Net\SSH2; -use phpseclib3\System\SSH\Agent\Identity; - -/** - * Pure-PHP ssh-agent client identity factory - * - * requestIdentities() method pumps out \phpseclib3\System\SSH\Agent\Identity objects - * - * @author Jim Wigginton - */ -class Agent -{ - use Common\Traits\ReadBytes; - - // Message numbers - - // to request SSH1 keys you have to use SSH_AGENTC_REQUEST_RSA_IDENTITIES (1) - const SSH_AGENTC_REQUEST_IDENTITIES = 11; - // this is the SSH2 response; the SSH1 response is SSH_AGENT_RSA_IDENTITIES_ANSWER (2). - const SSH_AGENT_IDENTITIES_ANSWER = 12; - // the SSH1 request is SSH_AGENTC_RSA_CHALLENGE (3) - const SSH_AGENTC_SIGN_REQUEST = 13; - // the SSH1 response is SSH_AGENT_RSA_RESPONSE (4) - const SSH_AGENT_SIGN_RESPONSE = 14; - - // Agent forwarding status - - // no forwarding requested and not active - const FORWARD_NONE = 0; - // request agent forwarding when opportune - const FORWARD_REQUEST = 1; - // forwarding has been request and is active - const FORWARD_ACTIVE = 2; - - /** - * Unused - */ - const SSH_AGENT_FAILURE = 5; - - /** - * Socket Resource - * - * @var resource - */ - private $fsock; - - /** - * Agent forwarding status - * - * @var int - */ - private $forward_status = self::FORWARD_NONE; - - /** - * Buffer for accumulating forwarded authentication - * agent data arriving on SSH data channel destined - * for agent unix socket - * - * @var string - */ - private $socket_buffer = ''; - - /** - * Tracking the number of bytes we are expecting - * to arrive for the agent socket on the SSH data - * channel - * - * @var int - */ - private $expected_bytes = 0; - - /** - * Default Constructor - * - * @return \phpseclib3\System\SSH\Agent - * @throws \phpseclib3\Exception\BadConfigurationException if SSH_AUTH_SOCK cannot be found - * @throws \RuntimeException on connection errors - */ - public function __construct($address = null) - { - if (!$address) { - switch (true) { - case isset($_SERVER['SSH_AUTH_SOCK']): - $address = $_SERVER['SSH_AUTH_SOCK']; - break; - case isset($_ENV['SSH_AUTH_SOCK']): - $address = $_ENV['SSH_AUTH_SOCK']; - break; - default: - throw new BadConfigurationException('SSH_AUTH_SOCK not found'); - } - } - - if (in_array('unix', stream_get_transports())) { - $this->fsock = fsockopen('unix://' . $address, 0, $errno, $errstr); - if (!$this->fsock) { - throw new \RuntimeException("Unable to connect to ssh-agent (Error $errno: $errstr)"); - } - } else { - if (substr($address, 0, 9) != '\\\\.\\pipe\\' || strpos(substr($address, 9), '\\') !== false) { - throw new \RuntimeException('Address is not formatted as a named pipe should be'); - } - - $this->fsock = fopen($address, 'r+b'); - if (!$this->fsock) { - throw new \RuntimeException('Unable to open address'); - } - } - } - - /** - * Request Identities - * - * See "2.5.2 Requesting a list of protocol 2 keys" - * Returns an array containing zero or more \phpseclib3\System\SSH\Agent\Identity objects - * - * @return array - * @throws \RuntimeException on receipt of unexpected packets - */ - public function requestIdentities() - { - if (!$this->fsock) { - return []; - } - - $packet = pack('NC', 1, self::SSH_AGENTC_REQUEST_IDENTITIES); - if (strlen($packet) != fputs($this->fsock, $packet)) { - throw new \RuntimeException('Connection closed while requesting identities'); - } - - $length = current(unpack('N', $this->readBytes(4))); - $packet = $this->readBytes($length); - - list($type, $keyCount) = Strings::unpackSSH2('CN', $packet); - if ($type != self::SSH_AGENT_IDENTITIES_ANSWER) { - throw new \RuntimeException('Unable to request identities'); - } - - $identities = []; - for ($i = 0; $i < $keyCount; $i++) { - list($key_blob, $comment) = Strings::unpackSSH2('ss', $packet); - $temp = $key_blob; - list($key_type) = Strings::unpackSSH2('s', $temp); - switch ($key_type) { - case 'ssh-rsa': - case 'ssh-dss': - case 'ssh-ed25519': - case 'ecdsa-sha2-nistp256': - case 'ecdsa-sha2-nistp384': - case 'ecdsa-sha2-nistp521': - $key = PublicKeyLoader::load($key_type . ' ' . base64_encode($key_blob)); - } - // resources are passed by reference by default - if (isset($key)) { - $identity = (new Identity($this->fsock)) - ->withPublicKey($key) - ->withPublicKeyBlob($key_blob); - $identities[] = $identity; - unset($key); - } - } - - return $identities; - } - - /** - * Signal that agent forwarding should - * be requested when a channel is opened - * - * @return void - */ - public function startSSHForwarding() - { - if ($this->forward_status == self::FORWARD_NONE) { - $this->forward_status = self::FORWARD_REQUEST; - } - } - - /** - * Request agent forwarding of remote server - * - * @param \phpseclib3\Net\SSH2 $ssh - * @return bool - */ - private function request_forwarding(SSH2 $ssh) - { - if (!$ssh->requestAgentForwarding()) { - return false; - } - - $this->forward_status = self::FORWARD_ACTIVE; - - return true; - } - - /** - * On successful channel open - * - * This method is called upon successful channel - * open to give the SSH Agent an opportunity - * to take further action. i.e. request agent forwarding - * - * @param \phpseclib3\Net\SSH2 $ssh - */ - public function registerChannelOpen(SSH2 $ssh) - { - if ($this->forward_status == self::FORWARD_REQUEST) { - $this->request_forwarding($ssh); - } - } - - /** - * Forward data to SSH Agent and return data reply - * - * @param string $data - * @return string Data from SSH Agent - * @throws \RuntimeException on connection errors - */ - public function forwardData($data) - { - if ($this->expected_bytes > 0) { - $this->socket_buffer .= $data; - $this->expected_bytes -= strlen($data); - } else { - $agent_data_bytes = current(unpack('N', $data)); - $current_data_bytes = strlen($data); - $this->socket_buffer = $data; - if ($current_data_bytes != $agent_data_bytes + 4) { - $this->expected_bytes = ($agent_data_bytes + 4) - $current_data_bytes; - return false; - } - } - - if (strlen($this->socket_buffer) != fwrite($this->fsock, $this->socket_buffer)) { - throw new \RuntimeException('Connection closed attempting to forward data to SSH agent'); - } - - $this->socket_buffer = ''; - $this->expected_bytes = 0; - - $agent_reply_bytes = current(unpack('N', $this->readBytes(4))); - - $agent_reply_data = $this->readBytes($agent_reply_bytes); - $agent_reply_data = current(unpack('a*', $agent_reply_data)); - - return pack('Na*', $agent_reply_bytes, $agent_reply_data); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php deleted file mode 100644 index 653e8ea..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Agent/Identity.php +++ /dev/null @@ -1,320 +0,0 @@ - - * @copyright 2009 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\System\SSH\Agent; - -use phpseclib3\Common\Functions\Strings; -use phpseclib3\Crypt\Common\PrivateKey; -use phpseclib3\Crypt\Common\PublicKey; -use phpseclib3\Crypt\DSA; -use phpseclib3\Crypt\EC; -use phpseclib3\Crypt\RSA; -use phpseclib3\Exception\UnsupportedAlgorithmException; -use phpseclib3\System\SSH\Agent; -use phpseclib3\System\SSH\Common\Traits\ReadBytes; - -/** - * Pure-PHP ssh-agent client identity object - * - * Instantiation should only be performed by \phpseclib3\System\SSH\Agent class. - * This could be thought of as implementing an interface that phpseclib3\Crypt\RSA - * implements. ie. maybe a Net_SSH_Auth_PublicKey interface or something. - * The methods in this interface would be getPublicKey and sign since those are the - * methods phpseclib looks for to perform public key authentication. - * - * @author Jim Wigginton - * @internal - */ -class Identity implements PrivateKey -{ - use ReadBytes; - - // Signature Flags - // See https://tools.ietf.org/html/draft-miller-ssh-agent-00#section-5.3 - const SSH_AGENT_RSA2_256 = 2; - const SSH_AGENT_RSA2_512 = 4; - - /** - * Key Object - * - * @var PublicKey - * @see self::getPublicKey() - */ - private $key; - - /** - * Key Blob - * - * @var string - * @see self::sign() - */ - private $key_blob; - - /** - * Socket Resource - * - * @var resource - * @see self::sign() - */ - private $fsock; - - /** - * Signature flags - * - * @var int - * @see self::sign() - * @see self::setHash() - */ - private $flags = 0; - - /** - * Curve Aliases - * - * @var array - */ - private static $curveAliases = [ - 'secp256r1' => 'nistp256', - 'secp384r1' => 'nistp384', - 'secp521r1' => 'nistp521', - 'Ed25519' => 'Ed25519' - ]; - - /** - * Default Constructor. - * - * @param resource $fsock - */ - public function __construct($fsock) - { - $this->fsock = $fsock; - } - - /** - * Set Public Key - * - * Called by \phpseclib3\System\SSH\Agent::requestIdentities() - * - * @param \phpseclib3\Crypt\Common\PublicKey $key - */ - public function withPublicKey(PublicKey $key) - { - if ($key instanceof EC) { - if (is_array($key->getCurve()) || !isset(self::$curveAliases[$key->getCurve()])) { - throw new UnsupportedAlgorithmException('The only supported curves are nistp256, nistp384, nistp512 and Ed25519'); - } - } - - $new = clone $this; - $new->key = $key; - return $new; - } - - /** - * Set Public Key - * - * Called by \phpseclib3\System\SSH\Agent::requestIdentities(). The key blob could be extracted from $this->key - * but this saves a small amount of computation. - * - * @param string $key_blob - */ - public function withPublicKeyBlob($key_blob) - { - $new = clone $this; - $new->key_blob = $key_blob; - return $new; - } - - /** - * Get Public Key - * - * Wrapper for $this->key->getPublicKey() - * - * @param string $type optional - * @return mixed - */ - public function getPublicKey($type = 'PKCS8') - { - return $this->key; - } - - /** - * Sets the hash - * - * @param string $hash - */ - public function withHash($hash) - { - $new = clone $this; - - $hash = strtolower($hash); - - if ($this->key instanceof RSA) { - $new->flags = 0; - switch ($hash) { - case 'sha1': - break; - case 'sha256': - $new->flags = self::SSH_AGENT_RSA2_256; - break; - case 'sha512': - $new->flags = self::SSH_AGENT_RSA2_512; - break; - default: - throw new UnsupportedAlgorithmException('The only supported hashes for RSA are sha1, sha256 and sha512'); - } - } - if ($this->key instanceof EC) { - switch ($this->key->getCurve()) { - case 'secp256r1': - $expectedHash = 'sha256'; - break; - case 'secp384r1': - $expectedHash = 'sha384'; - break; - //case 'secp521r1': - //case 'Ed25519': - default: - $expectedHash = 'sha512'; - } - if ($hash != $expectedHash) { - throw new UnsupportedAlgorithmException('The only supported hash for ' . self::$curveAliases[$this->key->getCurve()] . ' is ' . $expectedHash); - } - } - if ($this->key instanceof DSA) { - if ($hash != 'sha1') { - throw new UnsupportedAlgorithmException('The only supported hash for DSA is sha1'); - } - } - return $new; - } - - /** - * Sets the padding - * - * Only PKCS1 padding is supported - * - * @param string $padding - */ - public function withPadding($padding) - { - if (!$this->key instanceof RSA) { - throw new UnsupportedAlgorithmException('Only RSA keys support padding'); - } - if ($padding != RSA::SIGNATURE_PKCS1 && $padding != RSA::SIGNATURE_RELAXED_PKCS1) { - throw new UnsupportedAlgorithmException('ssh-agent can only create PKCS1 signatures'); - } - return $this; - } - - /** - * Determines the signature padding mode - * - * Valid values are: ASN1, SSH2, Raw - * - * @param string $format - */ - public function withSignatureFormat($format) - { - if ($this->key instanceof RSA) { - throw new UnsupportedAlgorithmException('Only DSA and EC keys support signature format setting'); - } - if ($format != 'SSH2') { - throw new UnsupportedAlgorithmException('Only SSH2-formatted signatures are currently supported'); - } - - return $this; - } - - /** - * Returns the curve - * - * Returns a string if it's a named curve, an array if not - * - * @return string|array - */ - public function getCurve() - { - if (!$this->key instanceof EC) { - throw new UnsupportedAlgorithmException('Only EC keys have curves'); - } - - return $this->key->getCurve(); - } - - /** - * Create a signature - * - * See "2.6.2 Protocol 2 private key signature request" - * - * @param string $message - * @return string - * @throws \RuntimeException on connection errors - * @throws \phpseclib3\Exception\UnsupportedAlgorithmException if the algorithm is unsupported - */ - public function sign($message) - { - // the last parameter (currently 0) is for flags and ssh-agent only defines one flag (for ssh-dss): SSH_AGENT_OLD_SIGNATURE - $packet = Strings::packSSH2( - 'CssN', - Agent::SSH_AGENTC_SIGN_REQUEST, - $this->key_blob, - $message, - $this->flags - ); - $packet = Strings::packSSH2('s', $packet); - if (strlen($packet) != fputs($this->fsock, $packet)) { - throw new \RuntimeException('Connection closed during signing'); - } - - $length = current(unpack('N', $this->readBytes(4))); - $packet = $this->readBytes($length); - - list($type, $signature_blob) = Strings::unpackSSH2('Cs', $packet); - if ($type != Agent::SSH_AGENT_SIGN_RESPONSE) { - throw new \RuntimeException('Unable to retrieve signature'); - } - - if (!$this->key instanceof RSA) { - return $signature_blob; - } - - list($type, $signature_blob) = Strings::unpackSSH2('ss', $signature_blob); - - return $signature_blob; - } - - /** - * Returns the private key - * - * @param string $type - * @param array $options optional - * @return string - */ - public function toString($type, array $options = []) - { - throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); - } - - /** - * Sets the password - * - * @param string|bool $password - * @return never - */ - public function withPassword($password = false) - { - throw new \RuntimeException('ssh-agent does not provide a mechanism to get the private key'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php deleted file mode 100644 index 6fd032b..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/System/SSH/Common/Traits/ReadBytes.php +++ /dev/null @@ -1,37 +0,0 @@ - - * @copyright 2015 Jim Wigginton - * @license http://www.opensource.org/licenses/mit-license.html MIT License - * @link http://phpseclib.sourceforge.net - */ - -namespace phpseclib3\System\SSH\Common\Traits; - -/** - * ReadBytes trait - * - * @author Jim Wigginton - */ -trait ReadBytes -{ - /** - * Read data - * - * @param int $length - * @throws \RuntimeException on connection errors - */ - public function readBytes($length) - { - $temp = fread($this->fsock, $length); - if (strlen($temp) != $length) { - throw new \RuntimeException("Expected $length bytes; got " . strlen($temp)); - } - return $temp; - } -} diff --git a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php b/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php deleted file mode 100644 index 517106c..0000000 --- a/utilities/signing_and_verification/php/vendor/phpseclib/phpseclib/phpseclib/bootstrap.php +++ /dev/null @@ -1,22 +0,0 @@ -=7.2 -- gmp -- mbstring - -## Installation - -This library is available on -[Packagist](https://packagist.org/packages/sop/asn1). - -```sh -composer require sop/asn1 -``` - -## Usage - -The general idea is that each ASN.1 type has its corresponding PHP class, -that knows the details of encoding and decoding the specific type. - -To decode DER data, use `fromDER` static method of the expected type. -To encode object to DER, use `toDER` instance method. - -Many methods return an `UnspecifiedType` object, that works as an intermediate -wrapper with accessor methods ensuring type safety. - -All objects are immutable and method chaining is promoted for the fluency -of the API. Exception shall be thrown on errors. - -## [Code Examples](https://github.com/sop/asn1/tree/master/examples) - -Here are some simple usage examples. Namespaces are omitted for brevity. - -### [Encode](https://github.com/sop/asn1/blob/master/examples/encode.php) - -Encode a sequence containing a UTF-8 string, an integer -and an explicitly tagged object identifier, conforming to the following -ASN.1 specification: - -```asn.1 -Example ::= SEQUENCE { - greeting UTF8String, - answer INTEGER, - type [1] EXPLICIT OBJECT IDENTIFIER -} -``` - -```php -$seq = new Sequence( - new UTF8String('Hello'), - new Integer(42), - new ExplicitlyTaggedType( - 1, new ObjectIdentifier('1.3.6.1.3')) -); -$der = $seq->toDER(); -``` - -### [Decode](https://github.com/sop/asn1/blob/master/examples/decode.php) - -Decode DER encoding from above. - -```php -$seq = UnspecifiedType::fromDER($der)->asSequence(); -$greeting = $seq->at(0)->asUTF8String()->string(); -$answer = $seq->at(1)->asInteger()->intNumber(); -$type = $seq->at(2)->asTagged()->asExplicit()->asObjectIdentifier()->oid(); -``` - -### Real-World Examples - -See the following for more practical real-world usage examples. - -- EC Private Key - - [Decode](https://github.com/sop/crypto-types/blob/a27fa76d5f5e8c4596cb65a7be9d02a08421ba1e/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php#L72) - - [Encode](https://github.com/sop/crypto-types/blob/a27fa76d5f5e8c4596cb65a7be9d02a08421ba1e/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php#L206) -- X.501 Attribute - - [Decode](https://github.com/sop/x501/blob/c6bdb04673d5c04b9d49f83020e75b8ba7a20064/lib/X501/ASN1/Attribute.php#L55) - - [Encode](https://github.com/sop/x501/blob/c6bdb04673d5c04b9d49f83020e75b8ba7a20064/lib/X501/ASN1/Attribute.php#L114) -- X.509 Certificate (`TBSCertificate` sequence) - - [Decode](https://github.com/sop/x509/blob/f762c743b6930af4f45ef857ccc9f6199980a92e/lib/X509/Certificate/TBSCertificate.php#L130) - - [Encode](https://github.com/sop/x509/blob/f762c743b6930af4f45ef857ccc9f6199980a92e/lib/X509/Certificate/TBSCertificate.php#L576) - -## ASN.1 References - -- [ITU-T X.690 07/2002](https://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf) -- [ITU-T X.690 08/2015](https://www.itu.int/rec/T-REC-X.690-201508-I/en) -- Hosted by [OSS Nokalva](http://www.oss.com/asn1/resources/books-whitepapers-pubs/asn1-books.html) - - [ASN.1 — Communication Between Heterogeneous Systems by Olivier Dubuisson](http://www.oss.com/asn1/resources/books-whitepapers-pubs/dubuisson-asn1-book.PDF) - - [ASN.1 Complete by Professor John Larmouth](http://www.oss.com/asn1/resources/books-whitepapers-pubs/larmouth-asn1-book.pdf) - -## License - -This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/composer.json b/utilities/signing_and_verification/php/vendor/sop/asn1/composer.json deleted file mode 100644 index 630511d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "sop/asn1", - "description": "A PHP library for X.690 ASN.1 DER encoding and decoding.", - "homepage": "https://github.com/sop/asn1", - "license": "MIT", - "type": "library", - "keywords": [ - "asn1", - "asn.1", - "x690", - "x.690", - "der" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "require": { - "php": ">=7.2", - "ext-gmp": "*", - "ext-mbstring": "*" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "autoload": { - "psr-4": { - "Sop\\ASN1\\": "lib/ASN1/" - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php deleted file mode 100644 index 42d512f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Identifier.php +++ /dev/null @@ -1,290 +0,0 @@ - 'UNIVERSAL', - self::CLASS_APPLICATION => 'APPLICATION', - self::CLASS_CONTEXT_SPECIFIC => 'CONTEXT SPECIFIC', - self::CLASS_PRIVATE => 'PRIVATE', - ]; - - // P/C enumerations - const PRIMITIVE = 0b0; - const CONSTRUCTED = 0b1; - - /** - * Type class. - * - * @var int - */ - private $_class; - - /** - * Primitive or Constructed. - * - * @var int - */ - private $_pc; - - /** - * Content type tag. - * - * @var BigInt - */ - private $_tag; - - /** - * Constructor. - * - * @param int $class Type class - * @param int $pc Primitive / Constructed - * @param \GMP|int|string $tag Type tag number - */ - public function __construct(int $class, int $pc, $tag) - { - $this->_class = 0b11 & $class; - $this->_pc = 0b1 & $pc; - $this->_tag = new BigInt($tag); - } - - /** - * Decode identifier component from DER data. - * - * @param string $data DER encoded data - * @param null|int $offset Reference to the variable that contains offset - * into the data where to start parsing. - * Variable is updated to the offset next to the - * parsed identifier. If null, start from offset 0. - * - * @throws DecodeException If decoding fails - * - * @return self - */ - public static function fromDER(string $data, int &$offset = null): Identifier - { - $idx = $offset ?? 0; - $datalen = strlen($data); - if ($idx >= $datalen) { - throw new DecodeException('Invalid offset.'); - } - $byte = ord($data[$idx++]); - // bits 8 and 7 (class) - // 0 = universal, 1 = application, 2 = context-specific, 3 = private - $class = (0b11000000 & $byte) >> 6; - // bit 6 (0 = primitive / 1 = constructed) - $pc = (0b00100000 & $byte) >> 5; - // bits 5 to 1 (tag number) - $tag = (0b00011111 & $byte); - // long-form identifier - if (0x1f === $tag) { - $tag = self::_decodeLongFormTag($data, $idx); - } - if (isset($offset)) { - $offset = $idx; - } - return new self($class, $pc, $tag); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - $bytes = []; - $byte = $this->_class << 6 | $this->_pc << 5; - $tag = $this->_tag->gmpObj(); - if ($tag < 0x1f) { - $bytes[] = $byte | $tag; - } - // long-form identifier - else { - $bytes[] = $byte | 0x1f; - $octets = []; - for (; $tag > 0; $tag >>= 7) { - array_push($octets, gmp_intval(0x80 | ($tag & 0x7f))); - } - // last octet has bit 8 set to zero - $octets[0] &= 0x7f; - foreach (array_reverse($octets) as $octet) { - $bytes[] = $octet; - } - } - return pack('C*', ...$bytes); - } - - /** - * Get class of the type. - */ - public function typeClass(): int - { - return $this->_class; - } - - /** - * Get P/C. - */ - public function pc(): int - { - return $this->_pc; - } - - /** - * Get the tag number. - * - * @return string Base 10 integer string - */ - public function tag(): string - { - return $this->_tag->base10(); - } - - /** - * Get the tag as an integer. - */ - public function intTag(): int - { - return $this->_tag->intVal(); - } - - /** - * Check whether type is of an universal class. - */ - public function isUniversal(): bool - { - return self::CLASS_UNIVERSAL === $this->_class; - } - - /** - * Check whether type is of an application class. - */ - public function isApplication(): bool - { - return self::CLASS_APPLICATION === $this->_class; - } - - /** - * Check whether type is of a context specific class. - */ - public function isContextSpecific(): bool - { - return self::CLASS_CONTEXT_SPECIFIC === $this->_class; - } - - /** - * Check whether type is of a private class. - */ - public function isPrivate(): bool - { - return self::CLASS_PRIVATE === $this->_class; - } - - /** - * Check whether content is primitive type. - */ - public function isPrimitive(): bool - { - return self::PRIMITIVE === $this->_pc; - } - - /** - * Check hether content is constructed type. - */ - public function isConstructed(): bool - { - return self::CONSTRUCTED === $this->_pc; - } - - /** - * Get self with given type class. - * - * @param int $class One of `CLASS_*` enumerations - * - * @return self - */ - public function withClass(int $class): Identifier - { - $obj = clone $this; - $obj->_class = 0b11 & $class; - return $obj; - } - - /** - * Get self with given type tag. - * - * @param \GMP|int|string $tag Tag number - * - * @return self - */ - public function withTag($tag): Identifier - { - $obj = clone $this; - $obj->_tag = new BigInt($tag); - return $obj; - } - - /** - * Get human readable name of the type class. - */ - public static function classToName(int $class): string - { - if (!array_key_exists($class, self::MAP_CLASS_TO_NAME)) { - return "CLASS {$class}"; - } - return self::MAP_CLASS_TO_NAME[$class]; - } - - /** - * Parse long form tag. - * - * @param string $data DER data - * @param int $offset Reference to the variable containing offset to data - * - * @throws DecodeException If decoding fails - * - * @return \GMP Tag number - */ - private static function _decodeLongFormTag(string $data, int &$offset): \GMP - { - $datalen = strlen($data); - $tag = gmp_init(0, 10); - while (true) { - if ($offset >= $datalen) { - throw new DecodeException( - 'Unexpected end of data while decoding long form identifier.'); - } - $byte = ord($data[$offset++]); - $tag <<= 7; - $tag |= 0x7f & $byte; - // last byte has bit 8 set to zero - if (!(0x80 & $byte)) { - break; - } - } - return $tag; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php deleted file mode 100644 index 27216e8..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Component/Length.php +++ /dev/null @@ -1,225 +0,0 @@ -_length = new BigInt($length); - $this->_indefinite = $indefinite; - } - - /** - * Decode length component from DER data. - * - * @param string $data DER encoded data - * @param null|int $offset Reference to the variable that contains offset - * into the data where to start parsing. - * Variable is updated to the offset next to the - * parsed length component. If null, start from offset 0. - * - * @throws DecodeException If decoding fails - */ - public static function fromDER(string $data, int &$offset = null): self - { - $idx = $offset ?? 0; - $datalen = strlen($data); - if ($idx >= $datalen) { - throw new DecodeException( - 'Unexpected end of data while decoding length.'); - } - $indefinite = false; - $byte = ord($data[$idx++]); - // bits 7 to 1 - $length = (0x7f & $byte); - // long form - if (0x80 & $byte) { - if (!$length) { - $indefinite = true; - } else { - if ($idx + $length > $datalen) { - throw new DecodeException( - 'Unexpected end of data while decoding long form length.'); - } - $length = self::_decodeLongFormLength($length, $data, $idx); - } - } - if (isset($offset)) { - $offset = $idx; - } - return new self($length, $indefinite); - } - - /** - * Decode length from DER. - * - * Throws an exception if length doesn't match with expected or if data - * doesn't contain enough bytes. - * - * Requirement of definite length is relaxed contrary to the specification - * (sect. 10.1). - * - * @see self::fromDER - * - * @param string $data DER data - * @param int $offset Reference to the offset variable - * @param null|int $expected Expected length, null to bypass checking - * - * @throws DecodeException If decoding or expectation fails - */ - public static function expectFromDER(string $data, int &$offset, - int $expected = null): self - { - $idx = $offset; - $length = self::fromDER($data, $idx); - // if certain length was expected - if (isset($expected)) { - if ($length->isIndefinite()) { - throw new DecodeException( - sprintf('Expected length %d, got indefinite.', $expected)); - } - if ($expected !== $length->intLength()) { - throw new DecodeException( - sprintf('Expected length %d, got %d.', $expected, - $length->intLength())); - } - } - // check that enough data is available - if (!$length->isIndefinite() - && strlen($data) < $idx + $length->intLength()) { - throw new DecodeException( - sprintf('Length %d overflows data, %d bytes left.', - $length->intLength(), strlen($data) - $idx)); - } - $offset = $idx; - return $length; - } - - /** - * {@inheritdoc} - * - * @throws \DomainException If length is too large to encode - */ - public function toDER(): string - { - $bytes = []; - if ($this->_indefinite) { - $bytes[] = 0x80; - } else { - $num = $this->_length->gmpObj(); - // long form - if ($num > 127) { - $octets = []; - for (; $num > 0; $num >>= 8) { - $octets[] = gmp_intval(0xff & $num); - } - $count = count($octets); - // first octet must not be 0xff - if ($count >= 127) { - throw new \DomainException('Too many length octets.'); - } - $bytes[] = 0x80 | $count; - foreach (array_reverse($octets) as $octet) { - $bytes[] = $octet; - } - } - // short form - else { - $bytes[] = gmp_intval($num); - } - } - return pack('C*', ...$bytes); - } - - /** - * Get the length. - * - * @throws \LogicException If length is indefinite - * - * @return string Length as an integer string - */ - public function length(): string - { - if ($this->_indefinite) { - throw new \LogicException('Length is indefinite.'); - } - return $this->_length->base10(); - } - - /** - * Get the length as an integer. - * - * @throws \LogicException If length is indefinite - * @throws \RuntimeException If length overflows integer size - */ - public function intLength(): int - { - if ($this->_indefinite) { - throw new \LogicException('Length is indefinite.'); - } - return $this->_length->intVal(); - } - - /** - * Whether length is indefinite. - */ - public function isIndefinite(): bool - { - return $this->_indefinite; - } - - /** - * Decode long form length. - * - * @param int $length Number of octets - * @param string $data Data - * @param int $offset reference to the variable containing offset to the data - * - * @throws DecodeException If decoding fails - */ - private static function _decodeLongFormLength(int $length, string $data, - int &$offset): \GMP - { - // first octet must not be 0xff (spec 8.1.3.5c) - if (127 === $length) { - throw new DecodeException('Invalid number of length octets.'); - } - $num = gmp_init(0, 10); - while (--$length >= 0) { - $byte = ord($data[$offset++]); - $num <<= 8; - $num |= $byte; - } - return $num; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php deleted file mode 100644 index 055de94..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/DERData.php +++ /dev/null @@ -1,89 +0,0 @@ -_identifier = Identifier::fromDER($data, $this->_contentOffset); - // check that length encoding is valid - Length::expectFromDER($data, $this->_contentOffset); - $this->_der = $data; - $this->_typeTag = $this->_identifier->intTag(); - } - - /** - * {@inheritdoc} - */ - public function typeClass(): int - { - return $this->_identifier->typeClass(); - } - - /** - * {@inheritdoc} - */ - public function isConstructed(): bool - { - return $this->_identifier->isConstructed(); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->_der; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - // if there's no content payload - if (strlen($this->_der) === $this->_contentOffset) { - return ''; - } - return substr($this->_der, $this->_contentOffset); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php deleted file mode 100644 index 864fe36..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Element.php +++ /dev/null @@ -1,465 +0,0 @@ - Primitive\EOC::class, - self::TYPE_BOOLEAN => Primitive\Boolean::class, - self::TYPE_INTEGER => Primitive\Integer::class, - self::TYPE_BIT_STRING => Primitive\BitString::class, - self::TYPE_OCTET_STRING => Primitive\OctetString::class, - self::TYPE_NULL => Primitive\NullType::class, - self::TYPE_OBJECT_IDENTIFIER => Primitive\ObjectIdentifier::class, - self::TYPE_OBJECT_DESCRIPTOR => Primitive\ObjectDescriptor::class, - self::TYPE_REAL => Primitive\Real::class, - self::TYPE_ENUMERATED => Primitive\Enumerated::class, - self::TYPE_UTF8_STRING => Primitive\UTF8String::class, - self::TYPE_RELATIVE_OID => Primitive\RelativeOID::class, - self::TYPE_SEQUENCE => Constructed\Sequence::class, - self::TYPE_SET => Constructed\Set::class, - self::TYPE_NUMERIC_STRING => Primitive\NumericString::class, - self::TYPE_PRINTABLE_STRING => Primitive\PrintableString::class, - self::TYPE_T61_STRING => Primitive\T61String::class, - self::TYPE_VIDEOTEX_STRING => Primitive\VideotexString::class, - self::TYPE_IA5_STRING => Primitive\IA5String::class, - self::TYPE_UTC_TIME => Primitive\UTCTime::class, - self::TYPE_GENERALIZED_TIME => Primitive\GeneralizedTime::class, - self::TYPE_GRAPHIC_STRING => Primitive\GraphicString::class, - self::TYPE_VISIBLE_STRING => Primitive\VisibleString::class, - self::TYPE_GENERAL_STRING => Primitive\GeneralString::class, - self::TYPE_UNIVERSAL_STRING => Primitive\UniversalString::class, - self::TYPE_CHARACTER_STRING => Primitive\CharacterString::class, - self::TYPE_BMP_STRING => Primitive\BMPString::class, - ]; - - /** - * Pseudotype for all string types. - * - * May be used as an expectation parameter. - * - * @var int - */ - const TYPE_STRING = -1; - - /** - * Pseudotype for all time types. - * - * May be used as an expectation parameter. - * - * @var int - */ - const TYPE_TIME = -2; - - /** - * Pseudotype for constructed strings. - * - * May be used as an expectation parameter. - * - * @var int - */ - const TYPE_CONSTRUCTED_STRING = -3; - - /** - * Mapping from universal type tag to human readable name. - * - * @internal - * - * @var array - */ - const MAP_TYPE_TO_NAME = [ - self::TYPE_EOC => 'EOC', - self::TYPE_BOOLEAN => 'BOOLEAN', - self::TYPE_INTEGER => 'INTEGER', - self::TYPE_BIT_STRING => 'BIT STRING', - self::TYPE_OCTET_STRING => 'OCTET STRING', - self::TYPE_NULL => 'NULL', - self::TYPE_OBJECT_IDENTIFIER => 'OBJECT IDENTIFIER', - self::TYPE_OBJECT_DESCRIPTOR => 'ObjectDescriptor', - self::TYPE_EXTERNAL => 'EXTERNAL', - self::TYPE_REAL => 'REAL', - self::TYPE_ENUMERATED => 'ENUMERATED', - self::TYPE_EMBEDDED_PDV => 'EMBEDDED PDV', - self::TYPE_UTF8_STRING => 'UTF8String', - self::TYPE_RELATIVE_OID => 'RELATIVE-OID', - self::TYPE_SEQUENCE => 'SEQUENCE', - self::TYPE_SET => 'SET', - self::TYPE_NUMERIC_STRING => 'NumericString', - self::TYPE_PRINTABLE_STRING => 'PrintableString', - self::TYPE_T61_STRING => 'T61String', - self::TYPE_VIDEOTEX_STRING => 'VideotexString', - self::TYPE_IA5_STRING => 'IA5String', - self::TYPE_UTC_TIME => 'UTCTime', - self::TYPE_GENERALIZED_TIME => 'GeneralizedTime', - self::TYPE_GRAPHIC_STRING => 'GraphicString', - self::TYPE_VISIBLE_STRING => 'VisibleString', - self::TYPE_GENERAL_STRING => 'GeneralString', - self::TYPE_UNIVERSAL_STRING => 'UniversalString', - self::TYPE_CHARACTER_STRING => 'CHARACTER STRING', - self::TYPE_BMP_STRING => 'BMPString', - self::TYPE_STRING => 'Any String', - self::TYPE_TIME => 'Any Time', - self::TYPE_CONSTRUCTED_STRING => 'Constructed String', - ]; - - /** - * Element's type tag. - * - * @var int - */ - protected $_typeTag; - - /** - * Whether type shall be encoded with indefinite length. - * - * @var bool - */ - protected $_indefiniteLength = false; - - /** - * {@inheritdoc} - */ - abstract public function typeClass(): int; - - /** - * {@inheritdoc} - */ - abstract public function isConstructed(): bool; - - /** - * Decode element from DER data. - * - * @param string $data DER encoded data - * @param null|int $offset Reference to the variable that contains offset - * into the data where to start parsing. - * Variable is updated to the offset next to the - * parsed element. If null, start from offset 0. - * - * @throws DecodeException If decoding fails - * @throws \UnexpectedValueException If called in the context of an expected - * type, but decoding yields another type - */ - public static function fromDER(string $data, int &$offset = null): ElementBase - { - $idx = $offset ?? 0; - // decode identifier - $identifier = Identifier::fromDER($data, $idx); - // determine class that implements type specific decoding - $cls = self::_determineImplClass($identifier); - // decode remaining element - $element = $cls::_decodeFromDER($identifier, $data, $idx); - // if called in the context of a concrete class, check - // that decoded type matches the type of a calling class - $called_class = get_called_class(); - if (self::class !== $called_class) { - if (!$element instanceof $called_class) { - throw new \UnexpectedValueException( - sprintf('%s expected, got %s.', $called_class, get_class($element))); - } - } - // update offset for the caller - if (isset($offset)) { - $offset = $idx; - } - return $element; - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - $identifier = new Identifier($this->typeClass(), - $this->isConstructed() ? Identifier::CONSTRUCTED : Identifier::PRIMITIVE, - $this->_typeTag); - $content = $this->_encodedContentDER(); - if ($this->_indefiniteLength) { - $length = new Length(0, true); - $eoc = new Primitive\EOC(); - return $identifier->toDER() . $length->toDER() . $content . $eoc->toDER(); - } - $length = new Length(strlen($content)); - return $identifier->toDER() . $length->toDER() . $content; - } - - /** - * {@inheritdoc} - */ - public function tag(): int - { - return $this->_typeTag; - } - - /** - * {@inheritdoc} - */ - public function isType(int $tag): bool - { - // if element is context specific - if (Identifier::CLASS_CONTEXT_SPECIFIC === $this->typeClass()) { - return false; - } - // negative tags identify an abstract pseudotype - if ($tag < 0) { - return $this->_isPseudoType($tag); - } - return $this->_isConcreteType($tag); - } - - /** - * {@inheritdoc} - */ - public function expectType(int $tag): ElementBase - { - if (!$this->isType($tag)) { - throw new \UnexpectedValueException( - sprintf('%s expected, got %s.', self::tagToName($tag), - $this->_typeDescriptorString())); - } - return $this; - } - - /** - * {@inheritdoc} - */ - public function isTagged(): bool - { - return $this instanceof TaggedType; - } - - /** - * {@inheritdoc} - */ - public function expectTagged(?int $tag = null): TaggedType - { - if (!$this->isTagged()) { - throw new \UnexpectedValueException( - sprintf('Context specific element expected, got %s.', - Identifier::classToName($this->typeClass()))); - } - if (isset($tag) && $this->tag() !== $tag) { - throw new \UnexpectedValueException( - sprintf('Tag %d expected, got %d.', $tag, $this->tag())); - } - return $this; - } - - /** - * Whether element has indefinite length. - */ - public function hasIndefiniteLength(): bool - { - return $this->_indefiniteLength; - } - - /** - * Get self with indefinite length encoding set. - * - * @param bool $indefinite True for indefinite length, false for definite length - */ - public function withIndefiniteLength(bool $indefinite = true): self - { - $obj = clone $this; - $obj->_indefiniteLength = $indefinite; - return $obj; - } - - /** - * {@inheritdoc} - */ - final public function asElement(): Element - { - return $this; - } - - /** - * Get element decorated with `UnspecifiedType` object. - */ - public function asUnspecified(): UnspecifiedType - { - return new UnspecifiedType($this); - } - - /** - * Get human readable name for an universal tag. - */ - public static function tagToName(int $tag): string - { - if (!array_key_exists($tag, self::MAP_TYPE_TO_NAME)) { - return "TAG {$tag}"; - } - return self::MAP_TYPE_TO_NAME[$tag]; - } - - /** - * Get the content encoded in DER. - * - * Returns the DER encoded content without identifier and length header octets. - */ - abstract protected function _encodedContentDER(): string; - - /** - * Decode type-specific element from DER. - * - * @param Identifier $identifier Pre-parsed identifier - * @param string $data DER data - * @param int $offset Offset in data to the next byte after identifier - * - * @throws DecodeException If decoding fails - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - throw new \BadMethodCallException( - __METHOD__ . ' must be implemented in derived class.'); - } - - /** - * Determine the class that implements the type. - * - * @return string Class name - */ - protected static function _determineImplClass(Identifier $identifier): string - { - switch ($identifier->typeClass()) { - case Identifier::CLASS_UNIVERSAL: - $cls = self::_determineUniversalImplClass($identifier->intTag()); - // constructed strings may be present in BER - if ($identifier->isConstructed() - && is_subclass_of($cls, StringType::class)) { - $cls = ConstructedString::class; - } - return $cls; - case Identifier::CLASS_CONTEXT_SPECIFIC: - return ContextSpecificType::class; - case Identifier::CLASS_APPLICATION: - return ApplicationType::class; - case Identifier::CLASS_PRIVATE: - return PrivateType::class; - } - throw new \UnexpectedValueException(sprintf('%s %d not implemented.', - Identifier::classToName($identifier->typeClass()), $identifier->tag())); - } - - /** - * Determine the class that implements an universal type of the given tag. - * - * @throws \UnexpectedValueException - * - * @return string Class name - */ - protected static function _determineUniversalImplClass(int $tag): string - { - if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) { - throw new \UnexpectedValueException( - "Universal tag {$tag} not implemented."); - } - return self::MAP_TAG_TO_CLASS[$tag]; - } - - /** - * Get textual description of the type for debugging purposes. - */ - protected function _typeDescriptorString(): string - { - if (Identifier::CLASS_UNIVERSAL === $this->typeClass()) { - return self::tagToName($this->_typeTag); - } - return sprintf('%s TAG %d', Identifier::classToName($this->typeClass()), - $this->_typeTag); - } - - /** - * Check whether the element is a concrete type of a given tag. - */ - private function _isConcreteType(int $tag): bool - { - // if tag doesn't match - if ($this->tag() !== $tag) { - return false; - } - // if type is universal check that instance is of a correct class - if (Identifier::CLASS_UNIVERSAL === $this->typeClass()) { - $cls = self::_determineUniversalImplClass($tag); - if (!$this instanceof $cls) { - return false; - } - } - return true; - } - - /** - * Check whether the element is a pseudotype. - */ - private function _isPseudoType(int $tag): bool - { - switch ($tag) { - case self::TYPE_STRING: - return $this instanceof StringType; - case self::TYPE_TIME: - return $this instanceof TimeType; - case self::TYPE_CONSTRUCTED_STRING: - return $this instanceof ConstructedString; - } - return false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php deleted file mode 100644 index 6d53b44..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Exception/DecodeException.php +++ /dev/null @@ -1,12 +0,0 @@ -_validateString($string)) { - throw new \InvalidArgumentException( - sprintf('Not a valid %s string.', self::tagToName($this->_typeTag))); - } - $this->_string = $string; - } - - /** - * {@inheritdoc} - */ - public function __toString(): string - { - return $this->string(); - } - - /** - * Get the string value. - */ - public function string(): string - { - return $this->_string; - } - - /** - * Check whether string is valid for the concrete type. - */ - protected function _validateString(string $string): bool - { - // Override in derived classes - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php deleted file mode 100644 index 3723926..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/BaseTime.php +++ /dev/null @@ -1,107 +0,0 @@ -_dateTime = $dt; - } - - /** - * {@inheritdoc} - */ - public function __toString(): string - { - return $this->string(); - } - - /** - * Initialize from datetime string. - * - * @see http://php.net/manual/en/datetime.formats.php - * - * @param string $time Time string - * @param null|string $tz timezone, if null use default - * - * @throws \RuntimeException - */ - public static function fromString(string $time, ?string $tz = null): self - { - try { - if (!isset($tz)) { - $tz = date_default_timezone_get(); - } - return new static( - new \DateTimeImmutable($time, self::_createTimeZone($tz))); - } catch (\Exception $e) { - throw new \RuntimeException( - 'Failed to create DateTime: ' . - self::_getLastDateTimeImmutableErrorsStr(), 0, $e); - } - } - - /** - * Get the date and time. - */ - public function dateTime(): \DateTimeImmutable - { - return $this->_dateTime; - } - - /** - * Get the date and time as a type specific string. - */ - public function string(): string - { - return $this->_encodedContentDER(); - } - - /** - * Create `DateTimeZone` object from string. - * - * @throws \UnexpectedValueException If timezone is invalid - */ - protected static function _createTimeZone(string $tz): \DateTimeZone - { - try { - return new \DateTimeZone($tz); - } catch (\Exception $e) { - throw new \UnexpectedValueException('Invalid timezone.', 0, $e); - } - } - - /** - * Get last error caused by `DateTimeImmutable`. - */ - protected static function _getLastDateTimeImmutableErrorsStr(): string - { - $errors = \DateTimeImmutable::getLastErrors()['errors']; - return implode(', ', $errors); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php deleted file mode 100644 index d45dc4d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/ConstructedString.php +++ /dev/null @@ -1,131 +0,0 @@ -string(); - } - - /** - * Create from a list of string type elements. - * - * All strings must have the same type. - * - * @param StringType ...$elements - * - * @throws \LogicException - */ - public static function create(StringType ...$elements): self - { - if (!count($elements)) { - throw new \LogicException('No elements, unable to determine type tag.'); - } - $tag = $elements[0]->tag(); - foreach ($elements as $el) { - if ($el->tag() !== $tag) { - throw new \LogicException( - 'All elements in constructed string must have the same type.'); - } - } - return self::createWithTag($tag, ...$elements); - } - - /** - * Create from strings with a given type tag. - * - * Does not perform any validation on types. - * - * @param int $tag Type tag for the constructed string element - * @param StringType ...$elements Any number of elements - * - * @return self - */ - public static function createWithTag(int $tag, StringType ...$elements) - { - $el = new self(...$elements); - $el->_typeTag = $tag; - return $el; - } - - /** - * Get a list of strings in this structure. - * - * @return string[] - */ - public function strings(): array - { - return array_map(function (StringType $el) { - return $el->string(); - }, $this->_elements); - } - - /** - * Get the contained strings concatenated together. - * - * NOTE: It's unclear how bit strings with unused bits should be concatenated. - */ - public function string(): string - { - return implode('', $this->strings()); - } - - /** - * {@inheritdoc} - * - * @return self - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - /** @var ConstructedString $type */ - $type = forward_static_call_array([parent::class, __FUNCTION__], - [$identifier, $data, &$offset]); - $type->_typeTag = $identifier->intTag(); - return $type; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php deleted file mode 100644 index 52f0b86..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Sequence.php +++ /dev/null @@ -1,25 +0,0 @@ -_typeTag = self::TYPE_SEQUENCE; - parent::__construct(...$elements); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php deleted file mode 100644 index ce54442..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Constructed/Set.php +++ /dev/null @@ -1,63 +0,0 @@ -_typeTag = self::TYPE_SET; - parent::__construct(...$elements); - } - - /** - * Sort by canonical ascending order. - * - * Used for DER encoding of *SET* type. - */ - public function sortedSet(): self - { - $obj = clone $this; - usort($obj->_elements, - function (Element $a, Element $b) { - if ($a->typeClass() !== $b->typeClass()) { - return $a->typeClass() < $b->typeClass() ? -1 : 1; - } - if ($a->tag() === $b->tag()) { - return 0; - } - return $a->tag() < $b->tag() ? -1 : 1; - }); - return $obj; - } - - /** - * Sort by encoding ascending order. - * - * Used for DER encoding of *SET OF* type. - */ - public function sortedSetOf(): self - { - $obj = clone $this; - usort($obj->_elements, - function (Element $a, Element $b) { - $a_der = $a->toDER(); - $b_der = $b->toDER(); - return strcmp($a_der, $b_der); - }); - return $obj; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php deleted file mode 100644 index eb9e20d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BMPString.php +++ /dev/null @@ -1,40 +0,0 @@ -_typeTag = self::TYPE_BMP_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - // UCS-2 has fixed with of 2 octets (16 bits) - if (0 !== strlen($string) % 2) { - return false; - } - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php deleted file mode 100644 index c8be9cc..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/BitString.php +++ /dev/null @@ -1,201 +0,0 @@ -_typeTag = self::TYPE_BIT_STRING; - parent::__construct($string); - $this->_unusedBits = $unused_bits; - } - - /** - * Get the number of bits in the string. - */ - public function numBits(): int - { - return strlen($this->_string) * 8 - $this->_unusedBits; - } - - /** - * Get the number of unused bits in the last octet of the string. - */ - public function unusedBits(): int - { - return $this->_unusedBits; - } - - /** - * Test whether bit is set. - * - * @param int $idx Bit index. Most significant bit of the first octet is index 0. - */ - public function testBit(int $idx): bool - { - // octet index - $oi = (int) floor($idx / 8); - // if octet is outside range - if ($oi < 0 || $oi >= strlen($this->_string)) { - throw new \OutOfBoundsException('Index is out of bounds.'); - } - // bit index - $bi = $idx % 8; - // if tested bit is last octet's unused bit - if ($oi === strlen($this->_string) - 1) { - if ($bi >= 8 - $this->_unusedBits) { - throw new \OutOfBoundsException('Index refers to an unused bit.'); - } - } - $byte = $this->_string[$oi]; - // index 0 is the most significant bit in byte - $mask = 0x01 << (7 - $bi); - return (ord($byte) & $mask) > 0; - } - - /** - * Get range of bits. - * - * @param int $start Index of first bit - * @param int $length Number of bits in range - * - * @throws \OutOfBoundsException - * - * @return string Integer of $length bits - */ - public function range(int $start, int $length): string - { - if (!$length) { - return '0'; - } - if ($start + $length > $this->numBits()) { - throw new \OutOfBoundsException('Not enough bits.'); - } - $bits = gmp_init(0); - $idx = $start; - $end = $start + $length; - while (true) { - $bit = $this->testBit($idx) ? 1 : 0; - $bits |= $bit; - if (++$idx >= $end) { - break; - } - $bits <<= 1; - } - return gmp_strval($bits, 10); - } - - /** - * Get a copy of the bit string with trailing zeroes removed. - */ - public function withoutTrailingZeroes(): self - { - // if bit string was empty - if (!strlen($this->_string)) { - return new self(''); - } - $bits = $this->_string; - // count number of empty trailing octets - $unused_octets = 0; - for ($idx = strlen($bits) - 1; $idx >= 0; --$idx, ++$unused_octets) { - if ("\x0" !== $bits[$idx]) { - break; - } - } - // strip trailing octets - if ($unused_octets) { - $bits = substr($bits, 0, -$unused_octets); - } - // if bit string was full of zeroes - if (!strlen($bits)) { - return new self(''); - } - // count number of trailing zeroes in the last octet - $unused_bits = 0; - $byte = ord($bits[strlen($bits) - 1]); - while (!($byte & 0x01)) { - ++$unused_bits; - $byte >>= 1; - } - return new self($bits, $unused_bits); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - $der = chr($this->_unusedBits); - $der .= $this->_string; - if ($this->_unusedBits) { - $octet = $der[strlen($der) - 1]; - // set unused bits to zero - $octet &= chr(0xff & ~((1 << $this->_unusedBits) - 1)); - $der[strlen($der) - 1] = $octet; - } - return $der; - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $length = Length::expectFromDER($data, $idx); - if ($length->intLength() < 1) { - throw new DecodeException('Bit string length must be at least 1.'); - } - $unused_bits = ord($data[$idx++]); - if ($unused_bits > 7) { - throw new DecodeException( - 'Unused bits in a bit string must be less than 8.'); - } - $str_len = $length->intLength() - 1; - if ($str_len) { - $str = substr($data, $idx, $str_len); - if ($unused_bits) { - $mask = (1 << $unused_bits) - 1; - if (ord($str[strlen($str) - 1]) & $mask) { - throw new DecodeException( - 'DER encoded bit string must have zero padding.'); - } - } - } else { - $str = ''; - } - $offset = $idx + $str_len; - return new self($str, $unused_bits); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php deleted file mode 100644 index 4c2f020..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Boolean.php +++ /dev/null @@ -1,73 +0,0 @@ -_typeTag = self::TYPE_BOOLEAN; - $this->_bool = $bool; - } - - /** - * Get the value. - */ - public function value(): bool - { - return $this->_bool; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - return $this->_bool ? chr(0xff) : chr(0); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - Length::expectFromDER($data, $idx, 1); - $byte = ord($data[$idx++]); - if (0 !== $byte) { - if (0xff !== $byte) { - throw new DecodeException( - 'DER encoded boolean true must have all bits set to 1.'); - } - } - $offset = $idx; - return new self(0 !== $byte); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php deleted file mode 100644 index cf9476e..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/CharacterString.php +++ /dev/null @@ -1,25 +0,0 @@ -_typeTag = self::TYPE_CHARACTER_STRING; - parent::__construct($string); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php deleted file mode 100644 index 394ed7f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/EOC.php +++ /dev/null @@ -1,54 +0,0 @@ -_typeTag = self::TYPE_EOC; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - return ''; - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - if (!$identifier->isPrimitive()) { - throw new DecodeException('EOC value must be primitive.'); - } - // EOC type has always zero length - Length::expectFromDER($data, $idx, 0); - $offset = $idx; - return new self(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php deleted file mode 100644 index 98f467b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Enumerated.php +++ /dev/null @@ -1,22 +0,0 @@ -_typeTag = self::TYPE_ENUMERATED; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php deleted file mode 100644 index a781a49..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralString.php +++ /dev/null @@ -1,34 +0,0 @@ -_typeTag = self::TYPE_GENERAL_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - // allow everything - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php deleted file mode 100644 index 9cfba85..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GeneralizedTime.php +++ /dev/null @@ -1,125 +0,0 @@ -_typeTag = self::TYPE_GENERALIZED_TIME; - parent::__construct($dt); - } - - /** - * Clear cached variables on clone. - */ - public function __clone() - { - $this->_formatted = null; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - if (!isset($this->_formatted)) { - $dt = $this->_dateTime->setTimezone( - self::_createTimeZone(self::TZ_UTC)); - $this->_formatted = $dt->format('YmdHis'); - // if fractions were used - $frac = $dt->format('u'); - if (0 !== intval($frac)) { - $frac = rtrim($frac, '0'); - $this->_formatted .= ".{$frac}"; - } - // timezone - $this->_formatted .= 'Z'; - } - return $this->_formatted; - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $length = Length::expectFromDER($data, $idx)->intLength(); - $str = substr($data, $idx, $length); - $idx += $length; - /** @var string[] $match */ - if (!preg_match(self::REGEX, $str, $match)) { - throw new DecodeException('Invalid GeneralizedTime format.'); - } - [, $year, $month, $day, $hour, $minute, $second] = $match; - // if fractions match, there's at least one digit - if (isset($match[7])) { - $frac = $match[7]; - // DER restricts trailing zeroes in fractional seconds component - if ('0' === $frac[strlen($frac) - 1]) { - throw new DecodeException( - 'Fractional seconds must omit trailing zeroes.'); - } - $frac = $frac; - } else { - $frac = '0'; - } - $time = $year . $month . $day . $hour . $minute . $second . '.' . $frac . - self::TZ_UTC; - $dt = \DateTimeImmutable::createFromFormat('!YmdHis.uT', $time, - self::_createTimeZone(self::TZ_UTC)); - if (!$dt) { - throw new DecodeException( - 'Failed to decode GeneralizedTime: ' . - self::_getLastDateTimeImmutableErrorsStr()); - } - $offset = $idx; - return new self($dt); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php deleted file mode 100644 index 0fa2480..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/GraphicString.php +++ /dev/null @@ -1,34 +0,0 @@ -_typeTag = self::TYPE_GRAPHIC_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - // allow everything - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php deleted file mode 100644 index 4dd29ed..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/IA5String.php +++ /dev/null @@ -1,33 +0,0 @@ -_typeTag = self::TYPE_IA5_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - return 0 == preg_match('/[^\x00-\x7f]/', $string); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php deleted file mode 100644 index ed77b22..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Integer.php +++ /dev/null @@ -1,105 +0,0 @@ -_typeTag = self::TYPE_INTEGER; - if (!self::_validateNumber($number)) { - $var = is_scalar($number) ? strval($number) : gettype($number); - throw new \InvalidArgumentException("'{$var}' is not a valid number."); - } - $this->_number = new BigInt($number); - } - - /** - * Get the number as a base 10. - * - * @return string Integer as a string - */ - public function number(): string - { - return $this->_number->base10(); - } - - /** - * Get the number as an integer type. - */ - public function intNumber(): int - { - return $this->_number->intVal(); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - return $this->_number->signedOctets(); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $length = Length::expectFromDER($data, $idx)->intLength(); - $bytes = substr($data, $idx, $length); - $idx += $length; - $num = BigInt::fromSignedOctets($bytes)->gmpObj(); - $offset = $idx; - // late static binding since enumerated extends integer type - return new static($num); - } - - /** - * Test that number is valid for this context. - * - * @param mixed $num - */ - private static function _validateNumber($num): bool - { - if (is_int($num)) { - return true; - } - if (is_string($num) && preg_match('/-?\d+/', $num)) { - return true; - } - if ($num instanceof \GMP) { - return true; - } - return false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php deleted file mode 100644 index fa3e86b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NullType.php +++ /dev/null @@ -1,54 +0,0 @@ -_typeTag = self::TYPE_NULL; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - return ''; - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - if (!$identifier->isPrimitive()) { - throw new DecodeException('Null value must be primitive.'); - } - // null type has always zero length - Length::expectFromDER($data, $idx, 0); - $offset = $idx; - return new self(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php deleted file mode 100644 index 5a2454d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/NumericString.php +++ /dev/null @@ -1,33 +0,0 @@ -_typeTag = self::TYPE_NUMERIC_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - return 0 == preg_match('/[^0-9 ]/', $string); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php deleted file mode 100644 index c40bdc1..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectDescriptor.php +++ /dev/null @@ -1,33 +0,0 @@ -_string = $descriptor; - $this->_typeTag = self::TYPE_OBJECT_DESCRIPTOR; - } - - /** - * Get the object descriptor. - */ - public function descriptor(): string - { - return $this->_string; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php deleted file mode 100644 index f8cc9d8..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/ObjectIdentifier.php +++ /dev/null @@ -1,207 +0,0 @@ -_oid = $oid; - $this->_subids = self::_explodeDottedOID($oid); - // if OID is non-empty - if (count($this->_subids) > 0) { - // check that at least two nodes are set - if (count($this->_subids) < 2) { - throw new \UnexpectedValueException( - 'OID must have at least two nodes.'); - } - // check that root arc is in 0..2 range - if ($this->_subids[0] > 2) { - throw new \UnexpectedValueException( - 'Root arc must be in range of 0..2.'); - } - // if root arc is 0 or 1, second node must be in 0..39 range - if ($this->_subids[0] < 2 && $this->_subids[1] >= 40) { - throw new \UnexpectedValueException( - 'Second node must be in 0..39 range for root arcs 0 and 1.'); - } - } - $this->_typeTag = self::TYPE_OBJECT_IDENTIFIER; - } - - /** - * Get OID in dotted format. - */ - public function oid(): string - { - return $this->_oid; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - $subids = $this->_subids; - // encode first two subids to one according to spec section 8.19.4 - if (count($subids) >= 2) { - $num = ($subids[0] * 40) + $subids[1]; - array_splice($subids, 0, 2, [$num]); - } - return self::_encodeSubIDs(...$subids); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $len = Length::expectFromDER($data, $idx)->intLength(); - $subids = self::_decodeSubIDs(substr($data, $idx, $len)); - $idx += $len; - // decode first subidentifier according to spec section 8.19.4 - if (isset($subids[0])) { - if ($subids[0] < 80) { - [$x, $y] = gmp_div_qr($subids[0], '40'); - } else { - $x = gmp_init(2, 10); - $y = $subids[0] - 80; - } - array_splice($subids, 0, 1, [$x, $y]); - } - $offset = $idx; - return new self(self::_implodeSubIDs(...$subids)); - } - - /** - * Explode dotted OID to an array of sub ID's. - * - * @param string $oid OID in dotted format - * - * @return \GMP[] Array of GMP numbers - */ - protected static function _explodeDottedOID(string $oid): array - { - $subids = []; - if (strlen($oid)) { - foreach (explode('.', $oid) as $subid) { - $n = @gmp_init($subid, 10); - if (false === $n) { - throw new \UnexpectedValueException( - "'{$subid}' is not a number."); - } - $subids[] = $n; - } - } - return $subids; - } - - /** - * Implode an array of sub IDs to dotted OID format. - * - * @param \GMP ...$subids - */ - protected static function _implodeSubIDs(\GMP ...$subids): string - { - return implode('.', - array_map(function ($num) { - return gmp_strval($num, 10); - }, $subids)); - } - - /** - * Encode sub ID's to DER. - * - * @param \GMP ...$subids - */ - protected static function _encodeSubIDs(\GMP ...$subids): string - { - $data = ''; - foreach ($subids as $subid) { - // if number fits to one base 128 byte - if ($subid < 128) { - $data .= chr(intval($subid)); - } else { // encode to multiple bytes - $bytes = []; - do { - array_unshift($bytes, 0x7f & gmp_intval($subid)); - $subid >>= 7; - } while ($subid > 0); - // all bytes except last must have bit 8 set to one - foreach (array_splice($bytes, 0, -1) as $byte) { - $data .= chr(0x80 | $byte); - } - $data .= chr(reset($bytes)); - } - } - return $data; - } - - /** - * Decode sub ID's from DER data. - * - * @throws DecodeException - * - * @return \GMP[] Array of GMP numbers - */ - protected static function _decodeSubIDs(string $data): array - { - $subids = []; - $idx = 0; - $end = strlen($data); - while ($idx < $end) { - $num = gmp_init('0', 10); - while (true) { - if ($idx >= $end) { - throw new DecodeException('Unexpected end of data.'); - } - $byte = ord($data[$idx++]); - $num |= $byte & 0x7f; - // bit 8 of the last octet is zero - if (!($byte & 0x80)) { - break; - } - $num <<= 7; - } - $subids[] = $num; - } - return $subids; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php deleted file mode 100644 index 547d040..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/OctetString.php +++ /dev/null @@ -1,25 +0,0 @@ -_typeTag = self::TYPE_OCTET_STRING; - parent::__construct($string); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php deleted file mode 100644 index 0b17d22..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/PrintableString.php +++ /dev/null @@ -1,34 +0,0 @@ -_typeTag = self::TYPE_PRINTABLE_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - $chars = preg_quote(" '()+,-./:=?]", '/'); - return 0 == preg_match('/[^A-Za-z0-9' . $chars . ']/', $string); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php deleted file mode 100644 index 3efd67f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/Real.php +++ /dev/null @@ -1,698 +0,0 @@ -[+\-])?' . // sign - '(?\d+)' . // integer - '$/'; - - /** - * Regex pattern to parse NR2 form number. - * - * @var string - */ - const NR2_REGEX = '/^\s*' . - '(?[+\-])?' . // sign - '(?(?:\d+[\.,]\d*)|(?:\d*[\.,]\d+))' . // decimal number - '$/'; - - /** - * Regex pattern to parse NR3 form number. - * - * @var string - */ - const NR3_REGEX = '/^\s*' . - '(?[+\-])?' . // mantissa sign - '(?(?:\d+[\.,]\d*)|(?:\d*[\.,]\d+))' . // mantissa - '[Ee](?[+\-])?' . // exponent sign - '(?\d+)' . // exponent - '$/'; - - /** - * Regex pattern to parse PHP exponent number format. - * - * @see http://php.net/manual/en/language.types.float.php - * - * @var string - */ - const PHP_EXPONENT_DNUM = '/^' . - '(?[+\-])?' . // sign - '(?' . - '\d+' . // LNUM - '|' . - '(?:\d*\.\d+|\d+\.\d*)' . // DNUM - ')[eE]' . - '(?[+\-])?(?\d+)' . // exponent - '$/'; - - /** - * Exponent when value is positive or negative infinite. - * - * @var int - */ - const INF_EXPONENT = 2047; - - /** - * Exponent bias for IEEE 754 double precision float. - * - * @var int - */ - const EXP_BIAS = -1023; - - /** - * Signed integer mantissa. - * - * @var BigInt - */ - private $_mantissa; - - /** - * Signed integer exponent. - * - * @var BigInt - */ - private $_exponent; - - /** - * Abstract value base. - * - * Must be 2 or 10. - * - * @var int - */ - private $_base; - - /** - * Whether to encode strictly in DER. - * - * @var bool - */ - private $_strictDer; - - /** - * Number as a native float. - * - * @internal Lazily initialized - * - * @var null|float - */ - private $_float; - - /** - * Constructor. - * - * @param \GMP|int|string $mantissa Integer mantissa - * @param \GMP|int|string $exponent Integer exponent - * @param int $base Base, 2 or 10 - */ - public function __construct($mantissa, $exponent, int $base = 10) - { - if (10 !== $base && 2 !== $base) { - throw new \UnexpectedValueException('Base must be 2 or 10.'); - } - $this->_typeTag = self::TYPE_REAL; - $this->_strictDer = true; - $this->_mantissa = new BigInt($mantissa); - $this->_exponent = new BigInt($exponent); - $this->_base = $base; - } - - /** - * {@inheritdoc} - */ - public function __toString(): string - { - return sprintf('%g', $this->floatVal()); - } - - /** - * Create base 2 real number from float. - */ - public static function fromFloat(float $number): self - { - if (is_infinite($number)) { - return self::_fromInfinite($number); - } - if (is_nan($number)) { - throw new \UnexpectedValueException('NaN values not supported.'); - } - [$m, $e] = self::_parse754Double(pack('E', $number)); - return new self($m, $e, 2); - } - - /** - * Create base 10 real number from string. - * - * @param string $number Real number in base-10 textual form - */ - public static function fromString(string $number): self - { - [$m, $e] = self::_parseString($number); - return new self($m, $e, 10); - } - - /** - * Get self with strict DER flag set or unset. - * - * @param bool $strict whether to encode strictly in DER - */ - public function withStrictDER(bool $strict): self - { - $obj = clone $this; - $obj->_strictDer = $strict; - return $obj; - } - - /** - * Get the mantissa. - */ - public function mantissa(): BigInt - { - return $this->_mantissa; - } - - /** - * Get the exponent. - */ - public function exponent(): BigInt - { - return $this->_exponent; - } - - /** - * Get the base. - */ - public function base(): int - { - return $this->_base; - } - - /** - * Get number as a float. - */ - public function floatVal(): float - { - if (!isset($this->_float)) { - $m = $this->_mantissa->intVal(); - $e = $this->_exponent->intVal(); - $this->_float = (float) ($m * pow($this->_base, $e)); - } - return $this->_float; - } - - /** - * Get number as a NR3 form string conforming to DER rules. - */ - public function nr3Val(): string - { - // convert to base 10 - if (2 === $this->_base) { - [$m, $e] = self::_parseString(sprintf('%15E', $this->floatVal())); - } else { - $m = $this->_mantissa->gmpObj(); - $e = $this->_exponent->gmpObj(); - } - // shift trailing zeroes from the mantissa to the exponent - // (X.690 07-2002, section 11.3.2.4) - while (0 != $m && 0 == $m % 10) { - $m /= 10; - ++$e; - } - // if exponent is zero, it must be prefixed with a "+" sign - // (X.690 07-2002, section 11.3.2.6) - if (0 == $e) { - $es = '+'; - } else { - $es = $e < 0 ? '-' : ''; - } - return sprintf('%s.E%s%s', gmp_strval($m), $es, gmp_strval(gmp_abs($e))); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - if (self::INF_EXPONENT == $this->_exponent->gmpObj()) { - return $this->_encodeSpecial(); - } - // if the real value is the value zero, there shall be no contents - // octets in the encoding. (X.690 07-2002, section 8.5.2) - if (0 == $this->_mantissa->gmpObj()) { - return ''; - } - if (10 === $this->_base) { - return $this->_encodeDecimal(); - } - return $this->_encodeBinary(); - } - - /** - * Encode in binary format. - */ - protected function _encodeBinary(): string - { - [$base, $sign, $m, $e] = $this->_prepareBinaryEncoding(); - $zero = gmp_init(0, 10); - $byte = 0x80; - if ($sign < 0) { - $byte |= 0x40; - } - // normalization: mantissa must be 0 or odd - if (2 === $base) { - // while last bit is zero - while ($m > 0 && 0 === gmp_cmp($m & 0x01, $zero)) { - $m >>= 1; - ++$e; - } - } elseif (8 === $base) { - $byte |= 0x10; - // while last 3 bits are zero - while ($m > 0 && 0 === gmp_cmp($m & 0x07, $zero)) { - $m >>= 3; - ++$e; - } - } else { // base === 16 - $byte |= 0x20; - // while last 4 bits are zero - while ($m > 0 && 0 === gmp_cmp($m & 0x0f, $zero)) { - $m >>= 4; - ++$e; - } - } - // scale factor - $scale = 0; - while ($m > 0 && 0 === gmp_cmp($m & 0x01, $zero)) { - $m >>= 1; - ++$scale; - } - $byte |= ($scale & 0x03) << 2; - // encode exponent - $exp_bytes = (new BigInt($e))->signedOctets(); - $exp_len = strlen($exp_bytes); - if ($exp_len > 0xff) { - throw new \RangeException('Exponent encoding is too long.'); - } - if ($exp_len <= 3) { - $byte |= ($exp_len - 1) & 0x03; - $bytes = chr($byte); - } else { - $byte |= 0x03; - $bytes = chr($byte) . chr($exp_len); - } - $bytes .= $exp_bytes; - // encode mantissa - $bytes .= (new BigInt($m))->unsignedOctets(); - return $bytes; - } - - /** - * Encode in decimal format. - */ - protected function _encodeDecimal(): string - { - // encode in NR3 decimal encoding - return chr(0x03) . $this->nr3Val(); - } - - /** - * Encode special value. - */ - protected function _encodeSpecial(): string - { - switch ($this->_mantissa->intVal()) { - // positive infitinity - case 1: - return chr(0x40); - // negative infinity - case -1: - return chr(0x41); - } - throw new \LogicException('Invalid special value.'); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $length = Length::expectFromDER($data, $idx)->intLength(); - // if length is zero, value is zero (spec 8.5.2) - if (!$length) { - $obj = new self(0, 0, 10); - } else { - $bytes = substr($data, $idx, $length); - $byte = ord($bytes[0]); - if (0x80 & $byte) { // bit 8 = 1 - $obj = self::_decodeBinaryEncoding($bytes); - } elseif (0x00 === $byte >> 6) { // bit 8 = 0, bit 7 = 0 - $obj = self::_decodeDecimalEncoding($bytes); - } else { // bit 8 = 0, bit 7 = 1 - $obj = self::_decodeSpecialRealValue($bytes); - } - } - $offset = $idx + $length; - return $obj; - } - - /** - * Decode binary encoding. - */ - protected static function _decodeBinaryEncoding(string $data) - { - $byte = ord($data[0]); - // bit 7 is set if mantissa is negative - $neg = (bool) (0x40 & $byte); - // encoding base in bits 6 and 5 - switch (($byte >> 4) & 0x03) { - case 0b00: - $base = 2; - break; - case 0b01: - $base = 8; - break; - case 0b10: - $base = 16; - break; - default: - throw new DecodeException( - 'Reserved REAL binary encoding base not supported.'); - } - // scaling factor in bits 4 and 3 - $scale = ($byte >> 2) & 0x03; - $idx = 1; - // content length in bits 2 and 1 - $len = ($byte & 0x03) + 1; - // if both bits are set, the next octet encodes the length - if ($len > 3) { - if (strlen($data) < 2) { - throw new DecodeException( - 'Unexpected end of data while decoding REAL exponent length.'); - } - $len = ord($data[1]); - $idx = 2; - } - if (strlen($data) < $idx + $len) { - throw new DecodeException( - 'Unexpected end of data while decoding REAL exponent.'); - } - // decode exponent - $octets = substr($data, $idx, $len); - $exp = BigInt::fromSignedOctets($octets)->gmpObj(); - if (8 === $base) { - $exp *= 3; - } elseif (16 === $base) { - $exp *= 4; - } - if (strlen($data) <= $idx + $len) { - throw new DecodeException( - 'Unexpected end of data while decoding REAL mantissa.'); - } - // decode mantissa - $octets = substr($data, $idx + $len); - $n = BigInt::fromUnsignedOctets($octets)->gmpObj(); - $n *= 2 ** $scale; - if ($neg) { - $n = gmp_neg($n); - } - return new self($n, $exp, 2); - } - - /** - * Decode decimal encoding. - * - * @throws \RuntimeException - */ - protected static function _decodeDecimalEncoding(string $data): self - { - $nr = ord($data[0]) & 0x3f; - if (!in_array($nr, [1, 2, 3])) { - throw new DecodeException('Unsupported decimal encoding form.'); - } - $str = substr($data, 1); - return self::fromString($str); - } - - /** - * Decode special encoding. - */ - protected static function _decodeSpecialRealValue(string $data): self - { - if (1 !== strlen($data)) { - throw new DecodeException( - 'SpecialRealValue must have one content octet.'); - } - $byte = ord($data[0]); - if (0x40 === $byte) { // positive infinity - return self::_fromInfinite(INF); - } - if (0x41 === $byte) { // negative infinity - return self::_fromInfinite(-INF); - } - throw new DecodeException('Invalid SpecialRealValue encoding.'); - } - - /** - * Prepare value for binary encoding. - * - * @return array (int) base, (int) sign, (\GMP) mantissa and (\GMP) exponent - */ - protected function _prepareBinaryEncoding(): array - { - $base = 2; - $m = $this->_mantissa->gmpObj(); - $ms = gmp_sign($m); - $m = gmp_abs($m); - $e = $this->_exponent->gmpObj(); - $es = gmp_sign($e); - $e = gmp_abs($e); - // DER uses only base 2 binary encoding - if (!$this->_strictDer) { - if (0 == $e % 4) { - $base = 16; - $e = gmp_div_q($e, 4); - } elseif (0 == $e % 3) { - $base = 8; - $e = gmp_div_q($e, 3); - } - } - return [$base, $ms, $m, $e * $es]; - } - - /** - * Initialize from INF or -INF. - */ - private static function _fromInfinite(float $inf): self - { - return new self($inf === -INF ? -1 : 1, self::INF_EXPONENT, 2); - } - - /** - * Parse IEEE 754 big endian formatted double precision float to base 2 - * mantissa and exponent. - * - * @param string $octets 64 bits - * - * @return \GMP[] Tuple of mantissa and exponent - */ - private static function _parse754Double(string $octets): array - { - $n = gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - // sign bit - $neg = gmp_testbit($n, 63); - // 11 bits of biased exponent - $exp = (gmp_and($n, '0x7ff0000000000000') >> 52) + self::EXP_BIAS; - // 52 bits of mantissa - $man = gmp_and($n, '0xfffffffffffff'); - // zero, ASN.1 doesn't differentiate -0 from +0 - if (self::EXP_BIAS == $exp && 0 == $man) { - return [gmp_init(0, 10), gmp_init(0, 10)]; - } - // denormalized value, shift binary point - if (self::EXP_BIAS == $exp) { - ++$exp; - } - // normalized value, insert implicit leading one before the binary point - else { - gmp_setbit($man, 52); - } - // find the last fraction bit that is set - $last = gmp_scan1($man, 0); - $bits_for_fraction = 52 - $last; - // adjust mantissa and exponent so that we have integer values - $man >>= $last; - $exp -= $bits_for_fraction; - // negate mantissa if number was negative - if ($neg) { - $man = gmp_neg($man); - } - return [$man, $exp]; - } - - /** - * Parse textual REAL number to base 10 mantissa and exponent. - * - * @param string $str Number - * - * @return \GMP[] Tuple of mantissa and exponent - */ - private static function _parseString(string $str): array - { - // PHP exponent format - if (preg_match(self::PHP_EXPONENT_DNUM, $str, $match)) { - [$m, $e] = self::_parsePHPExponentMatch($match); - } - // NR3 format - elseif (preg_match(self::NR3_REGEX, $str, $match)) { - [$m, $e] = self::_parseNR3Match($match); - } - // NR2 format - elseif (preg_match(self::NR2_REGEX, $str, $match)) { - [$m, $e] = self::_parseNR2Match($match); - } - // NR1 format - elseif (preg_match(self::NR1_REGEX, $str, $match)) { - [$m, $e] = self::_parseNR1Match($match); - } - // invalid number - else { - throw new \UnexpectedValueException( - "{$str} could not be parsed to REAL."); - } - // normalize so that mantsissa has no trailing zeroes - while (0 != $m && 0 == $m % 10) { - $m /= 10; - ++$e; - } - return [$m, $e]; - } - - /** - * Parse PHP form float to base 10 mantissa and exponent. - * - * @param array $match Regexp match - * - * @return \GMP[] Tuple of mantissa and exponent - */ - private static function _parsePHPExponentMatch(array $match): array - { - // mantissa sign - $ms = '-' === $match['ms'] ? -1 : 1; - $m_parts = explode('.', $match['m']); - // integer part of the mantissa - $int = ltrim($m_parts[0], '0'); - // exponent sign - $es = '-' === $match['es'] ? -1 : 1; - // signed exponent - $e = gmp_init($match['e'], 10) * $es; - // if mantissa had fractional part - if (2 === count($m_parts)) { - $frac = rtrim($m_parts[1], '0'); - $e -= strlen($frac); - $int .= $frac; - } - $m = gmp_init($int, 10) * $ms; - return [$m, $e]; - } - - /** - * Parse NR3 form number to base 10 mantissa and exponent. - * - * @param array $match Regexp match - * - * @return \GMP[] Tuple of mantissa and exponent - */ - private static function _parseNR3Match(array $match): array - { - // mantissa sign - $ms = '-' === $match['ms'] ? -1 : 1; - // explode mantissa to integer and fraction parts - [$int, $frac] = explode('.', str_replace(',', '.', $match['m'])); - $int = ltrim($int, '0'); - $frac = rtrim($frac, '0'); - // exponent sign - $es = '-' === $match['es'] ? -1 : 1; - // signed exponent - $e = gmp_init($match['e'], 10) * $es; - // shift exponent by the number of base 10 fractions - $e -= strlen($frac); - // insert fractions to integer part and produce signed mantissa - $int .= $frac; - if ('' === $int) { - $int = '0'; - } - $m = gmp_init($int, 10) * $ms; - return [$m, $e]; - } - - /** - * Parse NR2 form number to base 10 mantissa and exponent. - * - * @param array $match Regexp match - * - * @return \GMP[] Tuple of mantissa and exponent - */ - private static function _parseNR2Match(array $match): array - { - $sign = '-' === $match['s'] ? -1 : 1; - // explode decimal number to integer and fraction parts - [$int, $frac] = explode('.', str_replace(',', '.', $match['d'])); - $int = ltrim($int, '0'); - $frac = rtrim($frac, '0'); - // shift exponent by the number of base 10 fractions - $e = gmp_init(0, 10); - $e -= strlen($frac); - // insert fractions to integer part and produce signed mantissa - $int .= $frac; - if ('' === $int) { - $int = '0'; - } - $m = gmp_init($int, 10) * $sign; - return [$m, $e]; - } - - /** - * Parse NR1 form number to base 10 mantissa and exponent. - * - * @param array $match Regexp match - * - * @return \GMP[] Tuple of mantissa and exponent - */ - private static function _parseNR1Match(array $match): array - { - $sign = '-' === $match['s'] ? -1 : 1; - $int = ltrim($match['i'], '0'); - if ('' === $int) { - $int = '0'; - } - $m = gmp_init($int, 10) * $sign; - return [$m, gmp_init(0, 10)]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php deleted file mode 100644 index b497527..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/RelativeOID.php +++ /dev/null @@ -1,48 +0,0 @@ -_oid = $oid; - $this->_subids = self::_explodeDottedOID($oid); - $this->_typeTag = self::TYPE_RELATIVE_OID; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - return self::_encodeSubIDs(...$this->_subids); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $len = Length::expectFromDER($data, $idx)->intLength(); - $subids = self::_decodeSubIDs(substr($data, $idx, $len)); - $offset = $idx + $len; - return new self(self::_implodeSubIDs(...$subids)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php deleted file mode 100644 index c2bcfbc..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/T61String.php +++ /dev/null @@ -1,35 +0,0 @@ -_typeTag = self::TYPE_T61_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - // allow everything since there's literally - // thousands of allowed characters (16 bit composed characters) - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php deleted file mode 100644 index 6d07d0d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTCTime.php +++ /dev/null @@ -1,83 +0,0 @@ -_typeTag = self::TYPE_UTC_TIME; - parent::__construct($dt); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - $dt = $this->_dateTime->setTimezone(self::_createTimeZone(self::TZ_UTC)); - return $dt->format('ymdHis\\Z'); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $length = Length::expectFromDER($data, $idx)->intLength(); - $str = substr($data, $idx, $length); - $idx += $length; - /** @var string[] $match */ - if (!preg_match(self::REGEX, $str, $match)) { - throw new DecodeException('Invalid UTCTime format.'); - } - [, $year, $month, $day, $hour, $minute, $second] = $match; - $time = $year . $month . $day . $hour . $minute . $second . self::TZ_UTC; - $dt = \DateTimeImmutable::createFromFormat('!ymdHisT', $time, - self::_createTimeZone(self::TZ_UTC)); - if (!$dt) { - throw new DecodeException('Failed to decode UTCTime: ' . - self::_getLastDateTimeImmutableErrorsStr()); - } - $offset = $idx; - return new self($dt); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php deleted file mode 100644 index 9cb9aa2..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UTF8String.php +++ /dev/null @@ -1,35 +0,0 @@ -_typeTag = self::TYPE_UTF8_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - return mb_check_encoding($string, 'UTF-8'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php deleted file mode 100644 index f0a6c23..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/UniversalString.php +++ /dev/null @@ -1,39 +0,0 @@ -_typeTag = self::TYPE_UNIVERSAL_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - // UCS-4 has fixed with of 4 octets (32 bits) - if (0 !== strlen($string) % 4) { - return false; - } - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php deleted file mode 100644 index d9a6721..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VideotexString.php +++ /dev/null @@ -1,34 +0,0 @@ -_typeTag = self::TYPE_VIDEOTEX_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - // allow everything - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php deleted file mode 100644 index 659317b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Primitive/VisibleString.php +++ /dev/null @@ -1,33 +0,0 @@ -_typeTag = self::TYPE_VISIBLE_STRING; - parent::__construct($string); - } - - /** - * {@inheritdoc} - */ - protected function _validateString(string $string): bool - { - return 0 == preg_match('/[^\x20-\x7e]/', $string); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php deleted file mode 100644 index 5fef105..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveString.php +++ /dev/null @@ -1,53 +0,0 @@ -_string; - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - if (!$identifier->isPrimitive()) { - throw new DecodeException('DER encoded string must be primitive.'); - } - $length = Length::expectFromDER($data, $idx)->intLength(); - $str = $length ? substr($data, $idx, $length) : ''; - // substr should never return false, since length is - // checked by Length::expectFromDER. - assert(is_string($str), new DecodeException('substr')); - $offset = $idx + $length; - try { - return new static($str); - } catch (\InvalidArgumentException $e) { - throw new DecodeException($e->getMessage(), 0, $e); - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php deleted file mode 100644 index c645e3f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/PrimitiveType.php +++ /dev/null @@ -1,19 +0,0 @@ -_elements = array_map( - function (ElementBase $el) { - return $el->asElement(); - }, $elements); - } - - /** - * Clone magic method. - */ - public function __clone() - { - // clear cache-variables - $this->_taggedMap = null; - $this->_unspecifiedTypes = null; - } - - /** - * {@inheritdoc} - */ - public function isConstructed(): bool - { - return true; - } - - /** - * Explode DER structure to DER encoded components that it contains. - * - * @throws DecodeException - * - * @return string[] - */ - public static function explodeDER(string $data): array - { - $offset = 0; - $identifier = Identifier::fromDER($data, $offset); - if (!$identifier->isConstructed()) { - throw new DecodeException('Element is not constructed.'); - } - $length = Length::expectFromDER($data, $offset); - if ($length->isIndefinite()) { - throw new DecodeException( - 'Explode not implemented for indefinite length encoding.'); - } - $end = $offset + $length->intLength(); - $parts = []; - while ($offset < $end) { - // start of the element - $idx = $offset; - // skip identifier - Identifier::fromDER($data, $offset); - // decode element length - $length = Length::expectFromDER($data, $offset)->intLength(); - // extract der encoding of the element - $parts[] = substr($data, $idx, $offset - $idx + $length); - // update offset over content - $offset += $length; - } - return $parts; - } - - /** - * Get self with an element at the given index replaced by another. - * - * @param int $idx Element index - * @param Element $el New element to insert into the structure - * - * @throws \OutOfBoundsException - */ - public function withReplaced(int $idx, Element $el): self - { - if (!isset($this->_elements[$idx])) { - throw new \OutOfBoundsException( - "Structure doesn't have element at index {$idx}."); - } - $obj = clone $this; - $obj->_elements[$idx] = $el; - return $obj; - } - - /** - * Get self with an element inserted before the given index. - * - * @param int $idx Element index - * @param Element $el New element to insert into the structure - * - * @throws \OutOfBoundsException - */ - public function withInserted(int $idx, Element $el): self - { - if (count($this->_elements) < $idx || $idx < 0) { - throw new \OutOfBoundsException("Index {$idx} is out of bounds."); - } - $obj = clone $this; - array_splice($obj->_elements, $idx, 0, [$el]); - return $obj; - } - - /** - * Get self with an element appended to the end. - * - * @param Element $el Element to insert into the structure - */ - public function withAppended(Element $el): self - { - $obj = clone $this; - array_push($obj->_elements, $el); - return $obj; - } - - /** - * Get self with an element prepended in the beginning. - * - * @param Element $el Element to insert into the structure - */ - public function withPrepended(Element $el): self - { - $obj = clone $this; - array_unshift($obj->_elements, $el); - return $obj; - } - - /** - * Get self with an element at the given index removed. - * - * @param int $idx Element index - * - * @throws \OutOfBoundsException - */ - public function withoutElement(int $idx): self - { - if (!isset($this->_elements[$idx])) { - throw new \OutOfBoundsException( - "Structure doesn't have element at index {$idx}."); - } - $obj = clone $this; - array_splice($obj->_elements, $idx, 1); - return $obj; - } - - /** - * Get elements in the structure. - * - * @return UnspecifiedType[] - */ - public function elements(): array - { - if (!isset($this->_unspecifiedTypes)) { - $this->_unspecifiedTypes = array_map( - function (Element $el) { - return new UnspecifiedType($el); - }, $this->_elements); - } - return $this->_unspecifiedTypes; - } - - /** - * Check whether the structure has an element at the given index, optionally - * satisfying given tag expectation. - * - * @param int $idx Index 0..n - * @param null|int $expectedTag Optional type tag expectation - */ - public function has(int $idx, ?int $expectedTag = null): bool - { - if (!isset($this->_elements[$idx])) { - return false; - } - if (isset($expectedTag)) { - if (!$this->_elements[$idx]->isType($expectedTag)) { - return false; - } - } - return true; - } - - /** - * Get the element at the given index, optionally checking that the element - * has a given tag. - * - * @param int $idx Index 0..n - * - * @throws \OutOfBoundsException If element doesn't exists - * @throws \UnexpectedValueException If expectation fails - */ - public function at(int $idx): UnspecifiedType - { - if (!isset($this->_elements[$idx])) { - throw new \OutOfBoundsException( - "Structure doesn't have an element at index {$idx}."); - } - return new UnspecifiedType($this->_elements[$idx]); - } - - /** - * Check whether the structure contains a context specific element with a - * given tag. - * - * @param int $tag Tag number - */ - public function hasTagged(int $tag): bool - { - // lazily build lookup map - if (!isset($this->_taggedMap)) { - $this->_taggedMap = []; - foreach ($this->_elements as $element) { - if ($element->isTagged()) { - $this->_taggedMap[$element->tag()] = $element; - } - } - } - return isset($this->_taggedMap[$tag]); - } - - /** - * Get a context specific element tagged with a given tag. - * - * @throws \LogicException If tag doesn't exists - */ - public function getTagged(int $tag): TaggedType - { - if (!$this->hasTagged($tag)) { - throw new \LogicException("No tagged element for tag {$tag}."); - } - return $this->_taggedMap[$tag]; - } - - /** - * @see \Countable::count() - */ - public function count(): int - { - return count($this->_elements); - } - - /** - * Get an iterator for the `UnspecifiedElement` objects. - * - * @see \IteratorAggregate::getIterator() - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator($this->elements()); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - $data = ''; - foreach ($this->_elements as $element) { - $data .= $element->toDER(); - } - return $data; - } - - /** - * {@inheritdoc} - * - * @return self - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - if (!$identifier->isConstructed()) { - throw new DecodeException( - 'Structured element must have constructed bit set.'); - } - $idx = $offset; - $length = Length::expectFromDER($data, $idx); - if ($length->isIndefinite()) { - $type = self::_decodeIndefiniteLength($data, $idx); - } else { - $type = self::_decodeDefiniteLength($data, $idx, - $length->intLength()); - } - $offset = $idx; - return $type; - } - - /** - * Decode elements for a definite length. - * - * @param string $data DER data - * @param int $offset Offset to data - * @param int $length Number of bytes to decode - * - * @throws DecodeException - */ - private static function _decodeDefiniteLength(string $data, int &$offset, - int $length): ElementBase - { - $idx = $offset; - $end = $idx + $length; - $elements = []; - while ($idx < $end) { - $elements[] = Element::fromDER($data, $idx); - // check that element didn't overflow length - if ($idx > $end) { - throw new DecodeException("Structure's content overflows length."); - } - } - $offset = $idx; - // return instance by static late binding - return new static(...$elements); - } - - /** - * Decode elements for an indefinite length. - * - * @param string $data DER data - * @param int $offset Offset to data - * - * @throws DecodeException - */ - private static function _decodeIndefiniteLength(string $data, int &$offset): ElementBase - { - $idx = $offset; - $elements = []; - $end = strlen($data); - while (true) { - if ($idx >= $end) { - throw new DecodeException( - 'Unexpected end of data while decoding indefinite length structure.'); - } - $el = Element::fromDER($data, $idx); - if ($el->isType(self::TYPE_EOC)) { - break; - } - $elements[] = $el; - } - $offset = $idx; - $type = new static(...$elements); - $type->_indefiniteLength = true; - return $type; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php deleted file mode 100644 index 9821e6e..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ApplicationType.php +++ /dev/null @@ -1,12 +0,0 @@ -_identifier = $identifier; - $this->_data = $data; - $this->_offset = $offset; - $this->_valueOffset = $value_offset; - $this->_valueLength = $value_length; - $this->_indefiniteLength = $indefinite_length; - $this->_typeTag = $identifier->intTag(); - } - - /** - * {@inheritdoc} - */ - public function typeClass(): int - { - return $this->_identifier->typeClass(); - } - - /** - * {@inheritdoc} - */ - public function isConstructed(): bool - { - return $this->_identifier->isConstructed(); - } - - /** - * {@inheritdoc} - */ - public function implicit(int $tag, int $class = Identifier::CLASS_UNIVERSAL): UnspecifiedType - { - $identifier = $this->_identifier->withClass($class)->withTag($tag); - $cls = self::_determineImplClass($identifier); - $idx = $this->_offset; - /** @var \Sop\ASN1\Feature\ElementBase $element */ - $element = $cls::_decodeFromDER($identifier, $this->_data, $idx); - return $element->asUnspecified(); - } - - /** - * {@inheritdoc} - */ - public function explicit(): UnspecifiedType - { - $idx = $this->_valueOffset; - return Element::fromDER($this->_data, $idx)->asUnspecified(); - } - - /** - * {@inheritdoc} - */ - protected static function _decodeFromDER(Identifier $identifier, - string $data, int &$offset): ElementBase - { - $idx = $offset; - $length = Length::expectFromDER($data, $idx); - // offset to inner value - $value_offset = $idx; - if ($length->isIndefinite()) { - if ($identifier->isPrimitive()) { - throw new DecodeException( - 'Primitive type with indefinite length is not supported.'); - } - while (!Element::fromDER($data, $idx)->isType(self::TYPE_EOC)); - // EOC consists of two octets. - $value_length = $idx - $value_offset - 2; - } else { - $value_length = $length->intLength(); - $idx += $value_length; - } - // late static binding since ApplicationType and PrivateType extend this class - $type = new static($identifier, $data, $offset, $value_offset, - $value_length, $length->isIndefinite()); - $offset = $idx; - return $type; - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - return substr($this->_data, $this->_valueOffset, $this->_valueLength); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php deleted file mode 100644 index be5a300..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ExplicitTagging.php +++ /dev/null @@ -1,19 +0,0 @@ -_typeTag = $tag; - $this->_element = $element; - $this->_class = $class; - } - - /** - * {@inheritdoc} - */ - public function isConstructed(): bool - { - return true; - } - - /** - * {@inheritdoc} - */ - public function explicit(): UnspecifiedType - { - return $this->_element->asUnspecified(); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - // get the full encoding of the wrapped element - return $this->_element->toDER(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php deleted file mode 100644 index ca2d5ed..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/ImplicitTagging.php +++ /dev/null @@ -1,25 +0,0 @@ -_typeTag = $tag; - $this->_element = $element; - $this->_class = $class; - } - - /** - * {@inheritdoc} - */ - public function isConstructed(): bool - { - // depends on the underlying type - return $this->_element->isConstructed(); - } - - /** - * {@inheritdoc} - */ - public function implicit( - int $tag, int $class = Identifier::CLASS_UNIVERSAL): UnspecifiedType - { - $this->_element->expectType($tag); - if ($this->_element->typeClass() !== $class) { - throw new \UnexpectedValueException( - sprintf('Type class %s expected, got %s.', - Identifier::classToName($class), - Identifier::classToName($this->_element->typeClass()))); - } - return $this->_element->asUnspecified(); - } - - /** - * {@inheritdoc} - */ - protected function _encodedContentDER(): string - { - // get only the content of the wrapped element. - return $this->_element->_encodedContentDER(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php deleted file mode 100644 index 6ab626b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/Tagged/PrivateType.php +++ /dev/null @@ -1,12 +0,0 @@ -_class; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php deleted file mode 100644 index 80ae37c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TaggedType.php +++ /dev/null @@ -1,84 +0,0 @@ -expectTagged($expectedTag); - } - return $el; - } - - /** - * Get the wrapped inner element employing explicit tagging. - * - * @param null|int $expectedTag Optional outer tag expectation - * - * @throws \UnexpectedValueException If expectation fails - */ - public function asExplicit(?int $expectedTag = null): UnspecifiedType - { - return $this->expectExplicit($expectedTag)->explicit(); - } - - /** - * Check whether element supports implicit tagging. - * - * @param null|int $expectedTag Optional outer tag expectation - * - * @throws \UnexpectedValueException If expectation fails - */ - public function expectImplicit(?int $expectedTag = null): ImplicitTagging - { - $el = $this; - if (!$el instanceof ImplicitTagging) { - throw new \UnexpectedValueException( - "Element doesn't implement implicit tagging."); - } - if (isset($expectedTag)) { - $el->expectTagged($expectedTag); - } - return $el; - } - - /** - * Get the wrapped inner element employing implicit tagging. - * - * @param int $tag Type tag of the inner element - * @param null|int $expectedTag Optional outer tag expectation - * @param int $expectedClass Optional inner type class expectation - * - * @throws \UnexpectedValueException If expectation fails - */ - public function asImplicit(int $tag, ?int $expectedTag = null, - int $expectedClass = Identifier::CLASS_UNIVERSAL): UnspecifiedType - { - return $this->expectImplicit($expectedTag)->implicit($tag, - $expectedClass); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php deleted file mode 100644 index cef1a49..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Type/TimeType.php +++ /dev/null @@ -1,16 +0,0 @@ -_element = $el; - } - - /** - * Initialize from DER data. - * - * @param string $data DER encoded data - */ - public static function fromDER(string $data): self - { - return Element::fromDER($data)->asUnspecified(); - } - - /** - * Initialize from `ElementBase` interface. - */ - public static function fromElementBase(ElementBase $el): self - { - // if element is already wrapped - if ($el instanceof self) { - return $el; - } - return new self($el->asElement()); - } - - /** - * Get the wrapped element as a context specific tagged type. - * - * @throws \UnexpectedValueException If the element is not tagged - */ - public function asTagged(): TaggedType - { - if (!$this->_element instanceof TaggedType) { - throw new \UnexpectedValueException( - 'Tagged element expected, got ' . $this->_typeDescriptorString()); - } - return $this->_element; - } - - /** - * Get the wrapped element as an application specific type. - * - * @throws \UnexpectedValueException If element is not application specific - * - * @return \Sop\ASN1\Type\Tagged\ApplicationType - */ - public function asApplication(): Tagged\ApplicationType - { - if (!$this->_element instanceof Tagged\ApplicationType) { - throw new \UnexpectedValueException( - 'Application type expected, got ' . $this->_typeDescriptorString()); - } - return $this->_element; - } - - /** - * Get the wrapped element as a private tagged type. - * - * @throws \UnexpectedValueException If element is not using private tagging - * - * @return \Sop\ASN1\Type\Tagged\PrivateType - */ - public function asPrivate(): Tagged\PrivateType - { - if (!$this->_element instanceof Tagged\PrivateType) { - throw new \UnexpectedValueException( - 'Private type expected, got ' . $this->_typeDescriptorString()); - } - return $this->_element; - } - - /** - * Get the wrapped element as a boolean type. - * - * @throws \UnexpectedValueException If the element is not a boolean - * - * @return \Sop\ASN1\Type\Primitive\Boolean - */ - public function asBoolean(): Primitive\Boolean - { - if (!$this->_element instanceof Primitive\Boolean) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_BOOLEAN)); - } - return $this->_element; - } - - /** - * Get the wrapped element as an integer type. - * - * @throws \UnexpectedValueException If the element is not an integer - * - * @return \Sop\ASN1\Type\Primitive\Integer - */ - public function asInteger(): Primitive\Integer - { - if (!$this->_element instanceof Primitive\Integer) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_INTEGER)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a bit string type. - * - * @throws \UnexpectedValueException If the element is not a bit string - * - * @return \Sop\ASN1\Type\Primitive\BitString - */ - public function asBitString(): Primitive\BitString - { - if (!$this->_element instanceof Primitive\BitString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_BIT_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as an octet string type. - * - * @throws \UnexpectedValueException If the element is not an octet string - * - * @return \Sop\ASN1\Type\Primitive\OctetString - */ - public function asOctetString(): Primitive\OctetString - { - if (!$this->_element instanceof Primitive\OctetString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_OCTET_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a null type. - * - * @throws \UnexpectedValueException If the element is not a null - * - * @return \Sop\ASN1\Type\Primitive\NullType - */ - public function asNull(): Primitive\NullType - { - if (!$this->_element instanceof Primitive\NullType) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_NULL)); - } - return $this->_element; - } - - /** - * Get the wrapped element as an object identifier type. - * - * @throws \UnexpectedValueException If the element is not an object identifier - * - * @return \Sop\ASN1\Type\Primitive\ObjectIdentifier - */ - public function asObjectIdentifier(): Primitive\ObjectIdentifier - { - if (!$this->_element instanceof Primitive\ObjectIdentifier) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_OBJECT_IDENTIFIER)); - } - return $this->_element; - } - - /** - * Get the wrapped element as an object descriptor type. - * - * @throws \UnexpectedValueException If the element is not an object descriptor - * - * @return \Sop\ASN1\Type\Primitive\ObjectDescriptor - */ - public function asObjectDescriptor(): Primitive\ObjectDescriptor - { - if (!$this->_element instanceof Primitive\ObjectDescriptor) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_OBJECT_DESCRIPTOR)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a real type. - * - * @throws \UnexpectedValueException If the element is not a real - * - * @return \Sop\ASN1\Type\Primitive\Real - */ - public function asReal(): Primitive\Real - { - if (!$this->_element instanceof Primitive\Real) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_REAL)); - } - return $this->_element; - } - - /** - * Get the wrapped element as an enumerated type. - * - * @throws \UnexpectedValueException If the element is not an enumerated - * - * @return \Sop\ASN1\Type\Primitive\Enumerated - */ - public function asEnumerated(): Primitive\Enumerated - { - if (!$this->_element instanceof Primitive\Enumerated) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_ENUMERATED)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a UTF8 string type. - * - * @throws \UnexpectedValueException If the element is not a UTF8 string - * - * @return \Sop\ASN1\Type\Primitive\UTF8String - */ - public function asUTF8String(): Primitive\UTF8String - { - if (!$this->_element instanceof Primitive\UTF8String) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_UTF8_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a relative OID type. - * - * @throws \UnexpectedValueException If the element is not a relative OID - * - * @return \Sop\ASN1\Type\Primitive\RelativeOID - */ - public function asRelativeOID(): Primitive\RelativeOID - { - if (!$this->_element instanceof Primitive\RelativeOID) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_RELATIVE_OID)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a sequence type. - * - * @throws \UnexpectedValueException If the element is not a sequence - * - * @return \Sop\ASN1\Type\Constructed\Sequence - */ - public function asSequence(): Constructed\Sequence - { - if (!$this->_element instanceof Constructed\Sequence) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_SEQUENCE)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a set type. - * - * @throws \UnexpectedValueException If the element is not a set - * - * @return \Sop\ASN1\Type\Constructed\Set - */ - public function asSet(): Constructed\Set - { - if (!$this->_element instanceof Constructed\Set) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_SET)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a numeric string type. - * - * @throws \UnexpectedValueException If the element is not a numeric string - * - * @return \Sop\ASN1\Type\Primitive\NumericString - */ - public function asNumericString(): Primitive\NumericString - { - if (!$this->_element instanceof Primitive\NumericString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_NUMERIC_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a printable string type. - * - * @throws \UnexpectedValueException If the element is not a printable string - * - * @return \Sop\ASN1\Type\Primitive\PrintableString - */ - public function asPrintableString(): Primitive\PrintableString - { - if (!$this->_element instanceof Primitive\PrintableString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_PRINTABLE_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a T61 string type. - * - * @throws \UnexpectedValueException If the element is not a T61 string - * - * @return \Sop\ASN1\Type\Primitive\T61String - */ - public function asT61String(): Primitive\T61String - { - if (!$this->_element instanceof Primitive\T61String) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_T61_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a videotex string type. - * - * @throws \UnexpectedValueException If the element is not a videotex string - * - * @return \Sop\ASN1\Type\Primitive\VideotexString - */ - public function asVideotexString(): Primitive\VideotexString - { - if (!$this->_element instanceof Primitive\VideotexString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_VIDEOTEX_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a IA5 string type. - * - * @throws \UnexpectedValueException If the element is not a IA5 string - * - * @return \Sop\ASN1\Type\Primitive\IA5String - */ - public function asIA5String(): Primitive\IA5String - { - if (!$this->_element instanceof Primitive\IA5String) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_IA5_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as an UTC time type. - * - * @throws \UnexpectedValueException If the element is not a UTC time - * - * @return \Sop\ASN1\Type\Primitive\UTCTime - */ - public function asUTCTime(): Primitive\UTCTime - { - if (!$this->_element instanceof Primitive\UTCTime) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_UTC_TIME)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a generalized time type. - * - * @throws \UnexpectedValueException If the element is not a generalized time - * - * @return \Sop\ASN1\Type\Primitive\GeneralizedTime - */ - public function asGeneralizedTime(): Primitive\GeneralizedTime - { - if (!$this->_element instanceof Primitive\GeneralizedTime) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_GENERALIZED_TIME)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a graphic string type. - * - * @throws \UnexpectedValueException If the element is not a graphic string - * - * @return \Sop\ASN1\Type\Primitive\GraphicString - */ - public function asGraphicString(): Primitive\GraphicString - { - if (!$this->_element instanceof Primitive\GraphicString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_GRAPHIC_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a visible string type. - * - * @throws \UnexpectedValueException If the element is not a visible string - * - * @return \Sop\ASN1\Type\Primitive\VisibleString - */ - public function asVisibleString(): Primitive\VisibleString - { - if (!$this->_element instanceof Primitive\VisibleString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_VISIBLE_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a general string type. - * - * @throws \UnexpectedValueException If the element is not general string - * - * @return \Sop\ASN1\Type\Primitive\GeneralString - */ - public function asGeneralString(): Primitive\GeneralString - { - if (!$this->_element instanceof Primitive\GeneralString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_GENERAL_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a universal string type. - * - * @throws \UnexpectedValueException If the element is not a universal string - * - * @return \Sop\ASN1\Type\Primitive\UniversalString - */ - public function asUniversalString(): Primitive\UniversalString - { - if (!$this->_element instanceof Primitive\UniversalString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_UNIVERSAL_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a character string type. - * - * @throws \UnexpectedValueException If the element is not a character string - * - * @return \Sop\ASN1\Type\Primitive\CharacterString - */ - public function asCharacterString(): Primitive\CharacterString - { - if (!$this->_element instanceof Primitive\CharacterString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_CHARACTER_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a BMP string type. - * - * @throws \UnexpectedValueException If the element is not a bmp string - * - * @return \Sop\ASN1\Type\Primitive\BMPString - */ - public function asBMPString(): Primitive\BMPString - { - if (!$this->_element instanceof Primitive\BMPString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_BMP_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as a constructed string type. - * - * @throws \UnexpectedValueException If the element is not a constructed string - * - * @return \Sop\ASN1\Type\Constructed\ConstructedString - */ - public function asConstructedString(): Constructed\ConstructedString - { - if (!$this->_element instanceof Constructed\ConstructedString) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_CONSTRUCTED_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as any string type. - * - * @throws \UnexpectedValueException If the element is not a string type - */ - public function asString(): StringType - { - if (!$this->_element instanceof StringType) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_STRING)); - } - return $this->_element; - } - - /** - * Get the wrapped element as any time type. - * - * @throws \UnexpectedValueException If the element is not a time type - */ - public function asTime(): TimeType - { - if (!$this->_element instanceof TimeType) { - throw new \UnexpectedValueException( - $this->_generateExceptionMessage(Element::TYPE_TIME)); - } - return $this->_element; - } - - /** - * {@inheritdoc} - */ - public function asElement(): Element - { - return $this->_element; - } - - /** - * {@inheritdoc} - */ - public function asUnspecified(): UnspecifiedType - { - return $this; - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->_element->toDER(); - } - - /** - * {@inheritdoc} - */ - public function typeClass(): int - { - return $this->_element->typeClass(); - } - - /** - * {@inheritdoc} - */ - public function tag(): int - { - return $this->_element->tag(); - } - - /** - * {@inheritdoc} - */ - public function isConstructed(): bool - { - return $this->_element->isConstructed(); - } - - /** - * {@inheritdoc} - */ - public function isType(int $tag): bool - { - return $this->_element->isType($tag); - } - - /** - * {@inheritdoc} - */ - public function isTagged(): bool - { - return $this->_element->isTagged(); - } - - /** - * {@inheritdoc} - * - * Consider using any of the `as*` accessor methods instead. - */ - public function expectType(int $tag): ElementBase - { - return $this->_element->expectType($tag); - } - - /** - * {@inheritdoc} - * - * Consider using `asTagged()` method instead and chaining - * with `TaggedType::asExplicit()` or `TaggedType::asImplicit()`. - */ - public function expectTagged(?int $tag = null): TaggedType - { - return $this->_element->expectTagged($tag); - } - - /** - * Generate message for exceptions thrown by `as*` methods. - * - * @param int $tag Type tag of the expected element - */ - private function _generateExceptionMessage(int $tag): string - { - return sprintf('%s expected, got %s.', Element::tagToName($tag), - $this->_typeDescriptorString()); - } - - /** - * Get textual description of the wrapped element for debugging purposes. - */ - private function _typeDescriptorString(): string - { - $type_cls = $this->_element->typeClass(); - $tag = $this->_element->tag(); - $str = $this->_element->isConstructed() ? 'constructed ' : 'primitive '; - if (Identifier::CLASS_UNIVERSAL === $type_cls) { - $str .= Element::tagToName($tag); - } else { - $str .= Identifier::classToName($type_cls) . " TAG {$tag}"; - } - return $str; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php deleted file mode 100644 index 28e5ccd..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/BigInt.php +++ /dev/null @@ -1,218 +0,0 @@ -_gmp = $num; - } - - public function __toString(): string - { - return $this->base10(); - } - - /** - * Initialize from an arbitrary length of octets as an unsigned integer. - */ - public static function fromUnsignedOctets(string $octets): self - { - if (!strlen($octets)) { - throw new \InvalidArgumentException('Empty octets.'); - } - return new self(gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN)); - } - - /** - * Initialize from an arbitrary length of octets as an signed integer - * having two's complement encoding. - */ - public static function fromSignedOctets(string $octets): self - { - if (!strlen($octets)) { - throw new \InvalidArgumentException('Empty octets.'); - } - $neg = ord($octets[0]) & 0x80; - // negative, apply inversion of two's complement - if ($neg) { - $octets = ~$octets; - } - $num = gmp_import($octets, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - // negative, apply addition of two's complement and produce negative result - if ($neg) { - $num = gmp_neg($num + 1); - } - return new self($num); - } - - /** - * Get the number as a base 10 integer string. - */ - public function base10(): string - { - if (!isset($this->_num)) { - $this->_num = gmp_strval($this->_gmp, 10); - } - return $this->_num; - } - - /** - * Get the number as an integer. - * - * @throws \RuntimeException If number overflows integer size - */ - public function intVal(): int - { - if (!isset($this->_intNum)) { - if (gmp_cmp($this->_gmp, $this->_intMaxGmp()) > 0) { - throw new \RuntimeException('Integer overflow.'); - } - if (gmp_cmp($this->_gmp, $this->_intMinGmp()) < 0) { - throw new \RuntimeException('Integer underflow.'); - } - $this->_intNum = gmp_intval($this->_gmp); - } - return $this->_intNum; - } - - /** - * Get the number as a `GMP` object. - * - * @throws \RuntimeException if number is not a valid integer - */ - public function gmpObj(): \GMP - { - return clone $this->_gmp; - } - - /** - * Get the number as an unsigned integer encoded in binary. - */ - public function unsignedOctets(): string - { - return gmp_export($this->_gmp, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - } - - /** - * Get the number as a signed integer encoded in two's complement binary. - */ - public function signedOctets(): string - { - switch (gmp_sign($this->_gmp)) { - case 1: - return $this->_signedPositiveOctets(); - case -1: - return $this->_signedNegativeOctets(); - } - // zero - return chr(0); - } - - /** - * Encode positive integer in two's complement binary. - */ - private function _signedPositiveOctets(): string - { - $bin = gmp_export($this->_gmp, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - // if first bit is 1, prepend full zero byte to represent positive two's complement - if (ord($bin[0]) & 0x80) { - $bin = chr(0x00) . $bin; - } - return $bin; - } - - /** - * Encode negative integer in two's complement binary. - */ - private function _signedNegativeOctets(): string - { - $num = gmp_abs($this->_gmp); - // compute number of bytes required - $width = 1; - if ($num > 128) { - $tmp = $num; - do { - ++$width; - $tmp >>= 8; - } while ($tmp > 128); - } - // compute two's complement 2^n - x - $num = gmp_pow('2', 8 * $width) - $num; - $bin = gmp_export($num, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - // if first bit is 0, prepend full inverted byte to represent negative two's complement - if (!(ord($bin[0]) & 0x80)) { - $bin = chr(0xff) . $bin; - } - return $bin; - } - - /** - * Get the maximum integer value. - */ - private function _intMaxGmp(): \GMP - { - static $gmp; - if (!isset($gmp)) { - $gmp = gmp_init(PHP_INT_MAX, 10); - } - return $gmp; - } - - /** - * Get the minimum integer value. - */ - private function _intMinGmp(): \GMP - { - static $gmp; - if (!isset($gmp)) { - $gmp = gmp_init(PHP_INT_MIN, 10); - } - return $gmp; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php b/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php deleted file mode 100644 index 60c2b0f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/asn1/lib/ASN1/Util/Flags.php +++ /dev/null @@ -1,144 +0,0 @@ -_flags = ''; - } else { - // calculate number of unused bits in last octet - $last_octet_bits = $width % 8; - $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; - $num = gmp_init($flags); - // mask bits outside bitfield width - $mask = gmp_sub(gmp_init(1) << $width, 1); - $num &= $mask; - // shift towards MSB if needed - $data = gmp_export($num << $unused_bits, 1, - GMP_MSW_FIRST | GMP_BIG_ENDIAN); - $octets = unpack('C*', $data); - assert(is_array($octets), new \RuntimeException('unpack() failed')); - $bits = count($octets) * 8; - // pad with zeroes - while ($bits < $width) { - array_unshift($octets, 0); - $bits += 8; - } - $this->_flags = pack('C*', ...$octets); - } - $this->_width = $width; - } - - /** - * Initialize from `BitString`. - */ - public static function fromBitString(BitString $bs, int $width): self - { - $num_bits = $bs->numBits(); - $num = gmp_import($bs->string(), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - $num >>= $bs->unusedBits(); - if ($num_bits < $width) { - $num <<= ($width - $num_bits); - } - return new self(gmp_strval($num, 10), $width); - } - - /** - * Check whether a bit at given index is set. - * - * Index 0 is the leftmost bit. - * - * @throws \OutOfBoundsException - */ - public function test(int $idx): bool - { - if ($idx >= $this->_width) { - throw new \OutOfBoundsException('Index is out of bounds.'); - } - // octet index - $oi = (int) floor($idx / 8); - $byte = $this->_flags[$oi]; - // bit index - $bi = $idx % 8; - // index 0 is the most significant bit in byte - $mask = 0x01 << (7 - $bi); - return (ord($byte) & $mask) > 0; - } - - /** - * Get flags as an octet string. - * - * Zeroes are appended to the last octet if width is not divisible by 8. - */ - public function string(): string - { - return $this->_flags; - } - - /** - * Get flags as a base 10 integer. - * - * @return string Integer as a string - */ - public function number(): string - { - $num = gmp_import($this->_flags, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - $last_octet_bits = $this->_width % 8; - $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; - $num >>= $unused_bits; - return gmp_strval($num, 10); - } - - /** - * Get flags as an integer. - */ - public function intNumber(): int - { - $num = new BigInt($this->number()); - return $num->intVal(); - } - - /** - * Get flags as a `BitString` object. - * - * Unused bits are set accordingly. Trailing zeroes are not stripped. - */ - public function bitString(): BitString - { - $last_octet_bits = $this->_width % 8; - $unused_bits = $last_octet_bits ? 8 - $last_octet_bits : 0; - return new BitString($this->_flags, $unused_bits); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE deleted file mode 100644 index 146b5cf..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016-2019 Joni Eskelinen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md deleted file mode 100644 index 38770b1..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/README.md +++ /dev/null @@ -1,24 +0,0 @@ -# CryptoEncoding - -[![Build Status](https://travis-ci.org/sop/crypto-encoding.svg?branch=master)](https://travis-ci.org/sop/crypto-encoding) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sop/crypto-encoding/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sop/crypto-encoding/?branch=master) -[![Coverage Status](https://coveralls.io/repos/github/sop/crypto-encoding/badge.svg?branch=master)](https://coveralls.io/github/sop/crypto-encoding?branch=master) -[![License](https://poser.pugx.org/sop/crypto-encoding/license)](https://github.com/sop/crypto-encoding/blob/master/LICENSE) - -A PHP implementation of [RFC 7468](https://tools.ietf.org/html/rfc7468) -textual encodings of cryptographic structures _(PEM)_. - -## Requirements - -- PHP >=7.2 - -## Installation - -This library is available on -[Packagist](https://packagist.org/packages/sop/crypto-encoding). - - composer require sop/crypto-encoding - -## License - -This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json deleted file mode 100644 index d1764e1..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/composer.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "sop/crypto-encoding", - "description": "A PHP implementation of textual encodings of cryptographic structures.", - "homepage": "https://github.com/sop/crypto-encoding", - "license": "MIT", - "type": "library", - "keywords": [ - "pem", - "public key", - "private key", - "certificate" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "require": { - "php": ">=7.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "autoload": { - "psr-4": { - "Sop\\CryptoEncoding\\": "lib/CryptoEncoding/" - } - } -} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php deleted file mode 100644 index d55b858..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEM.php +++ /dev/null @@ -1,145 +0,0 @@ -_type = $type; - $this->_data = $data; - } - - /** - * @return string - */ - public function __toString(): string - { - return $this->string(); - } - - /** - * Initialize from a PEM-formatted string. - * - * @param string $str - * - * @throws \UnexpectedValueException If string is not valid PEM - * - * @return self - */ - public static function fromString(string $str): self - { - if (!preg_match(self::PEM_REGEX, $str, $match)) { - throw new \UnexpectedValueException('Not a PEM formatted string.'); - } - $payload = preg_replace('/\s+/', '', $match[2]); - $data = base64_decode($payload, true); - if (false === $data) { - throw new \UnexpectedValueException('Failed to decode PEM data.'); - } - return new self($match[1], $data); - } - - /** - * Initialize from a file. - * - * @param string $filename Path to file - * - * @throws \RuntimeException If file reading fails - * - * @return self - */ - public static function fromFile(string $filename): self - { - if (!is_readable($filename) || - false === ($str = file_get_contents($filename))) { - throw new \RuntimeException("Failed to read {$filename}."); - } - return self::fromString($str); - } - - /** - * Get content type. - * - * @return string - */ - public function type(): string - { - return $this->_type; - } - - /** - * Get payload. - * - * @return string - */ - public function data(): string - { - return $this->_data; - } - - /** - * Encode to PEM string. - * - * @return string - */ - public function string(): string - { - return "-----BEGIN {$this->_type}-----\n" . - trim(chunk_split(base64_encode($this->_data), 64, "\n")) . "\n" . - "-----END {$this->_type}-----"; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php b/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php deleted file mode 100644 index 54c528d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-encoding/lib/CryptoEncoding/PEMBundle.php +++ /dev/null @@ -1,173 +0,0 @@ -_pems = $pems; - } - - /** - * @return string - */ - public function __toString(): string - { - return $this->string(); - } - - /** - * Initialize from a string. - * - * @param string $str - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromString(string $str): self - { - if (!preg_match_all(PEM::PEM_REGEX, $str, $matches, PREG_SET_ORDER)) { - throw new \UnexpectedValueException('No PEM blocks.'); - } - $pems = array_map( - function ($match) { - $payload = preg_replace('/\s+/', '', $match[2]); - $data = base64_decode($payload, true); - if (false === $data) { - throw new \UnexpectedValueException( - 'Failed to decode PEM data.'); - } - return new PEM($match[1], $data); - }, $matches); - return new self(...$pems); - } - - /** - * Initialize from a file. - * - * @param string $filename - * - * @throws \RuntimeException If file reading fails - * - * @return self - */ - public static function fromFile(string $filename): self - { - if (!is_readable($filename) || - false === ($str = file_get_contents($filename))) { - throw new \RuntimeException("Failed to read {$filename}."); - } - return self::fromString($str); - } - - /** - * Get self with PEM objects appended. - * - * @param PEM ...$pems - * - * @return self - */ - public function withPEMs(PEM ...$pems): self - { - $obj = clone $this; - $obj->_pems = array_merge($obj->_pems, $pems); - return $obj; - } - - /** - * Get all PEMs in a bundle. - * - * @return PEM[] - */ - public function all(): array - { - return $this->_pems; - } - - /** - * Get the first PEM in a bundle. - * - * @throws \LogicException If bundle contains no PEM objects - * - * @return PEM - */ - public function first(): PEM - { - if (!count($this->_pems)) { - throw new \LogicException('No PEMs.'); - } - return $this->_pems[0]; - } - - /** - * Get the last PEM in a bundle. - * - * @throws \LogicException If bundle contains no PEM objects - * - * @return PEM - */ - public function last(): PEM - { - if (!count($this->_pems)) { - throw new \LogicException('No PEMs.'); - } - return $this->_pems[count($this->_pems) - 1]; - } - - /** - * @see \Countable::count() - * - * @return int - */ - public function count(): int - { - return count($this->_pems); - } - - /** - * Get iterator for PEMs. - * - * @see \IteratorAggregate::getIterator() - * - * @return \ArrayIterator - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator($this->_pems); - } - - /** - * Encode bundle to a string of contiguous PEM blocks. - * - * @return string - */ - public function string(): string - { - return implode("\n", - array_map( - function (PEM $pem) { - return $pem->string(); - }, $this->_pems)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE b/utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE deleted file mode 100644 index 0453e40..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016-2021 Joni Eskelinen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md b/utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md deleted file mode 100644 index bbdccd4..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# CryptoTypes - -[![Build Status](https://travis-ci.com/sop/crypto-types.svg?branch=master)](https://travis-ci.com/sop/crypto-types) -[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/sop/crypto-types/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/sop/crypto-types/?branch=master) -[![Coverage Status](https://coveralls.io/repos/github/sop/crypto-types/badge.svg?branch=master)](https://coveralls.io/github/sop/crypto-types?branch=master) -[![License](https://poser.pugx.org/sop/crypto-types/license)](https://github.com/sop/crypto-types/blob/master/LICENSE) - -A PHP library of various ASN.1 types for cryptographic applications. - -## Requirements - -- PHP >=7.2 -- gmp -- [sop/asn1](https://github.com/sop/asn1) -- [sop/crypto-encoding](https://github.com/sop/crypto-encoding) -- [sop/x501](https://github.com/sop/x501) - -## Features - -- Asymmetric keys - - [`RSAPrivateKey`](https://tools.ietf.org/html/rfc2437#section-11.1.2), - [`RSAPublicKey`](https://tools.ietf.org/html/rfc2437#section-11.1.1) - - [`ECPrivateKey`](https://tools.ietf.org/html/rfc5915#section-3), - [`ECPublicKey`](https://tools.ietf.org/html/rfc5480#section-2.2) - - [`PrivateKeyInfo`](https://tools.ietf.org/html/rfc5208#section-5) - ([PKCS #8](https://tools.ietf.org/html/rfc5208)) - - [`SubjectPublicKeyInfo`](https://tools.ietf.org/html/rfc5280#section-4.1) - ([X.509](https://tools.ietf.org/html/rfc5280)) -- [RSA](https://tools.ietf.org/html/rfc2313#section-10) and - [EC](https://tools.ietf.org/html/rfc3278#section-8.2) signature types -- Various `AlgorithmIdentifier` types and their OID's - -## Installation - -This library is available on -[Packagist](https://packagist.org/packages/sop/crypto-types). - - composer require sop/crypto-types - -## License - -This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json b/utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json deleted file mode 100644 index d8ba537..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/composer.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "sop/crypto-types", - "description": "A PHP library of various ASN.1 types for cryptographic applications.", - "homepage": "https://github.com/sop/crypto-types", - "license": "MIT", - "type": "library", - "keywords": [ - "cryptography", - "asn1", - "algorithm identifier", - "rsa", - "ec", - "public key", - "private key", - "signature" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "require": { - "php": ">=7.2", - "ext-gmp": "*", - "sop/asn1": "^4.0.0", - "sop/crypto-encoding": "^0.3.0", - "sop/x501": "0.6.1" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "autoload": { - "psr-4": { - "Sop\\CryptoTypes\\": "lib/CryptoTypes/" - } - } -} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php deleted file mode 100644 index 239940f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifier.php +++ /dev/null @@ -1,116 +0,0 @@ -parse($seq); - } - - /** - * {@inheritdoc} - */ - public function oid(): string - { - return $this->_oid; - } - - /** - * {@inheritdoc} - */ - public function toASN1(): Sequence - { - $elements = [new ObjectIdentifier($this->_oid)]; - $params = $this->_paramsASN1(); - if (isset($params)) { - $elements[] = $params; - } - return new Sequence(...$elements); - } - - /** - * Get algorithm identifier parameters as ASN.1. - * - * If type allows parameters to be omitted, return null. - */ - abstract protected function _paramsASN1(): ?Element; -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php deleted file mode 100644 index 3dc182c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierFactory.php +++ /dev/null @@ -1,119 +0,0 @@ - Asymmetric\RSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_EC_PUBLIC_KEY => Asymmetric\ECPublicKeyAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_X25519 => Asymmetric\X25519AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_X448 => Asymmetric\X448AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ED25519 => Asymmetric\Ed25519AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ED448 => Asymmetric\Ed448AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_DES_CBC => Cipher\DESCBCAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_DES_EDE3_CBC => Cipher\DESEDE3CBCAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_RC2_CBC => Cipher\RC2CBCAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_AES_128_CBC => Cipher\AES128CBCAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_AES_192_CBC => Cipher\AES192CBCAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_AES_256_CBC => Cipher\AES256CBCAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_HMAC_WITH_SHA1 => Hash\HMACWithSHA1AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_HMAC_WITH_SHA224 => Hash\HMACWithSHA224AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_HMAC_WITH_SHA256 => Hash\HMACWithSHA256AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_HMAC_WITH_SHA384 => Hash\HMACWithSHA384AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_HMAC_WITH_SHA512 => Hash\HMACWithSHA512AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_MD5 => Hash\MD5AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA1 => Hash\SHA1AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA224 => Hash\SHA224AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA256 => Hash\SHA256AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA384 => Hash\SHA384AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA512 => Hash\SHA512AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_MD2_WITH_RSA_ENCRYPTION => Signature\MD2WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_MD4_WITH_RSA_ENCRYPTION => Signature\MD4WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_MD5_WITH_RSA_ENCRYPTION => Signature\MD5WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA1_WITH_RSA_ENCRYPTION => Signature\SHA1WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA224_WITH_RSA_ENCRYPTION => Signature\SHA224WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA256_WITH_RSA_ENCRYPTION => Signature\SHA256WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA384_WITH_RSA_ENCRYPTION => Signature\SHA384WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_SHA512_WITH_RSA_ENCRYPTION => Signature\SHA512WithRSAEncryptionAlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ECDSA_WITH_SHA1 => Signature\ECDSAWithSHA1AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ECDSA_WITH_SHA224 => Signature\ECDSAWithSHA224AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ECDSA_WITH_SHA256 => Signature\ECDSAWithSHA256AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ECDSA_WITH_SHA384 => Signature\ECDSAWithSHA384AlgorithmIdentifier::class, - AlgorithmIdentifier::OID_ECDSA_WITH_SHA512 => Signature\ECDSAWithSHA512AlgorithmIdentifier::class, - ]; - - /** - * Additional algorithm identifier providers. - * - * @var AlgorithmIdentifierProvider[] - */ - private $_additionalProviders; - - /** - * Constructor. - * - * @param AlgorithmIdentifierProvider ...$providers Additional providers - */ - public function __construct(AlgorithmIdentifierProvider ...$providers) - { - $this->_additionalProviders = $providers; - } - - /** - * Get the name of a class that implements algorithm identifier for given - * OID. - * - * @param string $oid Object identifier in dotted format - * - * @return null|string Fully qualified class name or null if not supported - */ - public function getClass(string $oid): ?string - { - // if OID is provided by this factory - if (array_key_exists($oid, self::MAP_OID_TO_CLASS)) { - return self::MAP_OID_TO_CLASS[$oid]; - } - // try additional providers - foreach ($this->_additionalProviders as $provider) { - if ($provider->supportsOID($oid)) { - return $provider->getClassByOID($oid); - } - } - return null; - } - - /** - * Parse AlgorithmIdentifier from an ASN.1 sequence. - */ - public function parse(Sequence $seq): AlgorithmIdentifier - { - $oid = $seq->at(0)->asObjectIdentifier()->oid(); - $params = $seq->has(1) ? $seq->at(1) : null; - /** @var SpecificAlgorithmIdentifier $cls */ - $cls = $this->getClass($oid); - if ($cls) { - return $cls::fromASN1Params($params); - } - // fallback to generic algorithm identifier - return new GenericAlgorithmIdentifier($oid, $params); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php deleted file mode 100644 index 5041677..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/AlgorithmIdentifierProvider.php +++ /dev/null @@ -1,35 +0,0 @@ - 192, - self::CURVE_PRIME192V2 => 192, - self::CURVE_PRIME192V3 => 192, - self::CURVE_PRIME239V1 => 239, - self::CURVE_PRIME239V2 => 239, - self::CURVE_PRIME239V3 => 239, - self::CURVE_PRIME256V1 => 256, - self::CURVE_SECP112R1 => 112, - self::CURVE_SECP112R2 => 112, - self::CURVE_SECP128R1 => 128, - self::CURVE_SECP128R2 => 128, - self::CURVE_SECP160K1 => 160, - self::CURVE_SECP160R1 => 160, - self::CURVE_SECP160R2 => 160, - self::CURVE_SECP192K1 => 192, - self::CURVE_SECP224K1 => 224, - self::CURVE_SECP224R1 => 224, - self::CURVE_SECP256K1 => 256, - self::CURVE_SECP384R1 => 384, - self::CURVE_SECP521R1 => 521, - ]; - - /** - * OID of the named curve. - * - * @var string - */ - protected $_namedCurve; - - /** - * Constructor. - * - * @param string $named_curve Curve identifier - */ - public function __construct(string $named_curve) - { - $this->_oid = self::OID_EC_PUBLIC_KEY; - $this->_namedCurve = $named_curve; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'ecPublicKey'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (!isset($params)) { - throw new \UnexpectedValueException('No parameters.'); - } - $named_curve = $params->asObjectIdentifier()->oid(); - return new self($named_curve); - } - - /** - * Get OID of the named curve. - */ - public function namedCurve(): string - { - return $this->_namedCurve; - } - - /** - * {@inheritdoc} - * - * @return ObjectIdentifier - */ - protected function _paramsASN1(): ?Element - { - return new ObjectIdentifier($this->_namedCurve); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php deleted file mode 100644 index b0fbe31..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed25519AlgorithmIdentifier.php +++ /dev/null @@ -1,44 +0,0 @@ -_oid = self::OID_ED25519; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'id-Ed25519'; - } - - /** - * {@inheritdoc} - */ - public function supportsKeyAlgorithm(AlgorithmIdentifier $algo): bool - { - return self::OID_ED25519 === $algo->oid(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php deleted file mode 100644 index 3b6b270..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/Ed448AlgorithmIdentifier.php +++ /dev/null @@ -1,44 +0,0 @@ -_oid = self::OID_ED448; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'id-Ed448'; - } - - /** - * {@inheritdoc} - */ - public function supportsKeyAlgorithm(AlgorithmIdentifier $algo): bool - { - return self::OID_ED448 === $algo->oid(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php deleted file mode 100644 index e1a6188..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/RFC8410EdAlgorithmIdentifier.php +++ /dev/null @@ -1,59 +0,0 @@ -_oid = self::OID_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'rsaEncryption'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (!isset($params)) { - throw new \UnexpectedValueException('No parameters.'); - } - $params->asNull(); - return new self(); - } - - /** - * {@inheritdoc} - * - * @return NullType - */ - protected function _paramsASN1(): ?Element - { - return new NullType(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php deleted file mode 100644 index f20005a..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X25519AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_X25519; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'id-X25519'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php deleted file mode 100644 index 86635b5..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Asymmetric/X448AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_X448; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'id-X448'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php deleted file mode 100644 index 6e043cf..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES128CBCAlgorithmIdentifier.php +++ /dev/null @@ -1,42 +0,0 @@ -_oid = self::OID_AES_128_CBC; - parent::__construct($iv); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'aes128-CBC'; - } - - /** - * {@inheritdoc} - */ - public function keySize(): int - { - return 16; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php deleted file mode 100644 index e228f13..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES192CBCAlgorithmIdentifier.php +++ /dev/null @@ -1,42 +0,0 @@ -_oid = self::OID_AES_192_CBC; - parent::__construct($iv); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'aes192-CBC'; - } - - /** - * {@inheritdoc} - */ - public function keySize(): int - { - return 24; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php deleted file mode 100644 index e076d09..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AES256CBCAlgorithmIdentifier.php +++ /dev/null @@ -1,42 +0,0 @@ -_oid = self::OID_AES_256_CBC; - parent::__construct($iv); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'aes256-CBC'; - } - - /** - * {@inheritdoc} - */ - public function keySize(): int - { - return 32; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php deleted file mode 100644 index 44fcb66..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/AESCBCAlgorithmIdentifier.php +++ /dev/null @@ -1,82 +0,0 @@ -_checkIVSize($iv); - $this->_initializationVector = $iv; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (!isset($params)) { - throw new \UnexpectedValueException('No parameters.'); - } - $iv = $params->asOctetString()->string(); - return new static($iv); - } - - /** - * {@inheritdoc} - */ - public function blockSize(): int - { - return 16; - } - - /** - * {@inheritdoc} - */ - public function ivSize(): int - { - return 16; - } - - /** - * {@inheritdoc} - * - * @return OctetString - */ - protected function _paramsASN1(): ?Element - { - if (!isset($this->_initializationVector)) { - throw new \LogicException('IV not set.'); - } - return new OctetString($this->_initializationVector); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php deleted file mode 100644 index 49f0f30..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/BlockCipherAlgorithmIdentifier.php +++ /dev/null @@ -1,16 +0,0 @@ -_initializationVector; - } - - /** - * Get copy of the object with given initialization vector. - * - * @param null|string $iv Initialization vector or null to remove - * - * @throws \UnexpectedValueException If initialization vector size is invalid - */ - public function withInitializationVector(?string $iv): self - { - $this->_checkIVSize($iv); - $obj = clone $this; - $obj->_initializationVector = $iv; - return $obj; - } - - /** - * Check that initialization vector size is valid for the cipher. - * - * @throws \UnexpectedValueException - */ - protected function _checkIVSize(?string $iv): void - { - if (null !== $iv && strlen($iv) !== $this->ivSize()) { - throw new \UnexpectedValueException('Invalid IV size.'); - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php deleted file mode 100644 index e3bd9c2..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESCBCAlgorithmIdentifier.php +++ /dev/null @@ -1,98 +0,0 @@ -_checkIVSize($iv); - $this->_oid = self::OID_DES_CBC; - $this->_initializationVector = $iv; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'desCBC'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (!isset($params)) { - throw new \UnexpectedValueException('No parameters.'); - } - $iv = $params->asOctetString()->string(); - return new self($iv); - } - - /** - * {@inheritdoc} - */ - public function blockSize(): int - { - return 8; - } - - /** - * {@inheritdoc} - */ - public function keySize(): int - { - return 8; - } - - /** - * {@inheritdoc} - */ - public function ivSize(): int - { - return 8; - } - - /** - * {@inheritdoc} - * - * @return OctetString - */ - protected function _paramsASN1(): ?Element - { - if (!isset($this->_initializationVector)) { - throw new \LogicException('IV not set.'); - } - return new OctetString($this->_initializationVector); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php deleted file mode 100644 index 79121d6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/DESEDE3CBCAlgorithmIdentifier.php +++ /dev/null @@ -1,99 +0,0 @@ -_checkIVSize($iv); - $this->_oid = self::OID_DES_EDE3_CBC; - $this->_initializationVector = $iv; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'des-EDE3-CBC'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (!isset($params)) { - throw new \UnexpectedValueException('No parameters.'); - } - $iv = $params->asOctetString()->string(); - return new self($iv); - } - - /** - * {@inheritdoc} - */ - public function blockSize(): int - { - return 8; - } - - /** - * {@inheritdoc} - */ - public function keySize(): int - { - return 24; - } - - /** - * {@inheritdoc} - */ - public function ivSize(): int - { - return 8; - } - - /** - * {@inheritdoc} - * - * @return OctetString - */ - protected function _paramsASN1(): ?Element - { - if (!isset($this->_initializationVector)) { - throw new \LogicException('IV not set.'); - } - return new OctetString($this->_initializationVector); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php deleted file mode 100644 index 52154a7..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Cipher/RC2CBCAlgorithmIdentifier.php +++ /dev/null @@ -1,215 +0,0 @@ - version - */ - private const EKB_TABLE = [ - 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, - 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, - 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, - 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, - 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, - 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, - 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, - 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, - 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, - 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, - 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, - 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, - 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, - 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, - 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, - 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, - 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, - 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, - 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, - 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, - 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, - 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, - 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, - 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, - 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, - 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, - 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, - 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, - 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, - 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, - 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, - 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab - ]; - - /** - * Effective key bits. - * - * @var int - */ - protected $_effectiveKeyBits; - - /** - * Constructor. - * - * @param int $key_bits Number of effective key bits - * @param null|string $iv Initialization vector - */ - public function __construct(int $key_bits = 64, ?string $iv = null) - { - $this->_checkIVSize($iv); - $this->_oid = self::OID_RC2_CBC; - $this->_effectiveKeyBits = $key_bits; - $this->_initializationVector = $iv; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'rc2-cbc'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (!isset($params)) { - throw new \UnexpectedValueException('No parameters.'); - } - $key_bits = 32; - // rfc2268 a choice containing only IV - if ($params->isType(Element::TYPE_OCTET_STRING)) { - $iv = $params->asOctetString()->string(); - } else { - $seq = $params->asSequence(); - $idx = 0; - // version is optional in rfc2898 - if ($seq->has($idx, Element::TYPE_INTEGER)) { - $version = $seq->at($idx++)->asInteger()->intNumber(); - $key_bits = self::_versionToEKB($version); - } - // IV is present in all variants - $iv = $seq->at($idx)->asOctetString()->string(); - } - return new self($key_bits, $iv); - } - - /** - * Get number of effective key bits. - */ - public function effectiveKeyBits(): int - { - return $this->_effectiveKeyBits; - } - - /** - * {@inheritdoc} - */ - public function blockSize(): int - { - return 8; - } - - /** - * {@inheritdoc} - */ - public function keySize(): int - { - return (int) round($this->_effectiveKeyBits / 8); - } - - /** - * {@inheritdoc} - */ - public function ivSize(): int - { - return 8; - } - - /** - * {@inheritdoc} - * - * @return Sequence - */ - protected function _paramsASN1(): ?Element - { - if ($this->_effectiveKeyBits >= 256) { - $version = $this->_effectiveKeyBits; - } else { - $version = self::EKB_TABLE[$this->_effectiveKeyBits]; - } - if (!isset($this->_initializationVector)) { - throw new \LogicException('IV not set.'); - } - return new Sequence(new Integer($version), - new OctetString($this->_initializationVector)); - } - - /** - * Translate version number to number of effective key bits. - */ - private static function _versionToEKB(int $version): int - { - static $lut; - if ($version > 255) { - return $version; - } - if (!isset($lut)) { - $lut = array_flip(self::EKB_TABLE); - } - return $lut[$version]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php deleted file mode 100644 index 5f03e5b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Feature/AlgorithmIdentifierType.php +++ /dev/null @@ -1,30 +0,0 @@ -_oid = $oid; - $this->_params = $params; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return $this->_oid; - } - - /** - * Get parameters. - */ - public function parameters(): ?UnspecifiedType - { - return $this->_params; - } - - /** - * {@inheritdoc} - */ - protected function _paramsASN1(): ?Element - { - return $this->_params ? $this->_params->asElement() : null; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php deleted file mode 100644 index 93e59b6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA1AlgorithmIdentifier.php +++ /dev/null @@ -1,66 +0,0 @@ -_oid = self::OID_HMAC_WITH_SHA1; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'hmacWithSHA1'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - if (isset($params)) { - throw new \UnexpectedValueException('Parameters must be omitted.'); - } - return new self(); - } - - /** - * {@inheritdoc} - */ - protected function _paramsASN1(): ?Element - { - return null; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php deleted file mode 100644 index 766da40..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA224AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_HMAC_WITH_SHA224; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'hmacWithSHA224'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php deleted file mode 100644 index ecec77f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA256AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_HMAC_WITH_SHA256; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'hmacWithSHA256'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php deleted file mode 100644 index 1867ac2..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA384AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_HMAC_WITH_SHA384; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'hmacWithSHA384'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php deleted file mode 100644 index 25f720e..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/HMACWithSHA512AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_HMAC_WITH_SHA512; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'hmacWithSHA512'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php deleted file mode 100644 index b592de3..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/MD5AlgorithmIdentifier.php +++ /dev/null @@ -1,85 +0,0 @@ -_oid = self::OID_MD5; - $this->_params = new NullType(); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'md5'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - $obj = new static(); - // if parameters field is present, it must be null type - if (isset($params)) { - $obj->_params = $params->asNull(); - } - return $obj; - } - - /** - * {@inheritdoc} - * - * @return null|NullType - */ - protected function _paramsASN1(): ?Element - { - return $this->_params; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php deleted file mode 100644 index 3a7f0bb..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/RFC4231HMACAlgorithmIdentifier.php +++ /dev/null @@ -1,56 +0,0 @@ -_params = $params->asNull(); - } - return $obj; - } - - /** - * {@inheritdoc} - * - * @return null|NullType - */ - protected function _paramsASN1(): ?Element - { - return $this->_params; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php deleted file mode 100644 index 60ce36b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA1AlgorithmIdentifier.php +++ /dev/null @@ -1,81 +0,0 @@ -_oid = self::OID_SHA1; - $this->_params = null; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha1'; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - $obj = new static(); - // if parameters field is present, it must be null type - if (isset($params)) { - $obj->_params = $params->asNull(); - } - return $obj; - } - - /** - * {@inheritdoc} - * - * @return null|NullType - */ - protected function _paramsASN1(): ?Element - { - return $this->_params; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php deleted file mode 100644 index daf566f..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA224AlgorithmIdentifier.php +++ /dev/null @@ -1,33 +0,0 @@ -_oid = self::OID_SHA224; - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha224'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php deleted file mode 100644 index 22677b8..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA256AlgorithmIdentifier.php +++ /dev/null @@ -1,32 +0,0 @@ -_oid = self::OID_SHA256; - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha256'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php deleted file mode 100644 index ed68edd..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA2AlgorithmIdentifier.php +++ /dev/null @@ -1,71 +0,0 @@ -_params = null; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - $obj = new static(); - // if parameters field is present, it must be null type - if (isset($params)) { - $obj->_params = $params->asNull(); - } - return $obj; - } - - /** - * {@inheritdoc} - * - * @return null|NullType - */ - protected function _paramsASN1(): ?Element - { - return $this->_params; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php deleted file mode 100644 index 846adad..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA384AlgorithmIdentifier.php +++ /dev/null @@ -1,32 +0,0 @@ -_oid = self::OID_SHA384; - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha384'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php deleted file mode 100644 index a38a24c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Hash/SHA512AlgorithmIdentifier.php +++ /dev/null @@ -1,32 +0,0 @@ -_oid = self::OID_SHA512; - parent::__construct(); - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha512'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php deleted file mode 100644 index 509c332..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA1AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_ECDSA_WITH_SHA1; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'ecdsa-with-SHA1'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php deleted file mode 100644 index 00c38cb..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA224AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_ECDSA_WITH_SHA224; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'ecdsa-with-SHA224'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php deleted file mode 100644 index 0ecef8b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA256AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_ECDSA_WITH_SHA256; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'ecdsa-with-SHA256'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php deleted file mode 100644 index 9b57697..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA384AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_ECDSA_WITH_SHA384; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'ecdsa-with-SHA384'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php deleted file mode 100644 index 4c2c2f5..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECDSAWithSHA512AlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_ECDSA_WITH_SHA512; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'ecdsa-with-SHA512'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php deleted file mode 100644 index 1fd0b09..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/ECSignatureAlgorithmIdentifier.php +++ /dev/null @@ -1,59 +0,0 @@ -oid(); - } - - /** - * {@inheritdoc} - */ - protected function _paramsASN1(): ?Element - { - return null; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index ec7cb4a..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD2WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_MD2_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'md2WithRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index 5a3e7e2..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD4WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_MD4_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'md4withRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index e50eeda..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/MD5WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_MD5_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'md5WithRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php deleted file mode 100644 index a2de151..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC3279RSASignatureAlgorithmIdentifier.php +++ /dev/null @@ -1,51 +0,0 @@ -asNull(); - return new static(); - } - - /** - * {@inheritdoc} - * - * @return NullType - */ - protected function _paramsASN1(): ?Element - { - return new NullType(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php deleted file mode 100644 index 001f744..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RFC4055RSASignatureAlgorithmIdentifier.php +++ /dev/null @@ -1,65 +0,0 @@ -_params = new NullType(); - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1Params( - ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier - { - $obj = new static(); - // store parameters so re-encoding doesn't change - if (isset($params)) { - $obj->_params = $params->asElement(); - } - return $obj; - } - - /** - * {@inheritdoc} - */ - protected function _paramsASN1(): ?Element - { - return $this->_params; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php deleted file mode 100644 index 074f6a1..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/RSASignatureAlgorithmIdentifier.php +++ /dev/null @@ -1,23 +0,0 @@ -oid(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index 49dca5c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA1WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = self::OID_SHA1_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha1-with-rsa-signature'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index 38db332..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA224WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ -_oid = self::OID_SHA224_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha224WithRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index 88fbf3c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA256WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ -_oid = self::OID_SHA256_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha256WithRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index 84f18d7..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA384WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ -_oid = self::OID_SHA384_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha384WithRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php deleted file mode 100644 index e4c1eba..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SHA512WithRSAEncryptionAlgorithmIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ -_oid = self::OID_SHA512_WITH_RSA_ENCRYPTION; - } - - /** - * {@inheritdoc} - */ - public function name(): string - { - return 'sha512WithRSAEncryption'; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php deleted file mode 100644 index 8c63ff4..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/Signature/SignatureAlgorithmIdentifierFactory.php +++ /dev/null @@ -1,105 +0,0 @@ - AlgorithmIdentifier::OID_MD5_WITH_RSA_ENCRYPTION, - AlgorithmIdentifier::OID_SHA1 => AlgorithmIdentifier::OID_SHA1_WITH_RSA_ENCRYPTION, - AlgorithmIdentifier::OID_SHA224 => AlgorithmIdentifier::OID_SHA224_WITH_RSA_ENCRYPTION, - AlgorithmIdentifier::OID_SHA256 => AlgorithmIdentifier::OID_SHA256_WITH_RSA_ENCRYPTION, - AlgorithmIdentifier::OID_SHA384 => AlgorithmIdentifier::OID_SHA384_WITH_RSA_ENCRYPTION, - AlgorithmIdentifier::OID_SHA512 => AlgorithmIdentifier::OID_SHA512_WITH_RSA_ENCRYPTION, - ]; - - /** - * Mapping of hash algorithm OID's to EC signature algorithm OID's. - * - * @internal - * - * @var array - */ - public const MAP_EC_OID = [ - AlgorithmIdentifier::OID_SHA1 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA1, - AlgorithmIdentifier::OID_SHA224 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA224, - AlgorithmIdentifier::OID_SHA256 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA256, - AlgorithmIdentifier::OID_SHA384 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA384, - AlgorithmIdentifier::OID_SHA512 => AlgorithmIdentifier::OID_ECDSA_WITH_SHA512, - ]; - - /** - * Get signature algorithm identifier of given asymmetric cryptographic type - * utilizing given hash algorithm. - * - * @param AsymmetricCryptoAlgorithmIdentifier $crypto_algo Cryptographic algorithm identifier, eg. RSA or EC - * @param HashAlgorithmIdentifier $hash_algo Hash algorithm identifier - * - * @throws \UnexpectedValueException - */ - public static function algoForAsymmetricCrypto( - AsymmetricCryptoAlgorithmIdentifier $crypto_algo, - HashAlgorithmIdentifier $hash_algo): SignatureAlgorithmIdentifier - { - switch ($crypto_algo->oid()) { - case AlgorithmIdentifier::OID_RSA_ENCRYPTION: - $oid = self::_oidForRSA($hash_algo); - break; - case AlgorithmIdentifier::OID_EC_PUBLIC_KEY: - $oid = self::_oidForEC($hash_algo); - break; - default: - throw new \UnexpectedValueException( - sprintf('Crypto algorithm %s not supported.', - $crypto_algo->name())); - } - $cls = (new AlgorithmIdentifierFactory())->getClass($oid); - return new $cls(); - } - - /** - * Get RSA signature algorithm OID for the given hash algorithm identifier. - * - * @throws \UnexpectedValueException - */ - private static function _oidForRSA(HashAlgorithmIdentifier $hash_algo): string - { - if (!array_key_exists($hash_algo->oid(), self::MAP_RSA_OID)) { - throw new \UnexpectedValueException( - sprintf('No RSA signature algorithm for %s.', $hash_algo->name())); - } - return self::MAP_RSA_OID[$hash_algo->oid()]; - } - - /** - * Get EC signature algorithm OID for the given hash algorithm identifier. - * - * @throws \UnexpectedValueException - */ - private static function _oidForEC(HashAlgorithmIdentifier $hash_algo): string - { - if (!array_key_exists($hash_algo->oid(), self::MAP_EC_OID)) { - throw new \UnexpectedValueException( - sprintf('No EC signature algorithm for %s.', $hash_algo->name())); - } - return self::MAP_EC_OID[$hash_algo->oid()]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php deleted file mode 100644 index f5d1320..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/AlgorithmIdentifier/SpecificAlgorithmIdentifier.php +++ /dev/null @@ -1,30 +0,0 @@ -string(); - if ($bs->unusedBits()) { - // @todo pad string - throw new \RuntimeException('Unaligned bitstrings to supported'); - } - return new OctetString($str); - } - - /** - * Perform Octet-String-to-Bit-String Conversion. - * - * Defined in SEC 1 section 2.3.2. - */ - public static function octetStringToBitString(OctetString $os): BitString - { - return new BitString($os->string()); - } - - /** - * Perform Integer-to-Octet-String Conversion. - * - * Defined in SEC 1 section 2.3.7. - * - * @param int $num - * @param null|int $mlen Optional desired output length - * - * @throws \UnexpectedValueException - */ - public static function integerToOctetString(Integer $num, ?int $mlen = null): OctetString - { - $gmp = gmp_init($num->number(), 10); - $str = gmp_export($gmp, 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - if (null !== $mlen) { - $len = strlen($str); - if ($len > $mlen) { - throw new \RangeException('Number is too large.'); - } - // pad with zeroes - if ($len < $mlen) { - $str = str_repeat("\0", $mlen - $len) . $str; - } - } - return new OctetString($str); - } - - /** - * Perform Octet-String-to-Integer Conversion. - * - * Defined in SEC 1 section 2.3.8. - * - * @return int - */ - public static function octetStringToInteger(OctetString $os): Integer - { - $num = gmp_import($os->string(), 1, GMP_MSW_FIRST | GMP_BIG_ENDIAN); - assert($num instanceof \GMP, new \RuntimeException('gmp_import() failed.')); - return new Integer(gmp_strval($num, 10)); - } - - /** - * Convert a base-10 number to octets. - * - * This is a convenicence method for integer <-> octet string conversion - * without the need for external ASN.1 dependencies. - * - * @param int|string $num Number in base-10 - * @param null|int $mlen Optional desired output length - */ - public static function numberToOctets($num, ?int $mlen = null): string - { - return self::integerToOctetString(new Integer($num), $mlen)->string(); - } - - /** - * Convert octets to a base-10 number. - * - * This is a convenicence method for integer <-> octet string conversion - * without the need for external ASN.1 dependencies. - * - * @return string Number in base-10 - */ - public static function octetsToNumber(string $str): string - { - return self::octetStringToInteger(new OctetString($str))->number(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php deleted file mode 100644 index 1649ae0..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPrivateKey.php +++ /dev/null @@ -1,223 +0,0 @@ -_privateKey = $private_key; - $this->_namedCurve = $named_curve; - $this->_publicKey = $public_key; - } - - /** - * Initialize from ASN.1. - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromASN1(Sequence $seq): ECPrivateKey - { - $version = $seq->at(0)->asInteger()->intNumber(); - if (1 !== $version) { - throw new \UnexpectedValueException('Version must be 1.'); - } - $private_key = $seq->at(1)->asOctetString()->string(); - $named_curve = null; - if ($seq->hasTagged(0)) { - $params = $seq->getTagged(0)->asExplicit(); - $named_curve = $params->asObjectIdentifier()->oid(); - } - $public_key = null; - if ($seq->hasTagged(1)) { - $public_key = $seq->getTagged(1)->asExplicit() - ->asBitString()->string(); - } - return new self($private_key, $named_curve, $public_key); - } - - /** - * Initialize from DER data. - * - * @return self - */ - public static function fromDER(string $data): ECPrivateKey - { - return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); - } - - /** - * @see PrivateKey::fromPEM() - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromPEM(PEM $pem): ECPrivateKey - { - $pk = parent::fromPEM($pem); - if (!($pk instanceof self)) { - throw new \UnexpectedValueException('Not an EC private key.'); - } - return $pk; - } - - /** - * Get the EC private key value. - * - * @return string Octets of the private key - */ - public function privateKeyOctets(): string - { - return $this->_privateKey; - } - - /** - * Whether named curve is present. - */ - public function hasNamedCurve(): bool - { - return isset($this->_namedCurve); - } - - /** - * Get named curve OID. - * - * @throws \LogicException - */ - public function namedCurve(): string - { - if (!$this->hasNamedCurve()) { - throw new \LogicException('namedCurve not set.'); - } - return $this->_namedCurve; - } - - /** - * Get self with named curve. - * - * @param null|string $named_curve Named curve OID - * - * @return self - */ - public function withNamedCurve(?string $named_curve): ECPrivateKey - { - $obj = clone $this; - $obj->_namedCurve = $named_curve; - return $obj; - } - - /** - * {@inheritdoc} - */ - public function algorithmIdentifier(): AlgorithmIdentifierType - { - return new ECPublicKeyAlgorithmIdentifier($this->namedCurve()); - } - - /** - * Whether public key is present. - */ - public function hasPublicKey(): bool - { - return isset($this->_publicKey); - } - - /** - * {@inheritdoc} - * - * @return ECPublicKey - */ - public function publicKey(): PublicKey - { - if (!$this->hasPublicKey()) { - throw new \LogicException('publicKey not set.'); - } - return new ECPublicKey($this->_publicKey, $this->namedCurve()); - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): Sequence - { - $elements = [new Integer(1), new OctetString($this->_privateKey)]; - if (isset($this->_namedCurve)) { - $elements[] = new ExplicitlyTaggedType(0, - new ObjectIdentifier($this->_namedCurve)); - } - if (isset($this->_publicKey)) { - $elements[] = new ExplicitlyTaggedType(1, - new BitString($this->_publicKey)); - } - return new Sequence(...$elements); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * {@inheritdoc} - */ - public function toPEM(): PEM - { - return new PEM(PEM::TYPE_EC_PRIVATE_KEY, $this->toDER()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php deleted file mode 100644 index f8b0e93..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/EC/ECPublicKey.php +++ /dev/null @@ -1,222 +0,0 @@ -_ecPoint = $ec_point; - $this->_namedCurve = $named_curve; - } - - /** - * Initialize from curve point coordinates. - * - * @param int|string $x X coordinate as a base10 number - * @param int|string $y Y coordinate as a base10 number - * @param null|string $named_curve Named curve OID - * @param null|int $bits Size of *p* in bits - * - * @return self - */ - public static function fromCoordinates($x, $y, - ?string $named_curve = null, ?int $bits = null): ECPublicKey - { - // if bitsize is not explicitly set, check from supported curves - if (!isset($bits) && isset($named_curve)) { - $bits = self::_curveSize($named_curve); - } - $mlen = null; - if (isset($bits)) { - $mlen = (int) ceil($bits / 8); - } - $x_os = ECConversion::integerToOctetString(new Integer($x), $mlen)->string(); - $y_os = ECConversion::integerToOctetString(new Integer($y), $mlen)->string(); - $ec_point = "\x4{$x_os}{$y_os}"; - return new self($ec_point, $named_curve); - } - - /** - * @see PublicKey::fromPEM() - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromPEM(PEM $pem): ECPublicKey - { - if (PEM::TYPE_PUBLIC_KEY !== $pem->type()) { - throw new \UnexpectedValueException('Not a public key.'); - } - $pki = PublicKeyInfo::fromDER($pem->data()); - $algo = $pki->algorithmIdentifier(); - if (AlgorithmIdentifier::OID_EC_PUBLIC_KEY !== $algo->oid() - || !($algo instanceof ECPublicKeyAlgorithmIdentifier)) { - throw new \UnexpectedValueException('Not an elliptic curve key.'); - } - // ECPoint is directly mapped into public key data - return new self($pki->publicKeyData()->string(), $algo->namedCurve()); - } - - /** - * Get ECPoint value. - */ - public function ECPoint(): string - { - return $this->_ecPoint; - } - - /** - * Get curve point coordinates. - * - * @return string[] Tuple of X and Y coordinates as base-10 numbers - */ - public function curvePoint(): array - { - return array_map( - function ($str) { - return ECConversion::octetsToNumber($str); - }, $this->curvePointOctets()); - } - - /** - * Get curve point coordinates in octet string representation. - * - * @return string[] tuple of X and Y field elements as a string - */ - public function curvePointOctets(): array - { - if ($this->isCompressed()) { - throw new \RuntimeException('EC point compression not supported.'); - } - $str = substr($this->_ecPoint, 1); - [$x, $y] = str_split($str, (int) floor(strlen($str) / 2)); - return [$x, $y]; - } - - /** - * Whether ECPoint is in compressed form. - */ - public function isCompressed(): bool - { - $c = ord($this->_ecPoint[0]); - return 4 !== $c; - } - - /** - * Whether named curve is present. - */ - public function hasNamedCurve(): bool - { - return isset($this->_namedCurve); - } - - /** - * Get named curve OID. - * - * @throws \LogicException - */ - public function namedCurve(): string - { - if (!$this->hasNamedCurve()) { - throw new \LogicException('namedCurve not set.'); - } - return $this->_namedCurve; - } - - /** - * {@inheritdoc} - */ - public function algorithmIdentifier(): AlgorithmIdentifierType - { - return new ECPublicKeyAlgorithmIdentifier($this->namedCurve()); - } - - /** - * Generate ASN.1 element. - */ - public function toASN1(): OctetString - { - return new OctetString($this->_ecPoint); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * {@inheritdoc} - * - * @see https://tools.ietf.org/html/rfc5480#section-2.2 - */ - public function subjectPublicKey(): BitString - { - // ECPoint is directly mapped to subjectPublicKey - return new BitString($this->_ecPoint); - } - - /** - * Get the curve size *p* in bits. - * - * @param string $oid Curve OID - */ - private static function _curveSize(string $oid): ?int - { - if (!array_key_exists($oid, ECPublicKeyAlgorithmIdentifier::MAP_CURVE_TO_SIZE)) { - return null; - } - return ECPublicKeyAlgorithmIdentifier::MAP_CURVE_TO_SIZE[$oid]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php deleted file mode 100644 index 5e7099e..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/OneAsymmetricKey.php +++ /dev/null @@ -1,359 +0,0 @@ -_version = self::VERSION_2; - $this->_algo = $algo; - $this->_privateKeyData = $key; - $this->_attributes = $attributes; - $this->_publicKeyData = $public_key; - } - - /** - * Initialize from ASN.1. - * - * @throws \UnexpectedValueException - */ - public static function fromASN1(Sequence $seq): self - { - $version = $seq->at(0)->asInteger()->intNumber(); - if (!in_array($version, [self::VERSION_1, self::VERSION_2])) { - throw new \UnexpectedValueException( - "Version {$version} not supported."); - } - $algo = AlgorithmIdentifier::fromASN1($seq->at(1)->asSequence()); - $key = $seq->at(2)->asOctetString()->string(); - $attribs = null; - if ($seq->hasTagged(0)) { - $attribs = OneAsymmetricKeyAttributes::fromASN1($seq->getTagged(0) - ->asImplicit(Element::TYPE_SET)->asSet()); - } - $pubkey = null; - if ($seq->hasTagged(1)) { - $pubkey = $seq->getTagged(1) - ->asImplicit(Element::TYPE_BIT_STRING)->asBitString(); - } - $obj = new static($algo, $key, $attribs, $pubkey); - $obj->_version = $version; - return $obj; - } - - /** - * Initialize from DER data. - */ - public static function fromDER(string $data): self - { - return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); - } - - /** - * Initialize from a `PrivateKey`. - * - * Note that `OneAsymmetricKey` <-> `PrivateKey` conversions may not be - * bidirectional with all key types, since `OneAsymmetricKey` may include - * attributes as well the public key that are not conveyed in a specific - * `PrivateKey` object. - */ - public static function fromPrivateKey(PrivateKey $private_key): self - { - return new static( - $private_key->algorithmIdentifier(), - $private_key->privateKeyData() - ); - } - - /** - * Initialize from PEM. - * - * @throws \UnexpectedValueException If PEM type is not supported - */ - public static function fromPEM(PEM $pem): self - { - switch ($pem->type()) { - case PEM::TYPE_PRIVATE_KEY: - return self::fromDER($pem->data()); - case PEM::TYPE_RSA_PRIVATE_KEY: - return self::fromPrivateKey( - RSA\RSAPrivateKey::fromDER($pem->data())); - case PEM::TYPE_EC_PRIVATE_KEY: - return self::fromPrivateKey( - EC\ECPrivateKey::fromDER($pem->data())); - } - throw new \UnexpectedValueException('Invalid PEM type.'); - } - - /** - * Get self with version set. - */ - public function withVersion(int $version): self - { - $obj = clone $this; - $obj->_version = $version; - return $obj; - } - - /** - * Get version number. - */ - public function version(): int - { - return $this->_version; - } - - /** - * Get algorithm identifier. - */ - public function algorithmIdentifier(): AlgorithmIdentifierType - { - return $this->_algo; - } - - /** - * Get private key data. - */ - public function privateKeyData(): string - { - return $this->_privateKeyData; - } - - /** - * Get private key. - * - * @throws \RuntimeException - */ - public function privateKey(): PrivateKey - { - $algo = $this->algorithmIdentifier(); - switch ($algo->oid()) { - // RSA - case AlgorithmIdentifier::OID_RSA_ENCRYPTION: - return RSA\RSAPrivateKey::fromDER($this->_privateKeyData); - // elliptic curve - case AlgorithmIdentifier::OID_EC_PUBLIC_KEY: - $pk = EC\ECPrivateKey::fromDER($this->_privateKeyData); - // NOTE: OpenSSL strips named curve from ECPrivateKey structure - // when serializing into PrivateKeyInfo. However RFC 5915 dictates - // that parameters (NamedCurve) must always be included. - // If private key doesn't encode named curve, assign from parameters. - if (!$pk->hasNamedCurve()) { - if (!$algo instanceof ECPublicKeyAlgorithmIdentifier) { - throw new \UnexpectedValueException('Not an EC algorithm.'); - } - $pk = $pk->withNamedCurve($algo->namedCurve()); - } - return $pk; - // Ed25519 - case AlgorithmIdentifier::OID_ED25519: - $pubkey = $this->_publicKeyData ? - $this->_publicKeyData->string() : null; - // RFC 8410 defines `CurvePrivateKey ::= OCTET STRING` that - // is encoded into private key data. So Ed25519 private key - // is doubly wrapped into octet string encodings. - return RFC8410\Curve25519\Ed25519PrivateKey::fromOctetString( - OctetString::fromDER($this->_privateKeyData), $pubkey) - ->withVersion($this->_version) - ->withAttributes($this->_attributes); - // X25519 - case AlgorithmIdentifier::OID_X25519: - $pubkey = $this->_publicKeyData ? - $this->_publicKeyData->string() : null; - return RFC8410\Curve25519\X25519PrivateKey::fromOctetString( - OctetString::fromDER($this->_privateKeyData), $pubkey) - ->withVersion($this->_version) - ->withAttributes($this->_attributes); - // Ed448 - case AlgorithmIdentifier::OID_ED448: - $pubkey = $this->_publicKeyData ? - $this->_publicKeyData->string() : null; - return RFC8410\Curve448\Ed448PrivateKey::fromOctetString( - OctetString::fromDER($this->_privateKeyData), $pubkey) - ->withVersion($this->_version) - ->withAttributes($this->_attributes); - // X448 - case AlgorithmIdentifier::OID_X448: - $pubkey = $this->_publicKeyData ? - $this->_publicKeyData->string() : null; - return RFC8410\Curve448\X448PrivateKey::fromOctetString( - OctetString::fromDER($this->_privateKeyData), $pubkey) - ->withVersion($this->_version) - ->withAttributes($this->_attributes); - } - throw new \RuntimeException( - 'Private key ' . $algo->name() . ' not supported.'); - } - - /** - * Get public key info corresponding to the private key. - */ - public function publicKeyInfo(): PublicKeyInfo - { - // if public key is explicitly defined - if ($this->hasPublicKeyData()) { - return new PublicKeyInfo($this->_algo, $this->_publicKeyData); - } - // else derive from private key - return $this->privateKey()->publicKey()->publicKeyInfo(); - } - - /** - * Whether attributes are present. - */ - public function hasAttributes(): bool - { - return isset($this->_attributes); - } - - /** - * Get attributes. - * - * @throws \LogicException If attributes are not present - */ - public function attributes(): OneAsymmetricKeyAttributes - { - if (!$this->hasAttributes()) { - throw new \LogicException('Attributes not set.'); - } - return $this->_attributes; - } - - /** - * Whether explicit public key data is present. - */ - public function hasPublicKeyData(): bool - { - return isset($this->_publicKeyData); - } - - /** - * Get the explicit public key data. - * - * @return \LogicException If public key is not present - */ - public function publicKeyData(): BitString - { - if (!$this->hasPublicKeyData()) { - throw new \LogicException('No explicit public key.'); - } - return $this->_publicKeyData; - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): Sequence - { - $elements = [ - new Integer($this->_version), - $this->_algo->toASN1(), - new OctetString($this->_privateKeyData) - ]; - if ($this->_attributes) { - $elements[] = new ImplicitlyTaggedType(0, - $this->_attributes->toASN1()); - } - if ($this->_publicKeyData) { - $elements[] = new ImplicitlyTaggedType(1, $this->_publicKeyData); - } - return new Sequence(...$elements); - } - - /** - * Generate DER encoding. - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * Generate PEM. - */ - public function toPEM(): PEM - { - return new PEM(PEM::TYPE_PRIVATE_KEY, $this->toDER()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php deleted file mode 100644 index c3b4bea..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKey.php +++ /dev/null @@ -1,74 +0,0 @@ -toDER(); - } - - /** - * Get the private key as a PrivateKeyInfo type. - */ - public function privateKeyInfo(): PrivateKeyInfo - { - return PrivateKeyInfo::fromPrivateKey($this); - } - - /** - * Initialize private key from PEM. - * - * @throws \UnexpectedValueException - * - * @return PrivateKey - */ - public static function fromPEM(PEM $pem) - { - switch ($pem->type()) { - case PEM::TYPE_RSA_PRIVATE_KEY: - return RSA\RSAPrivateKey::fromDER($pem->data()); - case PEM::TYPE_EC_PRIVATE_KEY: - return EC\ECPrivateKey::fromDER($pem->data()); - case PEM::TYPE_PRIVATE_KEY: - return PrivateKeyInfo::fromDER($pem->data())->privateKey(); - } - throw new \UnexpectedValueException( - 'PEM type ' . $pem->type() . ' is not a valid private key.'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php deleted file mode 100644 index f1a946e..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PrivateKeyInfo.php +++ /dev/null @@ -1,33 +0,0 @@ -_version = parent::VERSION_1; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php deleted file mode 100644 index 8b7e581..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKey.php +++ /dev/null @@ -1,60 +0,0 @@ -toDER()); - } - - /** - * Get the public key as a PublicKeyInfo type. - */ - public function publicKeyInfo(): PublicKeyInfo - { - return PublicKeyInfo::fromPublicKey($this); - } - - /** - * Initialize public key from PEM. - * - * @throws \UnexpectedValueException - * - * @return PublicKey - */ - public static function fromPEM(PEM $pem) - { - switch ($pem->type()) { - case PEM::TYPE_RSA_PUBLIC_KEY: - return RSA\RSAPublicKey::fromDER($pem->data()); - case PEM::TYPE_PUBLIC_KEY: - return PublicKeyInfo::fromPEM($pem)->publicKey(); - } - throw new \UnexpectedValueException( - 'PEM type ' . $pem->type() . ' is not a valid public key.'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php deleted file mode 100644 index 176b57b..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/PublicKeyInfo.php +++ /dev/null @@ -1,197 +0,0 @@ -_algo = $algo; - $this->_publicKey = $key; - } - - /** - * Initialize from ASN.1. - */ - public static function fromASN1(Sequence $seq): self - { - $algo = AlgorithmIdentifier::fromASN1($seq->at(0)->asSequence()); - $key = $seq->at(1)->asBitString(); - return new self($algo, $key); - } - - /** - * Initialize from a PublicKey. - */ - public static function fromPublicKey(PublicKey $key): self - { - return new self($key->algorithmIdentifier(), $key->subjectPublicKey()); - } - - /** - * Initialize from PEM. - * - * @throws \UnexpectedValueException - */ - public static function fromPEM(PEM $pem): self - { - switch ($pem->type()) { - case PEM::TYPE_PUBLIC_KEY: - return self::fromDER($pem->data()); - case PEM::TYPE_RSA_PUBLIC_KEY: - return RSA\RSAPublicKey::fromDER($pem->data())->publicKeyInfo(); - } - throw new \UnexpectedValueException('Invalid PEM type.'); - } - - /** - * Initialize from DER data. - */ - public static function fromDER(string $data): self - { - return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); - } - - /** - * Get algorithm identifier. - */ - public function algorithmIdentifier(): AlgorithmIdentifierType - { - return $this->_algo; - } - - /** - * Get public key data. - */ - public function publicKeyData(): BitString - { - return $this->_publicKey; - } - - /** - * Get public key. - * - * @throws \RuntimeException - */ - public function publicKey(): PublicKey - { - $algo = $this->algorithmIdentifier(); - switch ($algo->oid()) { - // RSA - case AlgorithmIdentifier::OID_RSA_ENCRYPTION: - return RSA\RSAPublicKey::fromDER($this->_publicKey->string()); - // Elliptic Curve - case AlgorithmIdentifier::OID_EC_PUBLIC_KEY: - if (!$algo instanceof ECPublicKeyAlgorithmIdentifier) { - throw new \UnexpectedValueException('Not an EC algorithm.'); - } - // ECPoint is directly mapped into public key data - return new EC\ECPublicKey($this->_publicKey->string(), - $algo->namedCurve()); - // Ed25519 - case AlgorithmIdentifier::OID_ED25519: - return new RFC8410\Curve25519\Ed25519PublicKey( - $this->_publicKey->string()); - // X25519 - case AlgorithmIdentifier::OID_X25519: - return new RFC8410\Curve25519\X25519PublicKey( - $this->_publicKey->string()); - // Ed448 - case AlgorithmIdentifier::OID_ED448: - return new RFC8410\Curve448\Ed448PublicKey( - $this->_publicKey->string()); - // X448 - case AlgorithmIdentifier::OID_X448: - return new RFC8410\Curve448\X448PublicKey( - $this->_publicKey->string()); - } - throw new \RuntimeException( - 'Public key ' . $algo->name() . ' not supported.'); - } - - /** - * Get key identifier using method 1 as described by RFC 5280. - * - * @see https://tools.ietf.org/html/rfc5280#section-4.2.1.2 - * - * @return string 20 bytes (160 bits) long identifier - */ - public function keyIdentifier(): string - { - return sha1($this->_publicKey->string(), true); - } - - /** - * Get key identifier using method 2 as described by RFC 5280. - * - * @see https://tools.ietf.org/html/rfc5280#section-4.2.1.2 - * - * @return string 8 bytes (64 bits) long identifier - */ - public function keyIdentifier64(): string - { - $id = substr($this->keyIdentifier(), -8); - $c = (ord($id[0]) & 0x0f) | 0x40; - $id[0] = chr($c); - return $id; - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): Sequence - { - return new Sequence($this->_algo->toASN1(), $this->_publicKey); - } - - /** - * Generate DER encoding. - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * Generate PEM. - */ - public function toPEM(): PEM - { - return new PEM(PEM::TYPE_PUBLIC_KEY, $this->toDER()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php deleted file mode 100644 index 5e11fdf..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Curve25519PrivateKey.php +++ /dev/null @@ -1,34 +0,0 @@ -hasPublicKey()) { - throw new \LogicException('Public key not set.'); - } - return new Ed25519PublicKey($this->_publicKeyData); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php deleted file mode 100644 index f111459..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/Ed25519PublicKey.php +++ /dev/null @@ -1,24 +0,0 @@ -hasPublicKey()) { - throw new \LogicException('Public key not set.'); - } - return new X25519PublicKey($this->_publicKeyData); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php deleted file mode 100644 index b9abd45..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve25519/X25519PublicKey.php +++ /dev/null @@ -1,24 +0,0 @@ -hasPublicKey()) { - throw new \LogicException('Public key not set.'); - } - return new Ed448PublicKey($this->_publicKeyData); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php deleted file mode 100644 index aa499ae..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/Ed448PublicKey.php +++ /dev/null @@ -1,39 +0,0 @@ -hasPublicKey()) { - throw new \LogicException('Public key not set.'); - } - return new X448PublicKey($this->_publicKeyData); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php deleted file mode 100644 index 7af5227..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/Curve448/X448PublicKey.php +++ /dev/null @@ -1,39 +0,0 @@ -_privateKeyData = $private_key; - $this->_publicKeyData = $public_key; - $this->_version = OneAsymmetricKey::VERSION_2; - $this->_attributes = null; - } - - /** - * Initialize from `CurvePrivateKey` OctetString. - * - * @param OctetString $str Private key data wrapped into OctetString - * @param null|string $public_key Optional public key data - */ - public static function fromOctetString(OctetString $str, - ?string $public_key = null): self - { - return new static($str->string(), $public_key); - } - - /** - * Get self with version number. - */ - public function withVersion(int $version): self - { - $obj = clone $this; - $obj->_version = $version; - return $obj; - } - - /** - * Get self with attributes. - */ - public function withAttributes(?OneAsymmetricKeyAttributes $attribs): self - { - $obj = clone $this; - $obj->_attributes = $attribs; - return $obj; - } - - /** - * {@inheritdoc} - */ - public function privateKeyData(): string - { - return $this->_privateKeyData; - } - - /** - * Whether public key is set. - */ - public function hasPublicKey(): bool - { - return isset($this->_publicKeyData); - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): OctetString - { - return new OctetString($this->_privateKeyData); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * {@inheritdoc} - */ - public function toPEM(): PEM - { - $pub = $this->_publicKeyData ? - new BitString($this->_publicKeyData) : null; - $pki = new OneAsymmetricKey($this->algorithmIdentifier(), - $this->toDER(), $this->_attributes, $pub); - return $pki->withVersion($this->_version)->toPEM(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php deleted file mode 100644 index 6a18542..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RFC8410/RFC8410PublicKey.php +++ /dev/null @@ -1,52 +0,0 @@ -_publicKey = $public_key; - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - throw new \LogicException("RFC 8410 public key doesn't have a DER encoding."); - } - - /** - * {@inheritdoc} - */ - public function subjectPublicKey(): BitString - { - return new BitString($this->_publicKey); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php deleted file mode 100644 index 15bf587..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPrivateKey.php +++ /dev/null @@ -1,286 +0,0 @@ -_modulus = strval($n); - $this->_publicExponent = strval($e); - $this->_privateExponent = strval($d); - $this->_prime1 = strval($p); - $this->_prime2 = strval($q); - $this->_exponent1 = strval($dp); - $this->_exponent2 = strval($dq); - $this->_coefficient = strval($qi); - } - - /** - * Initialize from ASN.1. - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromASN1(Sequence $seq): RSAPrivateKey - { - $version = $seq->at(0)->asInteger()->intNumber(); - if (0 !== $version) { - throw new \UnexpectedValueException('Version must be 0.'); - } - // helper function get integer from given index - $get_int = function ($idx) use ($seq) { - return $seq->at($idx)->asInteger()->number(); - }; - $n = $get_int(1); - $e = $get_int(2); - $d = $get_int(3); - $p = $get_int(4); - $q = $get_int(5); - $dp = $get_int(6); - $dq = $get_int(7); - $qi = $get_int(8); - return new self($n, $e, $d, $p, $q, $dp, $dq, $qi); - } - - /** - * Initialize from DER data. - * - * @return self - */ - public static function fromDER(string $data): RSAPrivateKey - { - return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); - } - - /** - * @see PrivateKey::fromPEM() - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromPEM(PEM $pem): RSAPrivateKey - { - $pk = parent::fromPEM($pem); - if (!($pk instanceof self)) { - throw new \UnexpectedValueException('Not an RSA private key.'); - } - return $pk; - } - - /** - * Get modulus. - * - * @return string Base 10 integer - */ - public function modulus(): string - { - return $this->_modulus; - } - - /** - * Get public exponent. - * - * @return string Base 10 integer - */ - public function publicExponent(): string - { - return $this->_publicExponent; - } - - /** - * Get private exponent. - * - * @return string Base 10 integer - */ - public function privateExponent(): string - { - return $this->_privateExponent; - } - - /** - * Get first prime factor. - * - * @return string Base 10 integer - */ - public function prime1(): string - { - return $this->_prime1; - } - - /** - * Get second prime factor. - * - * @return string Base 10 integer - */ - public function prime2(): string - { - return $this->_prime2; - } - - /** - * Get first factor exponent. - * - * @return string Base 10 integer - */ - public function exponent1(): string - { - return $this->_exponent1; - } - - /** - * Get second factor exponent. - * - * @return string Base 10 integer - */ - public function exponent2(): string - { - return $this->_exponent2; - } - - /** - * Get CRT coefficient of the second factor. - * - * @return string Base 10 integer - */ - public function coefficient(): string - { - return $this->_coefficient; - } - - /** - * {@inheritdoc} - */ - public function algorithmIdentifier(): AlgorithmIdentifierType - { - return new RSAEncryptionAlgorithmIdentifier(); - } - - /** - * {@inheritdoc} - * - * @return RSAPublicKey - */ - public function publicKey(): PublicKey - { - return new RSAPublicKey($this->_modulus, $this->_publicExponent); - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): Sequence - { - return new Sequence(new Integer(0), - new Integer($this->_modulus), - new Integer($this->_publicExponent), - new Integer($this->_privateExponent), - new Integer($this->_prime1), - new Integer($this->_prime2), - new Integer($this->_exponent1), - new Integer($this->_exponent2), - new Integer($this->_coefficient)); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * {@inheritdoc} - */ - public function toPEM(): PEM - { - return new PEM(PEM::TYPE_RSA_PRIVATE_KEY, $this->toDER()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php deleted file mode 100644 index b4e55d4..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Asymmetric/RSA/RSAPublicKey.php +++ /dev/null @@ -1,147 +0,0 @@ -_modulus = strval($n); - $this->_publicExponent = strval($e); - } - - /** - * Initialize from ASN.1. - * - * @return self - */ - public static function fromASN1(Sequence $seq): RSAPublicKey - { - $n = $seq->at(0)->asInteger()->number(); - $e = $seq->at(1)->asInteger()->number(); - return new self($n, $e); - } - - /** - * Initialize from DER data. - * - * @return self - */ - public static function fromDER(string $data): RSAPublicKey - { - return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); - } - - /** - * @see PublicKey::fromPEM() - * - * @throws \UnexpectedValueException - * - * @return self - */ - public static function fromPEM(PEM $pem): RSAPublicKey - { - switch ($pem->type()) { - case PEM::TYPE_RSA_PUBLIC_KEY: - return self::fromDER($pem->data()); - case PEM::TYPE_PUBLIC_KEY: - $pki = PublicKeyInfo::fromDER($pem->data()); - if (AlgorithmIdentifier::OID_RSA_ENCRYPTION !== - $pki->algorithmIdentifier()->oid()) { - throw new \UnexpectedValueException('Not an RSA public key.'); - } - return self::fromDER($pki->publicKeyData()->string()); - } - throw new \UnexpectedValueException('Invalid PEM type ' . $pem->type()); - } - - /** - * Get modulus. - * - * @return string Base 10 integer - */ - public function modulus(): string - { - return $this->_modulus; - } - - /** - * Get public exponent. - * - * @return string Base 10 integer - */ - public function publicExponent(): string - { - return $this->_publicExponent; - } - - /** - * {@inheritdoc} - */ - public function algorithmIdentifier(): AlgorithmIdentifierType - { - return new RSAEncryptionAlgorithmIdentifier(); - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): Sequence - { - return new Sequence(new Integer($this->_modulus), - new Integer($this->_publicExponent)); - } - - /** - * {@inheritdoc} - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * Generate PEM. - */ - public function toPEM(): PEM - { - return new PEM(PEM::TYPE_RSA_PUBLIC_KEY, $this->toDER()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php deleted file mode 100644 index 808f8e6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/ECSignature.php +++ /dev/null @@ -1,108 +0,0 @@ -_r = strval($r); - $this->_s = strval($s); - } - - /** - * Initialize from ASN.1. - */ - public static function fromASN1(Sequence $seq): self - { - $r = $seq->at(0)->asInteger()->number(); - $s = $seq->at(1)->asInteger()->number(); - return new self($r, $s); - } - - /** - * Initialize from DER. - */ - public static function fromDER(string $data): self - { - return self::fromASN1(UnspecifiedType::fromDER($data)->asSequence()); - } - - /** - * Get the r-value. - * - * @return string Base 10 integer string - */ - public function r(): string - { - return $this->_r; - } - - /** - * Get the s-value. - * - * @return string Base 10 integer string - */ - public function s(): string - { - return $this->_s; - } - - /** - * Generate ASN.1 structure. - */ - public function toASN1(): Sequence - { - return new Sequence(new Integer($this->_r), new Integer($this->_s)); - } - - /** - * Get DER encoding of the signature. - */ - public function toDER(): string - { - return $this->toASN1()->toDER(); - } - - /** - * {@inheritdoc} - */ - public function bitString(): BitString - { - return new BitString($this->toDER()); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php deleted file mode 100644 index 4d50108..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed25519Signature.php +++ /dev/null @@ -1,44 +0,0 @@ -_signature = $signature; - } - - /** - * {@inheritdoc} - */ - public function bitString(): BitString - { - return new BitString($this->_signature); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php deleted file mode 100644 index 9090a38..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Ed448Signature.php +++ /dev/null @@ -1,44 +0,0 @@ -_signature = $signature; - } - - /** - * {@inheritdoc} - */ - public function bitString(): BitString - { - return new BitString($this->_signature); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php deleted file mode 100644 index 4e6635a..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/GenericSignature.php +++ /dev/null @@ -1,56 +0,0 @@ -_signature = $signature; - $this->_signatureAlgorithm = $algo; - } - - /** - * Get the signature algorithm. - */ - public function signatureAlgorithm(): AlgorithmIdentifierType - { - return $this->_signatureAlgorithm; - } - - /** - * {@inheritdoc} - */ - public function bitString(): BitString - { - return $this->_signature; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php deleted file mode 100644 index cf3710d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/RSASignature.php +++ /dev/null @@ -1,58 +0,0 @@ -_signature = strval($signature); - return $obj; - } - - /** - * {@inheritdoc} - */ - public function bitString(): BitString - { - return new BitString($this->_signature); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php b/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php deleted file mode 100644 index 75ad8c0..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/crypto-types/lib/CryptoTypes/Signature/Signature.php +++ /dev/null @@ -1,49 +0,0 @@ -=7.2 -- intl -- mbstring -- [sop/asn1](https://github.com/sop/asn1) - -## Installation - -This library is available on -[Packagist](https://packagist.org/packages/sop/x501). - - composer require sop/x501 - -## License - -This project is licensed under the MIT License. diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/composer.json b/utilities/signing_and_verification/php/vendor/sop/x501/composer.json deleted file mode 100644 index 0901490..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/composer.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "sop/x501", - "description": "A PHP library for X.501 ASN.1 types, X.520 attributes and DN parsing.", - "homepage": "https://github.com/sop/x501", - "license": "MIT", - "type": "library", - "keywords": [ - "x501", - "x.501", - "x520", - "x.520", - "ldap", - "dn", - "rdn", - "attribute" - ], - "authors": [ - { - "name": "Joni Eskelinen", - "email": "jonieske@gmail.com", - "role": "Developer" - } - ], - "require": { - "php": ">=7.2", - "ext-intl": "*", - "ext-mbstring": "*", - "sop/asn1": "^4.0.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.1" - }, - "autoload": { - "psr-4": { - "Sop\\X501\\": "lib/X501/" - } - } -} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php deleted file mode 100644 index 9b3c08a..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Attribute.php +++ /dev/null @@ -1,176 +0,0 @@ -oid() !== $type->oid()) { - throw new \LogicException('Attribute OID mismatch.'); - } - } - $this->_type = $type; - $this->_values = $values; - } - - /** - * Initialize from ASN.1. - * - * @param Sequence $seq - * - * @return self - */ - public static function fromASN1(Sequence $seq): self - { - $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier()); - $values = array_map( - function (UnspecifiedType $el) use ($type) { - return AttributeValue::fromASN1ByOID($type->oid(), $el); - }, $seq->at(1)->asSet()->elements()); - return new self($type, ...$values); - } - - /** - * Convenience method to initialize from attribute values. - * - * @param AttributeValue ...$values One or more values - * - * @throws \LogicException - * - * @return self - */ - public static function fromAttributeValues(AttributeValue ...$values): self - { - // we need at least one value to determine OID - if (!count($values)) { - throw new \LogicException('No values.'); - } - $oid = reset($values)->oid(); - return new self(new AttributeType($oid), ...$values); - } - - /** - * Get first value of the attribute. - * - * @throws \LogicException - * - * @return AttributeValue - */ - public function first(): AttributeValue - { - if (!count($this->_values)) { - throw new \LogicException('Attribute contains no values.'); - } - return $this->_values[0]; - } - - /** - * Get all values. - * - * @return AttributeValue[] - */ - public function values(): array - { - return $this->_values; - } - - /** - * Generate ASN.1 structure. - * - * @return Sequence - */ - public function toASN1(): Sequence - { - $values = array_map( - function (AttributeValue $value) { - return $value->toASN1(); - }, $this->_values); - $valueset = new Set(...$values); - return new Sequence($this->_type->toASN1(), $valueset->sortedSetOf()); - } - - /** - * Cast attribute values to another AttributeValue class. - * - * This method is generally used to cast UnknownAttributeValue values - * to specific objects when class is declared outside this package. - * - * The new class must be derived from AttributeValue and have the same OID - * as current attribute values. - * - * @param string $cls AttributeValue class name - * - * @throws \LogicException - * - * @return self - */ - public function castValues(string $cls): self - { - // check that target class derives from AttributeValue - if (!is_subclass_of($cls, AttributeValue::class)) { - throw new \LogicException(sprintf( - '%s must be derived from %s.', $cls, AttributeValue::class)); - } - $values = array_map( - function (AttributeValue $value) use ($cls) { - /** @var AttributeValue $cls Class name as a string */ - $value = $cls::fromSelf($value); - if ($value->oid() !== $this->oid()) { - throw new \LogicException('Attribute OID mismatch.'); - } - return $value; - }, $this->_values); - return self::fromAttributeValues(...$values); - } - - /** - * @see \Countable::count() - * - * @return int - */ - public function count(): int - { - return count($this->_values); - } - - /** - * @see \IteratorAggregate::getIterator() - * - * @return \ArrayIterator - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator($this->_values); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php deleted file mode 100644 index c9c58d4..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeType.php +++ /dev/null @@ -1,457 +0,0 @@ - Element::TYPE_PRINTABLE_STRING, - self::OID_COUNTRY_NAME => Element::TYPE_PRINTABLE_STRING, - self::OID_SERIAL_NUMBER => Element::TYPE_PRINTABLE_STRING, - ]; - - /** - * OID to attribute names mapping. - * - * First name is the primary name. If there's more than one name, others may - * be used as an alias. - * - * Generated using ldap-attribs.py. - * - * @internal - * - * @var array - */ - const MAP_OID_TO_NAME = [ - '0.9.2342.19200300.100.1.1' => ['uid', 'userid'], - '0.9.2342.19200300.100.1.2' => ['textEncodedORAddress'], - '0.9.2342.19200300.100.1.3' => ['mail', 'rfc822Mailbox'], - '0.9.2342.19200300.100.1.4' => ['info'], - '0.9.2342.19200300.100.1.5' => ['drink', 'favouriteDrink'], - '0.9.2342.19200300.100.1.6' => ['roomNumber'], - '0.9.2342.19200300.100.1.7' => ['photo'], - '0.9.2342.19200300.100.1.8' => ['userClass'], - '0.9.2342.19200300.100.1.9' => ['host'], - '0.9.2342.19200300.100.1.10' => ['manager'], - '0.9.2342.19200300.100.1.11' => ['documentIdentifier'], - '0.9.2342.19200300.100.1.12' => ['documentTitle'], - '0.9.2342.19200300.100.1.13' => ['documentVersion'], - '0.9.2342.19200300.100.1.14' => ['documentAuthor'], - '0.9.2342.19200300.100.1.15' => ['documentLocation'], - '0.9.2342.19200300.100.1.20' => ['homePhone', 'homeTelephoneNumber'], - '0.9.2342.19200300.100.1.21' => ['secretary'], - '0.9.2342.19200300.100.1.22' => ['otherMailbox'], - '0.9.2342.19200300.100.1.25' => ['dc', 'domainComponent'], - '0.9.2342.19200300.100.1.26' => ['aRecord'], - '0.9.2342.19200300.100.1.27' => ['mDRecord'], - '0.9.2342.19200300.100.1.28' => ['mXRecord'], - '0.9.2342.19200300.100.1.29' => ['nSRecord'], - '0.9.2342.19200300.100.1.30' => ['sOARecord'], - '0.9.2342.19200300.100.1.31' => ['cNAMERecord'], - '0.9.2342.19200300.100.1.37' => ['associatedDomain'], - '0.9.2342.19200300.100.1.38' => ['associatedName'], - '0.9.2342.19200300.100.1.39' => ['homePostalAddress'], - '0.9.2342.19200300.100.1.40' => ['personalTitle'], - '0.9.2342.19200300.100.1.41' => ['mobile', 'mobileTelephoneNumber'], - '0.9.2342.19200300.100.1.42' => ['pager', 'pagerTelephoneNumber'], - '0.9.2342.19200300.100.1.43' => ['co', 'friendlyCountryName'], - '0.9.2342.19200300.100.1.44' => ['uniqueIdentifier'], - '0.9.2342.19200300.100.1.45' => ['organizationalStatus'], - '0.9.2342.19200300.100.1.46' => ['janetMailbox'], - '0.9.2342.19200300.100.1.47' => ['mailPreferenceOption'], - '0.9.2342.19200300.100.1.48' => ['buildingName'], - '0.9.2342.19200300.100.1.49' => ['dSAQuality'], - '0.9.2342.19200300.100.1.50' => ['singleLevelQuality'], - '0.9.2342.19200300.100.1.51' => ['subtreeMinimumQuality'], - '0.9.2342.19200300.100.1.52' => ['subtreeMaximumQuality'], - '0.9.2342.19200300.100.1.53' => ['personalSignature'], - '0.9.2342.19200300.100.1.54' => ['dITRedirect'], - '0.9.2342.19200300.100.1.55' => ['audio'], - '0.9.2342.19200300.100.1.56' => ['documentPublisher'], - '0.9.2342.19200300.100.1.60' => ['jpegPhoto'], - '1.2.840.113549.1.9.1' => ['email', 'emailAddress', 'pkcs9email'], - '1.2.840.113556.1.2.102' => ['memberOf'], - '1.3.6.1.1.1.1.0' => ['uidNumber'], - '1.3.6.1.1.1.1.1' => ['gidNumber'], - '1.3.6.1.1.1.1.2' => ['gecos'], - '1.3.6.1.1.1.1.3' => ['homeDirectory'], - '1.3.6.1.1.1.1.4' => ['loginShell'], - '1.3.6.1.1.1.1.5' => ['shadowLastChange'], - '1.3.6.1.1.1.1.6' => ['shadowMin'], - '1.3.6.1.1.1.1.7' => ['shadowMax'], - '1.3.6.1.1.1.1.8' => ['shadowWarning'], - '1.3.6.1.1.1.1.9' => ['shadowInactive'], - '1.3.6.1.1.1.1.10' => ['shadowExpire'], - '1.3.6.1.1.1.1.11' => ['shadowFlag'], - '1.3.6.1.1.1.1.12' => ['memberUid'], - '1.3.6.1.1.1.1.13' => ['memberNisNetgroup'], - '1.3.6.1.1.1.1.14' => ['nisNetgroupTriple'], - '1.3.6.1.1.1.1.15' => ['ipServicePort'], - '1.3.6.1.1.1.1.16' => ['ipServiceProtocol'], - '1.3.6.1.1.1.1.17' => ['ipProtocolNumber'], - '1.3.6.1.1.1.1.18' => ['oncRpcNumber'], - '1.3.6.1.1.1.1.19' => ['ipHostNumber'], - '1.3.6.1.1.1.1.20' => ['ipNetworkNumber'], - '1.3.6.1.1.1.1.21' => ['ipNetmaskNumber'], - '1.3.6.1.1.1.1.22' => ['macAddress'], - '1.3.6.1.1.1.1.23' => ['bootParameter'], - '1.3.6.1.1.1.1.24' => ['bootFile'], - '1.3.6.1.1.1.1.26' => ['nisMapName'], - '1.3.6.1.1.1.1.27' => ['nisMapEntry'], - '1.3.6.1.1.4' => ['vendorName'], - '1.3.6.1.1.5' => ['vendorVersion'], - '1.3.6.1.1.16.4' => ['entryUUID'], - '1.3.6.1.1.20' => ['entryDN'], - '2.5.4.0' => ['objectClass'], - '2.5.4.1' => ['aliasedObjectName', 'aliasedEntryName'], - '2.5.4.2' => ['knowledgeInformation'], - '2.5.4.3' => ['cn', 'commonName'], - '2.5.4.4' => ['sn', 'surname'], - '2.5.4.5' => ['serialNumber'], - '2.5.4.6' => ['c', 'countryName'], - '2.5.4.7' => ['l', 'localityName'], - '2.5.4.8' => ['st', 'stateOrProvinceName'], - '2.5.4.9' => ['street', 'streetAddress'], - '2.5.4.10' => ['o', 'organizationName'], - '2.5.4.11' => ['ou', 'organizationalUnitName'], - '2.5.4.12' => ['title'], - '2.5.4.13' => ['description'], - '2.5.4.14' => ['searchGuide'], - '2.5.4.15' => ['businessCategory'], - '2.5.4.16' => ['postalAddress'], - '2.5.4.17' => ['postalCode'], - '2.5.4.18' => ['postOfficeBox'], - '2.5.4.19' => ['physicalDeliveryOfficeName'], - '2.5.4.20' => ['telephoneNumber'], - '2.5.4.21' => ['telexNumber'], - '2.5.4.22' => ['teletexTerminalIdentifier'], - '2.5.4.23' => ['facsimileTelephoneNumber', 'fax'], - '2.5.4.24' => ['x121Address'], - '2.5.4.25' => ['internationaliSDNNumber'], - '2.5.4.26' => ['registeredAddress'], - '2.5.4.27' => ['destinationIndicator'], - '2.5.4.28' => ['preferredDeliveryMethod'], - '2.5.4.29' => ['presentationAddress'], - '2.5.4.30' => ['supportedApplicationContext'], - '2.5.4.31' => ['member'], - '2.5.4.32' => ['owner'], - '2.5.4.33' => ['roleOccupant'], - '2.5.4.34' => ['seeAlso'], - '2.5.4.35' => ['userPassword'], - '2.5.4.36' => ['userCertificate'], - '2.5.4.37' => ['cACertificate'], - '2.5.4.38' => ['authorityRevocationList'], - '2.5.4.39' => ['certificateRevocationList'], - '2.5.4.40' => ['crossCertificatePair'], - '2.5.4.41' => ['name'], - '2.5.4.42' => ['givenName', 'gn'], - '2.5.4.43' => ['initials'], - '2.5.4.44' => ['generationQualifier'], - '2.5.4.45' => ['x500UniqueIdentifier'], - '2.5.4.46' => ['dnQualifier'], - '2.5.4.47' => ['enhancedSearchGuide'], - '2.5.4.48' => ['protocolInformation'], - '2.5.4.49' => ['distinguishedName'], - '2.5.4.50' => ['uniqueMember'], - '2.5.4.51' => ['houseIdentifier'], - '2.5.4.52' => ['supportedAlgorithms'], - '2.5.4.53' => ['deltaRevocationList'], - '2.5.4.54' => ['dmdName'], - '2.5.4.65' => ['pseudonym'], - '2.5.18.1' => ['createTimestamp'], - '2.5.18.2' => ['modifyTimestamp'], - '2.5.18.3' => ['creatorsName'], - '2.5.18.4' => ['modifiersName'], - '2.5.18.5' => ['administrativeRole'], - '2.5.18.6' => ['subtreeSpecification'], - '2.5.18.9' => ['hasSubordinates'], - '2.5.18.10' => ['subschemaSubentry'], - '2.5.21.1' => ['dITStructureRules'], - '2.5.21.2' => ['dITContentRules'], - '2.5.21.4' => ['matchingRules'], - '2.5.21.5' => ['attributeTypes'], - '2.5.21.6' => ['objectClasses'], - '2.5.21.7' => ['nameForms'], - '2.5.21.8' => ['matchingRuleUse'], - '2.5.21.9' => ['structuralObjectClass'], - '2.16.840.1.113730.3.1.1' => ['carLicense'], - '2.16.840.1.113730.3.1.2' => ['departmentNumber'], - '2.16.840.1.113730.3.1.3' => ['employeeNumber'], - '2.16.840.1.113730.3.1.4' => ['employeeType'], - '2.16.840.1.113730.3.1.34' => ['ref'], - '2.16.840.1.113730.3.1.39' => ['preferredLanguage'], - '2.16.840.1.113730.3.1.40' => ['userSMIMECertificate'], - '2.16.840.1.113730.3.1.216' => ['userPKCS12'], - '2.16.840.1.113730.3.1.241' => ['displayName'], - ]; - - /** - * OID of the attribute. - * - * @var string - */ - protected $_oid; - - /** - * Constructor. - * - * @param string $oid OID in dotted format - */ - public function __construct(string $oid) - { - $this->_oid = $oid; - } - - /** - * Initialize from ASN.1. - * - * @param ObjectIdentifier $oi - * - * @return self - */ - public static function fromASN1(ObjectIdentifier $oi): self - { - return new self($oi->oid()); - } - - /** - * Initialize from attribute name. - * - * @param string $name - * - * @return self - */ - public static function fromName(string $name): self - { - $oid = self::attrNameToOID($name); - return new self($oid); - } - - /** - * Get OID of the attribute. - * - * @return string OID in dotted format - */ - public function oid(): string - { - return $this->_oid; - } - - /** - * Get name of the attribute. - * - * @return string - */ - public function typeName(): string - { - if (array_key_exists($this->_oid, self::MAP_OID_TO_NAME)) { - return self::MAP_OID_TO_NAME[$this->_oid][0]; - } - return $this->_oid; - } - - /** - * Generate ASN.1 element. - * - * @return ObjectIdentifier - */ - public function toASN1(): ObjectIdentifier - { - return new ObjectIdentifier($this->_oid); - } - - /** - * Convert attribute name to OID. - * - * @param string $name Primary attribute name or an alias - * - * @throws \OutOfBoundsException - * - * @return string OID in dotted format - */ - public static function attrNameToOID(string $name): string - { - // if already in OID form - if (preg_match('/^[0-9]+(?:\.[0-9]+)*$/', $name)) { - return $name; - } - $map = self::_oidReverseMap(); - $k = strtolower($name); - if (!isset($map[$k])) { - throw new \OutOfBoundsException("No OID for {$name}."); - } - return $map[$k]; - } - - /** - * Get ASN.1 string for given attribute type. - * - * @param string $oid Attribute OID - * @param string $str String - * - * @throws \LogicException - * - * @return StringType - */ - public static function asn1StringForType(string $oid, string $str): StringType - { - if (!array_key_exists($oid, self::MAP_ATTR_TO_STR_TYPE)) { - return new UTF8String($str); - } - switch (self::MAP_ATTR_TO_STR_TYPE[$oid]) { - case Element::TYPE_PRINTABLE_STRING: - return new PrintableString($str); - // @codeCoverageIgnoreStart - default: - // only reachable during development - throw new \LogicException(); - } - // @codeCoverageIgnoreEnd - } - - /** - * Get name to OID lookup map. - * - * @return array - */ - private static function _oidReverseMap(): array - { - static $map; - if (!isset($map)) { - $map = []; - // for each attribute type - foreach (self::MAP_OID_TO_NAME as $oid => $names) { - // for primary name and aliases - foreach ($names as $name) { - $map[strtolower($name)] = $oid; - } - } - } - return $map; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php deleted file mode 100644 index 6806d4a..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeTypeAndValue.php +++ /dev/null @@ -1,128 +0,0 @@ -_type = $type; - $this->_value = $value; - } - - /** - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Initialize from ASN.1. - * - * @param Sequence $seq - * - * @return self - */ - public static function fromASN1(Sequence $seq): self - { - $type = AttributeType::fromASN1($seq->at(0)->asObjectIdentifier()); - $value = AttributeValue::fromASN1ByOID($type->oid(), $seq->at(1)); - return new self($type, $value); - } - - /** - * Convenience method to initialize from attribute value. - * - * @param AttributeValue $value Attribute value - * - * @return self - */ - public static function fromAttributeValue(AttributeValue $value): self - { - return new self(new AttributeType($value->oid()), $value); - } - - /** - * Get attribute value. - * - * @return AttributeValue - */ - public function value(): AttributeValue - { - return $this->_value; - } - - /** - * Generate ASN.1 structure. - * - * @return Sequence - */ - public function toASN1(): Sequence - { - return new Sequence($this->_type->toASN1(), $this->_value->toASN1()); - } - - /** - * Get attributeTypeAndValue string conforming to RFC 2253. - * - * @see https://tools.ietf.org/html/rfc2253#section-2.3 - * - * @return string - */ - public function toString(): string - { - return $this->_type->typeName() . '=' . $this->_value->rfc2253String(); - } - - /** - * Check whether attribute is semantically equal to other. - * - * @param AttributeTypeAndValue $other Object to compare to - * - * @return bool - */ - public function equals(AttributeTypeAndValue $other): bool - { - // check that attribute types match - if ($this->oid() !== $other->oid()) { - return false; - } - $matcher = $this->_value->equalityMatchingRule(); - $result = $matcher->compare($this->_value->stringValue(), - $other->_value->stringValue()); - // match - if ($result) { - return true; - } - // no match or Undefined - return false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php deleted file mode 100644 index 89f061d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/AttributeValue.php +++ /dev/null @@ -1,174 +0,0 @@ - CommonNameValue::class, - AttributeType::OID_SURNAME => SurnameValue::class, - AttributeType::OID_SERIAL_NUMBER => SerialNumberValue::class, - AttributeType::OID_COUNTRY_NAME => CountryNameValue::class, - AttributeType::OID_LOCALITY_NAME => LocalityNameValue::class, - AttributeType::OID_STATE_OR_PROVINCE_NAME => StateOrProvinceNameValue::class, - AttributeType::OID_ORGANIZATION_NAME => OrganizationNameValue::class, - AttributeType::OID_ORGANIZATIONAL_UNIT_NAME => OrganizationalUnitNameValue::class, - AttributeType::OID_TITLE => TitleValue::class, - AttributeType::OID_DESCRIPTION => DescriptionValue::class, - AttributeType::OID_NAME => NameValue::class, - AttributeType::OID_GIVEN_NAME => GivenNameValue::class, - AttributeType::OID_PSEUDONYM => PseudonymValue::class, - ]; - - /** - * OID of the attribute type. - * - * @var string - */ - protected $_oid; - - /** - * Get attribute value as an UTF-8 encoded string. - * - * @return string - */ - public function __toString() - { - return $this->_transcodedString(); - } - - /** - * Generate ASN.1 element. - * - * @return Element - */ - abstract public function toASN1(): Element; - - /** - * Get attribute value as a string. - * - * @return string - */ - abstract public function stringValue(): string; - - /** - * Get matching rule for equality comparison. - * - * @return MatchingRule - */ - abstract public function equalityMatchingRule(): MatchingRule; - - /** - * Get attribute value as a string conforming to RFC 2253. - * - * @see https://tools.ietf.org/html/rfc2253#section-2.4 - * - * @return string - */ - abstract public function rfc2253String(): string; - - /** - * Initialize from ASN.1. - * - * @param UnspecifiedType $el - * - * @return self - */ - public static function fromASN1(UnspecifiedType $el): AttributeValue - { - throw new \BadMethodCallException( - 'ASN.1 parsing must be implemented in a concrete class.'); - } - - /** - * Initialize from ASN.1 with given OID hint. - * - * @param string $oid Attribute's OID - * @param UnspecifiedType $el - * - * @return self - */ - public static function fromASN1ByOID(string $oid, UnspecifiedType $el): self - { - if (!array_key_exists($oid, self::MAP_OID_TO_CLASS)) { - return new UnknownAttributeValue($oid, $el->asElement()); - } - $cls = self::MAP_OID_TO_CLASS[$oid]; - return $cls::fromASN1($el); - } - - /** - * Initialize from another AttributeValue. - * - * This method is generally used to cast UnknownAttributeValue to - * specific object when class is declared outside this package. - * - * @param self $obj Instance of AttributeValue - * - * @return self - */ - public static function fromSelf(self $obj): self - { - return static::fromASN1($obj->toASN1()->asUnspecified()); - } - - /** - * Get attribute type's OID. - * - * @return string - */ - public function oid(): string - { - return $this->_oid; - } - - /** - * Get Attribute object with this as a single value. - * - * @return Attribute - */ - public function toAttribute(): Attribute - { - return Attribute::fromAttributeValues($this); - } - - /** - * Get AttributeTypeAndValue object with this as a value. - * - * @return AttributeTypeAndValue - */ - public function toAttributeTypeAndValue(): AttributeTypeAndValue - { - return AttributeTypeAndValue::fromAttributeValue($this); - } - - /** - * Get attribute value as an UTF-8 string conforming to RFC 4518. - * - * @see https://tools.ietf.org/html/rfc4518#section-2.1 - * - * @return string - */ - abstract protected function _transcodedString(): string; -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php deleted file mode 100644 index 924aa52..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CommonNameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_COMMON_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php deleted file mode 100644 index 4d4f3b1..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/CountryNameValue.php +++ /dev/null @@ -1,27 +0,0 @@ -_oid = AttributeType::OID_COUNTRY_NAME; - parent::__construct($value); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php deleted file mode 100644 index 025b19e..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/DescriptionValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_DESCRIPTION; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php deleted file mode 100644 index 1d26453..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/DirectoryString.php +++ /dev/null @@ -1,179 +0,0 @@ - T61String::class, - self::PRINTABLE => PrintableString::class, - self::UNIVERSAL => UniversalString::class, - self::UTF8 => UTF8String::class, - self::BMP => BMPString::class, - ]; - - /** - * ASN.1 type tag for the chosen syntax. - * - * @var int - */ - protected $_stringTag; - - /** - * String value. - * - * @var string - */ - protected $_string; - - /** - * Constructor. - * - * @param string $value String value - * @param int $string_tag Syntax choice - */ - public function __construct(string $value, int $string_tag) - { - $this->_string = $value; - $this->_stringTag = $string_tag; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1(UnspecifiedType $el): AttributeValue - { - $tag = $el->tag(); - self::_tagToASN1Class($tag); - return new static($el->asString()->string(), $tag); - } - - /** - * {@inheritdoc} - */ - public function toASN1(): Element - { - $cls = self::_tagToASN1Class($this->_stringTag); - return new $cls($this->_string); - } - - /** - * {@inheritdoc} - */ - public function stringValue(): string - { - return $this->_string; - } - - /** - * {@inheritdoc} - */ - public function equalityMatchingRule(): MatchingRule - { - return new CaseIgnoreMatch($this->_stringTag); - } - - /** - * {@inheritdoc} - */ - public function rfc2253String(): string - { - // TeletexString is encoded as binary - if (self::TELETEX === $this->_stringTag) { - return $this->_transcodedString(); - } - return DNParser::escapeString($this->_transcodedString()); - } - - /** - * {@inheritdoc} - */ - protected function _transcodedString(): string - { - $step = new TranscodeStep($this->_stringTag); - return $step->apply($this->_string); - } - - /** - * Get ASN.1 class name for given DirectoryString type tag. - * - * @param int $tag - * - * @throws \UnexpectedValueException - * - * @return string - */ - private static function _tagToASN1Class(int $tag): string - { - if (!array_key_exists($tag, self::MAP_TAG_TO_CLASS)) { - throw new \UnexpectedValueException( - 'Type ' . Element::tagToName($tag) . - ' is not valid DirectoryString.'); - } - return self::MAP_TAG_TO_CLASS[$tag]; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php deleted file mode 100644 index f9c3e69..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/Feature/PrintableStringValue.php +++ /dev/null @@ -1,88 +0,0 @@ -_string = $value; - } - - /** - * {@inheritdoc} - * - * @return self - */ - public static function fromASN1(UnspecifiedType $el): AttributeValue - { - return new static($el->asPrintableString()->string()); - } - - /** - * {@inheritdoc} - */ - public function toASN1(): Element - { - return new PrintableString($this->_string); - } - - /** - * {@inheritdoc} - */ - public function stringValue(): string - { - return $this->_string; - } - - /** - * {@inheritdoc} - */ - public function equalityMatchingRule(): MatchingRule - { - // default to caseIgnoreMatch - return new CaseIgnoreMatch(Element::TYPE_PRINTABLE_STRING); - } - - /** - * {@inheritdoc} - */ - public function rfc2253String(): string - { - return DNParser::escapeString($this->_transcodedString()); - } - - /** - * {@inheritdoc} - */ - protected function _transcodedString(): string - { - // PrintableString maps directly to UTF-8 - return $this->_string; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php deleted file mode 100644 index 593f3b6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/GivenNameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_GIVEN_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php deleted file mode 100644 index a316b7c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/LocalityNameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_LOCALITY_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php deleted file mode 100644 index de6792d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/NameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php deleted file mode 100644 index 71fd859..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationNameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_ORGANIZATION_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php deleted file mode 100644 index a8743d5..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/OrganizationalUnitNameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_ORGANIZATIONAL_UNIT_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php deleted file mode 100644 index 674befb..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/PseudonymValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_PSEUDONYM; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php deleted file mode 100644 index 8ff3d65..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SerialNumberValue.php +++ /dev/null @@ -1,27 +0,0 @@ -_oid = AttributeType::OID_SERIAL_NUMBER; - parent::__construct($value); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php deleted file mode 100644 index 7759013..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/StateOrProvinceNameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_STATE_OR_PROVINCE_NAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php deleted file mode 100644 index 17b3eac..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/SurnameValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_SURNAME; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php deleted file mode 100644 index 9467035..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/TitleValue.php +++ /dev/null @@ -1,29 +0,0 @@ -_oid = AttributeType::OID_TITLE; - parent::__construct($value, $string_tag); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php deleted file mode 100644 index c8d0e49..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/AttributeValue/UnknownAttributeValue.php +++ /dev/null @@ -1,75 +0,0 @@ -_oid = $oid; - $this->_element = $el; - } - - /** - * {@inheritdoc} - */ - public function toASN1(): Element - { - return $this->_element; - } - - /** - * {@inheritdoc} - */ - public function stringValue(): string - { - // return DER encoding as a hexstring - return '#' . bin2hex($this->_element->toDER()); - } - - /** - * {@inheritdoc} - */ - public function equalityMatchingRule(): MatchingRule - { - return new BinaryMatch(); - } - - /** - * {@inheritdoc} - */ - public function rfc2253String(): string - { - return $this->stringValue(); - } - - /** - * {@inheritdoc} - */ - protected function _transcodedString(): string - { - return $this->stringValue(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php deleted file mode 100644 index 14114e6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/AttributeCollection.php +++ /dev/null @@ -1,221 +0,0 @@ -_attributes = $attribs; - } - - /** - * Initialize from attribute values. - * - * @param AttributeValue ...$values List of attribute values - * - * @return static - */ - public static function fromAttributeValues(AttributeValue ...$values): self - { - return new static(...array_map( - function (AttributeValue $value) { - return $value->toAttribute(); - }, $values)); - } - - /** - * Check whether attribute is present. - * - * @param string $name OID or attribute name - * - * @return bool - */ - public function has(string $name): bool - { - return null !== $this->_findFirst($name); - } - - /** - * Get first attribute by OID or attribute name. - * - * @param string $name OID or attribute name - * - * @throws \UnexpectedValueException if attribute is not present - * - * @return Attribute - */ - public function firstOf(string $name): Attribute - { - $attr = $this->_findFirst($name); - if (!$attr) { - throw new \UnexpectedValueException("No {$name} attribute."); - } - return $attr; - } - - /** - * Get all attributes of given name. - * - * @param string $name OID or attribute name - * - * @return Attribute[] - */ - public function allOf(string $name): array - { - $oid = AttributeType::attrNameToOID($name); - return array_values( - array_filter($this->_attributes, - function (Attribute $attr) use ($oid) { - return $attr->oid() === $oid; - })); - } - - /** - * Get all attributes. - * - * @return Attribute[] - */ - public function all(): array - { - return $this->_attributes; - } - - /** - * Get self with additional attributes added. - * - * @param Attribute ...$attribs List of attributes to add - * - * @return self - */ - public function withAdditional(Attribute ...$attribs): self - { - $obj = clone $this; - foreach ($attribs as $attr) { - $obj->_attributes[] = $attr; - } - return $obj; - } - - /** - * Get self with single unique attribute added. - * - * All previous attributes of the same type are removed. - * - * @param Attribute $attr Attribute to add - * - * @return self - */ - public function withUnique(Attribute $attr): self - { - $attribs = array_values( - array_filter($this->_attributes, - function (Attribute $a) use ($attr) { - return $a->oid() !== $attr->oid(); - })); - $attribs[] = $attr; - $obj = clone $this; - $obj->_attributes = $attribs; - return $obj; - } - - /** - * Get number of attributes. - * - * @see \Countable::count() - * - * @return int - */ - public function count(): int - { - return count($this->_attributes); - } - - /** - * Get iterator for attributes. - * - * @see \IteratorAggregate::getIterator() - * - * @return \ArrayIterator|Attribute[] - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator($this->_attributes); - } - - /** - * Find first attribute of given name or OID. - * - * @param string $name OID or attribute name - * - * @return null|Attribute - */ - protected function _findFirst(string $name): ?Attribute - { - $oid = AttributeType::attrNameToOID($name); - foreach ($this->_attributes as $attr) { - if ($attr->oid() === $oid) { - return $attr; - } - } - return null; - } - - /** - * Initialize from ASN.1 constructed element. - * - * @param Structure $struct ASN.1 structure - * - * @return static - */ - protected static function _fromASN1Structure(Structure $struct): self - { - return new static(...array_map( - function (UnspecifiedType $el) { - return static::_castAttributeValues( - Attribute::fromASN1($el->asSequence())); - }, $struct->elements())); - } - - /** - * Cast Attribute's AttributeValues to implementation specific objects. - * - * Overridden in derived classes. - * - * @param Attribute $attribute Attribute to cast - * - * @return Attribute - */ - protected static function _castAttributeValues(Attribute $attribute): Attribute - { - // pass through by default - return $attribute; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php deleted file mode 100644 index 9da1419..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SequenceOfAttributes.php +++ /dev/null @@ -1,44 +0,0 @@ -toASN1(); - }, $this->_attributes)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php deleted file mode 100644 index e38506c..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Collection/SetOfAttributes.php +++ /dev/null @@ -1,45 +0,0 @@ -toASN1(); - }, $this->_attributes)); - return $set->sortedSetOf(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php deleted file mode 100644 index 36c020d..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Feature/TypedAttribute.php +++ /dev/null @@ -1,40 +0,0 @@ -_type; - } - - /** - * Get OID of the attribute. - * - * @return string - */ - public function oid(): string - { - return $this->_type->oid(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php deleted file mode 100644 index f527c2a..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/Name.php +++ /dev/null @@ -1,227 +0,0 @@ -_rdns = $rdns; - } - - /** - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Initialize from ASN.1. - * - * @param Sequence $seq - * - * @return self - */ - public static function fromASN1(Sequence $seq): self - { - $rdns = array_map( - function (UnspecifiedType $el) { - return RDN::fromASN1($el->asSet()); - }, $seq->elements()); - return new self(...$rdns); - } - - /** - * Initialize from distinguished name string. - * - * @see https://tools.ietf.org/html/rfc1779 - * - * @param string $str - * - * @return self - */ - public static function fromString(string $str): self - { - $rdns = []; - foreach (DNParser::parseString($str) as $nameComponent) { - $attribs = []; - foreach ($nameComponent as [$name, $val]) { - $type = AttributeType::fromName($name); - // hexstrings are parsed to ASN.1 elements - if ($val instanceof Element) { - $el = $val; - } else { - $el = AttributeType::asn1StringForType($type->oid(), $val); - } - $value = AttributeValue::fromASN1ByOID($type->oid(), - $el->asUnspecified()); - $attribs[] = new AttributeTypeAndValue($type, $value); - } - $rdns[] = new RDN(...$attribs); - } - return new self(...$rdns); - } - - /** - * Generate ASN.1 structure. - * - * @return Sequence - */ - public function toASN1(): Sequence - { - $elements = array_map( - function (RDN $rdn) { - return $rdn->toASN1(); - }, $this->_rdns); - return new Sequence(...$elements); - } - - /** - * Get distinguised name string conforming to RFC 2253. - * - * @see https://tools.ietf.org/html/rfc2253#section-2.1 - * - * @return string - */ - public function toString(): string - { - $parts = array_map( - function (RDN $rdn) { - return $rdn->toString(); - }, array_reverse($this->_rdns)); - return implode(',', $parts); - } - - /** - * Whether name is semantically equal to other. - * - * Comparison conforms to RFC 4518 string preparation algorithm. - * - * @see https://tools.ietf.org/html/rfc4518 - * - * @param Name $other Object to compare to - * - * @return bool - */ - public function equals(Name $other): bool - { - // if RDN count doesn't match - if (count($this) !== count($other)) { - return false; - } - for ($i = count($this) - 1; $i >= 0; --$i) { - $rdn1 = $this->_rdns[$i]; - $rdn2 = $other->_rdns[$i]; - if (!$rdn1->equals($rdn2)) { - return false; - } - } - return true; - } - - /** - * Get all RDN objects. - * - * @return RDN[] - */ - public function all(): array - { - return $this->_rdns; - } - - /** - * Get the first AttributeValue of given type. - * - * Relative name components shall be traversed in encoding order, which is - * reversed in regards to the string representation. - * Multi-valued RDN with multiple attributes of the requested type is - * ambiguous and shall throw an exception. - * - * @param string $name Attribute OID or name - * - * @throws \RuntimeException If attribute cannot be resolved - * - * @return AttributeValue - */ - public function firstValueOf(string $name): AttributeValue - { - $oid = AttributeType::attrNameToOID($name); - foreach ($this->_rdns as $rdn) { - $tvs = $rdn->allOf($oid); - if (count($tvs) > 1) { - throw new \RangeException("RDN with multiple {$name} attributes."); - } - if (1 === count($tvs)) { - return $tvs[0]->value(); - } - } - throw new \RangeException("Attribute {$name} not found."); - } - - /** - * @see \Countable::count() - * - * @return int - */ - public function count(): int - { - return count($this->_rdns); - } - - /** - * Get the number of attributes of given type. - * - * @param string $name Attribute OID or name - * - * @return int - */ - public function countOfType(string $name): int - { - $oid = AttributeType::attrNameToOID($name); - return (int) array_sum( - array_map( - function (RDN $rdn) use ($oid): int { - return count($rdn->allOf($oid)); - }, $this->_rdns)); - } - - /** - * @see \IteratorAggregate::getIterator() - * - * @return \ArrayIterator - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator($this->_rdns); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php deleted file mode 100644 index 2a8b099..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/ASN1/RDN.php +++ /dev/null @@ -1,187 +0,0 @@ -_attribs = $attribs; - } - - /** - * @return string - */ - public function __toString() - { - return $this->toString(); - } - - /** - * Convenience method to initialize RDN from AttributeValue objects. - * - * @param AttributeValue ...$values One or more attributes - * - * @return self - */ - public static function fromAttributeValues(AttributeValue ...$values): self - { - $attribs = array_map( - function (AttributeValue $value) { - return new AttributeTypeAndValue( - new AttributeType($value->oid()), $value); - }, $values); - return new self(...$attribs); - } - - /** - * Initialize from ASN.1. - * - * @param Set $set - * - * @return self - */ - public static function fromASN1(Set $set): self - { - $attribs = array_map( - function (UnspecifiedType $el) { - return AttributeTypeAndValue::fromASN1($el->asSequence()); - }, $set->elements()); - return new self(...$attribs); - } - - /** - * Generate ASN.1 structure. - * - * @return Set - */ - public function toASN1(): Set - { - $elements = array_map( - function (AttributeTypeAndValue $tv) { - return $tv->toASN1(); - }, $this->_attribs); - $set = new Set(...$elements); - return $set->sortedSetOf(); - } - - /** - * Get name-component string conforming to RFC 2253. - * - * @see https://tools.ietf.org/html/rfc2253#section-2.2 - * - * @return string - */ - public function toString(): string - { - $parts = array_map( - function (AttributeTypeAndValue $tv) { - return $tv->toString(); - }, $this->_attribs); - return implode('+', $parts); - } - - /** - * Check whether RDN is semantically equal to other. - * - * @param RDN $other Object to compare to - * - * @return bool - */ - public function equals(RDN $other): bool - { - // if attribute count doesn't match - if (count($this) !== count($other)) { - return false; - } - $attribs1 = $this->_attribs; - $attribs2 = $other->_attribs; - // if there's multiple attributes, sort using SET OF rules - if (count($attribs1) > 1) { - $attribs1 = self::fromASN1($this->toASN1())->_attribs; - $attribs2 = self::fromASN1($other->toASN1())->_attribs; - } - for ($i = count($attribs1) - 1; $i >= 0; --$i) { - $tv1 = $attribs1[$i]; - $tv2 = $attribs2[$i]; - if (!$tv1->equals($tv2)) { - return false; - } - } - return true; - } - - /** - * Get all AttributeTypeAndValue objects. - * - * @return AttributeTypeAndValue[] - */ - public function all(): array - { - return $this->_attribs; - } - - /** - * Get all AttributeTypeAndValue objects of the given attribute type. - * - * @param string $name Attribute OID or name - * - * @return AttributeTypeAndValue[] - */ - public function allOf(string $name): array - { - $oid = AttributeType::attrNameToOID($name); - $attribs = array_filter($this->_attribs, - function (AttributeTypeAndValue $tv) use ($oid) { - return $tv->oid() === $oid; - }); - return array_values($attribs); - } - - /** - * @see \Countable::count() - * - * @return int - */ - public function count(): int - { - return count($this->_attribs); - } - - /** - * @see \IteratorAggregate::getIterator() - * - * @return \ArrayIterator - */ - public function getIterator(): \ArrayIterator - { - return new \ArrayIterator($this->_attribs); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php deleted file mode 100644 index 32b3228..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/DN/DNParser.php +++ /dev/null @@ -1,428 +0,0 @@ -#;'; - - /** - * DN string. - * - * @var string - */ - private $_dn; - - /** - * DN string length. - * - * @var int - */ - private $_len; - - /** - * Constructor. - * - * @param string $dn Distinguised name - */ - protected function __construct(string $dn) - { - $this->_dn = $dn; - $this->_len = strlen($dn); - } - - /** - * Parse distinguished name string to name-components. - * - * @param string $dn - * - * @return array - */ - public static function parseString(string $dn): array - { - $parser = new self($dn); - return $parser->parse(); - } - - /** - * Escape a AttributeValue string conforming to RFC 2253. - * - * @see https://tools.ietf.org/html/rfc2253#section-2.4 - * - * @param string $str - * - * @return string - */ - public static function escapeString(string $str): string - { - // one of the characters ",", "+", """, "\", "<", ">" or ";" - $str = preg_replace('/([,\+"\\\<\>;])/u', '\\\\$1', $str); - // a space character occurring at the end of the string - $str = preg_replace('/( )$/u', '\\\\$1', $str); - // a space or "#" character occurring at the beginning of the string - $str = preg_replace('/^([ #])/u', '\\\\$1', $str); - // implementation specific special characters - $str = preg_replace_callback('/([\pC])/u', - function ($m) { - $octets = str_split(bin2hex($m[1]), 2); - return implode('', - array_map( - function ($octet) { - return '\\' . strtoupper($octet); - }, $octets)); - }, $str); - return $str; - } - - /** - * Parse DN to name-components. - * - * @throws \RuntimeException - * - * @return array - */ - protected function parse(): array - { - $offset = 0; - $name = $this->_parseName($offset); - if ($offset < $this->_len) { - $remains = substr($this->_dn, $offset); - throw new \UnexpectedValueException( - 'Parser finished before the end of string' . - ", remaining: '{$remains}'."); - } - return $name; - } - - /** - * Parse 'name'. - * - * name-component *("," name-component) - * - * @param int $offset - * - * @return array Array of name-components - */ - private function _parseName(int &$offset): array - { - $idx = $offset; - $names = []; - while ($idx < $this->_len) { - $names[] = $this->_parseNameComponent($idx); - if ($idx >= $this->_len) { - break; - } - $this->_skipWs($idx); - if (',' != $this->_dn[$idx] && ';' != $this->_dn[$idx]) { - break; - } - ++$idx; - $this->_skipWs($idx); - } - $offset = $idx; - return array_reverse($names); - } - - /** - * Parse 'name-component'. - * - * attributeTypeAndValue *("+" attributeTypeAndValue) - * - * @param int $offset - * - * @return array Array of [type, value] tuples - */ - private function _parseNameComponent(int &$offset): array - { - $idx = $offset; - $tvpairs = []; - while ($idx < $this->_len) { - $tvpairs[] = $this->_parseAttrTypeAndValue($idx); - $this->_skipWs($idx); - if ($idx >= $this->_len || '+' != $this->_dn[$idx]) { - break; - } - ++$idx; - $this->_skipWs($idx); - } - $offset = $idx; - return $tvpairs; - } - - /** - * Parse 'attributeTypeAndValue'. - * - * attributeType "=" attributeValue - * - * @param int $offset - * - * @throws \UnexpectedValueException - * - * @return array A tuple of [type, value]. Value may be either a string or - * an Element, if it's encoded as hexstring. - */ - private function _parseAttrTypeAndValue(int &$offset): array - { - $idx = $offset; - $type = $this->_parseAttrType($idx); - $this->_skipWs($idx); - if ($idx >= $this->_len || '=' != $this->_dn[$idx++]) { - throw new \UnexpectedValueException('Invalid type and value pair.'); - } - $this->_skipWs($idx); - // hexstring - if ($idx < $this->_len && '#' == $this->_dn[$idx]) { - ++$idx; - $data = $this->_parseAttrHexValue($idx); - try { - $value = Element::fromDER($data); - } catch (DecodeException $e) { - throw new \UnexpectedValueException( - 'Invalid DER encoding from hexstring.', 0, $e); - } - } else { - $value = $this->_parseAttrStringValue($idx); - } - $offset = $idx; - return [$type, $value]; - } - - /** - * Parse 'attributeType'. - * - * (ALPHA 1*keychar) / oid - * - * @param int $offset - * - * @throws \UnexpectedValueException - * - * @return string - */ - private function _parseAttrType(int &$offset): string - { - $idx = $offset; - // dotted OID - $type = $this->_regexMatch('/^(?:oid\.)?([0-9]+(?:\.[0-9]+)*)/i', $idx); - if (null === $type) { - // name - $type = $this->_regexMatch('/^[a-z][a-z0-9\-]*/i', $idx); - if (null === $type) { - throw new \UnexpectedValueException('Invalid attribute type.'); - } - } - $offset = $idx; - return $type; - } - - /** - * Parse 'attributeValue' of string type. - * - * @param int $offset - * - * @throws \UnexpectedValueException - * - * @return string - */ - private function _parseAttrStringValue(int &$offset): string - { - $idx = $offset; - if ($idx >= $this->_len) { - return ''; - } - if ('"' == $this->_dn[$idx]) { // quoted string - $val = $this->_parseQuotedAttrString($idx); - } else { // string - $val = $this->_parseAttrString($idx); - } - $offset = $idx; - return $val; - } - - /** - * Parse plain 'attributeValue' string. - * - * @param int $offset - * - * @throws \UnexpectedValueException - * - * @return string - */ - private function _parseAttrString(int &$offset): string - { - $idx = $offset; - $val = ''; - $wsidx = null; - while ($idx < $this->_len) { - $c = $this->_dn[$idx]; - // pair (escape sequence) - if ('\\' == $c) { - ++$idx; - $val .= $this->_parsePairAfterSlash($idx); - $wsidx = null; - continue; - } - if ('"' == $c) { - throw new \UnexpectedValueException('Unexpected quotation.'); - } - if (false !== strpos(self::SPECIAL_CHARS, $c)) { - break; - } - // keep track of the first consecutive whitespace - if (' ' == $c) { - if (null === $wsidx) { - $wsidx = $idx; - } - } else { - $wsidx = null; - } - // stringchar - $val .= $c; - ++$idx; - } - // if there was non-escaped whitespace in the end of the value - if (null !== $wsidx) { - $val = substr($val, 0, -($idx - $wsidx)); - } - $offset = $idx; - return $val; - } - - /** - * Parse quoted 'attributeValue' string. - * - * @param int $offset Offset to starting quote - * - * @throws \UnexpectedValueException - * - * @return string - */ - private function _parseQuotedAttrString(int &$offset): string - { - $idx = $offset + 1; - $val = ''; - while ($idx < $this->_len) { - $c = $this->_dn[$idx]; - if ('\\' == $c) { // pair - ++$idx; - $val .= $this->_parsePairAfterSlash($idx); - continue; - } - if ('"' == $c) { - ++$idx; - break; - } - $val .= $c; - ++$idx; - } - $offset = $idx; - return $val; - } - - /** - * Parse 'attributeValue' of binary type. - * - * @param int $offset - * - * @throws \UnexpectedValueException - * - * @return string - */ - private function _parseAttrHexValue(int &$offset): string - { - $idx = $offset; - $hexstr = $this->_regexMatch('/^(?:[0-9a-f]{2})+/i', $idx); - if (null === $hexstr) { - throw new \UnexpectedValueException('Invalid hexstring.'); - } - $data = hex2bin($hexstr); - $offset = $idx; - return $data; - } - - /** - * Parse 'pair' after leading slash. - * - * @param int $offset - * - * @throws \UnexpectedValueException - * - * @return string - */ - private function _parsePairAfterSlash(int &$offset): string - { - $idx = $offset; - if ($idx >= $this->_len) { - throw new \UnexpectedValueException( - 'Unexpected end of escape sequence.'); - } - $c = $this->_dn[$idx++]; - // special | \ | " | SPACE - if (false !== strpos(self::SPECIAL_CHARS . '\\" ', $c)) { - $val = $c; - } else { // hexpair - if ($idx >= $this->_len) { - throw new \UnexpectedValueException('Unexpected end of hexpair.'); - } - $val = @hex2bin($c . $this->_dn[$idx++]); - if (false === $val) { - throw new \UnexpectedValueException('Invalid hexpair.'); - } - } - $offset = $idx; - return $val; - } - - /** - * Match DN to pattern and extract the last capture group. - * - * Updates offset to fully matched pattern. - * - * @param string $pattern - * @param int $offset - * - * @return null|string Null if pattern doesn't match - */ - private function _regexMatch(string $pattern, int &$offset): ?string - { - $idx = $offset; - if (!preg_match($pattern, substr($this->_dn, $idx), $match)) { - return null; - } - $idx += strlen($match[0]); - $offset = $idx; - return end($match); - } - - /** - * Skip consecutive spaces. - * - * @param int $offset - */ - private function _skipWs(int &$offset): void - { - $idx = $offset; - while ($idx < $this->_len) { - if (' ' != $this->_dn[$idx]) { - break; - } - ++$idx; - } - $offset = $idx; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php deleted file mode 100644 index 34af3c6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/BinaryMatch.php +++ /dev/null @@ -1,21 +0,0 @@ -withCaseFolding(true)); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php deleted file mode 100644 index 9997547..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/MatchingRule/MatchingRule.php +++ /dev/null @@ -1,24 +0,0 @@ -_prep = $preparer; - } - - /** - * {@inheritdoc} - */ - public function compare($assertion, $value): ?bool - { - $assertion = $this->_prep->prepare($assertion); - $value = $this->_prep->prepare($value); - return 0 === strcmp($assertion, $value); - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php deleted file mode 100644 index 9f65487..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/CheckBidiStep.php +++ /dev/null @@ -1,25 +0,0 @@ -_fold = $fold_case; - } - - /** - * @param string $string UTF-8 encoded string - * - * @return string - */ - public function apply(string $string): string - { - // @todo Implement character mappings - if ($this->_fold) { - $string = mb_convert_case($string, MB_CASE_LOWER, 'UTF-8'); - } - return $string; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php deleted file mode 100644 index fbca4fb..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/NormalizeStep.php +++ /dev/null @@ -1,24 +0,0 @@ -_steps = $steps; - } - - /** - * Get default instance for given string type. - * - * @param int $string_type ASN.1 string type tag. - * - * @return self - */ - public static function forStringType(int $string_type): self - { - $steps = [ - self::STEP_TRANSCODE => new TranscodeStep($string_type), - self::STEP_MAP => new MapStep(), - self::STEP_NORMALIZE => new NormalizeStep(), - self::STEP_PROHIBIT => new ProhibitStep(), - self::STEP_CHECK_BIDI => new CheckBidiStep(), - // @todo Vary by string type - self::STEP_INSIGNIFICANT_CHARS => new InsignificantNonSubstringSpaceStep(), - ]; - return new self($steps); - } - - /** - * Get self with case folding set. - * - * @param bool $fold True to apply case folding - * - * @return self - */ - public function withCaseFolding(bool $fold): self - { - $obj = clone $this; - $obj->_steps[self::STEP_MAP] = new MapStep($fold); - return $obj; - } - - /** - * Prepare string. - * - * @param string $string - * - * @return string - */ - public function prepare(string $string): string - { - foreach ($this->_steps as $step) { - $string = $step->apply($string); - } - return $string; - } -} diff --git a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php b/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php deleted file mode 100644 index 3d29fc6..0000000 --- a/utilities/signing_and_verification/php/vendor/sop/x501/lib/X501/StringPrep/TranscodeStep.php +++ /dev/null @@ -1,66 +0,0 @@ -_type = $type; - } - - /** - * @param string $string String to prepare - * - * @throws \LogicException If string type is not supported - * - * @return string UTF-8 encoded string - */ - public function apply(string $string): string - { - switch ($this->_type) { - // UTF-8 string as is - case Element::TYPE_UTF8_STRING: - return $string; - // PrintableString maps directly to UTF-8 - case Element::TYPE_PRINTABLE_STRING: - return $string; - // UCS-2 to UTF-8 - case Element::TYPE_BMP_STRING: - return mb_convert_encoding($string, 'UTF-8', 'UCS-2BE'); - // UCS-4 to UTF-8 - case Element::TYPE_UNIVERSAL_STRING: - return mb_convert_encoding($string, 'UTF-8', 'UCS-4BE'); - // TeletexString mapping is a local matter. - // We take a shortcut here and encode it as a hexstring. - case Element::TYPE_T61_STRING: - $el = new T61String($string); - return '#' . bin2hex($el->toDER()); - } - throw new \LogicException( - 'Unsupported string type ' . Element::tagToName($this->_type) . '.'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php deleted file mode 100644 index ba75a2c..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/Ctype.php +++ /dev/null @@ -1,232 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Ctype; - -/** - * Ctype implementation through regex. - * - * @internal - * - * @author Gert de Pagter - */ -final class Ctype -{ - /** - * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. - * - * @see https://php.net/ctype-alnum - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_alnum($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); - } - - /** - * Returns TRUE if every character in text is a letter, FALSE otherwise. - * - * @see https://php.net/ctype-alpha - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_alpha($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); - } - - /** - * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. - * - * @see https://php.net/ctype-cntrl - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_cntrl($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); - } - - /** - * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. - * - * @see https://php.net/ctype-digit - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_digit($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); - } - - /** - * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. - * - * @see https://php.net/ctype-graph - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_graph($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); - } - - /** - * Returns TRUE if every character in text is a lowercase letter. - * - * @see https://php.net/ctype-lower - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_lower($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); - } - - /** - * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. - * - * @see https://php.net/ctype-print - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_print($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); - } - - /** - * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. - * - * @see https://php.net/ctype-punct - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_punct($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); - } - - /** - * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. - * - * @see https://php.net/ctype-space - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_space($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); - } - - /** - * Returns TRUE if every character in text is an uppercase letter. - * - * @see https://php.net/ctype-upper - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_upper($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); - } - - /** - * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. - * - * @see https://php.net/ctype-xdigit - * - * @param mixed $text - * - * @return bool - */ - public static function ctype_xdigit($text) - { - $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); - - return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); - } - - /** - * Converts integers to their char versions according to normal ctype behaviour, if needed. - * - * If an integer between -128 and 255 inclusive is provided, - * it is interpreted as the ASCII value of a single character - * (negative values have 256 added in order to allow characters in the Extended ASCII range). - * Any other integer is interpreted as a string containing the decimal digits of the integer. - * - * @param mixed $int - * @param string $function - * - * @return mixed - */ - private static function convert_int_to_char_for_ctype($int, $function) - { - if (!\is_int($int)) { - return $int; - } - - if ($int < -128 || $int > 255) { - return (string) $int; - } - - if (\PHP_VERSION_ID >= 80100) { - @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); - } - - if ($int < 0) { - $int += 256; - } - - return \chr($int); - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE deleted file mode 100644 index 7536cae..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2018-present Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md deleted file mode 100644 index b144d03..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/README.md +++ /dev/null @@ -1,12 +0,0 @@ -Symfony Polyfill / Ctype -======================== - -This component provides `ctype_*` functions to users who run php versions without the ctype extension. - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php deleted file mode 100644 index d54524b..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap.php +++ /dev/null @@ -1,50 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Ctype as p; - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!function_exists('ctype_alnum')) { - function ctype_alnum($text) { return p\Ctype::ctype_alnum($text); } -} -if (!function_exists('ctype_alpha')) { - function ctype_alpha($text) { return p\Ctype::ctype_alpha($text); } -} -if (!function_exists('ctype_cntrl')) { - function ctype_cntrl($text) { return p\Ctype::ctype_cntrl($text); } -} -if (!function_exists('ctype_digit')) { - function ctype_digit($text) { return p\Ctype::ctype_digit($text); } -} -if (!function_exists('ctype_graph')) { - function ctype_graph($text) { return p\Ctype::ctype_graph($text); } -} -if (!function_exists('ctype_lower')) { - function ctype_lower($text) { return p\Ctype::ctype_lower($text); } -} -if (!function_exists('ctype_print')) { - function ctype_print($text) { return p\Ctype::ctype_print($text); } -} -if (!function_exists('ctype_punct')) { - function ctype_punct($text) { return p\Ctype::ctype_punct($text); } -} -if (!function_exists('ctype_space')) { - function ctype_space($text) { return p\Ctype::ctype_space($text); } -} -if (!function_exists('ctype_upper')) { - function ctype_upper($text) { return p\Ctype::ctype_upper($text); } -} -if (!function_exists('ctype_xdigit')) { - function ctype_xdigit($text) { return p\Ctype::ctype_xdigit($text); } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php deleted file mode 100644 index ab2f861..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/bootstrap80.php +++ /dev/null @@ -1,46 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Ctype as p; - -if (!function_exists('ctype_alnum')) { - function ctype_alnum(mixed $text): bool { return p\Ctype::ctype_alnum($text); } -} -if (!function_exists('ctype_alpha')) { - function ctype_alpha(mixed $text): bool { return p\Ctype::ctype_alpha($text); } -} -if (!function_exists('ctype_cntrl')) { - function ctype_cntrl(mixed $text): bool { return p\Ctype::ctype_cntrl($text); } -} -if (!function_exists('ctype_digit')) { - function ctype_digit(mixed $text): bool { return p\Ctype::ctype_digit($text); } -} -if (!function_exists('ctype_graph')) { - function ctype_graph(mixed $text): bool { return p\Ctype::ctype_graph($text); } -} -if (!function_exists('ctype_lower')) { - function ctype_lower(mixed $text): bool { return p\Ctype::ctype_lower($text); } -} -if (!function_exists('ctype_print')) { - function ctype_print(mixed $text): bool { return p\Ctype::ctype_print($text); } -} -if (!function_exists('ctype_punct')) { - function ctype_punct(mixed $text): bool { return p\Ctype::ctype_punct($text); } -} -if (!function_exists('ctype_space')) { - function ctype_space(mixed $text): bool { return p\Ctype::ctype_space($text); } -} -if (!function_exists('ctype_upper')) { - function ctype_upper(mixed $text): bool { return p\Ctype::ctype_upper($text); } -} -if (!function_exists('ctype_xdigit')) { - function ctype_xdigit(mixed $text): bool { return p\Ctype::ctype_xdigit($text); } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json b/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json deleted file mode 100644 index e5c978f..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-ctype/composer.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "symfony/polyfill-ctype", - "type": "library", - "description": "Symfony polyfill for ctype functions", - "keywords": ["polyfill", "compatibility", "portable", "ctype"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-ctype": "*" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Ctype\\": "" }, - "files": [ "bootstrap.php" ] - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE deleted file mode 100644 index 6e3afce..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2015-present Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php deleted file mode 100644 index 2e0b969..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Mbstring.php +++ /dev/null @@ -1,947 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Mbstring; - -/** - * Partial mbstring implementation in PHP, iconv based, UTF-8 centric. - * - * Implemented: - * - mb_chr - Returns a specific character from its Unicode code point - * - mb_convert_encoding - Convert character encoding - * - mb_convert_variables - Convert character code in variable(s) - * - mb_decode_mimeheader - Decode string in MIME header field - * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED - * - mb_decode_numericentity - Decode HTML numeric string reference to character - * - mb_encode_numericentity - Encode character to HTML numeric string reference - * - mb_convert_case - Perform case folding on a string - * - mb_detect_encoding - Detect character encoding - * - mb_get_info - Get internal settings of mbstring - * - mb_http_input - Detect HTTP input character encoding - * - mb_http_output - Set/Get HTTP output character encoding - * - mb_internal_encoding - Set/Get internal character encoding - * - mb_list_encodings - Returns an array of all supported encodings - * - mb_ord - Returns the Unicode code point of a character - * - mb_output_handler - Callback function converts character encoding in output buffer - * - mb_scrub - Replaces ill-formed byte sequences with substitute characters - * - mb_strlen - Get string length - * - mb_strpos - Find position of first occurrence of string in a string - * - mb_strrpos - Find position of last occurrence of a string in a string - * - mb_str_split - Convert a string to an array - * - mb_strtolower - Make a string lowercase - * - mb_strtoupper - Make a string uppercase - * - mb_substitute_character - Set/Get substitution character - * - mb_substr - Get part of string - * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive - * - mb_stristr - Finds first occurrence of a string within another, case insensitive - * - mb_strrchr - Finds the last occurrence of a character in a string within another - * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive - * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive - * - mb_strstr - Finds first occurrence of a string within another - * - mb_strwidth - Return width of string - * - mb_substr_count - Count the number of substring occurrences - * - * Not implemented: - * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) - * - mb_ereg_* - Regular expression with multibyte support - * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable - * - mb_preferred_mime_name - Get MIME charset string - * - mb_regex_encoding - Returns current encoding for multibyte regex as string - * - mb_regex_set_options - Set/Get the default options for mbregex functions - * - mb_send_mail - Send encoded mail - * - mb_split - Split multibyte string using regular expression - * - mb_strcut - Get part of string - * - mb_strimwidth - Get truncated string with specified width - * - * @author Nicolas Grekas - * - * @internal - */ -final class Mbstring -{ - public const MB_CASE_FOLD = \PHP_INT_MAX; - - private const SIMPLE_CASE_FOLD = [ - ['µ', 'ſ', "\xCD\x85", 'ς', "\xCF\x90", "\xCF\x91", "\xCF\x95", "\xCF\x96", "\xCF\xB0", "\xCF\xB1", "\xCF\xB5", "\xE1\xBA\x9B", "\xE1\xBE\xBE"], - ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "\xE1\xB9\xA1", 'ι'], - ]; - - private static $encodingList = ['ASCII', 'UTF-8']; - private static $language = 'neutral'; - private static $internalEncoding = 'UTF-8'; - - public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) - { - if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { - $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); - } else { - $fromEncoding = self::getEncoding($fromEncoding); - } - - $toEncoding = self::getEncoding($toEncoding); - - if ('BASE64' === $fromEncoding) { - $s = base64_decode($s); - $fromEncoding = $toEncoding; - } - - if ('BASE64' === $toEncoding) { - return base64_encode($s); - } - - if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) { - if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) { - $fromEncoding = 'Windows-1252'; - } - if ('UTF-8' !== $fromEncoding) { - $s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); - } - - return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); - } - - if ('HTML-ENTITIES' === $fromEncoding) { - $s = html_entity_decode($s, \ENT_COMPAT, 'UTF-8'); - $fromEncoding = 'UTF-8'; - } - - return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); - } - - public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) - { - $ok = true; - array_walk_recursive($vars, function (&$v) use (&$ok, $toEncoding, $fromEncoding) { - if (false === $v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding)) { - $ok = false; - } - }); - - return $ok ? $fromEncoding : false; - } - - public static function mb_decode_mimeheader($s) - { - return iconv_mime_decode($s, 2, self::$internalEncoding); - } - - public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) - { - trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING); - } - - public static function mb_decode_numericentity($s, $convmap, $encoding = null) - { - if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { - trigger_error('mb_decode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); - - return null; - } - - if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { - return false; - } - - if (null !== $encoding && !\is_scalar($encoding)) { - trigger_error('mb_decode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); - - return ''; // Instead of null (cf. mb_encode_numericentity). - } - - $s = (string) $s; - if ('' === $s) { - return ''; - } - - $encoding = self::getEncoding($encoding); - - if ('UTF-8' === $encoding) { - $encoding = null; - if (!preg_match('//u', $s)) { - $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); - } - } else { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); - } - - $cnt = floor(\count($convmap) / 4) * 4; - - for ($i = 0; $i < $cnt; $i += 4) { - // collector_decode_htmlnumericentity ignores $convmap[$i + 3] - $convmap[$i] += $convmap[$i + 2]; - $convmap[$i + 1] += $convmap[$i + 2]; - } - - $s = preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use ($cnt, $convmap) { - $c = isset($m[2]) ? (int) hexdec($m[2]) : $m[1]; - for ($i = 0; $i < $cnt; $i += 4) { - if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) { - return self::mb_chr($c - $convmap[$i + 2]); - } - } - - return $m[0]; - }, $s); - - if (null === $encoding) { - return $s; - } - - return iconv('UTF-8', $encoding.'//IGNORE', $s); - } - - public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) - { - if (null !== $s && !\is_scalar($s) && !(\is_object($s) && method_exists($s, '__toString'))) { - trigger_error('mb_encode_numericentity() expects parameter 1 to be string, '.\gettype($s).' given', \E_USER_WARNING); - - return null; - } - - if (!\is_array($convmap) || (80000 > \PHP_VERSION_ID && !$convmap)) { - return false; - } - - if (null !== $encoding && !\is_scalar($encoding)) { - trigger_error('mb_encode_numericentity() expects parameter 3 to be string, '.\gettype($s).' given', \E_USER_WARNING); - - return null; // Instead of '' (cf. mb_decode_numericentity). - } - - if (null !== $is_hex && !\is_scalar($is_hex)) { - trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, '.\gettype($s).' given', \E_USER_WARNING); - - return null; - } - - $s = (string) $s; - if ('' === $s) { - return ''; - } - - $encoding = self::getEncoding($encoding); - - if ('UTF-8' === $encoding) { - $encoding = null; - if (!preg_match('//u', $s)) { - $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); - } - } else { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); - } - - static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; - - $cnt = floor(\count($convmap) / 4) * 4; - $i = 0; - $len = \strlen($s); - $result = ''; - - while ($i < $len) { - $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; - $uchr = substr($s, $i, $ulen); - $i += $ulen; - $c = self::mb_ord($uchr); - - for ($j = 0; $j < $cnt; $j += 4) { - if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) { - $cOffset = ($c + $convmap[$j + 2]) & $convmap[$j + 3]; - $result .= $is_hex ? sprintf('&#x%X;', $cOffset) : '&#'.$cOffset.';'; - continue 2; - } - } - $result .= $uchr; - } - - if (null === $encoding) { - return $result; - } - - return iconv('UTF-8', $encoding.'//IGNORE', $result); - } - - public static function mb_convert_case($s, $mode, $encoding = null) - { - $s = (string) $s; - if ('' === $s) { - return ''; - } - - $encoding = self::getEncoding($encoding); - - if ('UTF-8' === $encoding) { - $encoding = null; - if (!preg_match('//u', $s)) { - $s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); - } - } else { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); - } - - if (\MB_CASE_TITLE == $mode) { - static $titleRegexp = null; - if (null === $titleRegexp) { - $titleRegexp = self::getData('titleCaseRegexp'); - } - $s = preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s); - } else { - if (\MB_CASE_UPPER == $mode) { - static $upper = null; - if (null === $upper) { - $upper = self::getData('upperCase'); - } - $map = $upper; - } else { - if (self::MB_CASE_FOLD === $mode) { - static $caseFolding = null; - if (null === $caseFolding) { - $caseFolding = self::getData('caseFolding'); - } - $s = strtr($s, $caseFolding); - } - - static $lower = null; - if (null === $lower) { - $lower = self::getData('lowerCase'); - } - $map = $lower; - } - - static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; - - $i = 0; - $len = \strlen($s); - - while ($i < $len) { - $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xF0"]; - $uchr = substr($s, $i, $ulen); - $i += $ulen; - - if (isset($map[$uchr])) { - $uchr = $map[$uchr]; - $nlen = \strlen($uchr); - - if ($nlen == $ulen) { - $nlen = $i; - do { - $s[--$nlen] = $uchr[--$ulen]; - } while ($ulen); - } else { - $s = substr_replace($s, $uchr, $i - $ulen, $ulen); - $len += $nlen - $ulen; - $i += $nlen - $ulen; - } - } - } - } - - if (null === $encoding) { - return $s; - } - - return iconv('UTF-8', $encoding.'//IGNORE', $s); - } - - public static function mb_internal_encoding($encoding = null) - { - if (null === $encoding) { - return self::$internalEncoding; - } - - $normalizedEncoding = self::getEncoding($encoding); - - if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { - self::$internalEncoding = $normalizedEncoding; - - return true; - } - - if (80000 > \PHP_VERSION_ID) { - return false; - } - - throw new \ValueError(sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding)); - } - - public static function mb_language($lang = null) - { - if (null === $lang) { - return self::$language; - } - - switch ($normalizedLang = strtolower($lang)) { - case 'uni': - case 'neutral': - self::$language = $normalizedLang; - - return true; - } - - if (80000 > \PHP_VERSION_ID) { - return false; - } - - throw new \ValueError(sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang)); - } - - public static function mb_list_encodings() - { - return ['UTF-8']; - } - - public static function mb_encoding_aliases($encoding) - { - switch (strtoupper($encoding)) { - case 'UTF8': - case 'UTF-8': - return ['utf8']; - } - - return false; - } - - public static function mb_check_encoding($var = null, $encoding = null) - { - if (PHP_VERSION_ID < 70200 && \is_array($var)) { - trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); - - return null; - } - - if (null === $encoding) { - if (null === $var) { - return false; - } - $encoding = self::$internalEncoding; - } - - if (!\is_array($var)) { - return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); - } - - foreach ($var as $key => $value) { - if (!self::mb_check_encoding($key, $encoding)) { - return false; - } - if (!self::mb_check_encoding($value, $encoding)) { - return false; - } - } - - return true; - - } - - public static function mb_detect_encoding($str, $encodingList = null, $strict = false) - { - if (null === $encodingList) { - $encodingList = self::$encodingList; - } else { - if (!\is_array($encodingList)) { - $encodingList = array_map('trim', explode(',', $encodingList)); - } - $encodingList = array_map('strtoupper', $encodingList); - } - - foreach ($encodingList as $enc) { - switch ($enc) { - case 'ASCII': - if (!preg_match('/[\x80-\xFF]/', $str)) { - return $enc; - } - break; - - case 'UTF8': - case 'UTF-8': - if (preg_match('//u', $str)) { - return 'UTF-8'; - } - break; - - default: - if (0 === strncmp($enc, 'ISO-8859-', 9)) { - return $enc; - } - } - } - - return false; - } - - public static function mb_detect_order($encodingList = null) - { - if (null === $encodingList) { - return self::$encodingList; - } - - if (!\is_array($encodingList)) { - $encodingList = array_map('trim', explode(',', $encodingList)); - } - $encodingList = array_map('strtoupper', $encodingList); - - foreach ($encodingList as $enc) { - switch ($enc) { - default: - if (strncmp($enc, 'ISO-8859-', 9)) { - return false; - } - // no break - case 'ASCII': - case 'UTF8': - case 'UTF-8': - } - } - - self::$encodingList = $encodingList; - - return true; - } - - public static function mb_strlen($s, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - return \strlen($s); - } - - return @iconv_strlen($s, $encoding); - } - - public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - return strpos($haystack, $needle, $offset); - } - - $needle = (string) $needle; - if ('' === $needle) { - if (80000 > \PHP_VERSION_ID) { - trigger_error(__METHOD__.': Empty delimiter', \E_USER_WARNING); - - return false; - } - - return 0; - } - - return iconv_strpos($haystack, $needle, $offset, $encoding); - } - - public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - return strrpos($haystack, $needle, $offset); - } - - if ($offset != (int) $offset) { - $offset = 0; - } elseif ($offset = (int) $offset) { - if ($offset < 0) { - if (0 > $offset += self::mb_strlen($needle)) { - $haystack = self::mb_substr($haystack, 0, $offset, $encoding); - } - $offset = 0; - } else { - $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding); - } - } - - $pos = '' !== $needle || 80000 > \PHP_VERSION_ID - ? iconv_strrpos($haystack, $needle, $encoding) - : self::mb_strlen($haystack, $encoding); - - return false !== $pos ? $offset + $pos : false; - } - - public static function mb_str_split($string, $split_length = 1, $encoding = null) - { - if (null !== $string && !\is_scalar($string) && !(\is_object($string) && method_exists($string, '__toString'))) { - trigger_error('mb_str_split() expects parameter 1 to be string, '.\gettype($string).' given', \E_USER_WARNING); - - return null; - } - - if (1 > $split_length = (int) $split_length) { - if (80000 > \PHP_VERSION_ID) { - trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING); - - return false; - } - - throw new \ValueError('Argument #2 ($length) must be greater than 0'); - } - - if (null === $encoding) { - $encoding = mb_internal_encoding(); - } - - if ('UTF-8' === $encoding = self::getEncoding($encoding)) { - $rx = '/('; - while (65535 < $split_length) { - $rx .= '.{65535}'; - $split_length -= 65535; - } - $rx .= '.{'.$split_length.'})/us'; - - return preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY); - } - - $result = []; - $length = mb_strlen($string, $encoding); - - for ($i = 0; $i < $length; $i += $split_length) { - $result[] = mb_substr($string, $i, $split_length, $encoding); - } - - return $result; - } - - public static function mb_strtolower($s, $encoding = null) - { - return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding); - } - - public static function mb_strtoupper($s, $encoding = null) - { - return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding); - } - - public static function mb_substitute_character($c = null) - { - if (null === $c) { - return 'none'; - } - if (0 === strcasecmp($c, 'none')) { - return true; - } - if (80000 > \PHP_VERSION_ID) { - return false; - } - if (\is_int($c) || 'long' === $c || 'entity' === $c) { - return false; - } - - throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint'); - } - - public static function mb_substr($s, $start, $length = null, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - return (string) substr($s, $start, null === $length ? 2147483647 : $length); - } - - if ($start < 0) { - $start = iconv_strlen($s, $encoding) + $start; - if ($start < 0) { - $start = 0; - } - } - - if (null === $length) { - $length = 2147483647; - } elseif ($length < 0) { - $length = iconv_strlen($s, $encoding) + $length - $start; - if ($length < 0) { - return ''; - } - } - - return (string) iconv_substr($s, $start, $length, $encoding); - } - - public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) - { - [$haystack, $needle] = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [ - self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), - self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding), - ]); - - return self::mb_strpos($haystack, $needle, $offset, $encoding); - } - - public static function mb_stristr($haystack, $needle, $part = false, $encoding = null) - { - $pos = self::mb_stripos($haystack, $needle, 0, $encoding); - - return self::getSubpart($pos, $part, $haystack, $encoding); - } - - public static function mb_strrchr($haystack, $needle, $part = false, $encoding = null) - { - $encoding = self::getEncoding($encoding); - if ('CP850' === $encoding || 'ASCII' === $encoding) { - $pos = strrpos($haystack, $needle); - } else { - $needle = self::mb_substr($needle, 0, 1, $encoding); - $pos = iconv_strrpos($haystack, $needle, $encoding); - } - - return self::getSubpart($pos, $part, $haystack, $encoding); - } - - public static function mb_strrichr($haystack, $needle, $part = false, $encoding = null) - { - $needle = self::mb_substr($needle, 0, 1, $encoding); - $pos = self::mb_strripos($haystack, $needle, $encoding); - - return self::getSubpart($pos, $part, $haystack, $encoding); - } - - public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) - { - $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding); - $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding); - - $haystack = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack); - $needle = str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle); - - return self::mb_strrpos($haystack, $needle, $offset, $encoding); - } - - public static function mb_strstr($haystack, $needle, $part = false, $encoding = null) - { - $pos = strpos($haystack, $needle); - if (false === $pos) { - return false; - } - if ($part) { - return substr($haystack, 0, $pos); - } - - return substr($haystack, $pos); - } - - public static function mb_get_info($type = 'all') - { - $info = [ - 'internal_encoding' => self::$internalEncoding, - 'http_output' => 'pass', - 'http_output_conv_mimetypes' => '^(text/|application/xhtml\+xml)', - 'func_overload' => 0, - 'func_overload_list' => 'no overload', - 'mail_charset' => 'UTF-8', - 'mail_header_encoding' => 'BASE64', - 'mail_body_encoding' => 'BASE64', - 'illegal_chars' => 0, - 'encoding_translation' => 'Off', - 'language' => self::$language, - 'detect_order' => self::$encodingList, - 'substitute_character' => 'none', - 'strict_detection' => 'Off', - ]; - - if ('all' === $type) { - return $info; - } - if (isset($info[$type])) { - return $info[$type]; - } - - return false; - } - - public static function mb_http_input($type = '') - { - return false; - } - - public static function mb_http_output($encoding = null) - { - return null !== $encoding ? 'pass' === $encoding : 'pass'; - } - - public static function mb_strwidth($s, $encoding = null) - { - $encoding = self::getEncoding($encoding); - - if ('UTF-8' !== $encoding) { - $s = iconv($encoding, 'UTF-8//IGNORE', $s); - } - - $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); - - return ($wide << 1) + iconv_strlen($s, 'UTF-8'); - } - - public static function mb_substr_count($haystack, $needle, $encoding = null) - { - return substr_count($haystack, $needle); - } - - public static function mb_output_handler($contents, $status) - { - return $contents; - } - - public static function mb_chr($code, $encoding = null) - { - if (0x80 > $code %= 0x200000) { - $s = \chr($code); - } elseif (0x800 > $code) { - $s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F); - } elseif (0x10000 > $code) { - $s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } else { - $s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F); - } - - if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { - $s = mb_convert_encoding($s, $encoding, 'UTF-8'); - } - - return $s; - } - - public static function mb_ord($s, $encoding = null) - { - if ('UTF-8' !== $encoding = self::getEncoding($encoding)) { - $s = mb_convert_encoding($s, 'UTF-8', $encoding); - } - - if (1 === \strlen($s)) { - return \ord($s); - } - - $code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0; - if (0xF0 <= $code) { - return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80; - } - if (0xE0 <= $code) { - return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80; - } - if (0xC0 <= $code) { - return (($code - 0xC0) << 6) + $s[2] - 0x80; - } - - return $code; - } - - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string - { - if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { - throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); - } - - if (null === $encoding) { - $encoding = self::mb_internal_encoding(); - } - - try { - $validEncoding = @self::mb_check_encoding('', $encoding); - } catch (\ValueError $e) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); - } - - // BC for PHP 7.3 and lower - if (!$validEncoding) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); - } - - if (self::mb_strlen($pad_string, $encoding) <= 0) { - throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string'); - } - - $paddingRequired = $length - self::mb_strlen($string, $encoding); - - if ($paddingRequired < 1) { - return $string; - } - - switch ($pad_type) { - case \STR_PAD_LEFT: - return self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding).$string; - case \STR_PAD_RIGHT: - return $string.self::mb_substr(str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding); - default: - $leftPaddingLength = floor($paddingRequired / 2); - $rightPaddingLength = $paddingRequired - $leftPaddingLength; - - return self::mb_substr(str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding).$string.self::mb_substr(str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding); - } - } - - private static function getSubpart($pos, $part, $haystack, $encoding) - { - if (false === $pos) { - return false; - } - if ($part) { - return self::mb_substr($haystack, 0, $pos, $encoding); - } - - return self::mb_substr($haystack, $pos, null, $encoding); - } - - private static function html_encoding_callback(array $m) - { - $i = 1; - $entities = ''; - $m = unpack('C*', htmlentities($m[0], \ENT_COMPAT, 'UTF-8')); - - while (isset($m[$i])) { - if (0x80 > $m[$i]) { - $entities .= \chr($m[$i++]); - continue; - } - if (0xF0 <= $m[$i]) { - $c = (($m[$i++] - 0xF0) << 18) + (($m[$i++] - 0x80) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; - } elseif (0xE0 <= $m[$i]) { - $c = (($m[$i++] - 0xE0) << 12) + (($m[$i++] - 0x80) << 6) + $m[$i++] - 0x80; - } else { - $c = (($m[$i++] - 0xC0) << 6) + $m[$i++] - 0x80; - } - - $entities .= '&#'.$c.';'; - } - - return $entities; - } - - private static function title_case(array $s) - { - return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8').self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8'); - } - - private static function getData($file) - { - if (file_exists($file = __DIR__.'/Resources/unidata/'.$file.'.php')) { - return require $file; - } - - return false; - } - - private static function getEncoding($encoding) - { - if (null === $encoding) { - return self::$internalEncoding; - } - - if ('UTF-8' === $encoding) { - return 'UTF-8'; - } - - $encoding = strtoupper($encoding); - - if ('8BIT' === $encoding || 'BINARY' === $encoding) { - return 'CP850'; - } - - if ('UTF8' === $encoding) { - return 'UTF-8'; - } - - return $encoding; - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md deleted file mode 100644 index 478b40d..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/README.md +++ /dev/null @@ -1,13 +0,0 @@ -Symfony Polyfill / Mbstring -=========================== - -This component provides a partial, native PHP implementation for the -[Mbstring](https://php.net/mbstring) extension. - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php deleted file mode 100644 index 512bba0..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/caseFolding.php +++ /dev/null @@ -1,119 +0,0 @@ - 'i̇', - 'µ' => 'μ', - 'ſ' => 's', - 'ͅ' => 'ι', - 'ς' => 'σ', - 'ϐ' => 'β', - 'ϑ' => 'θ', - 'ϕ' => 'φ', - 'ϖ' => 'π', - 'ϰ' => 'κ', - 'ϱ' => 'ρ', - 'ϵ' => 'ε', - 'ẛ' => 'ṡ', - 'ι' => 'ι', - 'ß' => 'ss', - 'ʼn' => 'ʼn', - 'ǰ' => 'ǰ', - 'ΐ' => 'ΐ', - 'ΰ' => 'ΰ', - 'և' => 'եւ', - 'ẖ' => 'ẖ', - 'ẗ' => 'ẗ', - 'ẘ' => 'ẘ', - 'ẙ' => 'ẙ', - 'ẚ' => 'aʾ', - 'ẞ' => 'ss', - 'ὐ' => 'ὐ', - 'ὒ' => 'ὒ', - 'ὔ' => 'ὔ', - 'ὖ' => 'ὖ', - 'ᾀ' => 'ἀι', - 'ᾁ' => 'ἁι', - 'ᾂ' => 'ἂι', - 'ᾃ' => 'ἃι', - 'ᾄ' => 'ἄι', - 'ᾅ' => 'ἅι', - 'ᾆ' => 'ἆι', - 'ᾇ' => 'ἇι', - 'ᾈ' => 'ἀι', - 'ᾉ' => 'ἁι', - 'ᾊ' => 'ἂι', - 'ᾋ' => 'ἃι', - 'ᾌ' => 'ἄι', - 'ᾍ' => 'ἅι', - 'ᾎ' => 'ἆι', - 'ᾏ' => 'ἇι', - 'ᾐ' => 'ἠι', - 'ᾑ' => 'ἡι', - 'ᾒ' => 'ἢι', - 'ᾓ' => 'ἣι', - 'ᾔ' => 'ἤι', - 'ᾕ' => 'ἥι', - 'ᾖ' => 'ἦι', - 'ᾗ' => 'ἧι', - 'ᾘ' => 'ἠι', - 'ᾙ' => 'ἡι', - 'ᾚ' => 'ἢι', - 'ᾛ' => 'ἣι', - 'ᾜ' => 'ἤι', - 'ᾝ' => 'ἥι', - 'ᾞ' => 'ἦι', - 'ᾟ' => 'ἧι', - 'ᾠ' => 'ὠι', - 'ᾡ' => 'ὡι', - 'ᾢ' => 'ὢι', - 'ᾣ' => 'ὣι', - 'ᾤ' => 'ὤι', - 'ᾥ' => 'ὥι', - 'ᾦ' => 'ὦι', - 'ᾧ' => 'ὧι', - 'ᾨ' => 'ὠι', - 'ᾩ' => 'ὡι', - 'ᾪ' => 'ὢι', - 'ᾫ' => 'ὣι', - 'ᾬ' => 'ὤι', - 'ᾭ' => 'ὥι', - 'ᾮ' => 'ὦι', - 'ᾯ' => 'ὧι', - 'ᾲ' => 'ὰι', - 'ᾳ' => 'αι', - 'ᾴ' => 'άι', - 'ᾶ' => 'ᾶ', - 'ᾷ' => 'ᾶι', - 'ᾼ' => 'αι', - 'ῂ' => 'ὴι', - 'ῃ' => 'ηι', - 'ῄ' => 'ήι', - 'ῆ' => 'ῆ', - 'ῇ' => 'ῆι', - 'ῌ' => 'ηι', - 'ῒ' => 'ῒ', - 'ῖ' => 'ῖ', - 'ῗ' => 'ῗ', - 'ῢ' => 'ῢ', - 'ῤ' => 'ῤ', - 'ῦ' => 'ῦ', - 'ῧ' => 'ῧ', - 'ῲ' => 'ὼι', - 'ῳ' => 'ωι', - 'ῴ' => 'ώι', - 'ῶ' => 'ῶ', - 'ῷ' => 'ῶι', - 'ῼ' => 'ωι', - 'ff' => 'ff', - 'fi' => 'fi', - 'fl' => 'fl', - 'ffi' => 'ffi', - 'ffl' => 'ffl', - 'ſt' => 'st', - 'st' => 'st', - 'ﬓ' => 'մն', - 'ﬔ' => 'մե', - 'ﬕ' => 'մի', - 'ﬖ' => 'վն', - 'ﬗ' => 'մխ', -]; diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php deleted file mode 100644 index fac60b0..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/lowerCase.php +++ /dev/null @@ -1,1397 +0,0 @@ - 'a', - 'B' => 'b', - 'C' => 'c', - 'D' => 'd', - 'E' => 'e', - 'F' => 'f', - 'G' => 'g', - 'H' => 'h', - 'I' => 'i', - 'J' => 'j', - 'K' => 'k', - 'L' => 'l', - 'M' => 'm', - 'N' => 'n', - 'O' => 'o', - 'P' => 'p', - 'Q' => 'q', - 'R' => 'r', - 'S' => 's', - 'T' => 't', - 'U' => 'u', - 'V' => 'v', - 'W' => 'w', - 'X' => 'x', - 'Y' => 'y', - 'Z' => 'z', - 'À' => 'à', - 'Á' => 'á', - 'Â' => 'â', - 'Ã' => 'ã', - 'Ä' => 'ä', - 'Å' => 'å', - 'Æ' => 'æ', - 'Ç' => 'ç', - 'È' => 'è', - 'É' => 'é', - 'Ê' => 'ê', - 'Ë' => 'ë', - 'Ì' => 'ì', - 'Í' => 'í', - 'Î' => 'î', - 'Ï' => 'ï', - 'Ð' => 'ð', - 'Ñ' => 'ñ', - 'Ò' => 'ò', - 'Ó' => 'ó', - 'Ô' => 'ô', - 'Õ' => 'õ', - 'Ö' => 'ö', - 'Ø' => 'ø', - 'Ù' => 'ù', - 'Ú' => 'ú', - 'Û' => 'û', - 'Ü' => 'ü', - 'Ý' => 'ý', - 'Þ' => 'þ', - 'Ā' => 'ā', - 'Ă' => 'ă', - 'Ą' => 'ą', - 'Ć' => 'ć', - 'Ĉ' => 'ĉ', - 'Ċ' => 'ċ', - 'Č' => 'č', - 'Ď' => 'ď', - 'Đ' => 'đ', - 'Ē' => 'ē', - 'Ĕ' => 'ĕ', - 'Ė' => 'ė', - 'Ę' => 'ę', - 'Ě' => 'ě', - 'Ĝ' => 'ĝ', - 'Ğ' => 'ğ', - 'Ġ' => 'ġ', - 'Ģ' => 'ģ', - 'Ĥ' => 'ĥ', - 'Ħ' => 'ħ', - 'Ĩ' => 'ĩ', - 'Ī' => 'ī', - 'Ĭ' => 'ĭ', - 'Į' => 'į', - 'İ' => 'i̇', - 'IJ' => 'ij', - 'Ĵ' => 'ĵ', - 'Ķ' => 'ķ', - 'Ĺ' => 'ĺ', - 'Ļ' => 'ļ', - 'Ľ' => 'ľ', - 'Ŀ' => 'ŀ', - 'Ł' => 'ł', - 'Ń' => 'ń', - 'Ņ' => 'ņ', - 'Ň' => 'ň', - 'Ŋ' => 'ŋ', - 'Ō' => 'ō', - 'Ŏ' => 'ŏ', - 'Ő' => 'ő', - 'Œ' => 'œ', - 'Ŕ' => 'ŕ', - 'Ŗ' => 'ŗ', - 'Ř' => 'ř', - 'Ś' => 'ś', - 'Ŝ' => 'ŝ', - 'Ş' => 'ş', - 'Š' => 'š', - 'Ţ' => 'ţ', - 'Ť' => 'ť', - 'Ŧ' => 'ŧ', - 'Ũ' => 'ũ', - 'Ū' => 'ū', - 'Ŭ' => 'ŭ', - 'Ů' => 'ů', - 'Ű' => 'ű', - 'Ų' => 'ų', - 'Ŵ' => 'ŵ', - 'Ŷ' => 'ŷ', - 'Ÿ' => 'ÿ', - 'Ź' => 'ź', - 'Ż' => 'ż', - 'Ž' => 'ž', - 'Ɓ' => 'ɓ', - 'Ƃ' => 'ƃ', - 'Ƅ' => 'ƅ', - 'Ɔ' => 'ɔ', - 'Ƈ' => 'ƈ', - 'Ɖ' => 'ɖ', - 'Ɗ' => 'ɗ', - 'Ƌ' => 'ƌ', - 'Ǝ' => 'ǝ', - 'Ə' => 'ə', - 'Ɛ' => 'ɛ', - 'Ƒ' => 'ƒ', - 'Ɠ' => 'ɠ', - 'Ɣ' => 'ɣ', - 'Ɩ' => 'ɩ', - 'Ɨ' => 'ɨ', - 'Ƙ' => 'ƙ', - 'Ɯ' => 'ɯ', - 'Ɲ' => 'ɲ', - 'Ɵ' => 'ɵ', - 'Ơ' => 'ơ', - 'Ƣ' => 'ƣ', - 'Ƥ' => 'ƥ', - 'Ʀ' => 'ʀ', - 'Ƨ' => 'ƨ', - 'Ʃ' => 'ʃ', - 'Ƭ' => 'ƭ', - 'Ʈ' => 'ʈ', - 'Ư' => 'ư', - 'Ʊ' => 'ʊ', - 'Ʋ' => 'ʋ', - 'Ƴ' => 'ƴ', - 'Ƶ' => 'ƶ', - 'Ʒ' => 'ʒ', - 'Ƹ' => 'ƹ', - 'Ƽ' => 'ƽ', - 'DŽ' => 'dž', - 'Dž' => 'dž', - 'LJ' => 'lj', - 'Lj' => 'lj', - 'NJ' => 'nj', - 'Nj' => 'nj', - 'Ǎ' => 'ǎ', - 'Ǐ' => 'ǐ', - 'Ǒ' => 'ǒ', - 'Ǔ' => 'ǔ', - 'Ǖ' => 'ǖ', - 'Ǘ' => 'ǘ', - 'Ǚ' => 'ǚ', - 'Ǜ' => 'ǜ', - 'Ǟ' => 'ǟ', - 'Ǡ' => 'ǡ', - 'Ǣ' => 'ǣ', - 'Ǥ' => 'ǥ', - 'Ǧ' => 'ǧ', - 'Ǩ' => 'ǩ', - 'Ǫ' => 'ǫ', - 'Ǭ' => 'ǭ', - 'Ǯ' => 'ǯ', - 'DZ' => 'dz', - 'Dz' => 'dz', - 'Ǵ' => 'ǵ', - 'Ƕ' => 'ƕ', - 'Ƿ' => 'ƿ', - 'Ǹ' => 'ǹ', - 'Ǻ' => 'ǻ', - 'Ǽ' => 'ǽ', - 'Ǿ' => 'ǿ', - 'Ȁ' => 'ȁ', - 'Ȃ' => 'ȃ', - 'Ȅ' => 'ȅ', - 'Ȇ' => 'ȇ', - 'Ȉ' => 'ȉ', - 'Ȋ' => 'ȋ', - 'Ȍ' => 'ȍ', - 'Ȏ' => 'ȏ', - 'Ȑ' => 'ȑ', - 'Ȓ' => 'ȓ', - 'Ȕ' => 'ȕ', - 'Ȗ' => 'ȗ', - 'Ș' => 'ș', - 'Ț' => 'ț', - 'Ȝ' => 'ȝ', - 'Ȟ' => 'ȟ', - 'Ƞ' => 'ƞ', - 'Ȣ' => 'ȣ', - 'Ȥ' => 'ȥ', - 'Ȧ' => 'ȧ', - 'Ȩ' => 'ȩ', - 'Ȫ' => 'ȫ', - 'Ȭ' => 'ȭ', - 'Ȯ' => 'ȯ', - 'Ȱ' => 'ȱ', - 'Ȳ' => 'ȳ', - 'Ⱥ' => 'ⱥ', - 'Ȼ' => 'ȼ', - 'Ƚ' => 'ƚ', - 'Ⱦ' => 'ⱦ', - 'Ɂ' => 'ɂ', - 'Ƀ' => 'ƀ', - 'Ʉ' => 'ʉ', - 'Ʌ' => 'ʌ', - 'Ɇ' => 'ɇ', - 'Ɉ' => 'ɉ', - 'Ɋ' => 'ɋ', - 'Ɍ' => 'ɍ', - 'Ɏ' => 'ɏ', - 'Ͱ' => 'ͱ', - 'Ͳ' => 'ͳ', - 'Ͷ' => 'ͷ', - 'Ϳ' => 'ϳ', - 'Ά' => 'ά', - 'Έ' => 'έ', - 'Ή' => 'ή', - 'Ί' => 'ί', - 'Ό' => 'ό', - 'Ύ' => 'ύ', - 'Ώ' => 'ώ', - 'Α' => 'α', - 'Β' => 'β', - 'Γ' => 'γ', - 'Δ' => 'δ', - 'Ε' => 'ε', - 'Ζ' => 'ζ', - 'Η' => 'η', - 'Θ' => 'θ', - 'Ι' => 'ι', - 'Κ' => 'κ', - 'Λ' => 'λ', - 'Μ' => 'μ', - 'Ν' => 'ν', - 'Ξ' => 'ξ', - 'Ο' => 'ο', - 'Π' => 'π', - 'Ρ' => 'ρ', - 'Σ' => 'σ', - 'Τ' => 'τ', - 'Υ' => 'υ', - 'Φ' => 'φ', - 'Χ' => 'χ', - 'Ψ' => 'ψ', - 'Ω' => 'ω', - 'Ϊ' => 'ϊ', - 'Ϋ' => 'ϋ', - 'Ϗ' => 'ϗ', - 'Ϙ' => 'ϙ', - 'Ϛ' => 'ϛ', - 'Ϝ' => 'ϝ', - 'Ϟ' => 'ϟ', - 'Ϡ' => 'ϡ', - 'Ϣ' => 'ϣ', - 'Ϥ' => 'ϥ', - 'Ϧ' => 'ϧ', - 'Ϩ' => 'ϩ', - 'Ϫ' => 'ϫ', - 'Ϭ' => 'ϭ', - 'Ϯ' => 'ϯ', - 'ϴ' => 'θ', - 'Ϸ' => 'ϸ', - 'Ϲ' => 'ϲ', - 'Ϻ' => 'ϻ', - 'Ͻ' => 'ͻ', - 'Ͼ' => 'ͼ', - 'Ͽ' => 'ͽ', - 'Ѐ' => 'ѐ', - 'Ё' => 'ё', - 'Ђ' => 'ђ', - 'Ѓ' => 'ѓ', - 'Є' => 'є', - 'Ѕ' => 'ѕ', - 'І' => 'і', - 'Ї' => 'ї', - 'Ј' => 'ј', - 'Љ' => 'љ', - 'Њ' => 'њ', - 'Ћ' => 'ћ', - 'Ќ' => 'ќ', - 'Ѝ' => 'ѝ', - 'Ў' => 'ў', - 'Џ' => 'џ', - 'А' => 'а', - 'Б' => 'б', - 'В' => 'в', - 'Г' => 'г', - 'Д' => 'д', - 'Е' => 'е', - 'Ж' => 'ж', - 'З' => 'з', - 'И' => 'и', - 'Й' => 'й', - 'К' => 'к', - 'Л' => 'л', - 'М' => 'м', - 'Н' => 'н', - 'О' => 'о', - 'П' => 'п', - 'Р' => 'р', - 'С' => 'с', - 'Т' => 'т', - 'У' => 'у', - 'Ф' => 'ф', - 'Х' => 'х', - 'Ц' => 'ц', - 'Ч' => 'ч', - 'Ш' => 'ш', - 'Щ' => 'щ', - 'Ъ' => 'ъ', - 'Ы' => 'ы', - 'Ь' => 'ь', - 'Э' => 'э', - 'Ю' => 'ю', - 'Я' => 'я', - 'Ѡ' => 'ѡ', - 'Ѣ' => 'ѣ', - 'Ѥ' => 'ѥ', - 'Ѧ' => 'ѧ', - 'Ѩ' => 'ѩ', - 'Ѫ' => 'ѫ', - 'Ѭ' => 'ѭ', - 'Ѯ' => 'ѯ', - 'Ѱ' => 'ѱ', - 'Ѳ' => 'ѳ', - 'Ѵ' => 'ѵ', - 'Ѷ' => 'ѷ', - 'Ѹ' => 'ѹ', - 'Ѻ' => 'ѻ', - 'Ѽ' => 'ѽ', - 'Ѿ' => 'ѿ', - 'Ҁ' => 'ҁ', - 'Ҋ' => 'ҋ', - 'Ҍ' => 'ҍ', - 'Ҏ' => 'ҏ', - 'Ґ' => 'ґ', - 'Ғ' => 'ғ', - 'Ҕ' => 'ҕ', - 'Җ' => 'җ', - 'Ҙ' => 'ҙ', - 'Қ' => 'қ', - 'Ҝ' => 'ҝ', - 'Ҟ' => 'ҟ', - 'Ҡ' => 'ҡ', - 'Ң' => 'ң', - 'Ҥ' => 'ҥ', - 'Ҧ' => 'ҧ', - 'Ҩ' => 'ҩ', - 'Ҫ' => 'ҫ', - 'Ҭ' => 'ҭ', - 'Ү' => 'ү', - 'Ұ' => 'ұ', - 'Ҳ' => 'ҳ', - 'Ҵ' => 'ҵ', - 'Ҷ' => 'ҷ', - 'Ҹ' => 'ҹ', - 'Һ' => 'һ', - 'Ҽ' => 'ҽ', - 'Ҿ' => 'ҿ', - 'Ӏ' => 'ӏ', - 'Ӂ' => 'ӂ', - 'Ӄ' => 'ӄ', - 'Ӆ' => 'ӆ', - 'Ӈ' => 'ӈ', - 'Ӊ' => 'ӊ', - 'Ӌ' => 'ӌ', - 'Ӎ' => 'ӎ', - 'Ӑ' => 'ӑ', - 'Ӓ' => 'ӓ', - 'Ӕ' => 'ӕ', - 'Ӗ' => 'ӗ', - 'Ә' => 'ә', - 'Ӛ' => 'ӛ', - 'Ӝ' => 'ӝ', - 'Ӟ' => 'ӟ', - 'Ӡ' => 'ӡ', - 'Ӣ' => 'ӣ', - 'Ӥ' => 'ӥ', - 'Ӧ' => 'ӧ', - 'Ө' => 'ө', - 'Ӫ' => 'ӫ', - 'Ӭ' => 'ӭ', - 'Ӯ' => 'ӯ', - 'Ӱ' => 'ӱ', - 'Ӳ' => 'ӳ', - 'Ӵ' => 'ӵ', - 'Ӷ' => 'ӷ', - 'Ӹ' => 'ӹ', - 'Ӻ' => 'ӻ', - 'Ӽ' => 'ӽ', - 'Ӿ' => 'ӿ', - 'Ԁ' => 'ԁ', - 'Ԃ' => 'ԃ', - 'Ԅ' => 'ԅ', - 'Ԇ' => 'ԇ', - 'Ԉ' => 'ԉ', - 'Ԋ' => 'ԋ', - 'Ԍ' => 'ԍ', - 'Ԏ' => 'ԏ', - 'Ԑ' => 'ԑ', - 'Ԓ' => 'ԓ', - 'Ԕ' => 'ԕ', - 'Ԗ' => 'ԗ', - 'Ԙ' => 'ԙ', - 'Ԛ' => 'ԛ', - 'Ԝ' => 'ԝ', - 'Ԟ' => 'ԟ', - 'Ԡ' => 'ԡ', - 'Ԣ' => 'ԣ', - 'Ԥ' => 'ԥ', - 'Ԧ' => 'ԧ', - 'Ԩ' => 'ԩ', - 'Ԫ' => 'ԫ', - 'Ԭ' => 'ԭ', - 'Ԯ' => 'ԯ', - 'Ա' => 'ա', - 'Բ' => 'բ', - 'Գ' => 'գ', - 'Դ' => 'դ', - 'Ե' => 'ե', - 'Զ' => 'զ', - 'Է' => 'է', - 'Ը' => 'ը', - 'Թ' => 'թ', - 'Ժ' => 'ժ', - 'Ի' => 'ի', - 'Լ' => 'լ', - 'Խ' => 'խ', - 'Ծ' => 'ծ', - 'Կ' => 'կ', - 'Հ' => 'հ', - 'Ձ' => 'ձ', - 'Ղ' => 'ղ', - 'Ճ' => 'ճ', - 'Մ' => 'մ', - 'Յ' => 'յ', - 'Ն' => 'ն', - 'Շ' => 'շ', - 'Ո' => 'ո', - 'Չ' => 'չ', - 'Պ' => 'պ', - 'Ջ' => 'ջ', - 'Ռ' => 'ռ', - 'Ս' => 'ս', - 'Վ' => 'վ', - 'Տ' => 'տ', - 'Ր' => 'ր', - 'Ց' => 'ց', - 'Ւ' => 'ւ', - 'Փ' => 'փ', - 'Ք' => 'ք', - 'Օ' => 'օ', - 'Ֆ' => 'ֆ', - 'Ⴀ' => 'ⴀ', - 'Ⴁ' => 'ⴁ', - 'Ⴂ' => 'ⴂ', - 'Ⴃ' => 'ⴃ', - 'Ⴄ' => 'ⴄ', - 'Ⴅ' => 'ⴅ', - 'Ⴆ' => 'ⴆ', - 'Ⴇ' => 'ⴇ', - 'Ⴈ' => 'ⴈ', - 'Ⴉ' => 'ⴉ', - 'Ⴊ' => 'ⴊ', - 'Ⴋ' => 'ⴋ', - 'Ⴌ' => 'ⴌ', - 'Ⴍ' => 'ⴍ', - 'Ⴎ' => 'ⴎ', - 'Ⴏ' => 'ⴏ', - 'Ⴐ' => 'ⴐ', - 'Ⴑ' => 'ⴑ', - 'Ⴒ' => 'ⴒ', - 'Ⴓ' => 'ⴓ', - 'Ⴔ' => 'ⴔ', - 'Ⴕ' => 'ⴕ', - 'Ⴖ' => 'ⴖ', - 'Ⴗ' => 'ⴗ', - 'Ⴘ' => 'ⴘ', - 'Ⴙ' => 'ⴙ', - 'Ⴚ' => 'ⴚ', - 'Ⴛ' => 'ⴛ', - 'Ⴜ' => 'ⴜ', - 'Ⴝ' => 'ⴝ', - 'Ⴞ' => 'ⴞ', - 'Ⴟ' => 'ⴟ', - 'Ⴠ' => 'ⴠ', - 'Ⴡ' => 'ⴡ', - 'Ⴢ' => 'ⴢ', - 'Ⴣ' => 'ⴣ', - 'Ⴤ' => 'ⴤ', - 'Ⴥ' => 'ⴥ', - 'Ⴧ' => 'ⴧ', - 'Ⴭ' => 'ⴭ', - 'Ꭰ' => 'ꭰ', - 'Ꭱ' => 'ꭱ', - 'Ꭲ' => 'ꭲ', - 'Ꭳ' => 'ꭳ', - 'Ꭴ' => 'ꭴ', - 'Ꭵ' => 'ꭵ', - 'Ꭶ' => 'ꭶ', - 'Ꭷ' => 'ꭷ', - 'Ꭸ' => 'ꭸ', - 'Ꭹ' => 'ꭹ', - 'Ꭺ' => 'ꭺ', - 'Ꭻ' => 'ꭻ', - 'Ꭼ' => 'ꭼ', - 'Ꭽ' => 'ꭽ', - 'Ꭾ' => 'ꭾ', - 'Ꭿ' => 'ꭿ', - 'Ꮀ' => 'ꮀ', - 'Ꮁ' => 'ꮁ', - 'Ꮂ' => 'ꮂ', - 'Ꮃ' => 'ꮃ', - 'Ꮄ' => 'ꮄ', - 'Ꮅ' => 'ꮅ', - 'Ꮆ' => 'ꮆ', - 'Ꮇ' => 'ꮇ', - 'Ꮈ' => 'ꮈ', - 'Ꮉ' => 'ꮉ', - 'Ꮊ' => 'ꮊ', - 'Ꮋ' => 'ꮋ', - 'Ꮌ' => 'ꮌ', - 'Ꮍ' => 'ꮍ', - 'Ꮎ' => 'ꮎ', - 'Ꮏ' => 'ꮏ', - 'Ꮐ' => 'ꮐ', - 'Ꮑ' => 'ꮑ', - 'Ꮒ' => 'ꮒ', - 'Ꮓ' => 'ꮓ', - 'Ꮔ' => 'ꮔ', - 'Ꮕ' => 'ꮕ', - 'Ꮖ' => 'ꮖ', - 'Ꮗ' => 'ꮗ', - 'Ꮘ' => 'ꮘ', - 'Ꮙ' => 'ꮙ', - 'Ꮚ' => 'ꮚ', - 'Ꮛ' => 'ꮛ', - 'Ꮜ' => 'ꮜ', - 'Ꮝ' => 'ꮝ', - 'Ꮞ' => 'ꮞ', - 'Ꮟ' => 'ꮟ', - 'Ꮠ' => 'ꮠ', - 'Ꮡ' => 'ꮡ', - 'Ꮢ' => 'ꮢ', - 'Ꮣ' => 'ꮣ', - 'Ꮤ' => 'ꮤ', - 'Ꮥ' => 'ꮥ', - 'Ꮦ' => 'ꮦ', - 'Ꮧ' => 'ꮧ', - 'Ꮨ' => 'ꮨ', - 'Ꮩ' => 'ꮩ', - 'Ꮪ' => 'ꮪ', - 'Ꮫ' => 'ꮫ', - 'Ꮬ' => 'ꮬ', - 'Ꮭ' => 'ꮭ', - 'Ꮮ' => 'ꮮ', - 'Ꮯ' => 'ꮯ', - 'Ꮰ' => 'ꮰ', - 'Ꮱ' => 'ꮱ', - 'Ꮲ' => 'ꮲ', - 'Ꮳ' => 'ꮳ', - 'Ꮴ' => 'ꮴ', - 'Ꮵ' => 'ꮵ', - 'Ꮶ' => 'ꮶ', - 'Ꮷ' => 'ꮷ', - 'Ꮸ' => 'ꮸ', - 'Ꮹ' => 'ꮹ', - 'Ꮺ' => 'ꮺ', - 'Ꮻ' => 'ꮻ', - 'Ꮼ' => 'ꮼ', - 'Ꮽ' => 'ꮽ', - 'Ꮾ' => 'ꮾ', - 'Ꮿ' => 'ꮿ', - 'Ᏸ' => 'ᏸ', - 'Ᏹ' => 'ᏹ', - 'Ᏺ' => 'ᏺ', - 'Ᏻ' => 'ᏻ', - 'Ᏼ' => 'ᏼ', - 'Ᏽ' => 'ᏽ', - 'Ა' => 'ა', - 'Ბ' => 'ბ', - 'Გ' => 'გ', - 'Დ' => 'დ', - 'Ე' => 'ე', - 'Ვ' => 'ვ', - 'Ზ' => 'ზ', - 'Თ' => 'თ', - 'Ი' => 'ი', - 'Კ' => 'კ', - 'Ლ' => 'ლ', - 'Მ' => 'მ', - 'Ნ' => 'ნ', - 'Ო' => 'ო', - 'Პ' => 'პ', - 'Ჟ' => 'ჟ', - 'Რ' => 'რ', - 'Ს' => 'ს', - 'Ტ' => 'ტ', - 'Უ' => 'უ', - 'Ფ' => 'ფ', - 'Ქ' => 'ქ', - 'Ღ' => 'ღ', - 'Ყ' => 'ყ', - 'Შ' => 'შ', - 'Ჩ' => 'ჩ', - 'Ც' => 'ც', - 'Ძ' => 'ძ', - 'Წ' => 'წ', - 'Ჭ' => 'ჭ', - 'Ხ' => 'ხ', - 'Ჯ' => 'ჯ', - 'Ჰ' => 'ჰ', - 'Ჱ' => 'ჱ', - 'Ჲ' => 'ჲ', - 'Ჳ' => 'ჳ', - 'Ჴ' => 'ჴ', - 'Ჵ' => 'ჵ', - 'Ჶ' => 'ჶ', - 'Ჷ' => 'ჷ', - 'Ჸ' => 'ჸ', - 'Ჹ' => 'ჹ', - 'Ჺ' => 'ჺ', - 'Ჽ' => 'ჽ', - 'Ჾ' => 'ჾ', - 'Ჿ' => 'ჿ', - 'Ḁ' => 'ḁ', - 'Ḃ' => 'ḃ', - 'Ḅ' => 'ḅ', - 'Ḇ' => 'ḇ', - 'Ḉ' => 'ḉ', - 'Ḋ' => 'ḋ', - 'Ḍ' => 'ḍ', - 'Ḏ' => 'ḏ', - 'Ḑ' => 'ḑ', - 'Ḓ' => 'ḓ', - 'Ḕ' => 'ḕ', - 'Ḗ' => 'ḗ', - 'Ḙ' => 'ḙ', - 'Ḛ' => 'ḛ', - 'Ḝ' => 'ḝ', - 'Ḟ' => 'ḟ', - 'Ḡ' => 'ḡ', - 'Ḣ' => 'ḣ', - 'Ḥ' => 'ḥ', - 'Ḧ' => 'ḧ', - 'Ḩ' => 'ḩ', - 'Ḫ' => 'ḫ', - 'Ḭ' => 'ḭ', - 'Ḯ' => 'ḯ', - 'Ḱ' => 'ḱ', - 'Ḳ' => 'ḳ', - 'Ḵ' => 'ḵ', - 'Ḷ' => 'ḷ', - 'Ḹ' => 'ḹ', - 'Ḻ' => 'ḻ', - 'Ḽ' => 'ḽ', - 'Ḿ' => 'ḿ', - 'Ṁ' => 'ṁ', - 'Ṃ' => 'ṃ', - 'Ṅ' => 'ṅ', - 'Ṇ' => 'ṇ', - 'Ṉ' => 'ṉ', - 'Ṋ' => 'ṋ', - 'Ṍ' => 'ṍ', - 'Ṏ' => 'ṏ', - 'Ṑ' => 'ṑ', - 'Ṓ' => 'ṓ', - 'Ṕ' => 'ṕ', - 'Ṗ' => 'ṗ', - 'Ṙ' => 'ṙ', - 'Ṛ' => 'ṛ', - 'Ṝ' => 'ṝ', - 'Ṟ' => 'ṟ', - 'Ṡ' => 'ṡ', - 'Ṣ' => 'ṣ', - 'Ṥ' => 'ṥ', - 'Ṧ' => 'ṧ', - 'Ṩ' => 'ṩ', - 'Ṫ' => 'ṫ', - 'Ṭ' => 'ṭ', - 'Ṯ' => 'ṯ', - 'Ṱ' => 'ṱ', - 'Ṳ' => 'ṳ', - 'Ṵ' => 'ṵ', - 'Ṷ' => 'ṷ', - 'Ṹ' => 'ṹ', - 'Ṻ' => 'ṻ', - 'Ṽ' => 'ṽ', - 'Ṿ' => 'ṿ', - 'Ẁ' => 'ẁ', - 'Ẃ' => 'ẃ', - 'Ẅ' => 'ẅ', - 'Ẇ' => 'ẇ', - 'Ẉ' => 'ẉ', - 'Ẋ' => 'ẋ', - 'Ẍ' => 'ẍ', - 'Ẏ' => 'ẏ', - 'Ẑ' => 'ẑ', - 'Ẓ' => 'ẓ', - 'Ẕ' => 'ẕ', - 'ẞ' => 'ß', - 'Ạ' => 'ạ', - 'Ả' => 'ả', - 'Ấ' => 'ấ', - 'Ầ' => 'ầ', - 'Ẩ' => 'ẩ', - 'Ẫ' => 'ẫ', - 'Ậ' => 'ậ', - 'Ắ' => 'ắ', - 'Ằ' => 'ằ', - 'Ẳ' => 'ẳ', - 'Ẵ' => 'ẵ', - 'Ặ' => 'ặ', - 'Ẹ' => 'ẹ', - 'Ẻ' => 'ẻ', - 'Ẽ' => 'ẽ', - 'Ế' => 'ế', - 'Ề' => 'ề', - 'Ể' => 'ể', - 'Ễ' => 'ễ', - 'Ệ' => 'ệ', - 'Ỉ' => 'ỉ', - 'Ị' => 'ị', - 'Ọ' => 'ọ', - 'Ỏ' => 'ỏ', - 'Ố' => 'ố', - 'Ồ' => 'ồ', - 'Ổ' => 'ổ', - 'Ỗ' => 'ỗ', - 'Ộ' => 'ộ', - 'Ớ' => 'ớ', - 'Ờ' => 'ờ', - 'Ở' => 'ở', - 'Ỡ' => 'ỡ', - 'Ợ' => 'ợ', - 'Ụ' => 'ụ', - 'Ủ' => 'ủ', - 'Ứ' => 'ứ', - 'Ừ' => 'ừ', - 'Ử' => 'ử', - 'Ữ' => 'ữ', - 'Ự' => 'ự', - 'Ỳ' => 'ỳ', - 'Ỵ' => 'ỵ', - 'Ỷ' => 'ỷ', - 'Ỹ' => 'ỹ', - 'Ỻ' => 'ỻ', - 'Ỽ' => 'ỽ', - 'Ỿ' => 'ỿ', - 'Ἀ' => 'ἀ', - 'Ἁ' => 'ἁ', - 'Ἂ' => 'ἂ', - 'Ἃ' => 'ἃ', - 'Ἄ' => 'ἄ', - 'Ἅ' => 'ἅ', - 'Ἆ' => 'ἆ', - 'Ἇ' => 'ἇ', - 'Ἐ' => 'ἐ', - 'Ἑ' => 'ἑ', - 'Ἒ' => 'ἒ', - 'Ἓ' => 'ἓ', - 'Ἔ' => 'ἔ', - 'Ἕ' => 'ἕ', - 'Ἠ' => 'ἠ', - 'Ἡ' => 'ἡ', - 'Ἢ' => 'ἢ', - 'Ἣ' => 'ἣ', - 'Ἤ' => 'ἤ', - 'Ἥ' => 'ἥ', - 'Ἦ' => 'ἦ', - 'Ἧ' => 'ἧ', - 'Ἰ' => 'ἰ', - 'Ἱ' => 'ἱ', - 'Ἲ' => 'ἲ', - 'Ἳ' => 'ἳ', - 'Ἴ' => 'ἴ', - 'Ἵ' => 'ἵ', - 'Ἶ' => 'ἶ', - 'Ἷ' => 'ἷ', - 'Ὀ' => 'ὀ', - 'Ὁ' => 'ὁ', - 'Ὂ' => 'ὂ', - 'Ὃ' => 'ὃ', - 'Ὄ' => 'ὄ', - 'Ὅ' => 'ὅ', - 'Ὑ' => 'ὑ', - 'Ὓ' => 'ὓ', - 'Ὕ' => 'ὕ', - 'Ὗ' => 'ὗ', - 'Ὠ' => 'ὠ', - 'Ὡ' => 'ὡ', - 'Ὢ' => 'ὢ', - 'Ὣ' => 'ὣ', - 'Ὤ' => 'ὤ', - 'Ὥ' => 'ὥ', - 'Ὦ' => 'ὦ', - 'Ὧ' => 'ὧ', - 'ᾈ' => 'ᾀ', - 'ᾉ' => 'ᾁ', - 'ᾊ' => 'ᾂ', - 'ᾋ' => 'ᾃ', - 'ᾌ' => 'ᾄ', - 'ᾍ' => 'ᾅ', - 'ᾎ' => 'ᾆ', - 'ᾏ' => 'ᾇ', - 'ᾘ' => 'ᾐ', - 'ᾙ' => 'ᾑ', - 'ᾚ' => 'ᾒ', - 'ᾛ' => 'ᾓ', - 'ᾜ' => 'ᾔ', - 'ᾝ' => 'ᾕ', - 'ᾞ' => 'ᾖ', - 'ᾟ' => 'ᾗ', - 'ᾨ' => 'ᾠ', - 'ᾩ' => 'ᾡ', - 'ᾪ' => 'ᾢ', - 'ᾫ' => 'ᾣ', - 'ᾬ' => 'ᾤ', - 'ᾭ' => 'ᾥ', - 'ᾮ' => 'ᾦ', - 'ᾯ' => 'ᾧ', - 'Ᾰ' => 'ᾰ', - 'Ᾱ' => 'ᾱ', - 'Ὰ' => 'ὰ', - 'Ά' => 'ά', - 'ᾼ' => 'ᾳ', - 'Ὲ' => 'ὲ', - 'Έ' => 'έ', - 'Ὴ' => 'ὴ', - 'Ή' => 'ή', - 'ῌ' => 'ῃ', - 'Ῐ' => 'ῐ', - 'Ῑ' => 'ῑ', - 'Ὶ' => 'ὶ', - 'Ί' => 'ί', - 'Ῠ' => 'ῠ', - 'Ῡ' => 'ῡ', - 'Ὺ' => 'ὺ', - 'Ύ' => 'ύ', - 'Ῥ' => 'ῥ', - 'Ὸ' => 'ὸ', - 'Ό' => 'ό', - 'Ὼ' => 'ὼ', - 'Ώ' => 'ώ', - 'ῼ' => 'ῳ', - 'Ω' => 'ω', - 'K' => 'k', - 'Å' => 'å', - 'Ⅎ' => 'ⅎ', - 'Ⅰ' => 'ⅰ', - 'Ⅱ' => 'ⅱ', - 'Ⅲ' => 'ⅲ', - 'Ⅳ' => 'ⅳ', - 'Ⅴ' => 'ⅴ', - 'Ⅵ' => 'ⅵ', - 'Ⅶ' => 'ⅶ', - 'Ⅷ' => 'ⅷ', - 'Ⅸ' => 'ⅸ', - 'Ⅹ' => 'ⅹ', - 'Ⅺ' => 'ⅺ', - 'Ⅻ' => 'ⅻ', - 'Ⅼ' => 'ⅼ', - 'Ⅽ' => 'ⅽ', - 'Ⅾ' => 'ⅾ', - 'Ⅿ' => 'ⅿ', - 'Ↄ' => 'ↄ', - 'Ⓐ' => 'ⓐ', - 'Ⓑ' => 'ⓑ', - 'Ⓒ' => 'ⓒ', - 'Ⓓ' => 'ⓓ', - 'Ⓔ' => 'ⓔ', - 'Ⓕ' => 'ⓕ', - 'Ⓖ' => 'ⓖ', - 'Ⓗ' => 'ⓗ', - 'Ⓘ' => 'ⓘ', - 'Ⓙ' => 'ⓙ', - 'Ⓚ' => 'ⓚ', - 'Ⓛ' => 'ⓛ', - 'Ⓜ' => 'ⓜ', - 'Ⓝ' => 'ⓝ', - 'Ⓞ' => 'ⓞ', - 'Ⓟ' => 'ⓟ', - 'Ⓠ' => 'ⓠ', - 'Ⓡ' => 'ⓡ', - 'Ⓢ' => 'ⓢ', - 'Ⓣ' => 'ⓣ', - 'Ⓤ' => 'ⓤ', - 'Ⓥ' => 'ⓥ', - 'Ⓦ' => 'ⓦ', - 'Ⓧ' => 'ⓧ', - 'Ⓨ' => 'ⓨ', - 'Ⓩ' => 'ⓩ', - 'Ⰰ' => 'ⰰ', - 'Ⰱ' => 'ⰱ', - 'Ⰲ' => 'ⰲ', - 'Ⰳ' => 'ⰳ', - 'Ⰴ' => 'ⰴ', - 'Ⰵ' => 'ⰵ', - 'Ⰶ' => 'ⰶ', - 'Ⰷ' => 'ⰷ', - 'Ⰸ' => 'ⰸ', - 'Ⰹ' => 'ⰹ', - 'Ⰺ' => 'ⰺ', - 'Ⰻ' => 'ⰻ', - 'Ⰼ' => 'ⰼ', - 'Ⰽ' => 'ⰽ', - 'Ⰾ' => 'ⰾ', - 'Ⰿ' => 'ⰿ', - 'Ⱀ' => 'ⱀ', - 'Ⱁ' => 'ⱁ', - 'Ⱂ' => 'ⱂ', - 'Ⱃ' => 'ⱃ', - 'Ⱄ' => 'ⱄ', - 'Ⱅ' => 'ⱅ', - 'Ⱆ' => 'ⱆ', - 'Ⱇ' => 'ⱇ', - 'Ⱈ' => 'ⱈ', - 'Ⱉ' => 'ⱉ', - 'Ⱊ' => 'ⱊ', - 'Ⱋ' => 'ⱋ', - 'Ⱌ' => 'ⱌ', - 'Ⱍ' => 'ⱍ', - 'Ⱎ' => 'ⱎ', - 'Ⱏ' => 'ⱏ', - 'Ⱐ' => 'ⱐ', - 'Ⱑ' => 'ⱑ', - 'Ⱒ' => 'ⱒ', - 'Ⱓ' => 'ⱓ', - 'Ⱔ' => 'ⱔ', - 'Ⱕ' => 'ⱕ', - 'Ⱖ' => 'ⱖ', - 'Ⱗ' => 'ⱗ', - 'Ⱘ' => 'ⱘ', - 'Ⱙ' => 'ⱙ', - 'Ⱚ' => 'ⱚ', - 'Ⱛ' => 'ⱛ', - 'Ⱜ' => 'ⱜ', - 'Ⱝ' => 'ⱝ', - 'Ⱞ' => 'ⱞ', - 'Ⱡ' => 'ⱡ', - 'Ɫ' => 'ɫ', - 'Ᵽ' => 'ᵽ', - 'Ɽ' => 'ɽ', - 'Ⱨ' => 'ⱨ', - 'Ⱪ' => 'ⱪ', - 'Ⱬ' => 'ⱬ', - 'Ɑ' => 'ɑ', - 'Ɱ' => 'ɱ', - 'Ɐ' => 'ɐ', - 'Ɒ' => 'ɒ', - 'Ⱳ' => 'ⱳ', - 'Ⱶ' => 'ⱶ', - 'Ȿ' => 'ȿ', - 'Ɀ' => 'ɀ', - 'Ⲁ' => 'ⲁ', - 'Ⲃ' => 'ⲃ', - 'Ⲅ' => 'ⲅ', - 'Ⲇ' => 'ⲇ', - 'Ⲉ' => 'ⲉ', - 'Ⲋ' => 'ⲋ', - 'Ⲍ' => 'ⲍ', - 'Ⲏ' => 'ⲏ', - 'Ⲑ' => 'ⲑ', - 'Ⲓ' => 'ⲓ', - 'Ⲕ' => 'ⲕ', - 'Ⲗ' => 'ⲗ', - 'Ⲙ' => 'ⲙ', - 'Ⲛ' => 'ⲛ', - 'Ⲝ' => 'ⲝ', - 'Ⲟ' => 'ⲟ', - 'Ⲡ' => 'ⲡ', - 'Ⲣ' => 'ⲣ', - 'Ⲥ' => 'ⲥ', - 'Ⲧ' => 'ⲧ', - 'Ⲩ' => 'ⲩ', - 'Ⲫ' => 'ⲫ', - 'Ⲭ' => 'ⲭ', - 'Ⲯ' => 'ⲯ', - 'Ⲱ' => 'ⲱ', - 'Ⲳ' => 'ⲳ', - 'Ⲵ' => 'ⲵ', - 'Ⲷ' => 'ⲷ', - 'Ⲹ' => 'ⲹ', - 'Ⲻ' => 'ⲻ', - 'Ⲽ' => 'ⲽ', - 'Ⲿ' => 'ⲿ', - 'Ⳁ' => 'ⳁ', - 'Ⳃ' => 'ⳃ', - 'Ⳅ' => 'ⳅ', - 'Ⳇ' => 'ⳇ', - 'Ⳉ' => 'ⳉ', - 'Ⳋ' => 'ⳋ', - 'Ⳍ' => 'ⳍ', - 'Ⳏ' => 'ⳏ', - 'Ⳑ' => 'ⳑ', - 'Ⳓ' => 'ⳓ', - 'Ⳕ' => 'ⳕ', - 'Ⳗ' => 'ⳗ', - 'Ⳙ' => 'ⳙ', - 'Ⳛ' => 'ⳛ', - 'Ⳝ' => 'ⳝ', - 'Ⳟ' => 'ⳟ', - 'Ⳡ' => 'ⳡ', - 'Ⳣ' => 'ⳣ', - 'Ⳬ' => 'ⳬ', - 'Ⳮ' => 'ⳮ', - 'Ⳳ' => 'ⳳ', - 'Ꙁ' => 'ꙁ', - 'Ꙃ' => 'ꙃ', - 'Ꙅ' => 'ꙅ', - 'Ꙇ' => 'ꙇ', - 'Ꙉ' => 'ꙉ', - 'Ꙋ' => 'ꙋ', - 'Ꙍ' => 'ꙍ', - 'Ꙏ' => 'ꙏ', - 'Ꙑ' => 'ꙑ', - 'Ꙓ' => 'ꙓ', - 'Ꙕ' => 'ꙕ', - 'Ꙗ' => 'ꙗ', - 'Ꙙ' => 'ꙙ', - 'Ꙛ' => 'ꙛ', - 'Ꙝ' => 'ꙝ', - 'Ꙟ' => 'ꙟ', - 'Ꙡ' => 'ꙡ', - 'Ꙣ' => 'ꙣ', - 'Ꙥ' => 'ꙥ', - 'Ꙧ' => 'ꙧ', - 'Ꙩ' => 'ꙩ', - 'Ꙫ' => 'ꙫ', - 'Ꙭ' => 'ꙭ', - 'Ꚁ' => 'ꚁ', - 'Ꚃ' => 'ꚃ', - 'Ꚅ' => 'ꚅ', - 'Ꚇ' => 'ꚇ', - 'Ꚉ' => 'ꚉ', - 'Ꚋ' => 'ꚋ', - 'Ꚍ' => 'ꚍ', - 'Ꚏ' => 'ꚏ', - 'Ꚑ' => 'ꚑ', - 'Ꚓ' => 'ꚓ', - 'Ꚕ' => 'ꚕ', - 'Ꚗ' => 'ꚗ', - 'Ꚙ' => 'ꚙ', - 'Ꚛ' => 'ꚛ', - 'Ꜣ' => 'ꜣ', - 'Ꜥ' => 'ꜥ', - 'Ꜧ' => 'ꜧ', - 'Ꜩ' => 'ꜩ', - 'Ꜫ' => 'ꜫ', - 'Ꜭ' => 'ꜭ', - 'Ꜯ' => 'ꜯ', - 'Ꜳ' => 'ꜳ', - 'Ꜵ' => 'ꜵ', - 'Ꜷ' => 'ꜷ', - 'Ꜹ' => 'ꜹ', - 'Ꜻ' => 'ꜻ', - 'Ꜽ' => 'ꜽ', - 'Ꜿ' => 'ꜿ', - 'Ꝁ' => 'ꝁ', - 'Ꝃ' => 'ꝃ', - 'Ꝅ' => 'ꝅ', - 'Ꝇ' => 'ꝇ', - 'Ꝉ' => 'ꝉ', - 'Ꝋ' => 'ꝋ', - 'Ꝍ' => 'ꝍ', - 'Ꝏ' => 'ꝏ', - 'Ꝑ' => 'ꝑ', - 'Ꝓ' => 'ꝓ', - 'Ꝕ' => 'ꝕ', - 'Ꝗ' => 'ꝗ', - 'Ꝙ' => 'ꝙ', - 'Ꝛ' => 'ꝛ', - 'Ꝝ' => 'ꝝ', - 'Ꝟ' => 'ꝟ', - 'Ꝡ' => 'ꝡ', - 'Ꝣ' => 'ꝣ', - 'Ꝥ' => 'ꝥ', - 'Ꝧ' => 'ꝧ', - 'Ꝩ' => 'ꝩ', - 'Ꝫ' => 'ꝫ', - 'Ꝭ' => 'ꝭ', - 'Ꝯ' => 'ꝯ', - 'Ꝺ' => 'ꝺ', - 'Ꝼ' => 'ꝼ', - 'Ᵹ' => 'ᵹ', - 'Ꝿ' => 'ꝿ', - 'Ꞁ' => 'ꞁ', - 'Ꞃ' => 'ꞃ', - 'Ꞅ' => 'ꞅ', - 'Ꞇ' => 'ꞇ', - 'Ꞌ' => 'ꞌ', - 'Ɥ' => 'ɥ', - 'Ꞑ' => 'ꞑ', - 'Ꞓ' => 'ꞓ', - 'Ꞗ' => 'ꞗ', - 'Ꞙ' => 'ꞙ', - 'Ꞛ' => 'ꞛ', - 'Ꞝ' => 'ꞝ', - 'Ꞟ' => 'ꞟ', - 'Ꞡ' => 'ꞡ', - 'Ꞣ' => 'ꞣ', - 'Ꞥ' => 'ꞥ', - 'Ꞧ' => 'ꞧ', - 'Ꞩ' => 'ꞩ', - 'Ɦ' => 'ɦ', - 'Ɜ' => 'ɜ', - 'Ɡ' => 'ɡ', - 'Ɬ' => 'ɬ', - 'Ɪ' => 'ɪ', - 'Ʞ' => 'ʞ', - 'Ʇ' => 'ʇ', - 'Ʝ' => 'ʝ', - 'Ꭓ' => 'ꭓ', - 'Ꞵ' => 'ꞵ', - 'Ꞷ' => 'ꞷ', - 'Ꞹ' => 'ꞹ', - 'Ꞻ' => 'ꞻ', - 'Ꞽ' => 'ꞽ', - 'Ꞿ' => 'ꞿ', - 'Ꟃ' => 'ꟃ', - 'Ꞔ' => 'ꞔ', - 'Ʂ' => 'ʂ', - 'Ᶎ' => 'ᶎ', - 'Ꟈ' => 'ꟈ', - 'Ꟊ' => 'ꟊ', - 'Ꟶ' => 'ꟶ', - 'A' => 'a', - 'B' => 'b', - 'C' => 'c', - 'D' => 'd', - 'E' => 'e', - 'F' => 'f', - 'G' => 'g', - 'H' => 'h', - 'I' => 'i', - 'J' => 'j', - 'K' => 'k', - 'L' => 'l', - 'M' => 'm', - 'N' => 'n', - 'O' => 'o', - 'P' => 'p', - 'Q' => 'q', - 'R' => 'r', - 'S' => 's', - 'T' => 't', - 'U' => 'u', - 'V' => 'v', - 'W' => 'w', - 'X' => 'x', - 'Y' => 'y', - 'Z' => 'z', - '𐐀' => '𐐨', - '𐐁' => '𐐩', - '𐐂' => '𐐪', - '𐐃' => '𐐫', - '𐐄' => '𐐬', - '𐐅' => '𐐭', - '𐐆' => '𐐮', - '𐐇' => '𐐯', - '𐐈' => '𐐰', - '𐐉' => '𐐱', - '𐐊' => '𐐲', - '𐐋' => '𐐳', - '𐐌' => '𐐴', - '𐐍' => '𐐵', - '𐐎' => '𐐶', - '𐐏' => '𐐷', - '𐐐' => '𐐸', - '𐐑' => '𐐹', - '𐐒' => '𐐺', - '𐐓' => '𐐻', - '𐐔' => '𐐼', - '𐐕' => '𐐽', - '𐐖' => '𐐾', - '𐐗' => '𐐿', - '𐐘' => '𐑀', - '𐐙' => '𐑁', - '𐐚' => '𐑂', - '𐐛' => '𐑃', - '𐐜' => '𐑄', - '𐐝' => '𐑅', - '𐐞' => '𐑆', - '𐐟' => '𐑇', - '𐐠' => '𐑈', - '𐐡' => '𐑉', - '𐐢' => '𐑊', - '𐐣' => '𐑋', - '𐐤' => '𐑌', - '𐐥' => '𐑍', - '𐐦' => '𐑎', - '𐐧' => '𐑏', - '𐒰' => '𐓘', - '𐒱' => '𐓙', - '𐒲' => '𐓚', - '𐒳' => '𐓛', - '𐒴' => '𐓜', - '𐒵' => '𐓝', - '𐒶' => '𐓞', - '𐒷' => '𐓟', - '𐒸' => '𐓠', - '𐒹' => '𐓡', - '𐒺' => '𐓢', - '𐒻' => '𐓣', - '𐒼' => '𐓤', - '𐒽' => '𐓥', - '𐒾' => '𐓦', - '𐒿' => '𐓧', - '𐓀' => '𐓨', - '𐓁' => '𐓩', - '𐓂' => '𐓪', - '𐓃' => '𐓫', - '𐓄' => '𐓬', - '𐓅' => '𐓭', - '𐓆' => '𐓮', - '𐓇' => '𐓯', - '𐓈' => '𐓰', - '𐓉' => '𐓱', - '𐓊' => '𐓲', - '𐓋' => '𐓳', - '𐓌' => '𐓴', - '𐓍' => '𐓵', - '𐓎' => '𐓶', - '𐓏' => '𐓷', - '𐓐' => '𐓸', - '𐓑' => '𐓹', - '𐓒' => '𐓺', - '𐓓' => '𐓻', - '𐲀' => '𐳀', - '𐲁' => '𐳁', - '𐲂' => '𐳂', - '𐲃' => '𐳃', - '𐲄' => '𐳄', - '𐲅' => '𐳅', - '𐲆' => '𐳆', - '𐲇' => '𐳇', - '𐲈' => '𐳈', - '𐲉' => '𐳉', - '𐲊' => '𐳊', - '𐲋' => '𐳋', - '𐲌' => '𐳌', - '𐲍' => '𐳍', - '𐲎' => '𐳎', - '𐲏' => '𐳏', - '𐲐' => '𐳐', - '𐲑' => '𐳑', - '𐲒' => '𐳒', - '𐲓' => '𐳓', - '𐲔' => '𐳔', - '𐲕' => '𐳕', - '𐲖' => '𐳖', - '𐲗' => '𐳗', - '𐲘' => '𐳘', - '𐲙' => '𐳙', - '𐲚' => '𐳚', - '𐲛' => '𐳛', - '𐲜' => '𐳜', - '𐲝' => '𐳝', - '𐲞' => '𐳞', - '𐲟' => '𐳟', - '𐲠' => '𐳠', - '𐲡' => '𐳡', - '𐲢' => '𐳢', - '𐲣' => '𐳣', - '𐲤' => '𐳤', - '𐲥' => '𐳥', - '𐲦' => '𐳦', - '𐲧' => '𐳧', - '𐲨' => '𐳨', - '𐲩' => '𐳩', - '𐲪' => '𐳪', - '𐲫' => '𐳫', - '𐲬' => '𐳬', - '𐲭' => '𐳭', - '𐲮' => '𐳮', - '𐲯' => '𐳯', - '𐲰' => '𐳰', - '𐲱' => '𐳱', - '𐲲' => '𐳲', - '𑢠' => '𑣀', - '𑢡' => '𑣁', - '𑢢' => '𑣂', - '𑢣' => '𑣃', - '𑢤' => '𑣄', - '𑢥' => '𑣅', - '𑢦' => '𑣆', - '𑢧' => '𑣇', - '𑢨' => '𑣈', - '𑢩' => '𑣉', - '𑢪' => '𑣊', - '𑢫' => '𑣋', - '𑢬' => '𑣌', - '𑢭' => '𑣍', - '𑢮' => '𑣎', - '𑢯' => '𑣏', - '𑢰' => '𑣐', - '𑢱' => '𑣑', - '𑢲' => '𑣒', - '𑢳' => '𑣓', - '𑢴' => '𑣔', - '𑢵' => '𑣕', - '𑢶' => '𑣖', - '𑢷' => '𑣗', - '𑢸' => '𑣘', - '𑢹' => '𑣙', - '𑢺' => '𑣚', - '𑢻' => '𑣛', - '𑢼' => '𑣜', - '𑢽' => '𑣝', - '𑢾' => '𑣞', - '𑢿' => '𑣟', - '𖹀' => '𖹠', - '𖹁' => '𖹡', - '𖹂' => '𖹢', - '𖹃' => '𖹣', - '𖹄' => '𖹤', - '𖹅' => '𖹥', - '𖹆' => '𖹦', - '𖹇' => '𖹧', - '𖹈' => '𖹨', - '𖹉' => '𖹩', - '𖹊' => '𖹪', - '𖹋' => '𖹫', - '𖹌' => '𖹬', - '𖹍' => '𖹭', - '𖹎' => '𖹮', - '𖹏' => '𖹯', - '𖹐' => '𖹰', - '𖹑' => '𖹱', - '𖹒' => '𖹲', - '𖹓' => '𖹳', - '𖹔' => '𖹴', - '𖹕' => '𖹵', - '𖹖' => '𖹶', - '𖹗' => '𖹷', - '𖹘' => '𖹸', - '𖹙' => '𖹹', - '𖹚' => '𖹺', - '𖹛' => '𖹻', - '𖹜' => '𖹼', - '𖹝' => '𖹽', - '𖹞' => '𖹾', - '𖹟' => '𖹿', - '𞤀' => '𞤢', - '𞤁' => '𞤣', - '𞤂' => '𞤤', - '𞤃' => '𞤥', - '𞤄' => '𞤦', - '𞤅' => '𞤧', - '𞤆' => '𞤨', - '𞤇' => '𞤩', - '𞤈' => '𞤪', - '𞤉' => '𞤫', - '𞤊' => '𞤬', - '𞤋' => '𞤭', - '𞤌' => '𞤮', - '𞤍' => '𞤯', - '𞤎' => '𞤰', - '𞤏' => '𞤱', - '𞤐' => '𞤲', - '𞤑' => '𞤳', - '𞤒' => '𞤴', - '𞤓' => '𞤵', - '𞤔' => '𞤶', - '𞤕' => '𞤷', - '𞤖' => '𞤸', - '𞤗' => '𞤹', - '𞤘' => '𞤺', - '𞤙' => '𞤻', - '𞤚' => '𞤼', - '𞤛' => '𞤽', - '𞤜' => '𞤾', - '𞤝' => '𞤿', - '𞤞' => '𞥀', - '𞤟' => '𞥁', - '𞤠' => '𞥂', - '𞤡' => '𞥃', -); diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php deleted file mode 100644 index 2a8f6e7..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/Resources/unidata/titleCaseRegexp.php +++ /dev/null @@ -1,5 +0,0 @@ - 'A', - 'b' => 'B', - 'c' => 'C', - 'd' => 'D', - 'e' => 'E', - 'f' => 'F', - 'g' => 'G', - 'h' => 'H', - 'i' => 'I', - 'j' => 'J', - 'k' => 'K', - 'l' => 'L', - 'm' => 'M', - 'n' => 'N', - 'o' => 'O', - 'p' => 'P', - 'q' => 'Q', - 'r' => 'R', - 's' => 'S', - 't' => 'T', - 'u' => 'U', - 'v' => 'V', - 'w' => 'W', - 'x' => 'X', - 'y' => 'Y', - 'z' => 'Z', - 'µ' => 'Μ', - 'à' => 'À', - 'á' => 'Á', - 'â' => 'Â', - 'ã' => 'Ã', - 'ä' => 'Ä', - 'å' => 'Å', - 'æ' => 'Æ', - 'ç' => 'Ç', - 'è' => 'È', - 'é' => 'É', - 'ê' => 'Ê', - 'ë' => 'Ë', - 'ì' => 'Ì', - 'í' => 'Í', - 'î' => 'Î', - 'ï' => 'Ï', - 'ð' => 'Ð', - 'ñ' => 'Ñ', - 'ò' => 'Ò', - 'ó' => 'Ó', - 'ô' => 'Ô', - 'õ' => 'Õ', - 'ö' => 'Ö', - 'ø' => 'Ø', - 'ù' => 'Ù', - 'ú' => 'Ú', - 'û' => 'Û', - 'ü' => 'Ü', - 'ý' => 'Ý', - 'þ' => 'Þ', - 'ÿ' => 'Ÿ', - 'ā' => 'Ā', - 'ă' => 'Ă', - 'ą' => 'Ą', - 'ć' => 'Ć', - 'ĉ' => 'Ĉ', - 'ċ' => 'Ċ', - 'č' => 'Č', - 'ď' => 'Ď', - 'đ' => 'Đ', - 'ē' => 'Ē', - 'ĕ' => 'Ĕ', - 'ė' => 'Ė', - 'ę' => 'Ę', - 'ě' => 'Ě', - 'ĝ' => 'Ĝ', - 'ğ' => 'Ğ', - 'ġ' => 'Ġ', - 'ģ' => 'Ģ', - 'ĥ' => 'Ĥ', - 'ħ' => 'Ħ', - 'ĩ' => 'Ĩ', - 'ī' => 'Ī', - 'ĭ' => 'Ĭ', - 'į' => 'Į', - 'ı' => 'I', - 'ij' => 'IJ', - 'ĵ' => 'Ĵ', - 'ķ' => 'Ķ', - 'ĺ' => 'Ĺ', - 'ļ' => 'Ļ', - 'ľ' => 'Ľ', - 'ŀ' => 'Ŀ', - 'ł' => 'Ł', - 'ń' => 'Ń', - 'ņ' => 'Ņ', - 'ň' => 'Ň', - 'ŋ' => 'Ŋ', - 'ō' => 'Ō', - 'ŏ' => 'Ŏ', - 'ő' => 'Ő', - 'œ' => 'Œ', - 'ŕ' => 'Ŕ', - 'ŗ' => 'Ŗ', - 'ř' => 'Ř', - 'ś' => 'Ś', - 'ŝ' => 'Ŝ', - 'ş' => 'Ş', - 'š' => 'Š', - 'ţ' => 'Ţ', - 'ť' => 'Ť', - 'ŧ' => 'Ŧ', - 'ũ' => 'Ũ', - 'ū' => 'Ū', - 'ŭ' => 'Ŭ', - 'ů' => 'Ů', - 'ű' => 'Ű', - 'ų' => 'Ų', - 'ŵ' => 'Ŵ', - 'ŷ' => 'Ŷ', - 'ź' => 'Ź', - 'ż' => 'Ż', - 'ž' => 'Ž', - 'ſ' => 'S', - 'ƀ' => 'Ƀ', - 'ƃ' => 'Ƃ', - 'ƅ' => 'Ƅ', - 'ƈ' => 'Ƈ', - 'ƌ' => 'Ƌ', - 'ƒ' => 'Ƒ', - 'ƕ' => 'Ƕ', - 'ƙ' => 'Ƙ', - 'ƚ' => 'Ƚ', - 'ƞ' => 'Ƞ', - 'ơ' => 'Ơ', - 'ƣ' => 'Ƣ', - 'ƥ' => 'Ƥ', - 'ƨ' => 'Ƨ', - 'ƭ' => 'Ƭ', - 'ư' => 'Ư', - 'ƴ' => 'Ƴ', - 'ƶ' => 'Ƶ', - 'ƹ' => 'Ƹ', - 'ƽ' => 'Ƽ', - 'ƿ' => 'Ƿ', - 'Dž' => 'DŽ', - 'dž' => 'DŽ', - 'Lj' => 'LJ', - 'lj' => 'LJ', - 'Nj' => 'NJ', - 'nj' => 'NJ', - 'ǎ' => 'Ǎ', - 'ǐ' => 'Ǐ', - 'ǒ' => 'Ǒ', - 'ǔ' => 'Ǔ', - 'ǖ' => 'Ǖ', - 'ǘ' => 'Ǘ', - 'ǚ' => 'Ǚ', - 'ǜ' => 'Ǜ', - 'ǝ' => 'Ǝ', - 'ǟ' => 'Ǟ', - 'ǡ' => 'Ǡ', - 'ǣ' => 'Ǣ', - 'ǥ' => 'Ǥ', - 'ǧ' => 'Ǧ', - 'ǩ' => 'Ǩ', - 'ǫ' => 'Ǫ', - 'ǭ' => 'Ǭ', - 'ǯ' => 'Ǯ', - 'Dz' => 'DZ', - 'dz' => 'DZ', - 'ǵ' => 'Ǵ', - 'ǹ' => 'Ǹ', - 'ǻ' => 'Ǻ', - 'ǽ' => 'Ǽ', - 'ǿ' => 'Ǿ', - 'ȁ' => 'Ȁ', - 'ȃ' => 'Ȃ', - 'ȅ' => 'Ȅ', - 'ȇ' => 'Ȇ', - 'ȉ' => 'Ȉ', - 'ȋ' => 'Ȋ', - 'ȍ' => 'Ȍ', - 'ȏ' => 'Ȏ', - 'ȑ' => 'Ȑ', - 'ȓ' => 'Ȓ', - 'ȕ' => 'Ȕ', - 'ȗ' => 'Ȗ', - 'ș' => 'Ș', - 'ț' => 'Ț', - 'ȝ' => 'Ȝ', - 'ȟ' => 'Ȟ', - 'ȣ' => 'Ȣ', - 'ȥ' => 'Ȥ', - 'ȧ' => 'Ȧ', - 'ȩ' => 'Ȩ', - 'ȫ' => 'Ȫ', - 'ȭ' => 'Ȭ', - 'ȯ' => 'Ȯ', - 'ȱ' => 'Ȱ', - 'ȳ' => 'Ȳ', - 'ȼ' => 'Ȼ', - 'ȿ' => 'Ȿ', - 'ɀ' => 'Ɀ', - 'ɂ' => 'Ɂ', - 'ɇ' => 'Ɇ', - 'ɉ' => 'Ɉ', - 'ɋ' => 'Ɋ', - 'ɍ' => 'Ɍ', - 'ɏ' => 'Ɏ', - 'ɐ' => 'Ɐ', - 'ɑ' => 'Ɑ', - 'ɒ' => 'Ɒ', - 'ɓ' => 'Ɓ', - 'ɔ' => 'Ɔ', - 'ɖ' => 'Ɖ', - 'ɗ' => 'Ɗ', - 'ə' => 'Ə', - 'ɛ' => 'Ɛ', - 'ɜ' => 'Ɜ', - 'ɠ' => 'Ɠ', - 'ɡ' => 'Ɡ', - 'ɣ' => 'Ɣ', - 'ɥ' => 'Ɥ', - 'ɦ' => 'Ɦ', - 'ɨ' => 'Ɨ', - 'ɩ' => 'Ɩ', - 'ɪ' => 'Ɪ', - 'ɫ' => 'Ɫ', - 'ɬ' => 'Ɬ', - 'ɯ' => 'Ɯ', - 'ɱ' => 'Ɱ', - 'ɲ' => 'Ɲ', - 'ɵ' => 'Ɵ', - 'ɽ' => 'Ɽ', - 'ʀ' => 'Ʀ', - 'ʂ' => 'Ʂ', - 'ʃ' => 'Ʃ', - 'ʇ' => 'Ʇ', - 'ʈ' => 'Ʈ', - 'ʉ' => 'Ʉ', - 'ʊ' => 'Ʊ', - 'ʋ' => 'Ʋ', - 'ʌ' => 'Ʌ', - 'ʒ' => 'Ʒ', - 'ʝ' => 'Ʝ', - 'ʞ' => 'Ʞ', - 'ͅ' => 'Ι', - 'ͱ' => 'Ͱ', - 'ͳ' => 'Ͳ', - 'ͷ' => 'Ͷ', - 'ͻ' => 'Ͻ', - 'ͼ' => 'Ͼ', - 'ͽ' => 'Ͽ', - 'ά' => 'Ά', - 'έ' => 'Έ', - 'ή' => 'Ή', - 'ί' => 'Ί', - 'α' => 'Α', - 'β' => 'Β', - 'γ' => 'Γ', - 'δ' => 'Δ', - 'ε' => 'Ε', - 'ζ' => 'Ζ', - 'η' => 'Η', - 'θ' => 'Θ', - 'ι' => 'Ι', - 'κ' => 'Κ', - 'λ' => 'Λ', - 'μ' => 'Μ', - 'ν' => 'Ν', - 'ξ' => 'Ξ', - 'ο' => 'Ο', - 'π' => 'Π', - 'ρ' => 'Ρ', - 'ς' => 'Σ', - 'σ' => 'Σ', - 'τ' => 'Τ', - 'υ' => 'Υ', - 'φ' => 'Φ', - 'χ' => 'Χ', - 'ψ' => 'Ψ', - 'ω' => 'Ω', - 'ϊ' => 'Ϊ', - 'ϋ' => 'Ϋ', - 'ό' => 'Ό', - 'ύ' => 'Ύ', - 'ώ' => 'Ώ', - 'ϐ' => 'Β', - 'ϑ' => 'Θ', - 'ϕ' => 'Φ', - 'ϖ' => 'Π', - 'ϗ' => 'Ϗ', - 'ϙ' => 'Ϙ', - 'ϛ' => 'Ϛ', - 'ϝ' => 'Ϝ', - 'ϟ' => 'Ϟ', - 'ϡ' => 'Ϡ', - 'ϣ' => 'Ϣ', - 'ϥ' => 'Ϥ', - 'ϧ' => 'Ϧ', - 'ϩ' => 'Ϩ', - 'ϫ' => 'Ϫ', - 'ϭ' => 'Ϭ', - 'ϯ' => 'Ϯ', - 'ϰ' => 'Κ', - 'ϱ' => 'Ρ', - 'ϲ' => 'Ϲ', - 'ϳ' => 'Ϳ', - 'ϵ' => 'Ε', - 'ϸ' => 'Ϸ', - 'ϻ' => 'Ϻ', - 'а' => 'А', - 'б' => 'Б', - 'в' => 'В', - 'г' => 'Г', - 'д' => 'Д', - 'е' => 'Е', - 'ж' => 'Ж', - 'з' => 'З', - 'и' => 'И', - 'й' => 'Й', - 'к' => 'К', - 'л' => 'Л', - 'м' => 'М', - 'н' => 'Н', - 'о' => 'О', - 'п' => 'П', - 'р' => 'Р', - 'с' => 'С', - 'т' => 'Т', - 'у' => 'У', - 'ф' => 'Ф', - 'х' => 'Х', - 'ц' => 'Ц', - 'ч' => 'Ч', - 'ш' => 'Ш', - 'щ' => 'Щ', - 'ъ' => 'Ъ', - 'ы' => 'Ы', - 'ь' => 'Ь', - 'э' => 'Э', - 'ю' => 'Ю', - 'я' => 'Я', - 'ѐ' => 'Ѐ', - 'ё' => 'Ё', - 'ђ' => 'Ђ', - 'ѓ' => 'Ѓ', - 'є' => 'Є', - 'ѕ' => 'Ѕ', - 'і' => 'І', - 'ї' => 'Ї', - 'ј' => 'Ј', - 'љ' => 'Љ', - 'њ' => 'Њ', - 'ћ' => 'Ћ', - 'ќ' => 'Ќ', - 'ѝ' => 'Ѝ', - 'ў' => 'Ў', - 'џ' => 'Џ', - 'ѡ' => 'Ѡ', - 'ѣ' => 'Ѣ', - 'ѥ' => 'Ѥ', - 'ѧ' => 'Ѧ', - 'ѩ' => 'Ѩ', - 'ѫ' => 'Ѫ', - 'ѭ' => 'Ѭ', - 'ѯ' => 'Ѯ', - 'ѱ' => 'Ѱ', - 'ѳ' => 'Ѳ', - 'ѵ' => 'Ѵ', - 'ѷ' => 'Ѷ', - 'ѹ' => 'Ѹ', - 'ѻ' => 'Ѻ', - 'ѽ' => 'Ѽ', - 'ѿ' => 'Ѿ', - 'ҁ' => 'Ҁ', - 'ҋ' => 'Ҋ', - 'ҍ' => 'Ҍ', - 'ҏ' => 'Ҏ', - 'ґ' => 'Ґ', - 'ғ' => 'Ғ', - 'ҕ' => 'Ҕ', - 'җ' => 'Җ', - 'ҙ' => 'Ҙ', - 'қ' => 'Қ', - 'ҝ' => 'Ҝ', - 'ҟ' => 'Ҟ', - 'ҡ' => 'Ҡ', - 'ң' => 'Ң', - 'ҥ' => 'Ҥ', - 'ҧ' => 'Ҧ', - 'ҩ' => 'Ҩ', - 'ҫ' => 'Ҫ', - 'ҭ' => 'Ҭ', - 'ү' => 'Ү', - 'ұ' => 'Ұ', - 'ҳ' => 'Ҳ', - 'ҵ' => 'Ҵ', - 'ҷ' => 'Ҷ', - 'ҹ' => 'Ҹ', - 'һ' => 'Һ', - 'ҽ' => 'Ҽ', - 'ҿ' => 'Ҿ', - 'ӂ' => 'Ӂ', - 'ӄ' => 'Ӄ', - 'ӆ' => 'Ӆ', - 'ӈ' => 'Ӈ', - 'ӊ' => 'Ӊ', - 'ӌ' => 'Ӌ', - 'ӎ' => 'Ӎ', - 'ӏ' => 'Ӏ', - 'ӑ' => 'Ӑ', - 'ӓ' => 'Ӓ', - 'ӕ' => 'Ӕ', - 'ӗ' => 'Ӗ', - 'ә' => 'Ә', - 'ӛ' => 'Ӛ', - 'ӝ' => 'Ӝ', - 'ӟ' => 'Ӟ', - 'ӡ' => 'Ӡ', - 'ӣ' => 'Ӣ', - 'ӥ' => 'Ӥ', - 'ӧ' => 'Ӧ', - 'ө' => 'Ө', - 'ӫ' => 'Ӫ', - 'ӭ' => 'Ӭ', - 'ӯ' => 'Ӯ', - 'ӱ' => 'Ӱ', - 'ӳ' => 'Ӳ', - 'ӵ' => 'Ӵ', - 'ӷ' => 'Ӷ', - 'ӹ' => 'Ӹ', - 'ӻ' => 'Ӻ', - 'ӽ' => 'Ӽ', - 'ӿ' => 'Ӿ', - 'ԁ' => 'Ԁ', - 'ԃ' => 'Ԃ', - 'ԅ' => 'Ԅ', - 'ԇ' => 'Ԇ', - 'ԉ' => 'Ԉ', - 'ԋ' => 'Ԋ', - 'ԍ' => 'Ԍ', - 'ԏ' => 'Ԏ', - 'ԑ' => 'Ԑ', - 'ԓ' => 'Ԓ', - 'ԕ' => 'Ԕ', - 'ԗ' => 'Ԗ', - 'ԙ' => 'Ԙ', - 'ԛ' => 'Ԛ', - 'ԝ' => 'Ԝ', - 'ԟ' => 'Ԟ', - 'ԡ' => 'Ԡ', - 'ԣ' => 'Ԣ', - 'ԥ' => 'Ԥ', - 'ԧ' => 'Ԧ', - 'ԩ' => 'Ԩ', - 'ԫ' => 'Ԫ', - 'ԭ' => 'Ԭ', - 'ԯ' => 'Ԯ', - 'ա' => 'Ա', - 'բ' => 'Բ', - 'գ' => 'Գ', - 'դ' => 'Դ', - 'ե' => 'Ե', - 'զ' => 'Զ', - 'է' => 'Է', - 'ը' => 'Ը', - 'թ' => 'Թ', - 'ժ' => 'Ժ', - 'ի' => 'Ի', - 'լ' => 'Լ', - 'խ' => 'Խ', - 'ծ' => 'Ծ', - 'կ' => 'Կ', - 'հ' => 'Հ', - 'ձ' => 'Ձ', - 'ղ' => 'Ղ', - 'ճ' => 'Ճ', - 'մ' => 'Մ', - 'յ' => 'Յ', - 'ն' => 'Ն', - 'շ' => 'Շ', - 'ո' => 'Ո', - 'չ' => 'Չ', - 'պ' => 'Պ', - 'ջ' => 'Ջ', - 'ռ' => 'Ռ', - 'ս' => 'Ս', - 'վ' => 'Վ', - 'տ' => 'Տ', - 'ր' => 'Ր', - 'ց' => 'Ց', - 'ւ' => 'Ւ', - 'փ' => 'Փ', - 'ք' => 'Ք', - 'օ' => 'Օ', - 'ֆ' => 'Ֆ', - 'ა' => 'Ა', - 'ბ' => 'Ბ', - 'გ' => 'Გ', - 'დ' => 'Დ', - 'ე' => 'Ე', - 'ვ' => 'Ვ', - 'ზ' => 'Ზ', - 'თ' => 'Თ', - 'ი' => 'Ი', - 'კ' => 'Კ', - 'ლ' => 'Ლ', - 'მ' => 'Მ', - 'ნ' => 'Ნ', - 'ო' => 'Ო', - 'პ' => 'Პ', - 'ჟ' => 'Ჟ', - 'რ' => 'Რ', - 'ს' => 'Ს', - 'ტ' => 'Ტ', - 'უ' => 'Უ', - 'ფ' => 'Ფ', - 'ქ' => 'Ქ', - 'ღ' => 'Ღ', - 'ყ' => 'Ყ', - 'შ' => 'Შ', - 'ჩ' => 'Ჩ', - 'ც' => 'Ც', - 'ძ' => 'Ძ', - 'წ' => 'Წ', - 'ჭ' => 'Ჭ', - 'ხ' => 'Ხ', - 'ჯ' => 'Ჯ', - 'ჰ' => 'Ჰ', - 'ჱ' => 'Ჱ', - 'ჲ' => 'Ჲ', - 'ჳ' => 'Ჳ', - 'ჴ' => 'Ჴ', - 'ჵ' => 'Ჵ', - 'ჶ' => 'Ჶ', - 'ჷ' => 'Ჷ', - 'ჸ' => 'Ჸ', - 'ჹ' => 'Ჹ', - 'ჺ' => 'Ჺ', - 'ჽ' => 'Ჽ', - 'ჾ' => 'Ჾ', - 'ჿ' => 'Ჿ', - 'ᏸ' => 'Ᏸ', - 'ᏹ' => 'Ᏹ', - 'ᏺ' => 'Ᏺ', - 'ᏻ' => 'Ᏻ', - 'ᏼ' => 'Ᏼ', - 'ᏽ' => 'Ᏽ', - 'ᲀ' => 'В', - 'ᲁ' => 'Д', - 'ᲂ' => 'О', - 'ᲃ' => 'С', - 'ᲄ' => 'Т', - 'ᲅ' => 'Т', - 'ᲆ' => 'Ъ', - 'ᲇ' => 'Ѣ', - 'ᲈ' => 'Ꙋ', - 'ᵹ' => 'Ᵹ', - 'ᵽ' => 'Ᵽ', - 'ᶎ' => 'Ᶎ', - 'ḁ' => 'Ḁ', - 'ḃ' => 'Ḃ', - 'ḅ' => 'Ḅ', - 'ḇ' => 'Ḇ', - 'ḉ' => 'Ḉ', - 'ḋ' => 'Ḋ', - 'ḍ' => 'Ḍ', - 'ḏ' => 'Ḏ', - 'ḑ' => 'Ḑ', - 'ḓ' => 'Ḓ', - 'ḕ' => 'Ḕ', - 'ḗ' => 'Ḗ', - 'ḙ' => 'Ḙ', - 'ḛ' => 'Ḛ', - 'ḝ' => 'Ḝ', - 'ḟ' => 'Ḟ', - 'ḡ' => 'Ḡ', - 'ḣ' => 'Ḣ', - 'ḥ' => 'Ḥ', - 'ḧ' => 'Ḧ', - 'ḩ' => 'Ḩ', - 'ḫ' => 'Ḫ', - 'ḭ' => 'Ḭ', - 'ḯ' => 'Ḯ', - 'ḱ' => 'Ḱ', - 'ḳ' => 'Ḳ', - 'ḵ' => 'Ḵ', - 'ḷ' => 'Ḷ', - 'ḹ' => 'Ḹ', - 'ḻ' => 'Ḻ', - 'ḽ' => 'Ḽ', - 'ḿ' => 'Ḿ', - 'ṁ' => 'Ṁ', - 'ṃ' => 'Ṃ', - 'ṅ' => 'Ṅ', - 'ṇ' => 'Ṇ', - 'ṉ' => 'Ṉ', - 'ṋ' => 'Ṋ', - 'ṍ' => 'Ṍ', - 'ṏ' => 'Ṏ', - 'ṑ' => 'Ṑ', - 'ṓ' => 'Ṓ', - 'ṕ' => 'Ṕ', - 'ṗ' => 'Ṗ', - 'ṙ' => 'Ṙ', - 'ṛ' => 'Ṛ', - 'ṝ' => 'Ṝ', - 'ṟ' => 'Ṟ', - 'ṡ' => 'Ṡ', - 'ṣ' => 'Ṣ', - 'ṥ' => 'Ṥ', - 'ṧ' => 'Ṧ', - 'ṩ' => 'Ṩ', - 'ṫ' => 'Ṫ', - 'ṭ' => 'Ṭ', - 'ṯ' => 'Ṯ', - 'ṱ' => 'Ṱ', - 'ṳ' => 'Ṳ', - 'ṵ' => 'Ṵ', - 'ṷ' => 'Ṷ', - 'ṹ' => 'Ṹ', - 'ṻ' => 'Ṻ', - 'ṽ' => 'Ṽ', - 'ṿ' => 'Ṿ', - 'ẁ' => 'Ẁ', - 'ẃ' => 'Ẃ', - 'ẅ' => 'Ẅ', - 'ẇ' => 'Ẇ', - 'ẉ' => 'Ẉ', - 'ẋ' => 'Ẋ', - 'ẍ' => 'Ẍ', - 'ẏ' => 'Ẏ', - 'ẑ' => 'Ẑ', - 'ẓ' => 'Ẓ', - 'ẕ' => 'Ẕ', - 'ẛ' => 'Ṡ', - 'ạ' => 'Ạ', - 'ả' => 'Ả', - 'ấ' => 'Ấ', - 'ầ' => 'Ầ', - 'ẩ' => 'Ẩ', - 'ẫ' => 'Ẫ', - 'ậ' => 'Ậ', - 'ắ' => 'Ắ', - 'ằ' => 'Ằ', - 'ẳ' => 'Ẳ', - 'ẵ' => 'Ẵ', - 'ặ' => 'Ặ', - 'ẹ' => 'Ẹ', - 'ẻ' => 'Ẻ', - 'ẽ' => 'Ẽ', - 'ế' => 'Ế', - 'ề' => 'Ề', - 'ể' => 'Ể', - 'ễ' => 'Ễ', - 'ệ' => 'Ệ', - 'ỉ' => 'Ỉ', - 'ị' => 'Ị', - 'ọ' => 'Ọ', - 'ỏ' => 'Ỏ', - 'ố' => 'Ố', - 'ồ' => 'Ồ', - 'ổ' => 'Ổ', - 'ỗ' => 'Ỗ', - 'ộ' => 'Ộ', - 'ớ' => 'Ớ', - 'ờ' => 'Ờ', - 'ở' => 'Ở', - 'ỡ' => 'Ỡ', - 'ợ' => 'Ợ', - 'ụ' => 'Ụ', - 'ủ' => 'Ủ', - 'ứ' => 'Ứ', - 'ừ' => 'Ừ', - 'ử' => 'Ử', - 'ữ' => 'Ữ', - 'ự' => 'Ự', - 'ỳ' => 'Ỳ', - 'ỵ' => 'Ỵ', - 'ỷ' => 'Ỷ', - 'ỹ' => 'Ỹ', - 'ỻ' => 'Ỻ', - 'ỽ' => 'Ỽ', - 'ỿ' => 'Ỿ', - 'ἀ' => 'Ἀ', - 'ἁ' => 'Ἁ', - 'ἂ' => 'Ἂ', - 'ἃ' => 'Ἃ', - 'ἄ' => 'Ἄ', - 'ἅ' => 'Ἅ', - 'ἆ' => 'Ἆ', - 'ἇ' => 'Ἇ', - 'ἐ' => 'Ἐ', - 'ἑ' => 'Ἑ', - 'ἒ' => 'Ἒ', - 'ἓ' => 'Ἓ', - 'ἔ' => 'Ἔ', - 'ἕ' => 'Ἕ', - 'ἠ' => 'Ἠ', - 'ἡ' => 'Ἡ', - 'ἢ' => 'Ἢ', - 'ἣ' => 'Ἣ', - 'ἤ' => 'Ἤ', - 'ἥ' => 'Ἥ', - 'ἦ' => 'Ἦ', - 'ἧ' => 'Ἧ', - 'ἰ' => 'Ἰ', - 'ἱ' => 'Ἱ', - 'ἲ' => 'Ἲ', - 'ἳ' => 'Ἳ', - 'ἴ' => 'Ἴ', - 'ἵ' => 'Ἵ', - 'ἶ' => 'Ἶ', - 'ἷ' => 'Ἷ', - 'ὀ' => 'Ὀ', - 'ὁ' => 'Ὁ', - 'ὂ' => 'Ὂ', - 'ὃ' => 'Ὃ', - 'ὄ' => 'Ὄ', - 'ὅ' => 'Ὅ', - 'ὑ' => 'Ὑ', - 'ὓ' => 'Ὓ', - 'ὕ' => 'Ὕ', - 'ὗ' => 'Ὗ', - 'ὠ' => 'Ὠ', - 'ὡ' => 'Ὡ', - 'ὢ' => 'Ὢ', - 'ὣ' => 'Ὣ', - 'ὤ' => 'Ὤ', - 'ὥ' => 'Ὥ', - 'ὦ' => 'Ὦ', - 'ὧ' => 'Ὧ', - 'ὰ' => 'Ὰ', - 'ά' => 'Ά', - 'ὲ' => 'Ὲ', - 'έ' => 'Έ', - 'ὴ' => 'Ὴ', - 'ή' => 'Ή', - 'ὶ' => 'Ὶ', - 'ί' => 'Ί', - 'ὸ' => 'Ὸ', - 'ό' => 'Ό', - 'ὺ' => 'Ὺ', - 'ύ' => 'Ύ', - 'ὼ' => 'Ὼ', - 'ώ' => 'Ώ', - 'ᾀ' => 'ἈΙ', - 'ᾁ' => 'ἉΙ', - 'ᾂ' => 'ἊΙ', - 'ᾃ' => 'ἋΙ', - 'ᾄ' => 'ἌΙ', - 'ᾅ' => 'ἍΙ', - 'ᾆ' => 'ἎΙ', - 'ᾇ' => 'ἏΙ', - 'ᾐ' => 'ἨΙ', - 'ᾑ' => 'ἩΙ', - 'ᾒ' => 'ἪΙ', - 'ᾓ' => 'ἫΙ', - 'ᾔ' => 'ἬΙ', - 'ᾕ' => 'ἭΙ', - 'ᾖ' => 'ἮΙ', - 'ᾗ' => 'ἯΙ', - 'ᾠ' => 'ὨΙ', - 'ᾡ' => 'ὩΙ', - 'ᾢ' => 'ὪΙ', - 'ᾣ' => 'ὫΙ', - 'ᾤ' => 'ὬΙ', - 'ᾥ' => 'ὭΙ', - 'ᾦ' => 'ὮΙ', - 'ᾧ' => 'ὯΙ', - 'ᾰ' => 'Ᾰ', - 'ᾱ' => 'Ᾱ', - 'ᾳ' => 'ΑΙ', - 'ι' => 'Ι', - 'ῃ' => 'ΗΙ', - 'ῐ' => 'Ῐ', - 'ῑ' => 'Ῑ', - 'ῠ' => 'Ῠ', - 'ῡ' => 'Ῡ', - 'ῥ' => 'Ῥ', - 'ῳ' => 'ΩΙ', - 'ⅎ' => 'Ⅎ', - 'ⅰ' => 'Ⅰ', - 'ⅱ' => 'Ⅱ', - 'ⅲ' => 'Ⅲ', - 'ⅳ' => 'Ⅳ', - 'ⅴ' => 'Ⅴ', - 'ⅵ' => 'Ⅵ', - 'ⅶ' => 'Ⅶ', - 'ⅷ' => 'Ⅷ', - 'ⅸ' => 'Ⅸ', - 'ⅹ' => 'Ⅹ', - 'ⅺ' => 'Ⅺ', - 'ⅻ' => 'Ⅻ', - 'ⅼ' => 'Ⅼ', - 'ⅽ' => 'Ⅽ', - 'ⅾ' => 'Ⅾ', - 'ⅿ' => 'Ⅿ', - 'ↄ' => 'Ↄ', - 'ⓐ' => 'Ⓐ', - 'ⓑ' => 'Ⓑ', - 'ⓒ' => 'Ⓒ', - 'ⓓ' => 'Ⓓ', - 'ⓔ' => 'Ⓔ', - 'ⓕ' => 'Ⓕ', - 'ⓖ' => 'Ⓖ', - 'ⓗ' => 'Ⓗ', - 'ⓘ' => 'Ⓘ', - 'ⓙ' => 'Ⓙ', - 'ⓚ' => 'Ⓚ', - 'ⓛ' => 'Ⓛ', - 'ⓜ' => 'Ⓜ', - 'ⓝ' => 'Ⓝ', - 'ⓞ' => 'Ⓞ', - 'ⓟ' => 'Ⓟ', - 'ⓠ' => 'Ⓠ', - 'ⓡ' => 'Ⓡ', - 'ⓢ' => 'Ⓢ', - 'ⓣ' => 'Ⓣ', - 'ⓤ' => 'Ⓤ', - 'ⓥ' => 'Ⓥ', - 'ⓦ' => 'Ⓦ', - 'ⓧ' => 'Ⓧ', - 'ⓨ' => 'Ⓨ', - 'ⓩ' => 'Ⓩ', - 'ⰰ' => 'Ⰰ', - 'ⰱ' => 'Ⰱ', - 'ⰲ' => 'Ⰲ', - 'ⰳ' => 'Ⰳ', - 'ⰴ' => 'Ⰴ', - 'ⰵ' => 'Ⰵ', - 'ⰶ' => 'Ⰶ', - 'ⰷ' => 'Ⰷ', - 'ⰸ' => 'Ⰸ', - 'ⰹ' => 'Ⰹ', - 'ⰺ' => 'Ⰺ', - 'ⰻ' => 'Ⰻ', - 'ⰼ' => 'Ⰼ', - 'ⰽ' => 'Ⰽ', - 'ⰾ' => 'Ⰾ', - 'ⰿ' => 'Ⰿ', - 'ⱀ' => 'Ⱀ', - 'ⱁ' => 'Ⱁ', - 'ⱂ' => 'Ⱂ', - 'ⱃ' => 'Ⱃ', - 'ⱄ' => 'Ⱄ', - 'ⱅ' => 'Ⱅ', - 'ⱆ' => 'Ⱆ', - 'ⱇ' => 'Ⱇ', - 'ⱈ' => 'Ⱈ', - 'ⱉ' => 'Ⱉ', - 'ⱊ' => 'Ⱊ', - 'ⱋ' => 'Ⱋ', - 'ⱌ' => 'Ⱌ', - 'ⱍ' => 'Ⱍ', - 'ⱎ' => 'Ⱎ', - 'ⱏ' => 'Ⱏ', - 'ⱐ' => 'Ⱐ', - 'ⱑ' => 'Ⱑ', - 'ⱒ' => 'Ⱒ', - 'ⱓ' => 'Ⱓ', - 'ⱔ' => 'Ⱔ', - 'ⱕ' => 'Ⱕ', - 'ⱖ' => 'Ⱖ', - 'ⱗ' => 'Ⱗ', - 'ⱘ' => 'Ⱘ', - 'ⱙ' => 'Ⱙ', - 'ⱚ' => 'Ⱚ', - 'ⱛ' => 'Ⱛ', - 'ⱜ' => 'Ⱜ', - 'ⱝ' => 'Ⱝ', - 'ⱞ' => 'Ⱞ', - 'ⱡ' => 'Ⱡ', - 'ⱥ' => 'Ⱥ', - 'ⱦ' => 'Ⱦ', - 'ⱨ' => 'Ⱨ', - 'ⱪ' => 'Ⱪ', - 'ⱬ' => 'Ⱬ', - 'ⱳ' => 'Ⱳ', - 'ⱶ' => 'Ⱶ', - 'ⲁ' => 'Ⲁ', - 'ⲃ' => 'Ⲃ', - 'ⲅ' => 'Ⲅ', - 'ⲇ' => 'Ⲇ', - 'ⲉ' => 'Ⲉ', - 'ⲋ' => 'Ⲋ', - 'ⲍ' => 'Ⲍ', - 'ⲏ' => 'Ⲏ', - 'ⲑ' => 'Ⲑ', - 'ⲓ' => 'Ⲓ', - 'ⲕ' => 'Ⲕ', - 'ⲗ' => 'Ⲗ', - 'ⲙ' => 'Ⲙ', - 'ⲛ' => 'Ⲛ', - 'ⲝ' => 'Ⲝ', - 'ⲟ' => 'Ⲟ', - 'ⲡ' => 'Ⲡ', - 'ⲣ' => 'Ⲣ', - 'ⲥ' => 'Ⲥ', - 'ⲧ' => 'Ⲧ', - 'ⲩ' => 'Ⲩ', - 'ⲫ' => 'Ⲫ', - 'ⲭ' => 'Ⲭ', - 'ⲯ' => 'Ⲯ', - 'ⲱ' => 'Ⲱ', - 'ⲳ' => 'Ⲳ', - 'ⲵ' => 'Ⲵ', - 'ⲷ' => 'Ⲷ', - 'ⲹ' => 'Ⲹ', - 'ⲻ' => 'Ⲻ', - 'ⲽ' => 'Ⲽ', - 'ⲿ' => 'Ⲿ', - 'ⳁ' => 'Ⳁ', - 'ⳃ' => 'Ⳃ', - 'ⳅ' => 'Ⳅ', - 'ⳇ' => 'Ⳇ', - 'ⳉ' => 'Ⳉ', - 'ⳋ' => 'Ⳋ', - 'ⳍ' => 'Ⳍ', - 'ⳏ' => 'Ⳏ', - 'ⳑ' => 'Ⳑ', - 'ⳓ' => 'Ⳓ', - 'ⳕ' => 'Ⳕ', - 'ⳗ' => 'Ⳗ', - 'ⳙ' => 'Ⳙ', - 'ⳛ' => 'Ⳛ', - 'ⳝ' => 'Ⳝ', - 'ⳟ' => 'Ⳟ', - 'ⳡ' => 'Ⳡ', - 'ⳣ' => 'Ⳣ', - 'ⳬ' => 'Ⳬ', - 'ⳮ' => 'Ⳮ', - 'ⳳ' => 'Ⳳ', - 'ⴀ' => 'Ⴀ', - 'ⴁ' => 'Ⴁ', - 'ⴂ' => 'Ⴂ', - 'ⴃ' => 'Ⴃ', - 'ⴄ' => 'Ⴄ', - 'ⴅ' => 'Ⴅ', - 'ⴆ' => 'Ⴆ', - 'ⴇ' => 'Ⴇ', - 'ⴈ' => 'Ⴈ', - 'ⴉ' => 'Ⴉ', - 'ⴊ' => 'Ⴊ', - 'ⴋ' => 'Ⴋ', - 'ⴌ' => 'Ⴌ', - 'ⴍ' => 'Ⴍ', - 'ⴎ' => 'Ⴎ', - 'ⴏ' => 'Ⴏ', - 'ⴐ' => 'Ⴐ', - 'ⴑ' => 'Ⴑ', - 'ⴒ' => 'Ⴒ', - 'ⴓ' => 'Ⴓ', - 'ⴔ' => 'Ⴔ', - 'ⴕ' => 'Ⴕ', - 'ⴖ' => 'Ⴖ', - 'ⴗ' => 'Ⴗ', - 'ⴘ' => 'Ⴘ', - 'ⴙ' => 'Ⴙ', - 'ⴚ' => 'Ⴚ', - 'ⴛ' => 'Ⴛ', - 'ⴜ' => 'Ⴜ', - 'ⴝ' => 'Ⴝ', - 'ⴞ' => 'Ⴞ', - 'ⴟ' => 'Ⴟ', - 'ⴠ' => 'Ⴠ', - 'ⴡ' => 'Ⴡ', - 'ⴢ' => 'Ⴢ', - 'ⴣ' => 'Ⴣ', - 'ⴤ' => 'Ⴤ', - 'ⴥ' => 'Ⴥ', - 'ⴧ' => 'Ⴧ', - 'ⴭ' => 'Ⴭ', - 'ꙁ' => 'Ꙁ', - 'ꙃ' => 'Ꙃ', - 'ꙅ' => 'Ꙅ', - 'ꙇ' => 'Ꙇ', - 'ꙉ' => 'Ꙉ', - 'ꙋ' => 'Ꙋ', - 'ꙍ' => 'Ꙍ', - 'ꙏ' => 'Ꙏ', - 'ꙑ' => 'Ꙑ', - 'ꙓ' => 'Ꙓ', - 'ꙕ' => 'Ꙕ', - 'ꙗ' => 'Ꙗ', - 'ꙙ' => 'Ꙙ', - 'ꙛ' => 'Ꙛ', - 'ꙝ' => 'Ꙝ', - 'ꙟ' => 'Ꙟ', - 'ꙡ' => 'Ꙡ', - 'ꙣ' => 'Ꙣ', - 'ꙥ' => 'Ꙥ', - 'ꙧ' => 'Ꙧ', - 'ꙩ' => 'Ꙩ', - 'ꙫ' => 'Ꙫ', - 'ꙭ' => 'Ꙭ', - 'ꚁ' => 'Ꚁ', - 'ꚃ' => 'Ꚃ', - 'ꚅ' => 'Ꚅ', - 'ꚇ' => 'Ꚇ', - 'ꚉ' => 'Ꚉ', - 'ꚋ' => 'Ꚋ', - 'ꚍ' => 'Ꚍ', - 'ꚏ' => 'Ꚏ', - 'ꚑ' => 'Ꚑ', - 'ꚓ' => 'Ꚓ', - 'ꚕ' => 'Ꚕ', - 'ꚗ' => 'Ꚗ', - 'ꚙ' => 'Ꚙ', - 'ꚛ' => 'Ꚛ', - 'ꜣ' => 'Ꜣ', - 'ꜥ' => 'Ꜥ', - 'ꜧ' => 'Ꜧ', - 'ꜩ' => 'Ꜩ', - 'ꜫ' => 'Ꜫ', - 'ꜭ' => 'Ꜭ', - 'ꜯ' => 'Ꜯ', - 'ꜳ' => 'Ꜳ', - 'ꜵ' => 'Ꜵ', - 'ꜷ' => 'Ꜷ', - 'ꜹ' => 'Ꜹ', - 'ꜻ' => 'Ꜻ', - 'ꜽ' => 'Ꜽ', - 'ꜿ' => 'Ꜿ', - 'ꝁ' => 'Ꝁ', - 'ꝃ' => 'Ꝃ', - 'ꝅ' => 'Ꝅ', - 'ꝇ' => 'Ꝇ', - 'ꝉ' => 'Ꝉ', - 'ꝋ' => 'Ꝋ', - 'ꝍ' => 'Ꝍ', - 'ꝏ' => 'Ꝏ', - 'ꝑ' => 'Ꝑ', - 'ꝓ' => 'Ꝓ', - 'ꝕ' => 'Ꝕ', - 'ꝗ' => 'Ꝗ', - 'ꝙ' => 'Ꝙ', - 'ꝛ' => 'Ꝛ', - 'ꝝ' => 'Ꝝ', - 'ꝟ' => 'Ꝟ', - 'ꝡ' => 'Ꝡ', - 'ꝣ' => 'Ꝣ', - 'ꝥ' => 'Ꝥ', - 'ꝧ' => 'Ꝧ', - 'ꝩ' => 'Ꝩ', - 'ꝫ' => 'Ꝫ', - 'ꝭ' => 'Ꝭ', - 'ꝯ' => 'Ꝯ', - 'ꝺ' => 'Ꝺ', - 'ꝼ' => 'Ꝼ', - 'ꝿ' => 'Ꝿ', - 'ꞁ' => 'Ꞁ', - 'ꞃ' => 'Ꞃ', - 'ꞅ' => 'Ꞅ', - 'ꞇ' => 'Ꞇ', - 'ꞌ' => 'Ꞌ', - 'ꞑ' => 'Ꞑ', - 'ꞓ' => 'Ꞓ', - 'ꞔ' => 'Ꞔ', - 'ꞗ' => 'Ꞗ', - 'ꞙ' => 'Ꞙ', - 'ꞛ' => 'Ꞛ', - 'ꞝ' => 'Ꞝ', - 'ꞟ' => 'Ꞟ', - 'ꞡ' => 'Ꞡ', - 'ꞣ' => 'Ꞣ', - 'ꞥ' => 'Ꞥ', - 'ꞧ' => 'Ꞧ', - 'ꞩ' => 'Ꞩ', - 'ꞵ' => 'Ꞵ', - 'ꞷ' => 'Ꞷ', - 'ꞹ' => 'Ꞹ', - 'ꞻ' => 'Ꞻ', - 'ꞽ' => 'Ꞽ', - 'ꞿ' => 'Ꞿ', - 'ꟃ' => 'Ꟃ', - 'ꟈ' => 'Ꟈ', - 'ꟊ' => 'Ꟊ', - 'ꟶ' => 'Ꟶ', - 'ꭓ' => 'Ꭓ', - 'ꭰ' => 'Ꭰ', - 'ꭱ' => 'Ꭱ', - 'ꭲ' => 'Ꭲ', - 'ꭳ' => 'Ꭳ', - 'ꭴ' => 'Ꭴ', - 'ꭵ' => 'Ꭵ', - 'ꭶ' => 'Ꭶ', - 'ꭷ' => 'Ꭷ', - 'ꭸ' => 'Ꭸ', - 'ꭹ' => 'Ꭹ', - 'ꭺ' => 'Ꭺ', - 'ꭻ' => 'Ꭻ', - 'ꭼ' => 'Ꭼ', - 'ꭽ' => 'Ꭽ', - 'ꭾ' => 'Ꭾ', - 'ꭿ' => 'Ꭿ', - 'ꮀ' => 'Ꮀ', - 'ꮁ' => 'Ꮁ', - 'ꮂ' => 'Ꮂ', - 'ꮃ' => 'Ꮃ', - 'ꮄ' => 'Ꮄ', - 'ꮅ' => 'Ꮅ', - 'ꮆ' => 'Ꮆ', - 'ꮇ' => 'Ꮇ', - 'ꮈ' => 'Ꮈ', - 'ꮉ' => 'Ꮉ', - 'ꮊ' => 'Ꮊ', - 'ꮋ' => 'Ꮋ', - 'ꮌ' => 'Ꮌ', - 'ꮍ' => 'Ꮍ', - 'ꮎ' => 'Ꮎ', - 'ꮏ' => 'Ꮏ', - 'ꮐ' => 'Ꮐ', - 'ꮑ' => 'Ꮑ', - 'ꮒ' => 'Ꮒ', - 'ꮓ' => 'Ꮓ', - 'ꮔ' => 'Ꮔ', - 'ꮕ' => 'Ꮕ', - 'ꮖ' => 'Ꮖ', - 'ꮗ' => 'Ꮗ', - 'ꮘ' => 'Ꮘ', - 'ꮙ' => 'Ꮙ', - 'ꮚ' => 'Ꮚ', - 'ꮛ' => 'Ꮛ', - 'ꮜ' => 'Ꮜ', - 'ꮝ' => 'Ꮝ', - 'ꮞ' => 'Ꮞ', - 'ꮟ' => 'Ꮟ', - 'ꮠ' => 'Ꮠ', - 'ꮡ' => 'Ꮡ', - 'ꮢ' => 'Ꮢ', - 'ꮣ' => 'Ꮣ', - 'ꮤ' => 'Ꮤ', - 'ꮥ' => 'Ꮥ', - 'ꮦ' => 'Ꮦ', - 'ꮧ' => 'Ꮧ', - 'ꮨ' => 'Ꮨ', - 'ꮩ' => 'Ꮩ', - 'ꮪ' => 'Ꮪ', - 'ꮫ' => 'Ꮫ', - 'ꮬ' => 'Ꮬ', - 'ꮭ' => 'Ꮭ', - 'ꮮ' => 'Ꮮ', - 'ꮯ' => 'Ꮯ', - 'ꮰ' => 'Ꮰ', - 'ꮱ' => 'Ꮱ', - 'ꮲ' => 'Ꮲ', - 'ꮳ' => 'Ꮳ', - 'ꮴ' => 'Ꮴ', - 'ꮵ' => 'Ꮵ', - 'ꮶ' => 'Ꮶ', - 'ꮷ' => 'Ꮷ', - 'ꮸ' => 'Ꮸ', - 'ꮹ' => 'Ꮹ', - 'ꮺ' => 'Ꮺ', - 'ꮻ' => 'Ꮻ', - 'ꮼ' => 'Ꮼ', - 'ꮽ' => 'Ꮽ', - 'ꮾ' => 'Ꮾ', - 'ꮿ' => 'Ꮿ', - 'a' => 'A', - 'b' => 'B', - 'c' => 'C', - 'd' => 'D', - 'e' => 'E', - 'f' => 'F', - 'g' => 'G', - 'h' => 'H', - 'i' => 'I', - 'j' => 'J', - 'k' => 'K', - 'l' => 'L', - 'm' => 'M', - 'n' => 'N', - 'o' => 'O', - 'p' => 'P', - 'q' => 'Q', - 'r' => 'R', - 's' => 'S', - 't' => 'T', - 'u' => 'U', - 'v' => 'V', - 'w' => 'W', - 'x' => 'X', - 'y' => 'Y', - 'z' => 'Z', - '𐐨' => '𐐀', - '𐐩' => '𐐁', - '𐐪' => '𐐂', - '𐐫' => '𐐃', - '𐐬' => '𐐄', - '𐐭' => '𐐅', - '𐐮' => '𐐆', - '𐐯' => '𐐇', - '𐐰' => '𐐈', - '𐐱' => '𐐉', - '𐐲' => '𐐊', - '𐐳' => '𐐋', - '𐐴' => '𐐌', - '𐐵' => '𐐍', - '𐐶' => '𐐎', - '𐐷' => '𐐏', - '𐐸' => '𐐐', - '𐐹' => '𐐑', - '𐐺' => '𐐒', - '𐐻' => '𐐓', - '𐐼' => '𐐔', - '𐐽' => '𐐕', - '𐐾' => '𐐖', - '𐐿' => '𐐗', - '𐑀' => '𐐘', - '𐑁' => '𐐙', - '𐑂' => '𐐚', - '𐑃' => '𐐛', - '𐑄' => '𐐜', - '𐑅' => '𐐝', - '𐑆' => '𐐞', - '𐑇' => '𐐟', - '𐑈' => '𐐠', - '𐑉' => '𐐡', - '𐑊' => '𐐢', - '𐑋' => '𐐣', - '𐑌' => '𐐤', - '𐑍' => '𐐥', - '𐑎' => '𐐦', - '𐑏' => '𐐧', - '𐓘' => '𐒰', - '𐓙' => '𐒱', - '𐓚' => '𐒲', - '𐓛' => '𐒳', - '𐓜' => '𐒴', - '𐓝' => '𐒵', - '𐓞' => '𐒶', - '𐓟' => '𐒷', - '𐓠' => '𐒸', - '𐓡' => '𐒹', - '𐓢' => '𐒺', - '𐓣' => '𐒻', - '𐓤' => '𐒼', - '𐓥' => '𐒽', - '𐓦' => '𐒾', - '𐓧' => '𐒿', - '𐓨' => '𐓀', - '𐓩' => '𐓁', - '𐓪' => '𐓂', - '𐓫' => '𐓃', - '𐓬' => '𐓄', - '𐓭' => '𐓅', - '𐓮' => '𐓆', - '𐓯' => '𐓇', - '𐓰' => '𐓈', - '𐓱' => '𐓉', - '𐓲' => '𐓊', - '𐓳' => '𐓋', - '𐓴' => '𐓌', - '𐓵' => '𐓍', - '𐓶' => '𐓎', - '𐓷' => '𐓏', - '𐓸' => '𐓐', - '𐓹' => '𐓑', - '𐓺' => '𐓒', - '𐓻' => '𐓓', - '𐳀' => '𐲀', - '𐳁' => '𐲁', - '𐳂' => '𐲂', - '𐳃' => '𐲃', - '𐳄' => '𐲄', - '𐳅' => '𐲅', - '𐳆' => '𐲆', - '𐳇' => '𐲇', - '𐳈' => '𐲈', - '𐳉' => '𐲉', - '𐳊' => '𐲊', - '𐳋' => '𐲋', - '𐳌' => '𐲌', - '𐳍' => '𐲍', - '𐳎' => '𐲎', - '𐳏' => '𐲏', - '𐳐' => '𐲐', - '𐳑' => '𐲑', - '𐳒' => '𐲒', - '𐳓' => '𐲓', - '𐳔' => '𐲔', - '𐳕' => '𐲕', - '𐳖' => '𐲖', - '𐳗' => '𐲗', - '𐳘' => '𐲘', - '𐳙' => '𐲙', - '𐳚' => '𐲚', - '𐳛' => '𐲛', - '𐳜' => '𐲜', - '𐳝' => '𐲝', - '𐳞' => '𐲞', - '𐳟' => '𐲟', - '𐳠' => '𐲠', - '𐳡' => '𐲡', - '𐳢' => '𐲢', - '𐳣' => '𐲣', - '𐳤' => '𐲤', - '𐳥' => '𐲥', - '𐳦' => '𐲦', - '𐳧' => '𐲧', - '𐳨' => '𐲨', - '𐳩' => '𐲩', - '𐳪' => '𐲪', - '𐳫' => '𐲫', - '𐳬' => '𐲬', - '𐳭' => '𐲭', - '𐳮' => '𐲮', - '𐳯' => '𐲯', - '𐳰' => '𐲰', - '𐳱' => '𐲱', - '𐳲' => '𐲲', - '𑣀' => '𑢠', - '𑣁' => '𑢡', - '𑣂' => '𑢢', - '𑣃' => '𑢣', - '𑣄' => '𑢤', - '𑣅' => '𑢥', - '𑣆' => '𑢦', - '𑣇' => '𑢧', - '𑣈' => '𑢨', - '𑣉' => '𑢩', - '𑣊' => '𑢪', - '𑣋' => '𑢫', - '𑣌' => '𑢬', - '𑣍' => '𑢭', - '𑣎' => '𑢮', - '𑣏' => '𑢯', - '𑣐' => '𑢰', - '𑣑' => '𑢱', - '𑣒' => '𑢲', - '𑣓' => '𑢳', - '𑣔' => '𑢴', - '𑣕' => '𑢵', - '𑣖' => '𑢶', - '𑣗' => '𑢷', - '𑣘' => '𑢸', - '𑣙' => '𑢹', - '𑣚' => '𑢺', - '𑣛' => '𑢻', - '𑣜' => '𑢼', - '𑣝' => '𑢽', - '𑣞' => '𑢾', - '𑣟' => '𑢿', - '𖹠' => '𖹀', - '𖹡' => '𖹁', - '𖹢' => '𖹂', - '𖹣' => '𖹃', - '𖹤' => '𖹄', - '𖹥' => '𖹅', - '𖹦' => '𖹆', - '𖹧' => '𖹇', - '𖹨' => '𖹈', - '𖹩' => '𖹉', - '𖹪' => '𖹊', - '𖹫' => '𖹋', - '𖹬' => '𖹌', - '𖹭' => '𖹍', - '𖹮' => '𖹎', - '𖹯' => '𖹏', - '𖹰' => '𖹐', - '𖹱' => '𖹑', - '𖹲' => '𖹒', - '𖹳' => '𖹓', - '𖹴' => '𖹔', - '𖹵' => '𖹕', - '𖹶' => '𖹖', - '𖹷' => '𖹗', - '𖹸' => '𖹘', - '𖹹' => '𖹙', - '𖹺' => '𖹚', - '𖹻' => '𖹛', - '𖹼' => '𖹜', - '𖹽' => '𖹝', - '𖹾' => '𖹞', - '𖹿' => '𖹟', - '𞤢' => '𞤀', - '𞤣' => '𞤁', - '𞤤' => '𞤂', - '𞤥' => '𞤃', - '𞤦' => '𞤄', - '𞤧' => '𞤅', - '𞤨' => '𞤆', - '𞤩' => '𞤇', - '𞤪' => '𞤈', - '𞤫' => '𞤉', - '𞤬' => '𞤊', - '𞤭' => '𞤋', - '𞤮' => '𞤌', - '𞤯' => '𞤍', - '𞤰' => '𞤎', - '𞤱' => '𞤏', - '𞤲' => '𞤐', - '𞤳' => '𞤑', - '𞤴' => '𞤒', - '𞤵' => '𞤓', - '𞤶' => '𞤔', - '𞤷' => '𞤕', - '𞤸' => '𞤖', - '𞤹' => '𞤗', - '𞤺' => '𞤘', - '𞤻' => '𞤙', - '𞤼' => '𞤚', - '𞤽' => '𞤛', - '𞤾' => '𞤜', - '𞤿' => '𞤝', - '𞥀' => '𞤞', - '𞥁' => '𞤟', - '𞥂' => '𞤠', - '𞥃' => '𞤡', - 'ß' => 'SS', - 'ff' => 'FF', - 'fi' => 'FI', - 'fl' => 'FL', - 'ffi' => 'FFI', - 'ffl' => 'FFL', - 'ſt' => 'ST', - 'st' => 'ST', - 'և' => 'ԵՒ', - 'ﬓ' => 'ՄՆ', - 'ﬔ' => 'ՄԵ', - 'ﬕ' => 'ՄԻ', - 'ﬖ' => 'ՎՆ', - 'ﬗ' => 'ՄԽ', - 'ʼn' => 'ʼN', - 'ΐ' => 'Ϊ́', - 'ΰ' => 'Ϋ́', - 'ǰ' => 'J̌', - 'ẖ' => 'H̱', - 'ẗ' => 'T̈', - 'ẘ' => 'W̊', - 'ẙ' => 'Y̊', - 'ẚ' => 'Aʾ', - 'ὐ' => 'Υ̓', - 'ὒ' => 'Υ̓̀', - 'ὔ' => 'Υ̓́', - 'ὖ' => 'Υ̓͂', - 'ᾶ' => 'Α͂', - 'ῆ' => 'Η͂', - 'ῒ' => 'Ϊ̀', - 'ΐ' => 'Ϊ́', - 'ῖ' => 'Ι͂', - 'ῗ' => 'Ϊ͂', - 'ῢ' => 'Ϋ̀', - 'ΰ' => 'Ϋ́', - 'ῤ' => 'Ρ̓', - 'ῦ' => 'Υ͂', - 'ῧ' => 'Ϋ͂', - 'ῶ' => 'Ω͂', - 'ᾈ' => 'ἈΙ', - 'ᾉ' => 'ἉΙ', - 'ᾊ' => 'ἊΙ', - 'ᾋ' => 'ἋΙ', - 'ᾌ' => 'ἌΙ', - 'ᾍ' => 'ἍΙ', - 'ᾎ' => 'ἎΙ', - 'ᾏ' => 'ἏΙ', - 'ᾘ' => 'ἨΙ', - 'ᾙ' => 'ἩΙ', - 'ᾚ' => 'ἪΙ', - 'ᾛ' => 'ἫΙ', - 'ᾜ' => 'ἬΙ', - 'ᾝ' => 'ἭΙ', - 'ᾞ' => 'ἮΙ', - 'ᾟ' => 'ἯΙ', - 'ᾨ' => 'ὨΙ', - 'ᾩ' => 'ὩΙ', - 'ᾪ' => 'ὪΙ', - 'ᾫ' => 'ὫΙ', - 'ᾬ' => 'ὬΙ', - 'ᾭ' => 'ὭΙ', - 'ᾮ' => 'ὮΙ', - 'ᾯ' => 'ὯΙ', - 'ᾼ' => 'ΑΙ', - 'ῌ' => 'ΗΙ', - 'ῼ' => 'ΩΙ', - 'ᾲ' => 'ᾺΙ', - 'ᾴ' => 'ΆΙ', - 'ῂ' => 'ῊΙ', - 'ῄ' => 'ΉΙ', - 'ῲ' => 'ῺΙ', - 'ῴ' => 'ΏΙ', - 'ᾷ' => 'Α͂Ι', - 'ῇ' => 'Η͂Ι', - 'ῷ' => 'Ω͂Ι', -); diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php deleted file mode 100644 index ecf1a03..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap.php +++ /dev/null @@ -1,151 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Mbstring as p; - -if (\PHP_VERSION_ID >= 80000) { - return require __DIR__.'/bootstrap80.php'; -} - -if (!function_exists('mb_convert_encoding')) { - function mb_convert_encoding($string, $to_encoding, $from_encoding = null) { return p\Mbstring::mb_convert_encoding($string, $to_encoding, $from_encoding); } -} -if (!function_exists('mb_decode_mimeheader')) { - function mb_decode_mimeheader($string) { return p\Mbstring::mb_decode_mimeheader($string); } -} -if (!function_exists('mb_encode_mimeheader')) { - function mb_encode_mimeheader($string, $charset = null, $transfer_encoding = null, $newline = "\r\n", $indent = 0) { return p\Mbstring::mb_encode_mimeheader($string, $charset, $transfer_encoding, $newline, $indent); } -} -if (!function_exists('mb_decode_numericentity')) { - function mb_decode_numericentity($string, $map, $encoding = null) { return p\Mbstring::mb_decode_numericentity($string, $map, $encoding); } -} -if (!function_exists('mb_encode_numericentity')) { - function mb_encode_numericentity($string, $map, $encoding = null, $hex = false) { return p\Mbstring::mb_encode_numericentity($string, $map, $encoding, $hex); } -} -if (!function_exists('mb_convert_case')) { - function mb_convert_case($string, $mode, $encoding = null) { return p\Mbstring::mb_convert_case($string, $mode, $encoding); } -} -if (!function_exists('mb_internal_encoding')) { - function mb_internal_encoding($encoding = null) { return p\Mbstring::mb_internal_encoding($encoding); } -} -if (!function_exists('mb_language')) { - function mb_language($language = null) { return p\Mbstring::mb_language($language); } -} -if (!function_exists('mb_list_encodings')) { - function mb_list_encodings() { return p\Mbstring::mb_list_encodings(); } -} -if (!function_exists('mb_encoding_aliases')) { - function mb_encoding_aliases($encoding) { return p\Mbstring::mb_encoding_aliases($encoding); } -} -if (!function_exists('mb_check_encoding')) { - function mb_check_encoding($value = null, $encoding = null) { return p\Mbstring::mb_check_encoding($value, $encoding); } -} -if (!function_exists('mb_detect_encoding')) { - function mb_detect_encoding($string, $encodings = null, $strict = false) { return p\Mbstring::mb_detect_encoding($string, $encodings, $strict); } -} -if (!function_exists('mb_detect_order')) { - function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } -} -if (!function_exists('mb_parse_str')) { - function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; } -} -if (!function_exists('mb_strlen')) { - function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } -} -if (!function_exists('mb_strpos')) { - function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strpos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_strtolower')) { - function mb_strtolower($string, $encoding = null) { return p\Mbstring::mb_strtolower($string, $encoding); } -} -if (!function_exists('mb_strtoupper')) { - function mb_strtoupper($string, $encoding = null) { return p\Mbstring::mb_strtoupper($string, $encoding); } -} -if (!function_exists('mb_substitute_character')) { - function mb_substitute_character($substitute_character = null) { return p\Mbstring::mb_substitute_character($substitute_character); } -} -if (!function_exists('mb_substr')) { - function mb_substr($string, $start, $length = 2147483647, $encoding = null) { return p\Mbstring::mb_substr($string, $start, $length, $encoding); } -} -if (!function_exists('mb_stripos')) { - function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_stripos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_stristr')) { - function mb_stristr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_stristr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_strrchr')) { - function mb_strrchr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrchr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_strrichr')) { - function mb_strrichr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strrichr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_strripos')) { - function mb_strripos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strripos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_strrpos')) { - function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) { return p\Mbstring::mb_strrpos($haystack, $needle, $offset, $encoding); } -} -if (!function_exists('mb_strstr')) { - function mb_strstr($haystack, $needle, $before_needle = false, $encoding = null) { return p\Mbstring::mb_strstr($haystack, $needle, $before_needle, $encoding); } -} -if (!function_exists('mb_get_info')) { - function mb_get_info($type = 'all') { return p\Mbstring::mb_get_info($type); } -} -if (!function_exists('mb_http_output')) { - function mb_http_output($encoding = null) { return p\Mbstring::mb_http_output($encoding); } -} -if (!function_exists('mb_strwidth')) { - function mb_strwidth($string, $encoding = null) { return p\Mbstring::mb_strwidth($string, $encoding); } -} -if (!function_exists('mb_substr_count')) { - function mb_substr_count($haystack, $needle, $encoding = null) { return p\Mbstring::mb_substr_count($haystack, $needle, $encoding); } -} -if (!function_exists('mb_output_handler')) { - function mb_output_handler($string, $status) { return p\Mbstring::mb_output_handler($string, $status); } -} -if (!function_exists('mb_http_input')) { - function mb_http_input($type = null) { return p\Mbstring::mb_http_input($type); } -} - -if (!function_exists('mb_convert_variables')) { - function mb_convert_variables($to_encoding, $from_encoding, &...$vars) { return p\Mbstring::mb_convert_variables($to_encoding, $from_encoding, ...$vars); } -} - -if (!function_exists('mb_ord')) { - function mb_ord($string, $encoding = null) { return p\Mbstring::mb_ord($string, $encoding); } -} -if (!function_exists('mb_chr')) { - function mb_chr($codepoint, $encoding = null) { return p\Mbstring::mb_chr($codepoint, $encoding); } -} -if (!function_exists('mb_scrub')) { - function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); } -} -if (!function_exists('mb_str_split')) { - function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstring::mb_str_split($string, $length, $encoding); } -} - -if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } -} - -if (extension_loaded('mbstring')) { - return; -} - -if (!defined('MB_CASE_UPPER')) { - define('MB_CASE_UPPER', 0); -} -if (!defined('MB_CASE_LOWER')) { - define('MB_CASE_LOWER', 1); -} -if (!defined('MB_CASE_TITLE')) { - define('MB_CASE_TITLE', 2); -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php deleted file mode 100644 index 2f9fb5b..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/bootstrap80.php +++ /dev/null @@ -1,147 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Mbstring as p; - -if (!function_exists('mb_convert_encoding')) { - function mb_convert_encoding(array|string|null $string, ?string $to_encoding, array|string|null $from_encoding = null): array|string|false { return p\Mbstring::mb_convert_encoding($string ?? '', (string) $to_encoding, $from_encoding); } -} -if (!function_exists('mb_decode_mimeheader')) { - function mb_decode_mimeheader(?string $string): string { return p\Mbstring::mb_decode_mimeheader((string) $string); } -} -if (!function_exists('mb_encode_mimeheader')) { - function mb_encode_mimeheader(?string $string, ?string $charset = null, ?string $transfer_encoding = null, ?string $newline = "\r\n", ?int $indent = 0): string { return p\Mbstring::mb_encode_mimeheader((string) $string, $charset, $transfer_encoding, (string) $newline, (int) $indent); } -} -if (!function_exists('mb_decode_numericentity')) { - function mb_decode_numericentity(?string $string, array $map, ?string $encoding = null): string { return p\Mbstring::mb_decode_numericentity((string) $string, $map, $encoding); } -} -if (!function_exists('mb_encode_numericentity')) { - function mb_encode_numericentity(?string $string, array $map, ?string $encoding = null, ?bool $hex = false): string { return p\Mbstring::mb_encode_numericentity((string) $string, $map, $encoding, (bool) $hex); } -} -if (!function_exists('mb_convert_case')) { - function mb_convert_case(?string $string, ?int $mode, ?string $encoding = null): string { return p\Mbstring::mb_convert_case((string) $string, (int) $mode, $encoding); } -} -if (!function_exists('mb_internal_encoding')) { - function mb_internal_encoding(?string $encoding = null): string|bool { return p\Mbstring::mb_internal_encoding($encoding); } -} -if (!function_exists('mb_language')) { - function mb_language(?string $language = null): string|bool { return p\Mbstring::mb_language($language); } -} -if (!function_exists('mb_list_encodings')) { - function mb_list_encodings(): array { return p\Mbstring::mb_list_encodings(); } -} -if (!function_exists('mb_encoding_aliases')) { - function mb_encoding_aliases(?string $encoding): array { return p\Mbstring::mb_encoding_aliases((string) $encoding); } -} -if (!function_exists('mb_check_encoding')) { - function mb_check_encoding(array|string|null $value = null, ?string $encoding = null): bool { return p\Mbstring::mb_check_encoding($value, $encoding); } -} -if (!function_exists('mb_detect_encoding')) { - function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); } -} -if (!function_exists('mb_detect_order')) { - function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); } -} -if (!function_exists('mb_parse_str')) { - function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; } -} -if (!function_exists('mb_strlen')) { - function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); } -} -if (!function_exists('mb_strpos')) { - function mb_strpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } -} -if (!function_exists('mb_strtolower')) { - function mb_strtolower(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtolower((string) $string, $encoding); } -} -if (!function_exists('mb_strtoupper')) { - function mb_strtoupper(?string $string, ?string $encoding = null): string { return p\Mbstring::mb_strtoupper((string) $string, $encoding); } -} -if (!function_exists('mb_substitute_character')) { - function mb_substitute_character(string|int|null $substitute_character = null): string|int|bool { return p\Mbstring::mb_substitute_character($substitute_character); } -} -if (!function_exists('mb_substr')) { - function mb_substr(?string $string, ?int $start, ?int $length = null, ?string $encoding = null): string { return p\Mbstring::mb_substr((string) $string, (int) $start, $length, $encoding); } -} -if (!function_exists('mb_stripos')) { - function mb_stripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_stripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } -} -if (!function_exists('mb_stristr')) { - function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } -} -if (!function_exists('mb_strrchr')) { - function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } -} -if (!function_exists('mb_strrichr')) { - function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } -} -if (!function_exists('mb_strripos')) { - function mb_strripos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strripos((string) $haystack, (string) $needle, (int) $offset, $encoding); } -} -if (!function_exists('mb_strrpos')) { - function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?string $encoding = null): int|false { return p\Mbstring::mb_strrpos((string) $haystack, (string) $needle, (int) $offset, $encoding); } -} -if (!function_exists('mb_strstr')) { - function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } -} -if (!function_exists('mb_get_info')) { - function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } -} -if (!function_exists('mb_http_output')) { - function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } -} -if (!function_exists('mb_strwidth')) { - function mb_strwidth(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strwidth((string) $string, $encoding); } -} -if (!function_exists('mb_substr_count')) { - function mb_substr_count(?string $haystack, ?string $needle, ?string $encoding = null): int { return p\Mbstring::mb_substr_count((string) $haystack, (string) $needle, $encoding); } -} -if (!function_exists('mb_output_handler')) { - function mb_output_handler(?string $string, ?int $status): string { return p\Mbstring::mb_output_handler((string) $string, (int) $status); } -} -if (!function_exists('mb_http_input')) { - function mb_http_input(?string $type = null): array|string|false { return p\Mbstring::mb_http_input($type); } -} - -if (!function_exists('mb_convert_variables')) { - function mb_convert_variables(?string $to_encoding, array|string|null $from_encoding, mixed &$var, mixed &...$vars): string|false { return p\Mbstring::mb_convert_variables((string) $to_encoding, $from_encoding ?? '', $var, ...$vars); } -} - -if (!function_exists('mb_ord')) { - function mb_ord(?string $string, ?string $encoding = null): int|false { return p\Mbstring::mb_ord((string) $string, $encoding); } -} -if (!function_exists('mb_chr')) { - function mb_chr(?int $codepoint, ?string $encoding = null): string|false { return p\Mbstring::mb_chr((int) $codepoint, $encoding); } -} -if (!function_exists('mb_scrub')) { - function mb_scrub(?string $string, ?string $encoding = null): string { $encoding ??= mb_internal_encoding(); return mb_convert_encoding((string) $string, $encoding, $encoding); } -} -if (!function_exists('mb_str_split')) { - function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = null): array { return p\Mbstring::mb_str_split((string) $string, (int) $length, $encoding); } -} - -if (!function_exists('mb_str_pad')) { - function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } -} - -if (extension_loaded('mbstring')) { - return; -} - -if (!defined('MB_CASE_UPPER')) { - define('MB_CASE_UPPER', 0); -} -if (!defined('MB_CASE_LOWER')) { - define('MB_CASE_LOWER', 1); -} -if (!defined('MB_CASE_TITLE')) { - define('MB_CASE_TITLE', 2); -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json b/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json deleted file mode 100644 index 943e502..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-mbstring/composer.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "symfony/polyfill-mbstring", - "type": "library", - "description": "Symfony polyfill for the Mbstring extension", - "keywords": ["polyfill", "shim", "compatibility", "portable", "mbstring"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "provide": { - "ext-mbstring": "*" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Mbstring\\": "" }, - "files": [ "bootstrap.php" ] - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE deleted file mode 100644 index 0ed3a24..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2020-present Fabien Potencier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php deleted file mode 100644 index 362dd1a..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Php80.php +++ /dev/null @@ -1,115 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php80; - -/** - * @author Ion Bazan - * @author Nico Oelgart - * @author Nicolas Grekas - * - * @internal - */ -final class Php80 -{ - public static function fdiv(float $dividend, float $divisor): float - { - return @($dividend / $divisor); - } - - public static function get_debug_type($value): string - { - switch (true) { - case null === $value: return 'null'; - case \is_bool($value): return 'bool'; - case \is_string($value): return 'string'; - case \is_array($value): return 'array'; - case \is_int($value): return 'int'; - case \is_float($value): return 'float'; - case \is_object($value): break; - case $value instanceof \__PHP_Incomplete_Class: return '__PHP_Incomplete_Class'; - default: - if (null === $type = @get_resource_type($value)) { - return 'unknown'; - } - - if ('Unknown' === $type) { - $type = 'closed'; - } - - return "resource ($type)"; - } - - $class = \get_class($value); - - if (false === strpos($class, '@')) { - return $class; - } - - return (get_parent_class($class) ?: key(class_implements($class)) ?: 'class').'@anonymous'; - } - - public static function get_resource_id($res): int - { - if (!\is_resource($res) && null === @get_resource_type($res)) { - throw new \TypeError(sprintf('Argument 1 passed to get_resource_id() must be of the type resource, %s given', get_debug_type($res))); - } - - return (int) $res; - } - - public static function preg_last_error_msg(): string - { - switch (preg_last_error()) { - case \PREG_INTERNAL_ERROR: - return 'Internal error'; - case \PREG_BAD_UTF8_ERROR: - return 'Malformed UTF-8 characters, possibly incorrectly encoded'; - case \PREG_BAD_UTF8_OFFSET_ERROR: - return 'The offset did not correspond to the beginning of a valid UTF-8 code point'; - case \PREG_BACKTRACK_LIMIT_ERROR: - return 'Backtrack limit exhausted'; - case \PREG_RECURSION_LIMIT_ERROR: - return 'Recursion limit exhausted'; - case \PREG_JIT_STACKLIMIT_ERROR: - return 'JIT stack limit exhausted'; - case \PREG_NO_ERROR: - return 'No error'; - default: - return 'Unknown error'; - } - } - - public static function str_contains(string $haystack, string $needle): bool - { - return '' === $needle || false !== strpos($haystack, $needle); - } - - public static function str_starts_with(string $haystack, string $needle): bool - { - return 0 === strncmp($haystack, $needle, \strlen($needle)); - } - - public static function str_ends_with(string $haystack, string $needle): bool - { - if ('' === $needle || $needle === $haystack) { - return true; - } - - if ('' === $haystack) { - return false; - } - - $needleLength = \strlen($needle); - - return $needleLength <= \strlen($haystack) && 0 === substr_compare($haystack, $needle, -$needleLength); - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php deleted file mode 100644 index fe6e691..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/PhpToken.php +++ /dev/null @@ -1,103 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Polyfill\Php80; - -/** - * @author Fedonyuk Anton - * - * @internal - */ -class PhpToken implements \Stringable -{ - /** - * @var int - */ - public $id; - - /** - * @var string - */ - public $text; - - /** - * @var int - */ - public $line; - - /** - * @var int - */ - public $pos; - - public function __construct(int $id, string $text, int $line = -1, int $position = -1) - { - $this->id = $id; - $this->text = $text; - $this->line = $line; - $this->pos = $position; - } - - public function getTokenName(): ?string - { - if ('UNKNOWN' === $name = token_name($this->id)) { - $name = \strlen($this->text) > 1 || \ord($this->text) < 32 ? null : $this->text; - } - - return $name; - } - - /** - * @param int|string|array $kind - */ - public function is($kind): bool - { - foreach ((array) $kind as $value) { - if (\in_array($value, [$this->id, $this->text], true)) { - return true; - } - } - - return false; - } - - public function isIgnorable(): bool - { - return \in_array($this->id, [\T_WHITESPACE, \T_COMMENT, \T_DOC_COMMENT, \T_OPEN_TAG], true); - } - - public function __toString(): string - { - return (string) $this->text; - } - - /** - * @return static[] - */ - public static function tokenize(string $code, int $flags = 0): array - { - $line = 1; - $position = 0; - $tokens = token_get_all($code, $flags); - foreach ($tokens as $index => $token) { - if (\is_string($token)) { - $id = \ord($token); - $text = $token; - } else { - [$id, $text, $line] = $token; - } - $tokens[$index] = new static($id, $text, $line, $position); - $position += \strlen($text); - } - - return $tokens; - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md deleted file mode 100644 index 3816c55..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/README.md +++ /dev/null @@ -1,25 +0,0 @@ -Symfony Polyfill / Php80 -======================== - -This component provides features added to PHP 8.0 core: - -- [`Stringable`](https://php.net/stringable) interface -- [`fdiv`](https://php.net/fdiv) -- [`ValueError`](https://php.net/valueerror) class -- [`UnhandledMatchError`](https://php.net/unhandledmatcherror) class -- `FILTER_VALIDATE_BOOL` constant -- [`get_debug_type`](https://php.net/get_debug_type) -- [`PhpToken`](https://php.net/phptoken) class -- [`preg_last_error_msg`](https://php.net/preg_last_error_msg) -- [`str_contains`](https://php.net/str_contains) -- [`str_starts_with`](https://php.net/str_starts_with) -- [`str_ends_with`](https://php.net/str_ends_with) -- [`get_resource_id`](https://php.net/get_resource_id) - -More information can be found in the -[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md). - -License -======= - -This library is released under the [MIT license](LICENSE). diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php deleted file mode 100644 index 2b95542..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Attribute.php +++ /dev/null @@ -1,31 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -#[Attribute(Attribute::TARGET_CLASS)] -final class Attribute -{ - public const TARGET_CLASS = 1; - public const TARGET_FUNCTION = 2; - public const TARGET_METHOD = 4; - public const TARGET_PROPERTY = 8; - public const TARGET_CLASS_CONSTANT = 16; - public const TARGET_PARAMETER = 32; - public const TARGET_ALL = 63; - public const IS_REPEATABLE = 64; - - /** @var int */ - public $flags; - - public function __construct(int $flags = self::TARGET_ALL) - { - $this->flags = $flags; - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php deleted file mode 100644 index bd1212f..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (\PHP_VERSION_ID < 80000 && extension_loaded('tokenizer')) { - class PhpToken extends Symfony\Polyfill\Php80\PhpToken - { - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php deleted file mode 100644 index 7c62d75..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php +++ /dev/null @@ -1,20 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (\PHP_VERSION_ID < 80000) { - interface Stringable - { - /** - * @return string - */ - public function __toString(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php deleted file mode 100644 index 01c6c6c..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/UnhandledMatchError.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (\PHP_VERSION_ID < 80000) { - class UnhandledMatchError extends Error - { - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php deleted file mode 100644 index 783dbc2..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/Resources/stubs/ValueError.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -if (\PHP_VERSION_ID < 80000) { - class ValueError extends Error - { - } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php deleted file mode 100644 index e5f7dbc..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/bootstrap.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -use Symfony\Polyfill\Php80 as p; - -if (\PHP_VERSION_ID >= 80000) { - return; -} - -if (!defined('FILTER_VALIDATE_BOOL') && defined('FILTER_VALIDATE_BOOLEAN')) { - define('FILTER_VALIDATE_BOOL', \FILTER_VALIDATE_BOOLEAN); -} - -if (!function_exists('fdiv')) { - function fdiv(float $num1, float $num2): float { return p\Php80::fdiv($num1, $num2); } -} -if (!function_exists('preg_last_error_msg')) { - function preg_last_error_msg(): string { return p\Php80::preg_last_error_msg(); } -} -if (!function_exists('str_contains')) { - function str_contains(?string $haystack, ?string $needle): bool { return p\Php80::str_contains($haystack ?? '', $needle ?? ''); } -} -if (!function_exists('str_starts_with')) { - function str_starts_with(?string $haystack, ?string $needle): bool { return p\Php80::str_starts_with($haystack ?? '', $needle ?? ''); } -} -if (!function_exists('str_ends_with')) { - function str_ends_with(?string $haystack, ?string $needle): bool { return p\Php80::str_ends_with($haystack ?? '', $needle ?? ''); } -} -if (!function_exists('get_debug_type')) { - function get_debug_type($value): string { return p\Php80::get_debug_type($value); } -} -if (!function_exists('get_resource_id')) { - function get_resource_id($resource): int { return p\Php80::get_resource_id($resource); } -} diff --git a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json b/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json deleted file mode 100644 index f1801f4..0000000 --- a/utilities/signing_and_verification/php/vendor/symfony/polyfill-php80/composer.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "symfony/polyfill-php80", - "type": "library", - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", - "keywords": ["polyfill", "shim", "compatibility", "portable"], - "homepage": "https://symfony.com", - "license": "MIT", - "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "require": { - "php": ">=7.1" - }, - "autoload": { - "psr-4": { "Symfony\\Polyfill\\Php80\\": "" }, - "files": [ "bootstrap.php" ], - "classmap": [ "Resources/stubs" ] - }, - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE deleted file mode 100644 index 922c552..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -BSD 3-Clause License - -Copyright (c) 2014, Graham Campbell. -Copyright (c) 2013, Vance Lucas. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json deleted file mode 100644 index fb972d7..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/composer.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "vlucas/phpdotenv", - "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", - "keywords": ["env", "dotenv", "environment"], - "license": "BSD-3-Clause", - "authors": [ - { - "name": "Graham Campbell", - "email": "hello@gjcampbell.co.uk", - "homepage": "https://github.com/GrahamCampbell" - }, - { - "name": "Vance Lucas", - "email": "vance@vancelucas.com", - "homepage": "https://github.com/vlucas" - } - ], - "require": { - "php": "^7.2.5 || ^8.0", - "ext-pcre": "*", - "graham-campbell/result-type": "^1.1.2", - "phpoption/phpoption": "^1.9.2", - "symfony/polyfill-ctype": "^1.24", - "symfony/polyfill-mbstring": "^1.24", - "symfony/polyfill-php80": "^1.24" - }, - "require-dev": { - "ext-filter": "*", - "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit":"^8.5.34 || ^9.6.13 || ^10.4.2" - }, - "autoload": { - "psr-4": { - "Dotenv\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Dotenv\\Tests\\": "tests/Dotenv/" - } - }, - "suggest": { - "ext-filter": "Required to use the boolean validator." - }, - "config": { - "allow-plugins": { - "bamarni/composer-bin-plugin": true - }, - "preferred-install": "dist" - }, - "extra": { - "bamarni-bin": { - "bin-links": true, - "forward-command": true - }, - "branch-alias": { - "dev-master": "5.6-dev" - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php deleted file mode 100644 index 0460ced..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Dotenv.php +++ /dev/null @@ -1,267 +0,0 @@ -store = $store; - $this->parser = $parser; - $this->loader = $loader; - $this->repository = $repository; - } - - /** - * Create a new dotenv instance. - * - * @param \Dotenv\Repository\RepositoryInterface $repository - * @param string|string[] $paths - * @param string|string[]|null $names - * @param bool $shortCircuit - * @param string|null $fileEncoding - * - * @return \Dotenv\Dotenv - */ - public static function create(RepositoryInterface $repository, $paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) - { - $builder = $names === null ? StoreBuilder::createWithDefaultName() : StoreBuilder::createWithNoNames(); - - foreach ((array) $paths as $path) { - $builder = $builder->addPath($path); - } - - foreach ((array) $names as $name) { - $builder = $builder->addName($name); - } - - if ($shortCircuit) { - $builder = $builder->shortCircuit(); - } - - return new self($builder->fileEncoding($fileEncoding)->make(), new Parser(), new Loader(), $repository); - } - - /** - * Create a new mutable dotenv instance with default repository. - * - * @param string|string[] $paths - * @param string|string[]|null $names - * @param bool $shortCircuit - * @param string|null $fileEncoding - * - * @return \Dotenv\Dotenv - */ - public static function createMutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) - { - $repository = RepositoryBuilder::createWithDefaultAdapters()->make(); - - return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); - } - - /** - * Create a new mutable dotenv instance with default repository with the putenv adapter. - * - * @param string|string[] $paths - * @param string|string[]|null $names - * @param bool $shortCircuit - * @param string|null $fileEncoding - * - * @return \Dotenv\Dotenv - */ - public static function createUnsafeMutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) - { - $repository = RepositoryBuilder::createWithDefaultAdapters() - ->addAdapter(PutenvAdapter::class) - ->make(); - - return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); - } - - /** - * Create a new immutable dotenv instance with default repository. - * - * @param string|string[] $paths - * @param string|string[]|null $names - * @param bool $shortCircuit - * @param string|null $fileEncoding - * - * @return \Dotenv\Dotenv - */ - public static function createImmutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) - { - $repository = RepositoryBuilder::createWithDefaultAdapters()->immutable()->make(); - - return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); - } - - /** - * Create a new immutable dotenv instance with default repository with the putenv adapter. - * - * @param string|string[] $paths - * @param string|string[]|null $names - * @param bool $shortCircuit - * @param string|null $fileEncoding - * - * @return \Dotenv\Dotenv - */ - public static function createUnsafeImmutable($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) - { - $repository = RepositoryBuilder::createWithDefaultAdapters() - ->addAdapter(PutenvAdapter::class) - ->immutable() - ->make(); - - return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); - } - - /** - * Create a new dotenv instance with an array backed repository. - * - * @param string|string[] $paths - * @param string|string[]|null $names - * @param bool $shortCircuit - * @param string|null $fileEncoding - * - * @return \Dotenv\Dotenv - */ - public static function createArrayBacked($paths, $names = null, bool $shortCircuit = true, string $fileEncoding = null) - { - $repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make(); - - return self::create($repository, $paths, $names, $shortCircuit, $fileEncoding); - } - - /** - * Parse the given content and resolve nested variables. - * - * This method behaves just like load(), only without mutating your actual - * environment. We do this by using an array backed repository. - * - * @param string $content - * - * @throws \Dotenv\Exception\InvalidFileException - * - * @return array - */ - public static function parse(string $content) - { - $repository = RepositoryBuilder::createWithNoAdapters()->addAdapter(ArrayAdapter::class)->make(); - - $phpdotenv = new self(new StringStore($content), new Parser(), new Loader(), $repository); - - return $phpdotenv->load(); - } - - /** - * Read and load environment file(s). - * - * @throws \Dotenv\Exception\InvalidPathException|\Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException - * - * @return array - */ - public function load() - { - $entries = $this->parser->parse($this->store->read()); - - return $this->loader->load($this->repository, $entries); - } - - /** - * Read and load environment file(s), silently failing if no files can be read. - * - * @throws \Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidFileException - * - * @return array - */ - public function safeLoad() - { - try { - return $this->load(); - } catch (InvalidPathException $e) { - // suppressing exception - return []; - } - } - - /** - * Required ensures that the specified variables exist, and returns a new validator object. - * - * @param string|string[] $variables - * - * @return \Dotenv\Validator - */ - public function required($variables) - { - return (new Validator($this->repository, (array) $variables))->required(); - } - - /** - * Returns a new validator object that won't check if the specified variables exist. - * - * @param string|string[] $variables - * - * @return \Dotenv\Validator - */ - public function ifPresent($variables) - { - return new Validator($this->repository, (array) $variables); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php deleted file mode 100644 index 1e80f53..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Exception/ExceptionInterface.php +++ /dev/null @@ -1,12 +0,0 @@ - - */ - public function load(RepositoryInterface $repository, array $entries) - { - return \array_reduce($entries, static function (array $vars, Entry $entry) use ($repository) { - $name = $entry->getName(); - - $value = $entry->getValue()->map(static function (Value $value) use ($repository) { - return Resolver::resolve($repository, $value); - }); - - if ($value->isDefined()) { - $inner = $value->get(); - if ($repository->set($name, $inner)) { - return \array_merge($vars, [$name => $inner]); - } - } else { - if ($repository->clear($name)) { - return \array_merge($vars, [$name => null]); - } - } - - return $vars; - }, []); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php deleted file mode 100644 index 275d98e..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/LoaderInterface.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ - public function load(RepositoryInterface $repository, array $entries); -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php deleted file mode 100644 index 36d7a4b..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Loader/Resolver.php +++ /dev/null @@ -1,65 +0,0 @@ -getVars(), static function (string $s, int $i) use ($repository) { - return Str::substr($s, 0, $i).self::resolveVariable($repository, Str::substr($s, $i)); - }, $value->getChars()); - } - - /** - * Resolve a single nested variable. - * - * @param \Dotenv\Repository\RepositoryInterface $repository - * @param string $str - * - * @return string - */ - private static function resolveVariable(RepositoryInterface $repository, string $str) - { - return Regex::replaceCallback( - '/\A\${([a-zA-Z0-9_.]+)}/', - static function (array $matches) use ($repository) { - return Option::fromValue($repository->get($matches[1])) - ->getOrElse($matches[0]); - }, - $str, - 1 - )->success()->getOrElse($str); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php deleted file mode 100644 index 7570f58..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Entry.php +++ /dev/null @@ -1,59 +0,0 @@ -name = $name; - $this->value = $value; - } - - /** - * Get the entry name. - * - * @return string - */ - public function getName() - { - return $this->name; - } - - /** - * Get the entry value. - * - * @return \PhpOption\Option<\Dotenv\Parser\Value> - */ - public function getValue() - { - /** @var \PhpOption\Option<\Dotenv\Parser\Value> */ - return Option::fromValue($this->value); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php deleted file mode 100644 index e286840..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/EntryParser.php +++ /dev/null @@ -1,300 +0,0 @@ - - */ - public static function parse(string $entry) - { - return self::splitStringIntoParts($entry)->flatMap(static function (array $parts) { - [$name, $value] = $parts; - - return self::parseName($name)->flatMap(static function (string $name) use ($value) { - /** @var Result */ - $parsedValue = $value === null ? Success::create(null) : self::parseValue($value); - - return $parsedValue->map(static function (?Value $value) use ($name) { - return new Entry($name, $value); - }); - }); - }); - } - - /** - * Split the compound string into parts. - * - * @param string $line - * - * @return \GrahamCampbell\ResultType\Result - */ - private static function splitStringIntoParts(string $line) - { - /** @var array{string,string|null} */ - $result = Str::pos($line, '=')->map(static function () use ($line) { - return \array_map('trim', \explode('=', $line, 2)); - })->getOrElse([$line, null]); - - if ($result[0] === '') { - /** @var \GrahamCampbell\ResultType\Result */ - return Error::create(self::getErrorMessage('an unexpected equals', $line)); - } - - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create($result); - } - - /** - * Parse the given variable name. - * - * That is, strip the optional quotes and leading "export" from the - * variable name. We wrap the answer in a result type. - * - * @param string $name - * - * @return \GrahamCampbell\ResultType\Result - */ - private static function parseName(string $name) - { - if (Str::len($name) > 8 && Str::substr($name, 0, 6) === 'export' && \ctype_space(Str::substr($name, 6, 1))) { - $name = \ltrim(Str::substr($name, 6)); - } - - if (self::isQuotedName($name)) { - $name = Str::substr($name, 1, -1); - } - - if (!self::isValidName($name)) { - /** @var \GrahamCampbell\ResultType\Result */ - return Error::create(self::getErrorMessage('an invalid name', $name)); - } - - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create($name); - } - - /** - * Is the given variable name quoted? - * - * @param string $name - * - * @return bool - */ - private static function isQuotedName(string $name) - { - if (Str::len($name) < 3) { - return false; - } - - $first = Str::substr($name, 0, 1); - $last = Str::substr($name, -1, 1); - - return ($first === '"' && $last === '"') || ($first === '\'' && $last === '\''); - } - - /** - * Is the given variable name valid? - * - * @param string $name - * - * @return bool - */ - private static function isValidName(string $name) - { - return Regex::matches('~(*UTF8)\A[\p{Ll}\p{Lu}\p{M}\p{N}_.]+\z~', $name)->success()->getOrElse(false); - } - - /** - * Parse the given variable value. - * - * This has the effect of stripping quotes and comments, dealing with - * special characters, and locating nested variables, but not resolving - * them. Formally, we run a finite state automaton with an output tape: a - * transducer. We wrap the answer in a result type. - * - * @param string $value - * - * @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> - */ - private static function parseValue(string $value) - { - if (\trim($value) === '') { - /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */ - return Success::create(Value::blank()); - } - - return \array_reduce(\iterator_to_array(Lexer::lex($value)), static function (Result $data, string $token) { - return $data->flatMap(static function (array $data) use ($token) { - return self::processToken($data[1], $token)->map(static function (array $val) use ($data) { - return [$data[0]->append($val[0], $val[1]), $val[2]]; - }); - }); - }, Success::create([Value::blank(), self::INITIAL_STATE]))->flatMap(static function (array $result) { - /** @psalm-suppress DocblockTypeContradiction */ - if (in_array($result[1], self::REJECT_STATES, true)) { - /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */ - return Error::create('a missing closing quote'); - } - - /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Value,string> */ - return Success::create($result[0]); - })->mapError(static function (string $err) use ($value) { - return self::getErrorMessage($err, $value); - }); - } - - /** - * Process the given token. - * - * @param int $state - * @param string $token - * - * @return \GrahamCampbell\ResultType\Result - */ - private static function processToken(int $state, string $token) - { - switch ($state) { - case self::INITIAL_STATE: - if ($token === '\'') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::SINGLE_QUOTED_STATE]); - } elseif ($token === '"') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::DOUBLE_QUOTED_STATE]); - } elseif ($token === '#') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::COMMENT_STATE]); - } elseif ($token === '$') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, true, self::UNQUOTED_STATE]); - } else { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, false, self::UNQUOTED_STATE]); - } - case self::UNQUOTED_STATE: - if ($token === '#') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::COMMENT_STATE]); - } elseif (\ctype_space($token)) { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::WHITESPACE_STATE]); - } elseif ($token === '$') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, true, self::UNQUOTED_STATE]); - } else { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, false, self::UNQUOTED_STATE]); - } - case self::SINGLE_QUOTED_STATE: - if ($token === '\'') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::WHITESPACE_STATE]); - } else { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, false, self::SINGLE_QUOTED_STATE]); - } - case self::DOUBLE_QUOTED_STATE: - if ($token === '"') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::WHITESPACE_STATE]); - } elseif ($token === '\\') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::ESCAPE_SEQUENCE_STATE]); - } elseif ($token === '$') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, true, self::DOUBLE_QUOTED_STATE]); - } else { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]); - } - case self::ESCAPE_SEQUENCE_STATE: - if ($token === '"' || $token === '\\') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]); - } elseif ($token === '$') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([$token, false, self::DOUBLE_QUOTED_STATE]); - } else { - $first = Str::substr($token, 0, 1); - if (\in_array($first, ['f', 'n', 'r', 't', 'v'], true)) { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create([\stripcslashes('\\'.$first).Str::substr($token, 1), false, self::DOUBLE_QUOTED_STATE]); - } else { - /** @var \GrahamCampbell\ResultType\Result */ - return Error::create('an unexpected escape sequence'); - } - } - case self::WHITESPACE_STATE: - if ($token === '#') { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::COMMENT_STATE]); - } elseif (!\ctype_space($token)) { - /** @var \GrahamCampbell\ResultType\Result */ - return Error::create('unexpected whitespace'); - } else { - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::WHITESPACE_STATE]); - } - case self::COMMENT_STATE: - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create(['', false, self::COMMENT_STATE]); - default: - throw new \Error('Parser entered invalid state.'); - } - } - - /** - * Generate a friendly error message. - * - * @param string $cause - * @param string $subject - * - * @return string - */ - private static function getErrorMessage(string $cause, string $subject) - { - return \sprintf( - 'Encountered %s at [%s].', - $cause, - \strtok($subject, "\n") - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php deleted file mode 100644 index 981af24..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lexer.php +++ /dev/null @@ -1,58 +0,0 @@ - - */ - public static function lex(string $content) - { - static $regex; - - if ($regex === null) { - $regex = '(('.\implode(')|(', self::PATTERNS).'))A'; - } - - $offset = 0; - - while (isset($content[$offset])) { - if (!\preg_match($regex, $content, $matches, 0, $offset)) { - throw new \Error(\sprintf('Lexer encountered unexpected character [%s].', $content[$offset])); - } - - $offset += \strlen($matches[0]); - - yield $matches[0]; - } - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php deleted file mode 100644 index 6497993..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Lines.php +++ /dev/null @@ -1,127 +0,0 @@ -map(static function () use ($line) { - return self::looksLikeMultilineStop($line, true) === false; - })->getOrElse(false); - } - - /** - * Determine if the given line can be the start of a multiline variable. - * - * @param string $line - * @param bool $started - * - * @return bool - */ - private static function looksLikeMultilineStop(string $line, bool $started) - { - if ($line === '"') { - return true; - } - - return Regex::occurrences('/(?=([^\\\\]"))/', \str_replace('\\\\', '', $line))->map(static function (int $count) use ($started) { - return $started ? $count > 1 : $count >= 1; - })->success()->getOrElse(false); - } - - /** - * Determine if the line in the file is a comment or whitespace. - * - * @param string $line - * - * @return bool - */ - private static function isCommentOrWhitespace(string $line) - { - $line = \trim($line); - - return $line === '' || (isset($line[0]) && $line[0] === '#'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php deleted file mode 100644 index 2d30dfd..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/Parser.php +++ /dev/null @@ -1,53 +0,0 @@ -mapError(static function () { - return 'Could not split into separate lines.'; - })->flatMap(static function (array $lines) { - return self::process(Lines::process($lines)); - })->mapError(static function (string $error) { - throw new InvalidFileException(\sprintf('Failed to parse dotenv file. %s', $error)); - })->success()->get(); - } - - /** - * Convert the raw entries into proper entries. - * - * @param string[] $entries - * - * @return \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[],string> - */ - private static function process(array $entries) - { - /** @var \GrahamCampbell\ResultType\Result<\Dotenv\Parser\Entry[],string> */ - return \array_reduce($entries, static function (Result $result, string $raw) { - return $result->flatMap(static function (array $entries) use ($raw) { - return EntryParser::parse($raw)->map(static function (Entry $entry) use ($entries) { - /** @var \Dotenv\Parser\Entry[] */ - return \array_merge($entries, [$entry]); - }); - }); - }, Success::create([])); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php deleted file mode 100644 index 17cc42a..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Parser/ParserInterface.php +++ /dev/null @@ -1,19 +0,0 @@ -chars = $chars; - $this->vars = $vars; - } - - /** - * Create an empty value instance. - * - * @return \Dotenv\Parser\Value - */ - public static function blank() - { - return new self('', []); - } - - /** - * Create a new value instance, appending the characters. - * - * @param string $chars - * @param bool $var - * - * @return \Dotenv\Parser\Value - */ - public function append(string $chars, bool $var) - { - return new self( - $this->chars.$chars, - $var ? \array_merge($this->vars, [Str::len($this->chars)]) : $this->vars - ); - } - - /** - * Get the string representation of the parsed value. - * - * @return string - */ - public function getChars() - { - return $this->chars; - } - - /** - * Get the locations of the variables in the value. - * - * @return int[] - */ - public function getVars() - { - $vars = $this->vars; - - \rsort($vars); - - return $vars; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php deleted file mode 100644 index 5604398..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/AdapterInterface.php +++ /dev/null @@ -1,15 +0,0 @@ - - */ - public static function create(); -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php deleted file mode 100644 index af0aae1..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ApacheAdapter.php +++ /dev/null @@ -1,89 +0,0 @@ - - */ - public static function create() - { - if (self::isSupported()) { - /** @var \PhpOption\Option */ - return Some::create(new self()); - } - - return None::create(); - } - - /** - * Determines if the adapter is supported. - * - * This happens if PHP is running as an Apache module. - * - * @return bool - */ - private static function isSupported() - { - return \function_exists('apache_getenv') && \function_exists('apache_setenv'); - } - - /** - * Read an environment variable, if it exists. - * - * @param non-empty-string $name - * - * @return \PhpOption\Option - */ - public function read(string $name) - { - /** @var \PhpOption\Option */ - return Option::fromValue(apache_getenv($name))->filter(static function ($value) { - return \is_string($value) && $value !== ''; - }); - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - return apache_setenv($name, $value); - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - return apache_setenv($name, ''); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php deleted file mode 100644 index df64cf6..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ArrayAdapter.php +++ /dev/null @@ -1,80 +0,0 @@ - - */ - private $variables; - - /** - * Create a new array adapter instance. - * - * @return void - */ - private function __construct() - { - $this->variables = []; - } - - /** - * Create a new instance of the adapter, if it is available. - * - * @return \PhpOption\Option<\Dotenv\Repository\Adapter\AdapterInterface> - */ - public static function create() - { - /** @var \PhpOption\Option */ - return Some::create(new self()); - } - - /** - * Read an environment variable, if it exists. - * - * @param non-empty-string $name - * - * @return \PhpOption\Option - */ - public function read(string $name) - { - return Option::fromArraysValue($this->variables, $name); - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - $this->variables[$name] = $value; - - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - unset($this->variables[$name]); - - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php deleted file mode 100644 index 9eb1947..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/EnvConstAdapter.php +++ /dev/null @@ -1,89 +0,0 @@ - - */ - public static function create() - { - /** @var \PhpOption\Option */ - return Some::create(new self()); - } - - /** - * Read an environment variable, if it exists. - * - * @param non-empty-string $name - * - * @return \PhpOption\Option - */ - public function read(string $name) - { - /** @var \PhpOption\Option */ - return Option::fromArraysValue($_ENV, $name) - ->filter(static function ($value) { - return \is_scalar($value); - }) - ->map(static function ($value) { - if ($value === false) { - return 'false'; - } - - if ($value === true) { - return 'true'; - } - - /** @psalm-suppress PossiblyInvalidCast */ - return (string) $value; - }); - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - $_ENV[$name] = $value; - - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - unset($_ENV[$name]); - - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php deleted file mode 100644 index fed8b9b..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/GuardedWriter.php +++ /dev/null @@ -1,85 +0,0 @@ -writer = $writer; - $this->allowList = $allowList; - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - // Don't set non-allowed variables - if (!$this->isAllowed($name)) { - return false; - } - - // Set the value on the inner writer - return $this->writer->write($name, $value); - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - // Don't clear non-allowed variables - if (!$this->isAllowed($name)) { - return false; - } - - // Set the value on the inner writer - return $this->writer->delete($name); - } - - /** - * Determine if the given variable is allowed. - * - * @param non-empty-string $name - * - * @return bool - */ - private function isAllowed(string $name) - { - return \in_array($name, $this->allowList, true); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php deleted file mode 100644 index 399e6f9..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ImmutableWriter.php +++ /dev/null @@ -1,110 +0,0 @@ - - */ - private $loaded; - - /** - * Create a new immutable writer instance. - * - * @param \Dotenv\Repository\Adapter\WriterInterface $writer - * @param \Dotenv\Repository\Adapter\ReaderInterface $reader - * - * @return void - */ - public function __construct(WriterInterface $writer, ReaderInterface $reader) - { - $this->writer = $writer; - $this->reader = $reader; - $this->loaded = []; - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - // Don't overwrite existing environment variables - // Ruby's dotenv does this with `ENV[key] ||= value` - if ($this->isExternallyDefined($name)) { - return false; - } - - // Set the value on the inner writer - if (!$this->writer->write($name, $value)) { - return false; - } - - // Record that we have loaded the variable - $this->loaded[$name] = ''; - - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - // Don't clear existing environment variables - if ($this->isExternallyDefined($name)) { - return false; - } - - // Clear the value on the inner writer - if (!$this->writer->delete($name)) { - return false; - } - - // Leave the variable as fair game - unset($this->loaded[$name]); - - return true; - } - - /** - * Determine if the given variable is externally defined. - * - * That is, is it an "existing" variable. - * - * @param non-empty-string $name - * - * @return bool - */ - private function isExternallyDefined(string $name) - { - return $this->reader->read($name)->isDefined() && !isset($this->loaded[$name]); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php deleted file mode 100644 index 0cfda6f..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiReader.php +++ /dev/null @@ -1,48 +0,0 @@ -readers = $readers; - } - - /** - * Read an environment variable, if it exists. - * - * @param non-empty-string $name - * - * @return \PhpOption\Option - */ - public function read(string $name) - { - foreach ($this->readers as $reader) { - $result = $reader->read($name); - if ($result->isDefined()) { - return $result; - } - } - - return None::create(); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php deleted file mode 100644 index 15a9d8f..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/MultiWriter.php +++ /dev/null @@ -1,64 +0,0 @@ -writers = $writers; - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - foreach ($this->writers as $writers) { - if (!$writers->write($name, $value)) { - return false; - } - } - - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - foreach ($this->writers as $writers) { - if (!$writers->delete($name)) { - return false; - } - } - - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php deleted file mode 100644 index 6d017cd..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/PutenvAdapter.php +++ /dev/null @@ -1,91 +0,0 @@ - - */ - public static function create() - { - if (self::isSupported()) { - /** @var \PhpOption\Option */ - return Some::create(new self()); - } - - return None::create(); - } - - /** - * Determines if the adapter is supported. - * - * @return bool - */ - private static function isSupported() - { - return \function_exists('getenv') && \function_exists('putenv'); - } - - /** - * Read an environment variable, if it exists. - * - * @param non-empty-string $name - * - * @return \PhpOption\Option - */ - public function read(string $name) - { - /** @var \PhpOption\Option */ - return Option::fromValue(\getenv($name), false)->filter(static function ($value) { - return \is_string($value); - }); - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - \putenv("$name=$value"); - - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - \putenv($name); - - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php deleted file mode 100644 index 306a63f..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReaderInterface.php +++ /dev/null @@ -1,17 +0,0 @@ - - */ - public function read(string $name); -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php deleted file mode 100644 index 98c0f04..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ReplacingWriter.php +++ /dev/null @@ -1,104 +0,0 @@ - - */ - private $seen; - - /** - * Create a new replacement writer instance. - * - * @param \Dotenv\Repository\Adapter\WriterInterface $writer - * @param \Dotenv\Repository\Adapter\ReaderInterface $reader - * - * @return void - */ - public function __construct(WriterInterface $writer, ReaderInterface $reader) - { - $this->writer = $writer; - $this->reader = $reader; - $this->seen = []; - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - if ($this->exists($name)) { - return $this->writer->write($name, $value); - } - - // succeed if nothing to do - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - if ($this->exists($name)) { - return $this->writer->delete($name); - } - - // succeed if nothing to do - return true; - } - - /** - * Does the given environment variable exist. - * - * Returns true if it currently exists, or existed at any point in the past - * that we are aware of. - * - * @param non-empty-string $name - * - * @return bool - */ - private function exists(string $name) - { - if (isset($this->seen[$name])) { - return true; - } - - if ($this->reader->read($name)->isDefined()) { - $this->seen[$name] = ''; - - return true; - } - - return false; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php deleted file mode 100644 index f93b6e5..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/ServerConstAdapter.php +++ /dev/null @@ -1,89 +0,0 @@ - - */ - public static function create() - { - /** @var \PhpOption\Option */ - return Some::create(new self()); - } - - /** - * Read an environment variable, if it exists. - * - * @param non-empty-string $name - * - * @return \PhpOption\Option - */ - public function read(string $name) - { - /** @var \PhpOption\Option */ - return Option::fromArraysValue($_SERVER, $name) - ->filter(static function ($value) { - return \is_scalar($value); - }) - ->map(static function ($value) { - if ($value === false) { - return 'false'; - } - - if ($value === true) { - return 'true'; - } - - /** @psalm-suppress PossiblyInvalidCast */ - return (string) $value; - }); - } - - /** - * Write to an environment variable, if possible. - * - * @param non-empty-string $name - * @param string $value - * - * @return bool - */ - public function write(string $name, string $value) - { - $_SERVER[$name] = $value; - - return true; - } - - /** - * Delete an environment variable, if possible. - * - * @param non-empty-string $name - * - * @return bool - */ - public function delete(string $name) - { - unset($_SERVER[$name]); - - return true; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php deleted file mode 100644 index 4cb3d61..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/Adapter/WriterInterface.php +++ /dev/null @@ -1,27 +0,0 @@ -reader = $reader; - $this->writer = $writer; - } - - /** - * Determine if the given environment variable is defined. - * - * @param string $name - * - * @return bool - */ - public function has(string $name) - { - return '' !== $name && $this->reader->read($name)->isDefined(); - } - - /** - * Get an environment variable. - * - * @param string $name - * - * @throws \InvalidArgumentException - * - * @return string|null - */ - public function get(string $name) - { - if ('' === $name) { - throw new InvalidArgumentException('Expected name to be a non-empty string.'); - } - - return $this->reader->read($name)->getOrElse(null); - } - - /** - * Set an environment variable. - * - * @param string $name - * @param string $value - * - * @throws \InvalidArgumentException - * - * @return bool - */ - public function set(string $name, string $value) - { - if ('' === $name) { - throw new InvalidArgumentException('Expected name to be a non-empty string.'); - } - - return $this->writer->write($name, $value); - } - - /** - * Clear an environment variable. - * - * @param string $name - * - * @throws \InvalidArgumentException - * - * @return bool - */ - public function clear(string $name) - { - if ('' === $name) { - throw new InvalidArgumentException('Expected name to be a non-empty string.'); - } - - return $this->writer->delete($name); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php deleted file mode 100644 index a042f9a..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryBuilder.php +++ /dev/null @@ -1,272 +0,0 @@ -readers = $readers; - $this->writers = $writers; - $this->immutable = $immutable; - $this->allowList = $allowList; - } - - /** - * Create a new repository builder instance with no adapters added. - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public static function createWithNoAdapters() - { - return new self(); - } - - /** - * Create a new repository builder instance with the default adapters added. - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public static function createWithDefaultAdapters() - { - $adapters = \iterator_to_array(self::defaultAdapters()); - - return new self($adapters, $adapters); - } - - /** - * Return the array of default adapters. - * - * @return \Generator<\Dotenv\Repository\Adapter\AdapterInterface> - */ - private static function defaultAdapters() - { - foreach (self::DEFAULT_ADAPTERS as $adapter) { - $instance = $adapter::create(); - if ($instance->isDefined()) { - yield $instance->get(); - } - } - } - - /** - * Determine if the given name if of an adapterclass. - * - * @param string $name - * - * @return bool - */ - private static function isAnAdapterClass(string $name) - { - if (!\class_exists($name)) { - return false; - } - - return (new ReflectionClass($name))->implementsInterface(AdapterInterface::class); - } - - /** - * Creates a repository builder with the given reader added. - * - * Accepts either a reader instance, or a class-string for an adapter. If - * the adapter is not supported, then we silently skip adding it. - * - * @param \Dotenv\Repository\Adapter\ReaderInterface|string $reader - * - * @throws \InvalidArgumentException - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public function addReader($reader) - { - if (!(\is_string($reader) && self::isAnAdapterClass($reader)) && !($reader instanceof ReaderInterface)) { - throw new InvalidArgumentException( - \sprintf( - 'Expected either an instance of %s or a class-string implementing %s', - ReaderInterface::class, - AdapterInterface::class - ) - ); - } - - $optional = Some::create($reader)->flatMap(static function ($reader) { - return \is_string($reader) ? $reader::create() : Some::create($reader); - }); - - $readers = \array_merge($this->readers, \iterator_to_array($optional)); - - return new self($readers, $this->writers, $this->immutable, $this->allowList); - } - - /** - * Creates a repository builder with the given writer added. - * - * Accepts either a writer instance, or a class-string for an adapter. If - * the adapter is not supported, then we silently skip adding it. - * - * @param \Dotenv\Repository\Adapter\WriterInterface|string $writer - * - * @throws \InvalidArgumentException - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public function addWriter($writer) - { - if (!(\is_string($writer) && self::isAnAdapterClass($writer)) && !($writer instanceof WriterInterface)) { - throw new InvalidArgumentException( - \sprintf( - 'Expected either an instance of %s or a class-string implementing %s', - WriterInterface::class, - AdapterInterface::class - ) - ); - } - - $optional = Some::create($writer)->flatMap(static function ($writer) { - return \is_string($writer) ? $writer::create() : Some::create($writer); - }); - - $writers = \array_merge($this->writers, \iterator_to_array($optional)); - - return new self($this->readers, $writers, $this->immutable, $this->allowList); - } - - /** - * Creates a repository builder with the given adapter added. - * - * Accepts either an adapter instance, or a class-string for an adapter. If - * the adapter is not supported, then we silently skip adding it. We will - * add the adapter as both a reader and a writer. - * - * @param \Dotenv\Repository\Adapter\WriterInterface|string $adapter - * - * @throws \InvalidArgumentException - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public function addAdapter($adapter) - { - if (!(\is_string($adapter) && self::isAnAdapterClass($adapter)) && !($adapter instanceof AdapterInterface)) { - throw new InvalidArgumentException( - \sprintf( - 'Expected either an instance of %s or a class-string implementing %s', - WriterInterface::class, - AdapterInterface::class - ) - ); - } - - $optional = Some::create($adapter)->flatMap(static function ($adapter) { - return \is_string($adapter) ? $adapter::create() : Some::create($adapter); - }); - - $readers = \array_merge($this->readers, \iterator_to_array($optional)); - $writers = \array_merge($this->writers, \iterator_to_array($optional)); - - return new self($readers, $writers, $this->immutable, $this->allowList); - } - - /** - * Creates a repository builder with mutability enabled. - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public function immutable() - { - return new self($this->readers, $this->writers, true, $this->allowList); - } - - /** - * Creates a repository builder with the given allow list. - * - * @param string[]|null $allowList - * - * @return \Dotenv\Repository\RepositoryBuilder - */ - public function allowList(array $allowList = null) - { - return new self($this->readers, $this->writers, $this->immutable, $allowList); - } - - /** - * Creates a new repository instance. - * - * @return \Dotenv\Repository\RepositoryInterface - */ - public function make() - { - $reader = new MultiReader($this->readers); - $writer = new MultiWriter($this->writers); - - if ($this->immutable) { - $writer = new ImmutableWriter($writer, $reader); - } - - if ($this->allowList !== null) { - $writer = new GuardedWriter($writer, $this->allowList); - } - - return new AdapterRepository($reader, $writer); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php deleted file mode 100644 index d9b18a4..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Repository/RepositoryInterface.php +++ /dev/null @@ -1,51 +0,0 @@ - - */ - public static function read(array $filePaths, bool $shortCircuit = true, string $fileEncoding = null) - { - $output = []; - - foreach ($filePaths as $filePath) { - $content = self::readFromFile($filePath, $fileEncoding); - if ($content->isDefined()) { - $output[$filePath] = $content->get(); - if ($shortCircuit) { - break; - } - } - } - - return $output; - } - - /** - * Read the given file. - * - * @param string $path - * @param string|null $encoding - * - * @throws \Dotenv\Exception\InvalidEncodingException - * - * @return \PhpOption\Option - */ - private static function readFromFile(string $path, string $encoding = null) - { - /** @var Option */ - $content = Option::fromValue(@\file_get_contents($path), false); - - return $content->flatMap(static function (string $content) use ($encoding) { - return Str::utf8($content, $encoding)->mapError(static function (string $error) { - throw new InvalidEncodingException($error); - })->success(); - }); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php deleted file mode 100644 index 43f6135..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/FileStore.php +++ /dev/null @@ -1,72 +0,0 @@ -filePaths = $filePaths; - $this->shortCircuit = $shortCircuit; - $this->fileEncoding = $fileEncoding; - } - - /** - * Read the content of the environment file(s). - * - * @throws \Dotenv\Exception\InvalidEncodingException|\Dotenv\Exception\InvalidPathException - * - * @return string - */ - public function read() - { - if ($this->filePaths === []) { - throw new InvalidPathException('At least one environment file path must be provided.'); - } - - $contents = Reader::read($this->filePaths, $this->shortCircuit, $this->fileEncoding); - - if (\count($contents) > 0) { - return \implode("\n", $contents); - } - - throw new InvalidPathException( - \sprintf('Unable to read any of the environment file(s) at [%s].', \implode(', ', $this->filePaths)) - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php deleted file mode 100644 index 304117f..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreBuilder.php +++ /dev/null @@ -1,141 +0,0 @@ -paths = $paths; - $this->names = $names; - $this->shortCircuit = $shortCircuit; - $this->fileEncoding = $fileEncoding; - } - - /** - * Create a new store builder instance with no names. - * - * @return \Dotenv\Store\StoreBuilder - */ - public static function createWithNoNames() - { - return new self(); - } - - /** - * Create a new store builder instance with the default name. - * - * @return \Dotenv\Store\StoreBuilder - */ - public static function createWithDefaultName() - { - return new self([], [self::DEFAULT_NAME]); - } - - /** - * Creates a store builder with the given path added. - * - * @param string $path - * - * @return \Dotenv\Store\StoreBuilder - */ - public function addPath(string $path) - { - return new self(\array_merge($this->paths, [$path]), $this->names, $this->shortCircuit, $this->fileEncoding); - } - - /** - * Creates a store builder with the given name added. - * - * @param string $name - * - * @return \Dotenv\Store\StoreBuilder - */ - public function addName(string $name) - { - return new self($this->paths, \array_merge($this->names, [$name]), $this->shortCircuit, $this->fileEncoding); - } - - /** - * Creates a store builder with short circuit mode enabled. - * - * @return \Dotenv\Store\StoreBuilder - */ - public function shortCircuit() - { - return new self($this->paths, $this->names, true, $this->fileEncoding); - } - - /** - * Creates a store builder with the specified file encoding. - * - * @param string|null $fileEncoding - * - * @return \Dotenv\Store\StoreBuilder - */ - public function fileEncoding(string $fileEncoding = null) - { - return new self($this->paths, $this->names, $this->shortCircuit, $fileEncoding); - } - - /** - * Creates a new store instance. - * - * @return \Dotenv\Store\StoreInterface - */ - public function make() - { - return new FileStore( - Paths::filePaths($this->paths, $this->names), - $this->shortCircuit, - $this->fileEncoding - ); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php deleted file mode 100644 index 6f5b986..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Store/StoreInterface.php +++ /dev/null @@ -1,17 +0,0 @@ -content = $content; - } - - /** - * Read the content of the environment file(s). - * - * @return string - */ - public function read() - { - return $this->content; - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php deleted file mode 100644 index 52c1578..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Regex.php +++ /dev/null @@ -1,112 +0,0 @@ - - */ - public static function matches(string $pattern, string $subject) - { - return self::pregAndWrap(static function (string $subject) use ($pattern) { - return @\preg_match($pattern, $subject) === 1; - }, $subject); - } - - /** - * Perform a preg match all, wrapping up the result. - * - * @param string $pattern - * @param string $subject - * - * @return \GrahamCampbell\ResultType\Result - */ - public static function occurrences(string $pattern, string $subject) - { - return self::pregAndWrap(static function (string $subject) use ($pattern) { - return (int) @\preg_match_all($pattern, $subject); - }, $subject); - } - - /** - * Perform a preg replace callback, wrapping up the result. - * - * @param string $pattern - * @param callable $callback - * @param string $subject - * @param int|null $limit - * - * @return \GrahamCampbell\ResultType\Result - */ - public static function replaceCallback(string $pattern, callable $callback, string $subject, int $limit = null) - { - return self::pregAndWrap(static function (string $subject) use ($pattern, $callback, $limit) { - return (string) @\preg_replace_callback($pattern, $callback, $subject, $limit ?? -1); - }, $subject); - } - - /** - * Perform a preg split, wrapping up the result. - * - * @param string $pattern - * @param string $subject - * - * @return \GrahamCampbell\ResultType\Result - */ - public static function split(string $pattern, string $subject) - { - return self::pregAndWrap(static function (string $subject) use ($pattern) { - /** @var string[] */ - return (array) @\preg_split($pattern, $subject); - }, $subject); - } - - /** - * Perform a preg operation, wrapping up the result. - * - * @template V - * - * @param callable(string):V $operation - * @param string $subject - * - * @return \GrahamCampbell\ResultType\Result - */ - private static function pregAndWrap(callable $operation, string $subject) - { - $result = $operation($subject); - - if (\preg_last_error() !== \PREG_NO_ERROR) { - /** @var \GrahamCampbell\ResultType\Result */ - return Error::create(\preg_last_error_msg()); - } - - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create($result); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php deleted file mode 100644 index 087e236..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Util/Str.php +++ /dev/null @@ -1,98 +0,0 @@ - - */ - public static function utf8(string $input, string $encoding = null) - { - if ($encoding !== null && !\in_array($encoding, \mb_list_encodings(), true)) { - /** @var \GrahamCampbell\ResultType\Result */ - return Error::create( - \sprintf('Illegal character encoding [%s] specified.', $encoding) - ); - } - $converted = $encoding === null ? - @\mb_convert_encoding($input, 'UTF-8') : - @\mb_convert_encoding($input, 'UTF-8', $encoding); - /** - * this is for support UTF-8 with BOM encoding - * @see https://en.wikipedia.org/wiki/Byte_order_mark - * @see https://github.com/vlucas/phpdotenv/issues/500 - */ - if (\substr($converted, 0, 3) == "\xEF\xBB\xBF") { - $converted = \substr($converted, 3); - } - /** @var \GrahamCampbell\ResultType\Result */ - return Success::create($converted); - } - - /** - * Search for a given substring of the input. - * - * @param string $haystack - * @param string $needle - * - * @return \PhpOption\Option - */ - public static function pos(string $haystack, string $needle) - { - /** @var \PhpOption\Option */ - return Option::fromValue(\mb_strpos($haystack, $needle, 0, 'UTF-8'), false); - } - - /** - * Grab the specified substring of the input. - * - * @param string $input - * @param int $start - * @param int|null $length - * - * @return string - */ - public static function substr(string $input, int $start, int $length = null) - { - return \mb_substr($input, $start, $length, 'UTF-8'); - } - - /** - * Compute the length of the given string. - * - * @param string $input - * - * @return int - */ - public static function len(string $input) - { - return \mb_strlen($input, 'UTF-8'); - } -} diff --git a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php b/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php deleted file mode 100644 index 0c04ab6..0000000 --- a/utilities/signing_and_verification/php/vendor/vlucas/phpdotenv/src/Validator.php +++ /dev/null @@ -1,209 +0,0 @@ -repository = $repository; - $this->variables = $variables; - } - - /** - * Assert that each variable is present. - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function required() - { - return $this->assert( - static function (?string $value) { - return $value !== null; - }, - 'is missing' - ); - } - - /** - * Assert that each variable is not empty. - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function notEmpty() - { - return $this->assertNullable( - static function (string $value) { - return Str::len(\trim($value)) > 0; - }, - 'is empty' - ); - } - - /** - * Assert that each specified variable is an integer. - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function isInteger() - { - return $this->assertNullable( - static function (string $value) { - return \ctype_digit($value); - }, - 'is not an integer' - ); - } - - /** - * Assert that each specified variable is a boolean. - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function isBoolean() - { - return $this->assertNullable( - static function (string $value) { - if ($value === '') { - return false; - } - - return \filter_var($value, \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE) !== null; - }, - 'is not a boolean' - ); - } - - /** - * Assert that each variable is amongst the given choices. - * - * @param string[] $choices - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function allowedValues(array $choices) - { - return $this->assertNullable( - static function (string $value) use ($choices) { - return \in_array($value, $choices, true); - }, - \sprintf('is not one of [%s]', \implode(', ', $choices)) - ); - } - - /** - * Assert that each variable matches the given regular expression. - * - * @param string $regex - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function allowedRegexValues(string $regex) - { - return $this->assertNullable( - static function (string $value) use ($regex) { - return Regex::matches($regex, $value)->success()->getOrElse(false); - }, - \sprintf('does not match "%s"', $regex) - ); - } - - /** - * Assert that the callback returns true for each variable. - * - * @param callable(?string):bool $callback - * @param string $message - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function assert(callable $callback, string $message) - { - $failing = []; - - foreach ($this->variables as $variable) { - if ($callback($this->repository->get($variable)) === false) { - $failing[] = \sprintf('%s %s', $variable, $message); - } - } - - if (\count($failing) > 0) { - throw new ValidationException(\sprintf( - 'One or more environment variables failed assertions: %s.', - \implode(', ', $failing) - )); - } - - return $this; - } - - /** - * Assert that the callback returns true for each variable. - * - * Skip checking null variable values. - * - * @param callable(string):bool $callback - * @param string $message - * - * @throws \Dotenv\Exception\ValidationException - * - * @return \Dotenv\Validator - */ - public function assertNullable(callable $callback, string $message) - { - return $this->assert( - static function (?string $value) use ($callback) { - if ($value === null) { - return true; - } - - return $callback($value); - }, - $message - ); - } -} From 3146cff50093824d528d82fc04a37c096d480791 Mon Sep 17 00:00:00 2001 From: Charanpreet Date: Fri, 2 Feb 2024 17:05:51 +0530 Subject: [PATCH 125/228] feat: added 1:1 utility for signing and verification in PHP --- .../signing_and_verification/php/README.md | 84 ++++++ .../php/composer.json | 14 - .../signing_and_verification/php/src/.env | 4 - .../php/src/index.php | 250 ++++++++++-------- 4 files changed, 229 insertions(+), 123 deletions(-) create mode 100644 utilities/signing_and_verification/php/README.md delete mode 100644 utilities/signing_and_verification/php/composer.json delete mode 100644 utilities/signing_and_verification/php/src/.env diff --git a/utilities/signing_and_verification/php/README.md b/utilities/signing_and_verification/php/README.md new file mode 100644 index 0000000..38fb8f9 --- /dev/null +++ b/utilities/signing_and_verification/php/README.md @@ -0,0 +1,84 @@ +# Signing and Verification +Steps for signing and verification + +1. Install php and dependencies + +```sh +# linux setup +# download php +sudo apt install php php-curl +# Download Composer +curl -sS https://getcomposer.org/installer -o composer-setup.php +# install composer +sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer +# change to cloned directory +cd /reference-implementations/utilities/signing_and_verification/php +composer install + +# brew setup +# install php +brew install php # latest version is 8.0.0, this will work for versions >= 7.4 +# install composer +brew install composer +# change to cloned directory +cd /reference-implementations/utilities/signing_and_verification/php +composer install +``` +2. ENV variables +```sh +SIGNING_PRIV_KEY="your signing private key" +SIGNING_PUB_KEY="your signing public key" +COUNTERPARTY_SIGNING_PUB_KEY="the other party's signing public key" +ENC_PUB_KEY="your encryption/crypto public key" +ENC_PRIV_KEY="your encryption/crypto private key" +COUNTERPARTY_PUB_KEY="the other party's encryption/crypto public key" +SUBSCRIBER_ID="your subscriber id" +UNIQUE_KEY_ID="your ukid" +AUTH_HEADER="the auth header that is to be verified" +REQUEST_BODY="json stringified payload" +``` +3. Generate keys +```sh +composer run start -- -g + +# OUTPUT +Signing priv key: VfwASYHVjMAC63LClJKVTvjHcvuUZ4oQKhXmpY6+pwsu7b5xNQzhD/drIPer5m3kasjjicaj/+lblZsNnlQMCw== +Signing pub key: Lu2+cTUM4Q/3ayD3q+Zt5GrI44nGo//pW5WbDZ5UDAs= +Encryption priv key: MC4CAQEwBQYDK2VuBCIEINaTmxwcMRLGuxX1lrwo0Lxd2FHqn84YqQoDzVQXe46+ +Encryption pub key: MCowBQYDK2VuAyEAFT6F4dxn1waTvLUbY5tdKh/IezuOp+tlHkAwQw82qXU= +``` +4. Create authorisation header +```sh +# REQUEST_BODY, SIGNING_PRIV_KEY, SUBSCRIBER_ID, UNIQUE_KEY_ID should be set +composer run start -- -s + +# OUTPUT +Signature keyId="buyer-app.ondc.org|207|ed25519",algorithm="ed25519",created="1641287875",expires="1641291475",headers="(created) (expires) digest",signature="fKQWvXhln4UdyZdL87ViXQObdBme0dHnsclD2LvvnHoNxIgcvAwUZOmwAnH5QKi9Upg5tRaxpoGhCFGHD+d+Bw==" +``` + +5. Verify authorisation header +```sh +# AUTH_HEADER, REQUEST_BODY, COUNTERPARTY_SIGNING_PUB_KEY should be set +composer run start -- -v + +#OUTPUT +0 | 1 # depending upon truth value (true = 1) +``` + +6. Encrypt Payload +```sh +# ENC_PRIV_KEY, COUNTERPARTY_PUB_KEY should be set +composer run start -- -e 'message to encrypt' + +#OUTPUT +dq6j2KZp61G6PMM9IhHW2fbOnquy7gkwJN/tVXkKAI4= +``` + +8. Decrypt Payload +```sh +# ENC_PRIV_KEY, ENC_PUB_KEY should be set +composer run start -d 'dq6j2KZp61G6PMM9IhHW2fbOnquy7gkwJN/tVXkKAI4=' + +#OUTPUT +message to encrypt +``` diff --git a/utilities/signing_and_verification/php/composer.json b/utilities/signing_and_verification/php/composer.json deleted file mode 100644 index 3e6e13a..0000000 --- a/utilities/signing_and_verification/php/composer.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "charnpreet/signver", - "type": "project", - "autoload": { - "psr-4": { - "Charnpreet\\Signver\\": "src/" - } - }, - "require": { - "vlucas/phpdotenv": "^5.6", - "sop/crypto-types": "dev-master", - "phpseclib/phpseclib": "^3.0" - } -} diff --git a/utilities/signing_and_verification/php/src/.env b/utilities/signing_and_verification/php/src/.env deleted file mode 100644 index 0bb1ff8..0000000 --- a/utilities/signing_and_verification/php/src/.env +++ /dev/null @@ -1,4 +0,0 @@ -PRIVATE_KEY="3LFlZAAuAMyppOq35pGz1b6ujlX4PAcEuGmMe6ONGuqyx2kXoC1/oh/VzDUzVSMdCqx2yZ3wtqTuoAvN58U5xg==" -PUBLIC_KEY="ssdpF6Atf6If1cw1M1UjHQqsdsmd8Lak7qALzefFOcY=" -SUBSCRIBER_ID="subscriber_id" -UNIQUE_KEY_ID="ukid" \ No newline at end of file diff --git a/utilities/signing_and_verification/php/src/index.php b/utilities/signing_and_verification/php/src/index.php index fe84563..b1b2936 100644 --- a/utilities/signing_and_verification/php/src/index.php +++ b/utilities/signing_and_verification/php/src/index.php @@ -1,135 +1,175 @@ load(); +$dotenv = Dotenv\Dotenv::createImmutable(dirname(__DIR__, 1)); +$dotenv->safeload(); -function hash_msg(string $msg): string{ - return base64_encode(sodium_crypto_generichash($msg,"",64)); +function hash_msg(string $msg): string +{ + return base64_encode(sodium_crypto_generichash($msg, "", 64)); } -function create_signing_string(string $digest_base64, string $created=null, string $expires=null): string { - $now = new DateTime(); - $one_hour = new DateInterval("PT1H"); - +function create_signing_string(string $digest_base64, string $created = null, string $expires = null): string +{ + $now = new DateTime(); + $one_hour = new DateInterval("PT1H"); - if ($created == null) { - $created = $now->getTimestamp(); - } + if ($created == null) { + $created = $now->getTimestamp(); + } - if ($expires == null) { - $expires = $now->add($one_hour)->getTimestamp(); - } + if ($expires == null) { + $expires = $now->add($one_hour)->getTimestamp(); + } - $signing_string = "(created): $created\n(expires): $expires\ndigest: BLAKE-512=$digest_base64"; - return $signing_string; + $signing_string = "(created): $created\n(expires): $expires\ndigest: BLAKE-512=$digest_base64"; + return $signing_string; } -function sign_response(string $signing_key, string $private_key): string { - return base64_encode(sodium_crypto_sign_detached($signing_key, base64_decode($private_key))); +function sign_response(string $signing_key, string $private_key): string +{ + return base64_encode(sodium_crypto_sign_detached($signing_key, base64_decode($private_key))); } -function verify_response(string $signature, string $signing_key, string $public_key): bool { - return sodium_crypto_sign_verify_detached(base64_decode($signature), $signing_key, base64_decode($public_key)); +function verify_response(string $signature, string $signing_key, string $public_key): bool +{ + return sodium_crypto_sign_verify_detached(base64_decode($signature), $signing_key, base64_decode($public_key)); } -function create_authorisation_header(string $request_body, string $created=null, string $expires=null) { - $now = new DateTime(); - $one_hour = new DateInterval("PT1H"); - - if($created == null) { - $created = $now->getTimestamp(); - } - - if($expires == null) { - $expires = $now->add($one_hour)->getTimeStamp(); - } - - $signing_key = create_signing_string(hash_msg($request_body), $created, $expires); - $signature = sign_response($signing_key, $_ENV['PRIVATE_KEY']); - - $subscriber_id = $_ENV['SUBSCRIBER_ID']; - $unique_key_id = $_ENV['UNIQUE_KEY_ID']; - - $header = "Signature keyId=\"$subscriber_id|$unique_key_id|ed25519\",algorithm=\"ed25519\",created=\"$created\",expires=\"$expires\",headers=\"($created) ($expires) digest\",signature=\"$signature\""; - return $header; +function create_authorisation_header(string $request_body, string $created = null, string $expires = null) +{ + $now = new DateTime(); + $one_hour = new DateInterval("PT1H"); + + if ($created == null) { + $created = $now->getTimestamp(); + } + + if ($expires == null) { + $expires = $now->add($one_hour)->getTimeStamp(); + } + + $signing_key = create_signing_string(hash_msg($request_body), $created, $expires); + $signature = sign_response($signing_key, $_ENV['SIGNING_PRIV_KEY']); + + $subscriber_id = $_ENV['SUBSCRIBER_ID']; + $unique_key_id = $_ENV['UNIQUE_KEY_ID']; + + $header = "Signature keyId=\"$subscriber_id|$unique_key_id|ed25519\",algorithm=\"ed25519\",created=\"$created\",expires=\"$expires\",headers=\"($created) ($expires) digest\",signature=\"$signature\""; + return $header; } // util -function get_filter_dict(string $filter_string) { - $filter_string_list = preg_split("/,/", $filter_string); - $filter_string_list = array_map(function($item) { return trim($item, " \n\r\t\v\0\""); }, $filter_string_list); - $filter_string_dict = []; - foreach($filter_string_list as $item) { - $split_item = preg_split("/=/", $item, 2); - $filter_string_dict[$split_item[0]] = trim($split_item[1], " \n\r\t\v\0\""); - } - return $filter_string_dict; +function get_filter_dict(string $filter_string) +{ + $filter_string_list = preg_split("/,/", $filter_string); + $filter_string_list = array_map(function ($item) {return trim($item, " \n\r\t\v\0\"");}, $filter_string_list); + $filter_string_dict = []; + foreach ($filter_string_list as $item) { + $split_item = preg_split("/=/", $item, 2); + $filter_string_dict[$split_item[0]] = trim($split_item[1], " \n\r\t\v\0\""); + } + return $filter_string_dict; +} + +function verify_authorisation_header(string $auth_header, string $request_body_str, string $public_key): bool +{ + $auth_header = str_replace("Signature ", "", $auth_header); + $header_parts = get_filter_dict($auth_header); + $created = (int) $header_parts["created"]; + $expires = (int) $header_parts["expires"]; + + $now = new DateTime(); + if ($created <= $now->getTimestamp() && $expires >= $now->getTimestamp()) { + $signing_key = create_signing_string(hash_msg($request_body_str), $created, $expires); + return verify_response($header_parts['signature'], $signing_key, $public_key); + } + return false; +} + +function gen_keys() +{ + $signkeypair = sodium_crypto_sign_keypair(); + $signprivkey = sodium_crypto_sign_secretkey($signkeypair); + $signpubkey = sodium_crypto_sign_publickey($signkeypair); + + // using libsodium + $enckeypair = sodium_crypto_box_keypair(); + $encprivkey = sodium_crypto_box_secretkey($enckeypair); + $encpubkey = sodium_crypto_box_publickey($enckeypair); + + // $openssl = openssl_pkey_get_private($encprivkey); + + // echo "Encryption priv key: ", base64_encode($encprivkey), "\n"; + $encprivkey = new OneAsymmetricKey(new X25519AlgorithmIdentifier(), "\x04\x20" . $encprivkey); + $encpubkey = new PublicKeyInfo(new X25519AlgorithmIdentifier(), new BitString($encpubkey)); + + echo "Signing priv key: ", base64_encode($signprivkey), "\n"; + echo "Signing pub key: ", base64_encode($signpubkey), "\n"; + echo "Encryption priv key: ", base64_encode($encprivkey->toDER()), "\n"; + echo "Encryption pub key: ", base64_encode($encpubkey->toDER()), "\n"; } -function verify_authorisation_header(string $auth_header, string $request_body_str, string $public_key): bool { - $auth_header = str_replace("Signature ", "", $auth_header); - $header_parts = get_filter_dict($auth_header); - $created = (int) $header_parts["created"]; - $expires = (int) $header_parts["expires"]; - - $now = new DateTime(); - if ($created <= $now->getTimestamp() && $expires >= $now->getTimestamp()) { - $signing_key = create_signing_string(hash_msg($request_body_str), $created, $expires); - return verify_response($header_parts['signature'], $signing_key, $public_key); - } - return false; +function encrypt(string $crypto_private_key, string $crypto_public_key, ?string $message = null): string +{ + $pkey = OneAsymmetricKey::fromDER(base64_decode($crypto_private_key)); + $pubkey = PublicKeyInfo::fromDER(base64_decode($crypto_public_key)); + $pkey = hex2bin(str_replace("0420", "", bin2hex($pkey->privateKeyData()))); + $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); + $shpkey = sodium_crypto_box_secretkey($shkey); + + $cipher = new AES('ecb'); + $cipher->setKey($shpkey); + return base64_encode($cipher->encrypt($message == null ? 'ONDC is a great initiative!' : $message)); } -function gen_keys() { - $signkeypair = sodium_crypto_sign_keypair(); - $signprivkey = sodium_crypto_sign_secretkey($signkeypair); - $signpubkey = sodium_crypto_sign_publickey($signkeypair); - - // using libsodium - $enckeypair = sodium_crypto_box_keypair(); - $encprivkey = sodium_crypto_box_secretkey($enckeypair); - $encpubkey = sodium_crypto_box_publickey($enckeypair); - - // $openssl = openssl_pkey_get_private($encprivkey); - - echo "Encryption priv key: ", base64_encode($encprivkey), "\n"; - $encprivkey = new OneAsymmetricKey(new X25519AlgorithmIdentifier(), "\x04\x20".$encprivkey); - $encpubkey = new PublicKeyInfo(new X25519AlgorithmIdentifier(), new BitString($encpubkey)); - - echo "Signing priv key: ", base64_encode($signprivkey), "\n"; - echo "Signing pub key: ", base64_encode($signpubkey), "\n"; - echo "Encryption priv key: ", base64_encode($encprivkey->toDER()), "\n"; - echo "Encryption pub key: ", base64_encode($encpubkey->toDER()), "\n"; +function decrypt(string $crypto_private_key, string $crypto_public_key, string $cipher_text): string +{ + $pkey = OneAsymmetricKey::fromDER(base64_decode($crypto_private_key)); + $pubkey = PublicKeyInfo::fromDER(base64_decode($crypto_public_key)); + $pkey = hex2bin(str_replace("0420", "", bin2hex($pkey->privateKeyData()))); + $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); + $shpkey = sodium_crypto_box_secretkey($shkey); + + $cipher = new AES('ecb'); + $cipher->setKey($shpkey); + return ($cipher->decrypt(base64_decode($cipher_text))); } -function encrypt(string $crypto_private_key, string $crypto_public_key, ?string $message=null): string { - $pkey = OneAsymmetricKey::fromDER(base64_decode($crypto_private_key)); - $pubkey = PublicKeyInfo::fromDER(base64_decode($crypto_public_key)); - $pkey = hex2bin(str_replace("0420","", bin2hex($pkey->privateKeyData()))); - $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); - $shpkey = sodium_crypto_box_secretkey($shkey); - - $cipher = new AES('ecb'); - $cipher->setKey($shpkey); - return base64_encode($cipher->encrypt($message == null ? 'ONDC is a great initiative!':$message)); +function main(array $args) +{ + switch ($args[1]) { + case "-g": + gen_keys(); + break; + case "-e": + echo encrypt($_ENV['ENC_PRIV_KEY'], $_ENV['COUNTERPARTY_PUB_KEY'], $args[2]); + break; + case "-d": + echo decrypt($_ENV['ENC_PRIV_KEY'], $_ENV['ENC_PUB_KEY'], $args[2]); + break; + case "-s": + echo create_authorisation_header($_ENV['REQUEST_BODY']); + break; + case "-v": + echo verify_authorisation_header($_ENV['AUTH_HEADER'] || '', $_ENV['REQUEST_BODY'] || '', $_ENV["COUNTERPARTY_SIGNING_PUB_KEY"]); + break; + default: + echo "$args[1] is not a valid argument: please check" . "\n"; + echo "signing and verification helper: " . "\n"; + echo "-g: generate signing and enc key pairs" . "\n"; + echo "-e: encrypt with enc keys" . "\n"; + echo "-d: decrypt with enc keys" . "\n"; + echo "-s: create signed header" . "\n"; + echo "-v: verify signed header" . "\n"; + } } -function decrypt(string $crypto_private_key, string $crypto_public_key, string $cipher_text): string { - $pkey = OneAsymmetricKey::fromDER(base64_decode($crypto_private_key)); - $pubkey = PublicKeyInfo::fromDER(base64_decode($crypto_public_key)); - $pkey = hex2bin(str_replace("0420","", bin2hex($pkey->privateKeyData()))); - $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); - $shpkey = sodium_crypto_box_secretkey($shkey); - - $cipher = new AES('ecb'); - $cipher->setKey($shpkey); - return ($cipher->decrypt(base64_decode($cipher_text))); -} \ No newline at end of file +main($argv); From 9966b0d3fc517152715138037fa243ab040273b6 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 5 Feb 2024 17:41:16 +0530 Subject: [PATCH 126/228] updated cancellation terms --- .../schema/B2B_json_schema/v2/confirm.js | 12 +++ .../schema/B2B_json_schema/v2/on_confirm.js | 1 + .../schema/B2B_json_schema/v2/on_init.js | 1 + .../schema/B2B_json_schema/v2/on_search.js | 101 +++++++++++------- .../schema/B2B_json_schema/v2/on_status.js | 7 +- .../utils/b2b/b2bOnSearch.js | 79 ++++++++------ .../utils/b2b/b2bOnStatus.js | 37 ++----- .../utils/constants.js | 4 +- .../log-verification-utility/utils/utils.js | 15 +++ 9 files changed, 155 insertions(+), 102 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 6598048..cece70e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -649,12 +649,24 @@ module.exports = { }, "@ondc/org/settlement_basis": { type: "string", + const: { + $data: + "/on_init/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, }, "@ondc/org/settlement_window": { type: "string", + const: { + $data: + "/on_init/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, }, "@ondc/org/withholding_amount": { type: "string", + const: { + $data: + "/on_init/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, }, "@ondc/org/settlement_details": { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 8b9be10..26b5267 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -583,6 +583,7 @@ module.exports = { required: ["currency", "value"], }, }, + additionalProperties: false, required: ["price"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 7095ff1..54867f3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -539,6 +539,7 @@ module.exports = { required: ["currency", "value"], }, }, + additionalProperties: false, required: ["price"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 4fbe8f6..d033b63 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -238,7 +238,8 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", @@ -700,68 +701,93 @@ module.exports = { }, required: ["descriptor"], }, - refund_eligible: { - type: "string", + reason_required: { + type: "boolean", }, - return_policy: { + cancellation_fee: { type: "object", properties: { - return_eligible: { - type: "string", - }, - return_within: { - type: "string", - }, - fulfillment_managed_by: { + percentage: { type: "string", }, - return_location: { + amount: { type: "object", properties: { - address: { + currency: { type: "string", }, - gps: { + value: { type: "string", }, }, - required: ["address", "gps"], + required: ["currency", "value"], }, }, - required: [ - "return_eligible", - "return_within", - "fulfillment_managed_by", - "return_location", - ], + required: [], }, }, - if: { + required: [ + "fulfillment_state", + "reason_required", + "cancellation_fee", + ], + }, + }, + return_terms: { + type: "object", + properties: { + fulfillment_state: { + type: "object", properties: { - fulfillment_state: { + descriptor: { + type: "object", properties: { - descriptor: { - properties: { - code: { - const: "Order-delivered", - }, - }, + code: { + type: "string", }, }, + required: ["code"], }, }, + required: ["descriptor"], }, - then: { - required: ["fulfillment_state", "return_policy"], + return_eligible: { + type: "boolean", }, - else: { - required: [ - "fulfillment_state", - "refund_eligible", - ], + return_time: { + type: "object", + properties: { + duration: { + type: "string", + }, + }, + required: ["duration"], + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + required: ["address", "gps"], + }, + fulfillment_managed_by: { + type: "string", }, }, + required: [ + "fulfillment_state", + "return_eligible", + "return_time", + "return_location", + "fulfillment_managed_by", + ], }, + replacement_terms: { type: "array", items: { @@ -840,7 +866,6 @@ module.exports = { }, required: [ "id", - "descriptor", "creator", "price", @@ -850,8 +875,8 @@ module.exports = { "location_ids", "payment_ids", "cancellation_terms", + "return_terms", "replacement_terms", - "matched", "recommended", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 0847c1e..2c63409 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -643,21 +643,21 @@ module.exports = { type: "string", const: { $data: - "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + "/on_confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", }, }, "@ondc/org/settlement_window": { type: "string", const: { $data: - "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + "/on_confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", }, }, "@ondc/org/withholding_amount": { type: "string", const: { $data: - "/confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + "/on_confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", }, }, "@ondc/org/settlement_details": { @@ -787,7 +787,6 @@ module.exports = { "fulfillments", "quote", "payments", - "documents", "created_at", "updated_at", ], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 1a77f78..9ed628e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -63,42 +63,59 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics - if (constants.ATTR_DOMAINS.includes(domain)) { - provider.items.forEach((item) => { - let itemTags = item?.tags; - let mandatoryAttr = []; - let attrPresent = false; - if (domain === "ONDC:RET12") { - mandatoryAttr = constants.FASHION_ATTRIBUTES; - } - if (domain === "ONDC:RET14") { - mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; - } - itemTags.map(({ descriptor, list }, index) => { - switch (descriptor?.code) { - case "attribute": - attrPresent = true; - const encounteredAttr = []; - list.map(({ descriptor, value }) => { - encounteredAttr.push(descriptor?.code); - }); + provider.items.forEach((item) => { + let itemTags = item?.tags; + let mandatoryAttr = []; + let attrPresent = false; + let missingAttr = []; + + itemTags.forEach((tag) => { + let { descriptor, list } = tag; + console.log(descriptor.code); + if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { + + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET14") { + mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + } + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { + mandatoryAttr = constants.MANDATORY_ATTRIBUTES; + } + attrPresent = true; + missingAttr = utils.findMissingTags( + list, + descriptor.code, + mandatoryAttr + ); - // Check if all mandatory attributes are encountered - const missingAttr = mandatoryAttr.filter( - (code) => !encounteredAttr.includes(code) - ); - if (missingAttr.length > 0) { - onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; - } - break; + if (missingAttr.length > 0) { + onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; } - }); + } + if (descriptor?.code === "g2") { + mandatoryAttr = constants.G2TAGS; + missingAttr = utils.findMissingTags( + list, + descriptor.code, + mandatoryAttr + ); - if (!attrPresent) - onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; + if (missingAttr.length > 0) { + onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; + } + } }); - } + if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { + onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; + } + }); + } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 7d1817a..32a9a12 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -16,6 +16,7 @@ const checkOnStatus = (data, msgIdSet) => { let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; let payments = on_status?.payments; + let invoice = on_status?.documents; try { console.log(`Checking payment object in /on_status`); @@ -42,34 +43,6 @@ const checkOnStatus = (data, msgIdSet) => { console.log(error); } - // try { - // console.log( - // `Checking if message id is unique for different on_status apis` - // ); - // if (msgIdSet.has(messageId)) { - // onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; - // } else { - // msgIdSet.add(messageId); - // } - // } catch (error) { - // console.log(`Error checking message id in /on_status API`); - // } - - // try { - // if (fulfillments.length > 1) { - // console.log( - // `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` - // ); - // fulfillments.forEach((fulfillment) => { - // ffState = fulfillment?.state?.descriptor?.code; - // if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { - // onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; - // } - // }); - // } - // } catch (error) { - // console.log(error); - // } try { fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; @@ -83,6 +56,7 @@ const checkOnStatus = (data, msgIdSet) => { ffState === "Agent-assigned" || ffState === "Packed" ) { + fulfillment.stops.forEach((stop) => { if (stop.type === "start") { if (stop?.time?.timestamp) { @@ -96,10 +70,12 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up` } //Order-picked-up if (ffState === "Order-picked-up") { + if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } @@ -122,10 +98,12 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required once the order is picked up` } //Out-for-delivery if (ffState === "Out-for-delivery") { + if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } @@ -149,10 +127,12 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required once the order is picked up` } //Order-delivered if (ffState === "Order-delivered") { + if (orderState !== "Completed") { onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; } @@ -184,6 +164,7 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required once the order is picked up` } } if (fulfillment.type === "Self-Pickup") { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index ad070b4..fdc48b3 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -171,7 +171,9 @@ module.exports = Object.freeze({ CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], + MANDATORY_ATTRIBUTES: ["brand"], TERMS:["buyer_id","bap_terms","bpp_terms"], B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], - ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"] + ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"], + G2TAGS:["time_to_ship","cancellable","tax_rate"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 3c407dc..4dcd474 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -235,6 +235,7 @@ function compareDates(dateString1, dateString2) { } } + function iso8601DurationToSeconds(duration) { const unitMap = { 'D': 24 * 60 * 60 * 1000, // Days to seconds @@ -403,6 +404,19 @@ function findDifferencesInArrays(array1, array2) { return differences; } + +const findMissingTags =(list,code,mandatoryAttr) =>{ + const encounteredAttr = []; + list.map(({ descriptor, value }) => { + encounteredAttr.push(descriptor?.code); + }); + // Check if all mandatory attributes are encountered + const missingAttr = mandatoryAttr.filter( + (code) => !encounteredAttr.includes(code) + ); + return missingAttr; + +} module.exports = { uuidCheck, timestampCheck, @@ -431,4 +445,5 @@ module.exports = { findDifferencesInArrays, grocery_categories_id, fnb_categories_id, + findMissingTags }; From 2d7911ce22ae6529f9565dba6aa5b4cb3759d8b3 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 6 Feb 2024 10:55:28 +0530 Subject: [PATCH 127/228] minor change --- .../schema/B2B_json_schema/v2/on_confirm.js | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 26b5267..8716ffd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -679,12 +679,24 @@ module.exports = { }, "@ondc/org/settlement_basis": { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, }, "@ondc/org/settlement_window": { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, }, "@ondc/org/withholding_amount": { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, }, "@ondc/org/settlement_details": { type: "array", @@ -694,6 +706,10 @@ module.exports = { settlement_counterparty: { type: "string", enum: ["seller-app", "buyer-app"], + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_counterparty", + }, }, settlement_phase: { type: "string", @@ -701,24 +717,52 @@ module.exports = { settlement_type: { type: "string", enum: ["upi", "neft", "rtgs"], + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_type", + }, }, beneficiary_name: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/beneficiary_name", + }, }, upi_address: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/upi_address", + }, }, settlement_bank_account_no: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_bank_account_no", + }, }, settlement_ifsc_code: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_ifsc_code", + }, }, bank_name: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/bank_name", + }, }, branch_name: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/branch_name", + }, }, }, allOf: [ From 76b271a82f3b3ab0775eb9a69fdb6fdfab0e550e Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 6 Feb 2024 13:37:23 +0530 Subject: [PATCH 128/228] bug fixes --- .../schema/B2B_json_schema/v2/on_confirm.js | 1 + .../schema/B2B_json_schema/v2/on_search.js | 1 + 2 files changed, 2 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 8716ffd..31c6737 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -298,6 +298,7 @@ module.exports = { }, "@ondc/org/provider_name": { type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1provider_name" }, }, state: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index d033b63..716a3f2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -864,6 +864,7 @@ module.exports = { }, }, }, + additionalProperties:false, required: [ "id", "descriptor", From aacf4b9847a389753d0928ce2474733fbbbb23a5 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 6 Feb 2024 22:29:31 +0530 Subject: [PATCH 129/228] few additions --- .../schema/logistics_api_json_schema/v1.2/onConfirmSchema.js | 2 ++ .../schema/logistics_api_json_schema/v1.2/updateSchema.js | 5 +++++ .../log-verification-utility/utils/logistics/logConfirm.js | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 2cef21f..8823f76 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -594,6 +594,8 @@ module.exports = { properties: { short_desc: { type: "string", + not: { const: { $data: "3/start/instructions/short_desc" } }, + errorMessage: "cannot be same as PCC - ${3/start/instructions/short_desc}" }, long_desc: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 209fc5f..13962f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -165,12 +165,14 @@ module.exports = { code: { type: "string", enum: PCC_CODE, + const: { $data: "/confirm/0/message/order/fulfillments/0/start/instructions/code" } }, name: { type: "string", }, short_desc: { type: "string", + const: { $data: "/confirm/0/message/order/fulfillments/0/end/instructions/short_desc" } }, long_desc: { type: "string", @@ -222,12 +224,15 @@ module.exports = { code: { type: "string", enum: DCC_CODE, + const: { $data: "/confirm/0/message/order/fulfillments/0/end/instructions/code" } }, name: { type: "string", }, short_desc: { type: "string", + not: { const: { $data: "3/start/instructions/short_desc" } }, + errorMessage: "cannot be same as PCC - ${3/start/instructions/short_desc}" }, long_desc: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 6716ca3..30107da 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -74,7 +74,7 @@ const checkConfirm = (data, msgIdSet) => { fulfillments.forEach((fulfillment) => { let avgPickupTime= fulfillment?.start?.time?.duration; console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); - if(avgPickupTime && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ + if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; From 4b3317c347e22943d8315e210b9ef94cbdde4fee Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 130/228] Update readme.md From 4c2a7bbf01a19264c69e3647b716e9a681198fcc Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 131/228] Update readme.md From f13a5569dfd6084c55859a0e1d822c9ecbb0823e Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 132/228] Update readme.md From bb7d61de9e99a645fc61a3c44980bd3bfb510c11 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 29 Jan 2024 16:07:20 +0530 Subject: [PATCH 133/228] minor bug fixes --- .../schema/B2B_json_schema/v2/on_confirm.js | 12 +++++++ .../schema/B2B_json_schema/v2/on_select.js | 2 ++ .../schema/B2B_json_schema/v2/on_status.js | 24 ++++++++++++++ .../schema/B2B_json_schema/v2/select.js | 1 + .../v1.2/initSchema.js | 33 ++++++++++++++----- .../utils/b2b/b2bOnSearch.js | 16 +++++---- .../utils/constants.js | 3 +- .../utils/logistics/logConfirm.js | 27 +++++++++++++-- .../utils/logistics/logOnSearch.js | 2 +- .../utils/reverseGeoCoding.js | 10 ++++-- 10 files changed, 107 insertions(+), 23 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 97cf393..8b9be10 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -676,6 +676,15 @@ module.exports = { type: "string", const: { $data: "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount" }, }, + "@ondc/org/settlement_basis": { + type: "string", + }, + "@ondc/org/settlement_window": { + type: "string", + }, + "@ondc/org/withholding_amount": { + type: "string", + }, "@ondc/org/settlement_details": { type: "array", items: { @@ -759,6 +768,9 @@ module.exports = { "collected_by", "@ondc/org/buyer_app_finder_fee_type", "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index fd73c5e..a8d8371 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onSelectSchema", type: "object", @@ -236,6 +237,7 @@ module.exports = { }, "@ondc/org/category": { type: "string", + enum: constants.CATEGORY_ID }, "@ondc/org/TAT": { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 2f37c00..0847c1e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -639,6 +639,27 @@ module.exports = { "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount", }, }, + "@ondc/org/settlement_basis": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, + }, + "@ondc/org/settlement_window": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, + }, + "@ondc/org/withholding_amount": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, + }, "@ondc/org/settlement_details": { type: "array", items: { @@ -722,6 +743,9 @@ module.exports = { "collected_by", "@ondc/org/buyer_app_finder_fee_type", "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 1652dfa..9c89d02 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -125,6 +125,7 @@ module.exports = { }, }, required: ["id", "locations", "ttl"], + errorMessage: "id, locations are mandatory attributes and ttl is required for RFQ Flow" }, items: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 0721b13..90f07c2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -196,8 +196,8 @@ module.exports = { type: "string", }, }, - isLengthValid:true, - + isLengthValid: true, + required: [ "name", "building", @@ -274,8 +274,8 @@ module.exports = { type: "string", }, }, - isLengthValid:true, - + isLengthValid: true, + required: [ "name", "building", @@ -456,15 +456,32 @@ module.exports = { type: "string", enum: constants.PAYMENT_TYPE, const: { $data: "/search/0/message/intent/payment/type" }, - errorMessage:"should be same as in /search - ${/search/0/message/intent/payment/type}" + errorMessage: + "should be same as in /search - ${/search/0/message/intent/payment/type}", + }, + collected_by: { + type: "string", + enum: constants.PAYMENT_COLLECTEDBY, + }, + }, + additionalProperties: false, + if: { + properties: { + type: { + const: "ON-ORDER", + }, }, }, - additionalProperties:false, - required: ["type"], + then: { + required: ["type", "collected_by"], + }, + else: { + required: ["type"], + }, }, }, additionalProperties: false, - required: ["provider", "items", "fulfillments", "billing","payment"], + required: ["provider", "items", "fulfillments", "billing", "payment"], }, }, required: ["order"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 56bc22a..1a77f78 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -11,7 +11,12 @@ const checkOnSearch = async (data, msgIdSet) => { onSearch = onSearch.message.catalog; //saving fulfillments - + try { + console.log("checking attr"); + console.log(constants.ATTR_DOMAINS.includes(domain)); + } catch (error) { + console.log(error); + } const fulfillments = onSearch?.fulfillments; dao.setValue("fulfillmentsArr", fulfillments); @@ -58,10 +63,10 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics - if (domain === "ONDC:RET12" || domain === "ONDC:RET14") { + if (constants.ATTR_DOMAINS.includes(domain)) { provider.items.forEach((item) => { let itemTags = item?.tags; - let mandatoryAttr; + let mandatoryAttr = []; let attrPresent = false; if (domain === "ONDC:RET12") { @@ -90,10 +95,7 @@ const checkOnSearch = async (data, msgIdSet) => { } }); - if ( - (domain === "ONDC:RET12" || domain === "ONDC:RET14") && - !attrPresent - ) + if (!attrPresent) onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; }); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 3ff9912..ad070b4 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -172,5 +172,6 @@ module.exports = Object.freeze({ FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], TERMS:["buyer_id","bap_terms","bpp_terms"], - B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"] + B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], + ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 5b91a63..d4be8b2 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -11,7 +11,7 @@ const checkConfirm = (data, msgIdSet) => { let onSearchProvArr = dao.getValue("providersArr"); confirm = confirm.message.order; let rts; - + let linkedOrder = confirm["@ondc/org/linked_order"] if (confirm?.updated_at > contextTimestamp) { cnfrmObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; } @@ -73,8 +73,8 @@ const checkConfirm = (data, msgIdSet) => { let p2h2p = dao.getValue("p2h2p"); fulfillments.forEach((fulfillment) => { let avgPickupTime= fulfillment?.start?.time?.duration; - - if(avgPickupTime && avgPickupTime!==dao.getValue("avgPickupTime")){ +console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); + if(avgPickupTime && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; @@ -83,6 +83,27 @@ const checkConfirm = (data, msgIdSet) => { } }); + try { + console.log("checking linked order in /confirm"); + + const orderWeight =linkedOrder?.order?.weight?.value; + + let totalUnitWeight=0; + + linkedOrder?.items.forEach(item=>{ + const quantity = item?.quantity?.measure?.value + const count = item?.quantity?.count + + const unitWeight = (quantity*count).toFixed(2) + totalUnitWeight+=unitWeight; + }) + + if(totalUnitWeight!=orderWeight.toFixed(2)){ + cnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` + } + } catch (error) { + console.log(error); + } dao.setValue("awbNo", awbNo); return cnfrmObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js index f295472..029063a 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnSearch.js @@ -107,7 +107,7 @@ const checkOnSearch = async (data, msgIdSet) => { ) { hasForwardShipment = true; avgPickupTime= fulfillment?.start?.time?.duration - dao.setValue("avgPickupTime",avgPickupTime) + dao.setValue(`${fulfillment?.id}-avgPickupTime`,avgPickupTime) } else if ( fulfillment.type === "RTO" || fulfillment.type === "Reverse QC" || diff --git a/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js b/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js index dc1abfc..fdd9549 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/reverseGeoCoding.js @@ -5,16 +5,20 @@ * @param {string} area_code The Area Code to check the above lat-long pair against * @returns {boolean} Returns `true` if `area_code` matched lat-long pair */ - require("dotenv").config(); +require("dotenv").config(); const reverseGeoCodingCheck = async (lat, long, area_code) => { var fetch = require("node-fetch"); var requestOptions = { method: "GET", }; try { - const res = await fetch(`https://apis.mappls.com/advancedmaps/v1/${process.env.MAPPLS_API_KEY}/rev_geocode?lat=${lat}&lng=${long}`, requestOptions); + const res = await fetch( + `https://apis.mappls.com/advancedmaps/v1/${process.env.MAPPLS_API_KEY}/rev_geocode?lat=${lat}&lng=${long}`, + requestOptions + ); const response = await res.json(); - return response.results[0].pincode === area_code + if (response.results) return response.results[0].pincode === area_code; + else return false; } catch (error) { console.log(error); } From f9f5deb769a04d25bb71606aaedc9ec38da2f7ef Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 30 Jan 2024 15:38:58 +0530 Subject: [PATCH 134/228] few checks added --- .../schema/B2B_json_schema/v2/search.js | 1 + .../schema/logistics_api_json_schema/v1.2/onConfirmSchema.js | 3 --- .../log-verification-utility/utils/logistics/logConfirm.js | 4 ++-- .../log-verification-utility/utils/logistics/logOnConfirm.js | 4 +++- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index 160bdd1..453ca21 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -117,6 +117,7 @@ module.exports = { properties: { type: { type: "string", + enum:["end"] }, location: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 952d783..2cef21f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -888,9 +888,6 @@ module.exports = { }, updated_at: { type: "string", - const: { $data: "3/context/timestamp" }, - errorMessage: - "does not match context/timestamp - ${3/context/timestamp}", }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index d4be8b2..6716ca3 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -94,11 +94,11 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); const quantity = item?.quantity?.measure?.value const count = item?.quantity?.count - const unitWeight = (quantity*count).toFixed(2) + const unitWeight = (quantity*count) totalUnitWeight+=unitWeight; }) - if(totalUnitWeight!=orderWeight.toFixed(2)){ + if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2)){ cnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` } } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index ce4ce33..5133fd0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -22,7 +22,9 @@ const checkOnConfirm = (data, msgIdSet) => { if (on_confirm?.created_at > contextTimestamp) { onCnfrmObj.createdAtErr = `order/created_at cannot be future dated w.r.t context/timestamp`; } - + if (on_confirm?.created_at > on_confirm?.updated_at) { + onCnfrmObj.createdAtErr = `order/created_at cannot be future dated w.r.t order/updated_at`; + } let categoryId; items.forEach(item=>{ categoryId=item.category_id; From 86001eb8b2a5f41f003432307d9cd69e52984b0d Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 5 Feb 2024 17:41:16 +0530 Subject: [PATCH 135/228] updated cancellation terms --- .../schema/B2B_json_schema/v2/confirm.js | 12 +++ .../schema/B2B_json_schema/v2/on_confirm.js | 1 + .../schema/B2B_json_schema/v2/on_init.js | 1 + .../schema/B2B_json_schema/v2/on_search.js | 101 +++++++++++------- .../schema/B2B_json_schema/v2/on_status.js | 7 +- .../utils/b2b/b2bOnSearch.js | 79 ++++++++------ .../utils/b2b/b2bOnStatus.js | 37 ++----- .../utils/constants.js | 4 +- .../log-verification-utility/utils/utils.js | 15 +++ 9 files changed, 155 insertions(+), 102 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 6598048..cece70e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -649,12 +649,24 @@ module.exports = { }, "@ondc/org/settlement_basis": { type: "string", + const: { + $data: + "/on_init/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, }, "@ondc/org/settlement_window": { type: "string", + const: { + $data: + "/on_init/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, }, "@ondc/org/withholding_amount": { type: "string", + const: { + $data: + "/on_init/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, }, "@ondc/org/settlement_details": { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 8b9be10..26b5267 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -583,6 +583,7 @@ module.exports = { required: ["currency", "value"], }, }, + additionalProperties: false, required: ["price"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 7095ff1..54867f3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -539,6 +539,7 @@ module.exports = { required: ["currency", "value"], }, }, + additionalProperties: false, required: ["price"], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 4fbe8f6..d033b63 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -238,7 +238,8 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", @@ -700,68 +701,93 @@ module.exports = { }, required: ["descriptor"], }, - refund_eligible: { - type: "string", + reason_required: { + type: "boolean", }, - return_policy: { + cancellation_fee: { type: "object", properties: { - return_eligible: { - type: "string", - }, - return_within: { - type: "string", - }, - fulfillment_managed_by: { + percentage: { type: "string", }, - return_location: { + amount: { type: "object", properties: { - address: { + currency: { type: "string", }, - gps: { + value: { type: "string", }, }, - required: ["address", "gps"], + required: ["currency", "value"], }, }, - required: [ - "return_eligible", - "return_within", - "fulfillment_managed_by", - "return_location", - ], + required: [], }, }, - if: { + required: [ + "fulfillment_state", + "reason_required", + "cancellation_fee", + ], + }, + }, + return_terms: { + type: "object", + properties: { + fulfillment_state: { + type: "object", properties: { - fulfillment_state: { + descriptor: { + type: "object", properties: { - descriptor: { - properties: { - code: { - const: "Order-delivered", - }, - }, + code: { + type: "string", }, }, + required: ["code"], }, }, + required: ["descriptor"], }, - then: { - required: ["fulfillment_state", "return_policy"], + return_eligible: { + type: "boolean", }, - else: { - required: [ - "fulfillment_state", - "refund_eligible", - ], + return_time: { + type: "object", + properties: { + duration: { + type: "string", + }, + }, + required: ["duration"], + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, + }, + required: ["address", "gps"], + }, + fulfillment_managed_by: { + type: "string", }, }, + required: [ + "fulfillment_state", + "return_eligible", + "return_time", + "return_location", + "fulfillment_managed_by", + ], }, + replacement_terms: { type: "array", items: { @@ -840,7 +866,6 @@ module.exports = { }, required: [ "id", - "descriptor", "creator", "price", @@ -850,8 +875,8 @@ module.exports = { "location_ids", "payment_ids", "cancellation_terms", + "return_terms", "replacement_terms", - "matched", "recommended", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 0847c1e..2c63409 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -643,21 +643,21 @@ module.exports = { type: "string", const: { $data: - "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + "/on_confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", }, }, "@ondc/org/settlement_window": { type: "string", const: { $data: - "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + "/on_confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", }, }, "@ondc/org/withholding_amount": { type: "string", const: { $data: - "/confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + "/on_confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", }, }, "@ondc/org/settlement_details": { @@ -787,7 +787,6 @@ module.exports = { "fulfillments", "quote", "payments", - "documents", "created_at", "updated_at", ], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 1a77f78..9ed628e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -63,42 +63,59 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics - if (constants.ATTR_DOMAINS.includes(domain)) { - provider.items.forEach((item) => { - let itemTags = item?.tags; - let mandatoryAttr = []; - let attrPresent = false; - if (domain === "ONDC:RET12") { - mandatoryAttr = constants.FASHION_ATTRIBUTES; - } - if (domain === "ONDC:RET14") { - mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; - } - itemTags.map(({ descriptor, list }, index) => { - switch (descriptor?.code) { - case "attribute": - attrPresent = true; - const encounteredAttr = []; - list.map(({ descriptor, value }) => { - encounteredAttr.push(descriptor?.code); - }); + provider.items.forEach((item) => { + let itemTags = item?.tags; + let mandatoryAttr = []; + let attrPresent = false; + let missingAttr = []; + + itemTags.forEach((tag) => { + let { descriptor, list } = tag; + console.log(descriptor.code); + if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { + + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET14") { + mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + } + if (domain === "ONDC:RET12") { + mandatoryAttr = constants.FASHION_ATTRIBUTES; + } + if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { + mandatoryAttr = constants.MANDATORY_ATTRIBUTES; + } + attrPresent = true; + missingAttr = utils.findMissingTags( + list, + descriptor.code, + mandatoryAttr + ); - // Check if all mandatory attributes are encountered - const missingAttr = mandatoryAttr.filter( - (code) => !encounteredAttr.includes(code) - ); - if (missingAttr.length > 0) { - onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; - } - break; + if (missingAttr.length > 0) { + onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; } - }); + } + if (descriptor?.code === "g2") { + mandatoryAttr = constants.G2TAGS; + missingAttr = utils.findMissingTags( + list, + descriptor.code, + mandatoryAttr + ); - if (!attrPresent) - onSrchObj.attrErr = `code = 'attribute' is required in items/tags for domain - ${domain} and provider/id - ${provider.id}`; + if (missingAttr.length > 0) { + onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; + } + } }); - } + if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { + onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; + } + }); + } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 7d1817a..32a9a12 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -16,6 +16,7 @@ const checkOnStatus = (data, msgIdSet) => { let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; let payments = on_status?.payments; + let invoice = on_status?.documents; try { console.log(`Checking payment object in /on_status`); @@ -42,34 +43,6 @@ const checkOnStatus = (data, msgIdSet) => { console.log(error); } - // try { - // console.log( - // `Checking if message id is unique for different on_status apis` - // ); - // if (msgIdSet.has(messageId)) { - // onStatusObj.msgIdErr = `Message Id should be unique for different /on_status APIs`; - // } else { - // msgIdSet.add(messageId); - // } - // } catch (error) { - // console.log(`Error checking message id in /on_status API`); - // } - - // try { - // if (fulfillments.length > 1) { - // console.log( - // `Checking for a valid 'Cancelled' fulfillment state for type 'Delivery' in case of RTO` - // ); - // fulfillments.forEach((fulfillment) => { - // ffState = fulfillment?.state?.descriptor?.code; - // if (fulfillment.type === "Prepaid" && ffState !== "Cancelled") { - // onStatusObj.flflmntstErr = `In case of RTO, fulfillment with type 'Prepaid' needs to in 'Cancelled' state`; - // } - // }); - // } - // } catch (error) { - // console.log(error); - // } try { fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; @@ -83,6 +56,7 @@ const checkOnStatus = (data, msgIdSet) => { ffState === "Agent-assigned" || ffState === "Packed" ) { + fulfillment.stops.forEach((stop) => { if (stop.type === "start") { if (stop?.time?.timestamp) { @@ -96,10 +70,12 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up` } //Order-picked-up if (ffState === "Order-picked-up") { + if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } @@ -122,10 +98,12 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required once the order is picked up` } //Out-for-delivery if (ffState === "Out-for-delivery") { + if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } @@ -149,10 +127,12 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required once the order is picked up` } //Order-delivered if (ffState === "Order-delivered") { + if (orderState !== "Completed") { onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; } @@ -184,6 +164,7 @@ const checkOnStatus = (data, msgIdSet) => { } } }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required once the order is picked up` } } if (fulfillment.type === "Self-Pickup") { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index ad070b4..fdc48b3 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -171,7 +171,9 @@ module.exports = Object.freeze({ CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], + MANDATORY_ATTRIBUTES: ["brand"], TERMS:["buyer_id","bap_terms","bpp_terms"], B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], - ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"] + ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"], + G2TAGS:["time_to_ship","cancellable","tax_rate"] }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 3c407dc..4dcd474 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -235,6 +235,7 @@ function compareDates(dateString1, dateString2) { } } + function iso8601DurationToSeconds(duration) { const unitMap = { 'D': 24 * 60 * 60 * 1000, // Days to seconds @@ -403,6 +404,19 @@ function findDifferencesInArrays(array1, array2) { return differences; } + +const findMissingTags =(list,code,mandatoryAttr) =>{ + const encounteredAttr = []; + list.map(({ descriptor, value }) => { + encounteredAttr.push(descriptor?.code); + }); + // Check if all mandatory attributes are encountered + const missingAttr = mandatoryAttr.filter( + (code) => !encounteredAttr.includes(code) + ); + return missingAttr; + +} module.exports = { uuidCheck, timestampCheck, @@ -431,4 +445,5 @@ module.exports = { findDifferencesInArrays, grocery_categories_id, fnb_categories_id, + findMissingTags }; From 5ff19586a0193ea37bb9758c13a58d2a4c79a979 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 6 Feb 2024 10:55:28 +0530 Subject: [PATCH 136/228] minor change --- .../schema/B2B_json_schema/v2/on_confirm.js | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 26b5267..8716ffd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -679,12 +679,24 @@ module.exports = { }, "@ondc/org/settlement_basis": { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, }, "@ondc/org/settlement_window": { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, }, "@ondc/org/withholding_amount": { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, }, "@ondc/org/settlement_details": { type: "array", @@ -694,6 +706,10 @@ module.exports = { settlement_counterparty: { type: "string", enum: ["seller-app", "buyer-app"], + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_counterparty", + }, }, settlement_phase: { type: "string", @@ -701,24 +717,52 @@ module.exports = { settlement_type: { type: "string", enum: ["upi", "neft", "rtgs"], + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_type", + }, }, beneficiary_name: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/beneficiary_name", + }, }, upi_address: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/upi_address", + }, }, settlement_bank_account_no: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_bank_account_no", + }, }, settlement_ifsc_code: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/settlement_ifsc_code", + }, }, bank_name: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/bank_name", + }, }, branch_name: { type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1settlement_details/0/branch_name", + }, }, }, allOf: [ From 52f31964d649ee60afc69746bbc924a32ff40097 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 6 Feb 2024 13:37:23 +0530 Subject: [PATCH 137/228] bug fixes --- .../schema/B2B_json_schema/v2/on_confirm.js | 1 + .../schema/B2B_json_schema/v2/on_search.js | 1 + 2 files changed, 2 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 8716ffd..31c6737 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -298,6 +298,7 @@ module.exports = { }, "@ondc/org/provider_name": { type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/@ondc~1org~1provider_name" }, }, state: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index d033b63..716a3f2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -864,6 +864,7 @@ module.exports = { }, }, }, + additionalProperties:false, required: [ "id", "descriptor", From 5560a45701c3a6185f0641eed1704860179b0210 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 6 Feb 2024 22:29:31 +0530 Subject: [PATCH 138/228] few additions --- .../schema/logistics_api_json_schema/v1.2/onConfirmSchema.js | 2 ++ .../schema/logistics_api_json_schema/v1.2/updateSchema.js | 5 +++++ .../log-verification-utility/utils/logistics/logConfirm.js | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 2cef21f..8823f76 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -594,6 +594,8 @@ module.exports = { properties: { short_desc: { type: "string", + not: { const: { $data: "3/start/instructions/short_desc" } }, + errorMessage: "cannot be same as PCC - ${3/start/instructions/short_desc}" }, long_desc: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 209fc5f..13962f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -165,12 +165,14 @@ module.exports = { code: { type: "string", enum: PCC_CODE, + const: { $data: "/confirm/0/message/order/fulfillments/0/start/instructions/code" } }, name: { type: "string", }, short_desc: { type: "string", + const: { $data: "/confirm/0/message/order/fulfillments/0/end/instructions/short_desc" } }, long_desc: { type: "string", @@ -222,12 +224,15 @@ module.exports = { code: { type: "string", enum: DCC_CODE, + const: { $data: "/confirm/0/message/order/fulfillments/0/end/instructions/code" } }, name: { type: "string", }, short_desc: { type: "string", + not: { const: { $data: "3/start/instructions/short_desc" } }, + errorMessage: "cannot be same as PCC - ${3/start/instructions/short_desc}" }, long_desc: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 6716ca3..30107da 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -74,7 +74,7 @@ const checkConfirm = (data, msgIdSet) => { fulfillments.forEach((fulfillment) => { let avgPickupTime= fulfillment?.start?.time?.duration; console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); - if(avgPickupTime && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ + if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; From 8103fd5cdbaa14d393a9e80aac4671a9b8d3bbdb Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 139/228] Update readme.md From 26c7e9ac37e0da9630472242ba404b2cc3df517a Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 140/228] Update readme.md From db41506738fc2f1eeba39844c3388d2d3b996362 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 141/228] Update readme.md From 8a1ceed00bf33ad1b97205c61adc573e9270868c Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 142/228] Update readme.md From 937a06ec999fee6fdfde05f7dc77cd0c3f397378 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 143/228] Update readme.md From 31f408d0f78724a62328e44261dddd0d9b5a020a Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 8 Feb 2024 18:44:40 +0530 Subject: [PATCH 144/228] added few vals --- .../v1.2/onSearchSchema.js | 1 + .../v1.2/onUpdateSchema.js | 8 +++ .../utils/logistics/logOnCancel.js | 51 +++++++++++-------- .../utils/logistics/logOnTrack.js | 12 +++-- .../utils/logistics/msgValidator.js | 16 +++--- 5 files changed, 57 insertions(+), 31 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js index 71dd9a7..30a361c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js @@ -304,6 +304,7 @@ module.exports = { additionalProperties:false, required: [ "id", + "parent_item_id", "category_id", "fulfillment_id", "descriptor", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index 7aff9a5..55d31d2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -157,9 +157,17 @@ module.exports = { }, duration: { type: "string", + const: { + $data: + "/on_confirm/0/message/order/items/0/time/duration", + }, }, timestamp: { type: "string", + const: { + $data: + "/on_confirm/0/message/order/items/0/time/timestamp", + }, }, }, required: ["label", "duration", "timestamp"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index 1dbeee1..1d1624b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -10,7 +10,7 @@ const checkOnCancel = (data, msgIdSet) => { let version = on_cancel.context.core_version; let messageId = on_cancel.context.message_id; const providerId = on_cancel.message?.provider?.id; - + let selectedItem; on_cancel = on_cancel.message.order; let onSearchItemsArr = dao.getValue(`${on_cancel?.provider?.id}itemsArr`); let ffState; @@ -44,9 +44,10 @@ const checkOnCancel = (data, msgIdSet) => { } catch (error) { console.log(error); } + if (onSearchItemsArr) { - let selectedItem = onSearchItemsArr.filter( - (element) => element.parent_item_id === dao.getValue("selectedItem") + selectedItem = onSearchItemsArr.filter( + (element) => element?.parent_item_id === dao.getValue("selectedItem") ); selectedItem = selectedItem[0]; } @@ -68,12 +69,15 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } if (fulfillments.length > 1) { - if (!fulfillment.start.time.timestamp) { + if (!fulfillment?.start?.time?.timestamp) { onCancelObj.msngPickupTimeErr = `Pickup timestamp (fulfillments/start/time/timestamp) is missing for fulfillment state - ${ffState}`; } } - if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { + if ( + fulfillment?.start?.time?.timestamp && + dao.getValue("pickupTime") + ) { if ( !_.isEqual( dao.getValue("pickupTime"), @@ -88,28 +92,33 @@ const checkOnCancel = (data, msgIdSet) => { if (version === "1.2.0") { if (dao.getValue("rts") === "yes") { if (!fulfillment?.start?.time) { - onCancelObj.msngStrtTime = `Pickup time range (fulfillments/start/time) is missing`; + onCancelObj.msngStrtTime = `Pickup time range (fulfillments/start/time) is missing for fulfillment type - '${fulfillment.type}'`; } if (!fulfillment?.end?.time) { - onCancelObj.msngDlvryTime = `Delivery time range (fulfillments/end/time) is missing`; + onCancelObj.msngDlvryTime = `Delivery time range (fulfillments/end/time) is missing for fulfillment type - '${fulfillment.type}'`; } } let fulTags = fulfillment?.tags; - let rtoID; - fulTags.forEach((tag) => { - if (tag.code === "rto_event") { - const lists = tag.list; - lists.forEach((list) => { - if (list.code === "rto_id") { - rtoID = list.value; + if (!fulTags) { + onCancelObj.msngflfllmntTags = `fulfillments/tags are required in case of RTO (rto_event, pre_cancel_state)`; + } else { + let rtoID; + + fulTags.forEach((tag) => { + if (tag.code === "rto_event") { + const lists = tag.list; + lists.forEach((list) => { + if (list.code === "rto_id") { + rtoID = list.value; - if (rtoID !== selectedItem.fulfillment_id) { - onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; + if (rtoID !== selectedItem.fulfillment_id) { + onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; + } } - } - }); - } - }); + }); + } + }); + } } } } else if (fulfillment.type === "RTO" || fulfillment.type === "Return") { @@ -135,7 +144,7 @@ const checkOnCancel = (data, msgIdSet) => { } }); } catch (error) { - console.log(`Error checking fulfillments/start in /on_cancel`); + console.trace(`Error checking fulfillments/start in /on_cancel`); } return onCancelObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js index 440291e..27566c1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js @@ -8,18 +8,22 @@ const checkOnTrack = (data, msgIdSet) => { let on_track = data; let contextTimestamp = on_track?.context?.timestamp; - on_track = on_track.message.tracking; + on_track = on_track?.message?.tracking; - if (on_track?.location.updated_at > contextTimestamp) { + if (on_track?.location?.updated_at > contextTimestamp) { onTrackObj.updatedAtErr = `tracking/location/updated_at cannot be future dated w.r.t context/timestamp`; } - if (on_track?.location.time.timestamp > contextTimestamp) { - onTrackObj.updatedAtErr = `tracking/location/time/timestamp cannot be future dated w.r.t context/timestamp`; + if (on_track?.location?.time?.timestamp > contextTimestamp) { + onTrackObj.lctnTimeAtErr = `tracking/location/time/timestamp cannot be future dated w.r.t context/timestamp`; } + console.log(on_track?.location?.updated_at, on_track?.location?.time?.timestamp); + if(on_track?.location?.updated_at < on_track?.location?.time?.timestamp){ + onTrackObj.updatedAtLctnErr = `tracking/location/time/timestamp cannot be future dated w.r.t tracking/location/updated_at`; + } return onTrackObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js index c7679dc..08ab857 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js @@ -7,6 +7,7 @@ const checkOnUpdate = require("./logOnUpdate"); const checkUpdate = require("./logUpdate"); const checkOnStatus = require("./logOnStatus"); const checkOnCancel = require("./logOnCancel"); +const checkOnTrack = require("./logOnTrack"); const checkSearch = require("./logSearch"); const _ = require("lodash"); @@ -32,17 +33,20 @@ const logisticsVal = async (element, action, msgIdSet) => { return checkOnConfirm(element, msgIdSet); case "update": - return checkUpdate(element,msgIdSet); + return checkUpdate(element, msgIdSet); case "on_update": - return checkOnUpdate(element,msgIdSet) + return checkOnUpdate(element, msgIdSet); case "on_status": - return checkOnStatus(element,msgIdSet) + return checkOnStatus(element, msgIdSet); - case "on_cancel": - return checkOnCancel(element,msgIdSet) + case "on_cancel": + return checkOnCancel(element, msgIdSet); + + case "on_track": + return checkOnTrack(element, msgIdSet); } return busnsErr; }; -module.exports = { logisticsVal }; \ No newline at end of file +module.exports = { logisticsVal }; From 9165eeef2e563ec8b26fc728d0cdad4d719f2599 Mon Sep 17 00:00:00 2001 From: Charanpreet Date: Mon, 12 Feb 2024 21:10:13 +0530 Subject: [PATCH 145/228] feat: added subscription utility in PHP --- utilities/on_subscibe-service/php/.env | 5 + .../on_subscibe-service/php/.env-example | 5 + utilities/on_subscibe-service/php/.gitignore | 474 ++++++++++++++++++ .../on_subscibe-service/php/composer.json | 20 + .../on_subscibe-service/php/src/index.php | 315 ++++++++++++ .../php/templates/ondc-site-verification.html | 8 + 6 files changed, 827 insertions(+) create mode 100644 utilities/on_subscibe-service/php/.env create mode 100644 utilities/on_subscibe-service/php/.env-example create mode 100644 utilities/on_subscibe-service/php/.gitignore create mode 100644 utilities/on_subscibe-service/php/composer.json create mode 100644 utilities/on_subscibe-service/php/src/index.php create mode 100644 utilities/on_subscibe-service/php/templates/ondc-site-verification.html diff --git a/utilities/on_subscibe-service/php/.env b/utilities/on_subscibe-service/php/.env new file mode 100644 index 0000000..953ad60 --- /dev/null +++ b/utilities/on_subscibe-service/php/.env @@ -0,0 +1,5 @@ +BAP_BASE_URL="buyer-ondc.ondc.org" +BPP_BASE_URL="seller-ondc.ondc.org" +REGISTERY_URL="reg.ondc.org" +APP_PORT=4000 +STATIC_FILE_PORT=3000 \ No newline at end of file diff --git a/utilities/on_subscibe-service/php/.env-example b/utilities/on_subscibe-service/php/.env-example new file mode 100644 index 0000000..953ad60 --- /dev/null +++ b/utilities/on_subscibe-service/php/.env-example @@ -0,0 +1,5 @@ +BAP_BASE_URL="buyer-ondc.ondc.org" +BPP_BASE_URL="seller-ondc.ondc.org" +REGISTERY_URL="reg.ondc.org" +APP_PORT=4000 +STATIC_FILE_PORT=3000 \ No newline at end of file diff --git a/utilities/on_subscibe-service/php/.gitignore b/utilities/on_subscibe-service/php/.gitignore new file mode 100644 index 0000000..fd7cca8 --- /dev/null +++ b/utilities/on_subscibe-service/php/.gitignore @@ -0,0 +1,474 @@ +##### Windows +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +##### Linux +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +##### MacOS +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +##### Backup +*.bak +*.gho +*.ori +*.orig +*.tmp + +##### GPG +secring.* + +##### Dropbox +# Dropbox settings and caches +.dropbox +.dropbox.attr +.dropbox.cache + +##### SynopsysVCS +# Waveform formats +*.vcd +*.vpd +*.evcd +*.fsdb + +# Default name of the simulation executable. A different name can be +# specified with this switch (the associated daidir database name is +# also taken from here): -o / +simv + +# Generated for Verilog and VHDL top configs +simv.daidir/ +simv.db.dir/ + +# Infrastructure necessary to co-simulate SystemC models with +# Verilog/VHDL models. An alternate directory may be specified with this +# switch: -Mdir= +csrc/ + +# Log file - the following switch allows to specify the file that will be +# used to write all messages from simulation: -l +*.log + +# Coverage results (generated with urg) and database location. The +# following switch can also be used: urg -dir .vdb +simv.vdb/ +urgReport/ + +# DVE and UCLI related files. +DVEfiles/ +ucli.key + +# When the design is elaborated for DirectC, the following file is created +# with declarations for C/C++ functions. +vc_hdrs.h + +##### SVN +.svn/ + +##### Mercurial +.hg/ +.hgignore +.hgsigs +.hgsub +.hgsubstate +.hgtags + +##### Bazaar +.bzr/ +.bzrignore + +##### CVS +/CVS/* +**/CVS/* +.cvsignore +*/.cvsignore + +##### TortoiseGit +# Project-level settings +/.tgitconfig + +##### PuTTY +# Private key +*.ppk + +##### Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +##### Emacs +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +##### SublimeText +# Cache files for Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache + +# Workspace files are user-specific +*.sublime-workspace + +# Project files should be checked into the repository, unless a significant +# proportion of contributors will probably not be using Sublime Text +# *.sublime-project + +# SFTP configuration file +sftp-config.json +sftp-config-alt*.json + +# Package control specific files +Package Control.last-run +Package Control.ca-list +Package Control.ca-bundle +Package Control.system-ca-bundle +Package Control.cache/ +Package Control.ca-certs/ +Package Control.merged-ca-bundle +Package Control.user-ca-bundle +oscrypto-ca-bundle.crt +bh_unicode_properties.cache + +# Sublime-github package stores a github token in this file +# https://packagecontrol.io/packages/sublime-github +GitHub.sublime-settings + +##### Notepad++ +# Notepad++ backups # +*.bak + +##### TextMate +*.tmproj +*.tmproject +tmtags + +##### VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +*.code-workspace + +# Local History for Visual Studio Code +.history/ + +##### NetBeans +**/nbproject/private/ +**/nbproject/Makefile-*.mk +**/nbproject/Package-*.bash +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +##### JetBrains +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/jarRepositories.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +##### Eclipse +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project + +##### Dreamweaver +# DW Dreamweaver added files +_notes +_compareTemp +configs/ +dwsync.xml +dw_php_codehinting.config +*.mno + +##### CodeKit +# General CodeKit files to ignore +config.codekit +config.codekit3 +/min + +##### Gradle +.gradle +**/build/ +!src/**/build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +##### Composer +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +composer.lock + +##### PHP CodeSniffer +# gitignore for the PHP Codesniffer framework +# website: https://github.com/squizlabs/PHP_CodeSniffer +# +# Recommended template: PHP.gitignore + +/wpcs/* + +##### SASS +.sass-cache/ +*.css.map +*.sass.map +*.scss.map \ No newline at end of file diff --git a/utilities/on_subscibe-service/php/composer.json b/utilities/on_subscibe-service/php/composer.json new file mode 100644 index 0000000..7ac0c77 --- /dev/null +++ b/utilities/on_subscibe-service/php/composer.json @@ -0,0 +1,20 @@ +{ + "name": "charnpreet/subscription", + "type": "project", + "autoload": { + "psr-4": { + "Charnpreet\\Subscription\\": "src/" + } + }, + "authors": [ + { + "name": "b" + } + ], + "require": { + "sop/crypto-types": "^0.3.0", + "phpseclib/phpseclib": "^3.0", + "vlucas/phpdotenv": "^5.6", + "ramsey/uuid": "^4.7" + } +} diff --git a/utilities/on_subscibe-service/php/src/index.php b/utilities/on_subscibe-service/php/src/index.php new file mode 100644 index 0000000..1f93e55 --- /dev/null +++ b/utilities/on_subscibe-service/php/src/index.php @@ -0,0 +1,315 @@ +safeLoad(); + +$bapBaseUrl = $_SERVER['BAP_BASE_URL']; +$bppBaseUrl = $_SERVER['BPP_BASE_URL']; +$registery_url = $_SERVER['REGISTERY_URL']; +$app_port = $_SERVER['APP_PORT']; +$static_file_port = $_SERVER['STATIC_FILE_PORT']; +$subscribers = []; +$subscribers_uniquekey_store = []; + +$bapSubscriberBody = [ + "context" => ["operation" => ["ops_no" => 1]], + "message" => [ + "request_id" => "", + "timestamp" => "", + "entity" => [ + "gst" => [ + "legal_entity_name" => "", + "business_address" => "", + "city_code" => ["std:080"], + "gst_no" => "", + ], + "pan" => [ + "name_as_per_pan" => "", + "pan_no" => "", + "date_of_incorporation" => "", + ], + "name_of_authorised_signatory" => "", + "email_id" => "email@domain.in", + "mobile_no" => "", + "country" => "IND", + "subscriber_id" => "", + "unique_key_id" => "", + "callback_url" => "/", + "key_pair" => [ + "signing_public_key" => "", + "encryption_public_key" => "", + "valid_from" => "", + "valid_until" => "2030-06-19T11:57:54.101Z", + ], + ], + "network_participant" => [ + [ + "subscriber_url" => "/", + "domain" => "ONDC:TRV10", + "type" => "buyerApp", + "msn" => false, + "city_code" => [], + ], + ], + ], +]; + +$bppSubscriberBody = [ + "context" => ["operation" => ["ops_no" => 2]], + "message" => [ + "request_id" => "", + "timestamp" => "", + "entity" => [ + "gst" => [ + "legal_entity_name" => "", + "business_address" => "", + "city_code" => ["std:080"], + "gst_no" => "...", + ], + "pan" => [ + "name_as_per_pan" => "...", + "pan_no" => "...", + "date_of_incorporation" => "...", + ], + "name_of_authorised_signatory" => "...", + "email_id" => "email@domain.in", + "mobile_no" => "", + "country" => "IND", + "subscriber_id" => "", + "unique_key_id" => "", + "callback_url" => "/", + "key_pair" => [ + "signing_public_key" => "", + "encryption_public_key" => "", + "valid_from" => "", + "valid_until" => "2030-06-19T11:57:54.101Z", + ], + ], + "network_participant" => [ + [ + "subscriber_url" => "/", + "domain" => "ONDC:TRV10", + "type" => "sellerApp", + "msn" => false, + "city_code" => [], + ], + ], + ], +]; + +function sign(string $signing_key, string $private_key): string +{ + return base64_encode(sodium_crypto_sign_detached($signing_key, base64_decode($private_key))); +} + +function decrypt(string $enc_public_key, string $enc_private_key, string $cipher_string): string +{ + $pkey = OneAsymmetricKey::fromDER(base64_decode($enc_private_key)); + $pubkey = PublicKeyInfo::fromDER(base64_decode($enc_public_key)); + $pkey = hex2bin(str_replace("0420", "", bin2hex($pkey->privateKeyData()))); + $shkey = sodium_crypto_box_keypair_from_secretkey_and_publickey($pkey, $pubkey->publicKeyData()); + $shpkey = sodium_crypto_box_secretkey($shkey); + + $cipher = new AES('ecb'); + $cipher->setKey($shpkey); + return ($cipher->decrypt(base64_decode($cipher_string))); +} + +function createHtml(array $subscriber, string $subscriber_id): void +{ + global $bapBaseUrl, $bppBaseUrl; + $signature = sign($subscriber['requestId'], $subscriber['signingPrivateKey']); + $htmlFile = " + \n + \t\n + \t\t\n + \t\n + \t\n + \t\tONDC Site Verification Page\n + \t\n + \n"; + + if ($subscriber['type'] == "BAP") { + $dir = "templates/" . substr($subscriber_id, strlen( + $subscriber['type'] == "BAP" + ? $bapBaseUrl + : ($subscriber['type'] == "BPP" + ? $bppBaseUrl + : "")) + + 1); + if (!file_exists($dir)) { + mkdir($dir); + } + } + + $siteVer = fopen("$dir/ondc-site-verfication.html", "w+"); + if ($siteVer) { + fwrite($siteVer, $htmlFile); + fclose($siteVer); + } +} + +function serve_file() +{ + global $static_file_port; + shell_exec("php -S localhost:$static_file_port ondc-verification"); +} +function subscribe_helper(mixed $subscribers) +{ + global $subscribers_uniquekey_store, $registery_url; + if ($subscribers != null) { + foreach ($subscribers as $subscriber_uk_id => $subscriber) { + list($subscriber_id, $unique_key_id) = explode(" | ", $subscriber_uk_id); + $subscribers_uniquekey_store[$subscriber_id] = $unique_key_id; + $request_id = (Uuid::uuid4())->toString(); + $subscribers[$subscriber_uk_id]["requestId"] = $request_id; + createHtml($subscriber, $subscriber_id); + } + + if (pcntl_fork() == -1) { + die('could not fork the process'); + } else { + if (function_exists('serve_file')) { + die('function subscribe helper does not exist'); + } + serve_file(); + } + sleep(5); + + foreach ($subscribers as $subscriber_uk_id => $subscriber) { + [$subscriber_id, $unique_key_id] = explode(" | ", $subscriber_uk_id); + $request_id = $subscriber["requestId"]; + $current_datetime = new DateTime("now", new DateTimeZone("Asia/Kolkata")); + $current_datetime_iso8601 = $current_datetime->format("Y-m-d\TH:i:s.u\Z"); + + if ($subscriber["type"] == "BAP") { + $bapSubscribeBody["message"]["request_id"] = $request_id; + $bapSubscribeBody["message"]["timestamp"] = $current_datetime_iso8601; + $bapSubscribeBody["message"]["entity"]["subscriber_id"] = $subscriber_id; + $bapSubscribeBody["message"]["entity"]["unique_key_id"] = $unique_key_id; + $bapSubscribeBody["message"]["entity"]["key_pair"]["signing_public_key"] = $subscriber["signingPublicKey"]; + $bapSubscribeBody["message"]["entity"]["key_pair"]["encryption_public_key"] = $subscriber["encPublicKey"]; + $bapSubscribeBody["message"]["entity"]["key_pair"]["valid_from"] = $current_datetime_iso8601; + $bapSubscribeBody["message"]["network_participant"][0]["city_code"] = [$subscriber["city"]]; + + echo json_encode($bapSubscribeBody) . "\n"; + + $curl = curl_init($registery_url); + curl_setopt_array($curl, [ + CURLOPT_POST => true, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POSTFIELDS => json_encode($bapSubscribeBody), + ]); + $response = curl_exec($curl); + if ($response != false) { + echo "/subscribe for $subscriber_uk_id request successful :: " . json_encode($response) . "\n"; + } else { + echo "/subscribe for $subscriber_uk_id request failed :: " . json_encode($response) . "\n"; + } + curl_close($curl); + } elseif ($subscriber["type"] == "BPP") { + $bppSubscribeBody["message"]["request_id"] = $request_id; + $bppSubscribeBody["message"]["timestamp"] = $current_datetime_iso8601; + $bppSubscribeBody["message"]["entity"]["subscriber_id"] = $subscriber_id; + $bppSubscribeBody["message"]["entity"]["unique_key_id"] = $unique_key_id; + $bppSubscribeBody["message"]["entity"]["key_pair"]["signing_public_key"] = $subscriber["signingPublicKey"]; + $bppSubscribeBody["message"]["entity"]["key_pair"]["encryption_public_key"] = $subscriber["encPublicKey"]; + $bppSubscribeBody["message"]["entity"]["key_pair"]["valid_from"] = $current_datetime_iso8601; + $bppSubscribeBody["message"]["network_participant"][0]["city_code"] = [$subscriber["city"]]; + + echo json_encode($bppSubscribeBody) . "\n"; + + $curl = curl_init($registery_url); + curl_setopt_array($curl, [ + CURLOPT_POST => true, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POSTFIELDS => json_encode($bppSubscribeBody), + ]); + $response = curl_exec($curl); + if ($response != false) { + echo "/subscribe for $subscriber_uk_id request successful :: " . json_encode($response) . "\n"; + } else { + echo "/subscribe for $subscriber_uk_id request failed :: " . json_encode($response) . "\n"; + } + } + } + sleep(300); + } +} + +function subscribe() +{ + $subscribers = json_decode( + file_get_contents("php://input"), + null, 512, JSON_OBJECT_AS_ARRAY + ); + + if (pcntl_fork() == -1) { + die('could not fork the process'); + } else { + if (!function_exists('subscribe_helper')) { + die('function subscribe helper does not exist'); + } + subscribe_helper($subscribers); + } + + print_r("/subscribe called :: Request ->"); + print_r($subscribers); + + return json_encode(["success" => "ACK"]); +} +function on_subscribe() +{ + global $subscribers_uniquekey_store, $subscribers; + $data = json_decode( + file_get_contents("php://input"), + null, 512, JSON_OBJECT_AS_ARRAY + ); + print("/on_subscribe called :: Request -> "); + print_r($data, true); + + $subscriber_id = $data["subscriber_id"]; + $unique_key_id = $subscribers_uniquekey_store[$subscriber_id]; + $subscriber = $subscribers[$subscriber_id . " | " . $unique_key_id]; + print($subscriber); + + return json_encode([ + "answer" => decrypt( + $subscriber["ondcPublicKey"], $subscriber["encPrivateKey"], $data["challenge"] + ), + ]); +} + +function verify_html(): string +{ + return "501: verify_html not implemented"; +} + +if (preg_match('/\.(?:png|jpeg|jpg|gif)$/', + $_SERVER['REQUEST_URI'])) { + return false; +} else { + $path = pathinfo($_SERVER['SCRIPT_NAME'])['basename']; + switch ($path) { + case 'subscribe': + header('Content-Type: application/json; charset=utf-8'); + echo subscribe(); + break; + case 'on_subscribe': + header('Content-Type: application/json; charset=utf-8'); + echo on_subscribe(); + break; + case 'ondc-site-verification.html': + echo file_get_contents("./templates/ondc-site-verification.html"); + break; + default: + echo '

          You just hit a non-existant path: 404'; + break; + } +} diff --git a/utilities/on_subscibe-service/php/templates/ondc-site-verification.html b/utilities/on_subscibe-service/php/templates/ondc-site-verification.html new file mode 100644 index 0000000..289e923 --- /dev/null +++ b/utilities/on_subscibe-service/php/templates/ondc-site-verification.html @@ -0,0 +1,8 @@ + + + + + + ONDC Site Verification Page + + \ No newline at end of file From e3ec6c8aaa65d9b2f020d48cf3107d759659b372 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 146/228] Update readme.md From 7d52c9ac9addd4d857b93e8debe932911951f002 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 147/228] Update readme.md From ab6ea4a98806fac8dce8d29f0999a8dcc7b929ef Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 148/228] Update readme.md From 3d68eda0aa091594548899fe7f811ebef361fd10 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 149/228] Update readme.md From ec1a1095a5fce28f75895d67fdbfa23368d4703f Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 150/228] Update readme.md From 308df399183c65f0570b925270c38114f0f435e6 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 151/228] Update readme.md From 211c7eb7df63854a52f5aaf43ea63926e5a406db Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 152/228] Update readme.md From b1f5e2673be2075cf49d577b45ef887921540254 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 153/228] Update readme.md From 44508e81a17e8f6162e81792d7d7345ba7b72d79 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 154/228] Update readme.md From cb6502bfd20a483dc3f9dfe40c516029cfc12f3f Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 155/228] Update readme.md From 7743767c80134dcfc088b1d103ccfe0c4f7f7800 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 156/228] Update readme.md From 9a995eb79af457dc089ccbcbe3ddf315f750b2aa Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 157/228] Update readme.md From 1dc39ca14ed6190aee2f04a36d1a87605eb74fef Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 158/228] Update readme.md From f72ba45730bf1e9f5649e384793d55b34c1266cb Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 159/228] Update readme.md From 61433ceb4314f6690e1165014a9099013281d860 Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 160/228] Update readme.md From bea39e4af527c421cd610528797967e9b152961f Mon Sep 17 00:00:00 2001 From: nishthamongaondc <150439595+nishthamongaondc@users.noreply.github.com> Date: Wed, 27 Dec 2023 15:47:13 +0530 Subject: [PATCH 161/228] Update readme.md From 19920a50a64d29e9311c44291cedc2cb9ced34bf Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 15 Feb 2024 17:45:06 +0530 Subject: [PATCH 162/228] added cancel on_cancel schema val for b2b --- .../schema/B2B_json_schema/schemaValidator.js | 5 + .../schema/B2B_json_schema/v2/cancel.js | 110 +++ .../schema/B2B_json_schema/v2/confirm.js | 4 + .../schema/B2B_json_schema/v2/init.js | 2 + .../schema/B2B_json_schema/v2/master.js | 12 + .../schema/B2B_json_schema/v2/on_cancel.js | 761 ++++++++++++++++++ .../schema/B2B_json_schema/v2/on_init.js | 2 + .../schema/B2B_json_schema/v2/on_search.js | 88 +- .../v1.2/onCancelSchema.js | 2 +- .../utils/b2b/b2bOnSearch.js | 1 - .../utils/b2b/b2bOnStatus.js | 2 +- .../utils/constants.js | 3 +- 12 files changed, 945 insertions(+), 47 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js index 66aa4f1..2eadac4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -57,6 +57,9 @@ const validate_schema = (data, schema,version) => { const statusSchema = loadSchema("status", version); const onStatusSchema = loadSchema("on_status", version); + const cancelSchema = loadSchema("cancel", version); + const onCancelSchema = loadSchema("on_cancel", version); + const Ajv = require("ajv"); const ajv = new Ajv({ allErrors: true, @@ -84,6 +87,8 @@ const validate_schema = (data, schema,version) => { .addSchema(onUpdateSchema) .addSchema(statusSchema) .addSchema(onStatusSchema) + .addSchema(cancelSchema) + .addSchema(onCancelSchema) .addKeyword("isEndTimeGreater", { validate: (schema, data) => isEndTimeGreater(data), }) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js new file mode 100644 index 0000000..55a5e8b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js @@ -0,0 +1,110 @@ +module.exports = { + $id: "http://example.com/schema/cancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/on_confirm/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { + $data: "/on_confirm/0/context/location/country/code", + }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "cancel", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/on_confirm/0/context/transaction_id" }, + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/on_confirm/0/message/order/id" }, + }, + cancellation_reason_id: { + order_id: { + type: "string", + }, + }, + + }, + additionalProperties: false, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], + +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index cece70e..952da95 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -105,6 +105,10 @@ module.exports = { properties: { id: { type: "string", + not: { + const: { $data: "3/context/transaction_id" }, + }, + errorMessage:"Order ID must not be the same as Transaction ID - ${3/context/transaction_id}." }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 70d6924..9dbf3bd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -263,6 +263,8 @@ module.exports = { }, tax_id: { type: "string", + pattern: "^[0-9]{2}[A-Z]{5}[0-9]{4}[0-9A-Z]{4}$", + errorMessage: "should be valid", }, email: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js index d01fe98..abd8ad0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js @@ -73,6 +73,18 @@ module.exports = { items: { $ref: "onStatusSchema#", }, + }, + cancel: { + type: "array", + items: { + $ref: "cancelSchema#", + }, + }, + on_cancel: { + type: "array", + items: { + $ref: "onCancelSchema#", + }, } }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js new file mode 100644 index 0000000..b956106 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js @@ -0,0 +1,761 @@ +const constants = require("../../../utils/constants"); +module.exports = { + $id: "http://example.com/schema/onCancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_cancel", + }, + version: { + type: "string", + const: "2.0.2", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + enum: ["Cancelled"], + }, + cancellation: { + type: "object", + properties: { + reason: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + cancelled_by: { + type: "string", + }, + }, + required: ["reason", "cancelled_by"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + payment_ids: { + type: "array", + items: { + type: "string", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + additionalProperties: false, + required: ["selected"], + }, + }, + required: ["id", "fulfillment_ids", "quantity", "payment_ids"], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + required: ["name"], + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + "@ondc/org/provider_name": { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Cancelled"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: ["start", "end"], + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["name"], + }, + gps: { + type: "string", + pattern: + "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + errorMessage: "Incorrect gps value", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", + }, + end: { + type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", + }, + }, + required: ["range"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "name", + "short_desc", + "long_desc", + "images", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + agent: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + }, + required: ["person", "contact"], + }, + }, + if: { properties: { type: { const: "start" } } }, + then: { + properties: { + location: { required: ["id", "descriptor", "gps"] }, + }, + }, + else: { + properties: { + location: { required: ["address", "gps"] }, + }, + }, + required: ["type", "location", "time", "contact"], + }, + }, + }, + required: [ + "id", + "@ondc/org/provider_name", + "type", + "tracking", + "state", + "stops", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + "@ondc/org/item_id": { + type: "string", + }, + "@ondc/org/item_quantity": { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + title: { + type: "string", + }, + "@ondc/org/title_type": { + type: "string", + enum: [ + "item", + "discount", + "packing", + "delivery", + "tax", + "misc", + "refund", + ], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["price"], + }, + }, + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching: true, + + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + params: { + type: "object", + properties: { + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + amount: { + type: "string", + }, + }, + required: ["currency", "amount"], + }, + status: { + type: "string", + enum: ["PAID", "NOT-PAID"], + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + + const: { + $data: "/on_confirm/0/message/order/payments/0/type", + }, + }, + collected_by: { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/collected_by", + }, + enum: ["BAP", "BPP"], + }, + "@ondc/org/buyer_app_finder_fee_type": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_type", + }, + }, + "@ondc/org/buyer_app_finder_fee_amount": { + type: "string", + const: { + $data: + "/confirm/0/message/order/payments/0/@ondc~1org~1buyer_app_finder_fee_amount", + }, + }, + "@ondc/org/settlement_basis": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/@ondc~1org~1settlement_basis", + }, + }, + "@ondc/org/settlement_window": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/@ondc~1org~1settlement_window", + }, + }, + "@ondc/org/withholding_amount": { + type: "string", + const: { + $data: + "/on_confirm/0/message/order/payments/0/@ondc~1org~1withholding_amount", + }, + }, + "@ondc/org/settlement_details": { + type: "array", + items: { + type: "object", + properties: { + settlement_counterparty: { + type: "string", + enum: ["seller-app", "buyer-app"], + }, + settlement_phase: { + type: "string", + }, + settlement_type: { + type: "string", + enum: ["upi", "neft", "rtgs"], + }, + beneficiary_name: { + type: "string", + }, + upi_address: { + type: "string", + }, + settlement_bank_account_no: { + type: "string", + }, + settlement_ifsc_code: { + type: "string", + }, + bank_name: { + type: "string", + }, + branch_name: { + type: "string", + }, + }, + allOf: [ + { + if: { + properties: { + settlement_type: { + const: "upi", + }, + }, + }, + then: { + required: ["upi_address"], + }, + }, + { + if: { + properties: { + settlement_type: { + const: ["neft", "rtgs"], + }, + }, + }, + then: { + required: [ + "settlement_ifsc_code", + "settlement_bank_account_no", + ], + }, + }, + ], + required: ["settlement_counterparty", "settlement_type"], + }, + }, + }, + if: { properties: { type: { const: "ON-FULFILLMENT" } } }, + then: { + properties: { + collected_by: { + const: "BPP", + }, + }, + }, + required: [ + "id", + "params", + "status", + "type", + "collected_by", + "@ondc/org/buyer_app_finder_fee_type", + "@ondc/org/buyer_app_finder_fee_amount", + "@ondc/org/settlement_basis", + "@ondc/org/settlement_window", + "@ondc/org/withholding_amount", + ], + }, + }, + + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", + }, + }, + required: ["url", "label"], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "order/created_at should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + }, + }, + additionalProperties: false, + required: [ + "id", + "state", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "cancellation", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 54867f3..daa224a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -117,6 +117,7 @@ module.exports = { }, }, required: ["id"], + additionalProperties: false }, provider_location: { type: "object", @@ -129,6 +130,7 @@ module.exports = { }, }, required: ["id"], + additionalProperties: false }, items: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 716a3f2..9afe1df 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -734,58 +734,60 @@ module.exports = { }, }, return_terms: { - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", + type: "array", + items: { + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, }, + required: ["code"], }, - required: ["code"], }, + required: ["descriptor"], }, - required: ["descriptor"], - }, - return_eligible: { - type: "boolean", - }, - return_time: { - type: "object", - properties: { - duration: { - type: "string", - }, + return_eligible: { + type: "boolean", }, - required: ["duration"], - }, - return_location: { - type: "object", - properties: { - address: { - type: "string", + return_time: { + type: "object", + properties: { + duration: { + type: "string", + }, }, - gps: { - type: "string", + required: ["duration"], + }, + return_location: { + type: "object", + properties: { + address: { + type: "string", + }, + gps: { + type: "string", + }, }, + required: ["address", "gps"], + }, + fulfillment_managed_by: { + type: "string", }, - required: ["address", "gps"], - }, - fulfillment_managed_by: { - type: "string", }, + required: [ + "fulfillment_state", + "return_eligible", + "return_time", + "return_location", + "fulfillment_managed_by", + ], }, - required: [ - "fulfillment_state", - "return_eligible", - "return_time", - "return_location", - "fulfillment_managed_by", - ], }, replacement_terms: { @@ -864,7 +866,7 @@ module.exports = { }, }, }, - additionalProperties:false, + additionalProperties: false, required: [ "id", "descriptor", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 56701b7..4f4e201 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -522,7 +522,7 @@ module.exports = { properties: { code: { type: "string", - const: "rto_event", + enum: constants.CANCELLATION_TAGS_CODES, }, list: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 9ed628e..72b9b68 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -72,7 +72,6 @@ const checkOnSearch = async (data, msgIdSet) => { itemTags.forEach((tag) => { let { descriptor, list } = tag; - console.log(descriptor.code); if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { if (domain === "ONDC:RET12") { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 32a9a12..bdb1ef6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -70,7 +70,7 @@ const checkOnStatus = (data, msgIdSet) => { } } }); - if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up` + if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up for Non RFQ Flow.` } //Order-picked-up diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index fdc48b3..7b3912a 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -168,7 +168,8 @@ module.exports = Object.freeze({ "RTO-Disposed", "Cancelled", ], - CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], + CANCELLATION_TAGS_CODES:["rto_event","precancel_state"], + CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by","fulfillment_state","updated_at"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], MANDATORY_ATTRIBUTES: ["brand"], From cc90b23b63023d8b1afe8fe0f9303bad575f44dc Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 16 Feb 2024 16:00:55 +0530 Subject: [PATCH 163/228] updated error messages --- .../schema/B2B_json_schema/v2/on_cancel.js | 38 +++++++++++++++++++ .../utils/b2b/b2bConfirm.js | 2 +- .../utils/b2b/b2bInit.js | 2 +- .../utils/b2b/b2bOnSelect.js | 8 +++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js index b956106..570a209 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js @@ -739,6 +739,44 @@ module.exports = { type: "string", format: "date-time", }, + tags: { + type: "array", + minItems: 3, + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: constants.TERMS, + }, + }, + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + enum: constants.B2B_BPP_TERMS, + }, + }, + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, }, additionalProperties: false, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index 2309ecf..17a33b3 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -11,7 +11,7 @@ const checkConfirm = async (data, msgIdSet) => { let payments = confirm?.payments; let items = confirm.items; - const selectedItems = dao.getValue("slctdItemsArray"); + const selectedItems = dao.getValue("onSlctdItemsArray"); try { console.log("Comparing items object with /select"); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index 2bc9084..2d6bbbf 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -9,7 +9,7 @@ const checkInit = (data, msgIdSet) => { init = init.message.order; let items = init.items; - const selectedItems = dao.getValue("slctdItemsArray"); + const selectedItems = dao.getValue("onSlctdItemsArray"); try { console.log("Comparing items object with /select"); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 49714a9..d948165 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -12,6 +12,8 @@ const checkOnSelect = async (data, msgIdSet) => { let fulfillments = onSelect?.fulfillments; let ffState, ffId; let deliveryQuoteItem = false; + let deliveryCharge = 0 + dao.setValue("onSlctdItemsArray", items) const selectedItems = dao.getValue("slctdItemsArray"); try { console.log("Checking fulfillment object in /on_select"); @@ -54,6 +56,8 @@ const checkOnSelect = async (data, msgIdSet) => { breakup["@ondc/org/item_id"] === ffId ) { deliveryQuoteItem = true; + deliveryCharge= breakup?.price?.value + console.log("deliverycharge",deliveryCharge); } if ( breakup["@ondc/org/title_type"] === "item" && @@ -82,8 +86,8 @@ const checkOnSelect = async (data, msgIdSet) => { if (!deliveryQuoteItem && ffState === "Serviceable") { onSelectObj.deliveryQuoteErr = `Delivery charges should be provided in quote/breakup when fulfillment is 'Serviceable'`; } - if (deliveryQuoteItem && ffState === "Non-serviceable") { - onSelectObj.deliveryQuoteErr = `Delivery charges are not required in quote/breakup when fulfillment is 'Non-serviceable'`; + if (deliveryQuoteItem && deliveryCharge!=0 && ffState === "Non-serviceable") { + onSelectObj.deliveryQuoteErr = `Delivery charges are not required or should be zero in quote/breakup when fulfillment is 'Non-serviceable'`; } if (ffState === "Non-serviceable" && !data.error) { From db91c3636c8e41a7b7a25e7809d68e40f61b487e Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 16 Feb 2024 17:39:42 +0530 Subject: [PATCH 164/228] fixed conflicts --- .../schema/B2B_json_schema/schemaValidator.js | 3 - .../schema/B2B_json_schema/v2/confirm.js | 3 - .../schema/B2B_json_schema/v2/init.js | 3 - .../schema/B2B_json_schema/v2/master.js | 3 - .../schema/B2B_json_schema/v2/on_init.js | 6 -- .../schema/B2B_json_schema/v2/on_search.js | 59 ------------------- .../utils/b2b/b2bInit.js | 4 -- .../utils/b2b/b2bOnSearch.js | 4 -- .../utils/b2b/b2bOnSelect.js | 11 ---- .../utils/b2b/b2bOnStatus.js | 4 -- 10 files changed, 100 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js index 9e3bce2..2eadac4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/schemaValidator.js @@ -57,12 +57,9 @@ const validate_schema = (data, schema,version) => { const statusSchema = loadSchema("status", version); const onStatusSchema = loadSchema("on_status", version); -<<<<<<< HEAD -======= const cancelSchema = loadSchema("cancel", version); const onCancelSchema = loadSchema("on_cancel", version); ->>>>>>> patch-reference-implementations-remote/main const Ajv = require("ajv"); const ajv = new Ajv({ allErrors: true, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 4d9b3b6..952da95 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -105,13 +105,10 @@ module.exports = { properties: { id: { type: "string", -<<<<<<< HEAD -======= not: { const: { $data: "3/context/transaction_id" }, }, errorMessage:"Order ID must not be the same as Transaction ID - ${3/context/transaction_id}." ->>>>>>> patch-reference-implementations-remote/main }, state: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 31e508a..9dbf3bd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -263,11 +263,8 @@ module.exports = { }, tax_id: { type: "string", -<<<<<<< HEAD -======= pattern: "^[0-9]{2}[A-Z]{5}[0-9]{4}[0-9A-Z]{4}$", errorMessage: "should be valid", ->>>>>>> patch-reference-implementations-remote/main }, email: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js index b10e275..abd8ad0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/master.js @@ -73,8 +73,6 @@ module.exports = { items: { $ref: "onStatusSchema#", }, -<<<<<<< HEAD -======= }, cancel: { type: "array", @@ -87,7 +85,6 @@ module.exports = { items: { $ref: "onCancelSchema#", }, ->>>>>>> patch-reference-implementations-remote/main } }, }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 4441985..daa224a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -117,10 +117,7 @@ module.exports = { }, }, required: ["id"], -<<<<<<< HEAD -======= additionalProperties: false ->>>>>>> patch-reference-implementations-remote/main }, provider_location: { type: "object", @@ -133,10 +130,7 @@ module.exports = { }, }, required: ["id"], -<<<<<<< HEAD -======= additionalProperties: false ->>>>>>> patch-reference-implementations-remote/main }, items: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 6e211c4..9afe1df 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -734,60 +734,6 @@ module.exports = { }, }, return_terms: { -<<<<<<< HEAD - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - return_eligible: { - type: "boolean", - }, - return_time: { - type: "object", - properties: { - duration: { - type: "string", - }, - }, - required: ["duration"], - }, - return_location: { - type: "object", - properties: { - address: { - type: "string", - }, - gps: { - type: "string", - }, - }, - required: ["address", "gps"], - }, - fulfillment_managed_by: { - type: "string", - }, - }, - required: [ - "fulfillment_state", - "return_eligible", - "return_time", - "return_location", - "fulfillment_managed_by", - ], -======= type: "array", items: { properties: { @@ -842,7 +788,6 @@ module.exports = { "fulfillment_managed_by", ], }, ->>>>>>> patch-reference-implementations-remote/main }, replacement_terms: { @@ -921,11 +866,7 @@ module.exports = { }, }, }, -<<<<<<< HEAD - additionalProperties:false, -======= additionalProperties: false, ->>>>>>> patch-reference-implementations-remote/main required: [ "id", "descriptor", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index 111aecd..2d6bbbf 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -9,11 +9,7 @@ const checkInit = (data, msgIdSet) => { init = init.message.order; let items = init.items; -<<<<<<< HEAD - const selectedItems = dao.getValue("slctdItemsArray"); -======= const selectedItems = dao.getValue("onSlctdItemsArray"); ->>>>>>> patch-reference-implementations-remote/main try { console.log("Comparing items object with /select"); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 88652e3..72b9b68 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -72,10 +72,6 @@ const checkOnSearch = async (data, msgIdSet) => { itemTags.forEach((tag) => { let { descriptor, list } = tag; -<<<<<<< HEAD - console.log(descriptor.code); -======= ->>>>>>> patch-reference-implementations-remote/main if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { if (domain === "ONDC:RET12") { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 4dbb248..d948165 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -12,11 +12,8 @@ const checkOnSelect = async (data, msgIdSet) => { let fulfillments = onSelect?.fulfillments; let ffState, ffId; let deliveryQuoteItem = false; -<<<<<<< HEAD -======= let deliveryCharge = 0 dao.setValue("onSlctdItemsArray", items) ->>>>>>> patch-reference-implementations-remote/main const selectedItems = dao.getValue("slctdItemsArray"); try { console.log("Checking fulfillment object in /on_select"); @@ -59,11 +56,8 @@ const checkOnSelect = async (data, msgIdSet) => { breakup["@ondc/org/item_id"] === ffId ) { deliveryQuoteItem = true; -<<<<<<< HEAD -======= deliveryCharge= breakup?.price?.value console.log("deliverycharge",deliveryCharge); ->>>>>>> patch-reference-implementations-remote/main } if ( breakup["@ondc/org/title_type"] === "item" && @@ -92,13 +86,8 @@ const checkOnSelect = async (data, msgIdSet) => { if (!deliveryQuoteItem && ffState === "Serviceable") { onSelectObj.deliveryQuoteErr = `Delivery charges should be provided in quote/breakup when fulfillment is 'Serviceable'`; } -<<<<<<< HEAD - if (deliveryQuoteItem && ffState === "Non-serviceable") { - onSelectObj.deliveryQuoteErr = `Delivery charges are not required in quote/breakup when fulfillment is 'Non-serviceable'`; -======= if (deliveryQuoteItem && deliveryCharge!=0 && ffState === "Non-serviceable") { onSelectObj.deliveryQuoteErr = `Delivery charges are not required or should be zero in quote/breakup when fulfillment is 'Non-serviceable'`; ->>>>>>> patch-reference-implementations-remote/main } if (ffState === "Non-serviceable" && !data.error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index 86a7cd4..bdb1ef6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -70,11 +70,7 @@ const checkOnStatus = (data, msgIdSet) => { } } }); -<<<<<<< HEAD - if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up` -======= if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up for Non RFQ Flow.` ->>>>>>> patch-reference-implementations-remote/main } //Order-picked-up From 7ab37590b27794543b340327def2a8ad06966d4e Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 16 Feb 2024 18:19:13 +0530 Subject: [PATCH 165/228] on_cancel schema val added --- .../schema/B2B_json_schema/v2/init.js | 3 +- .../utils/constants.js | 4 -- .../utils/logistics/logOnCancel.js | 37 ------------------- 3 files changed, 2 insertions(+), 42 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 9dbf3bd..dae8f08 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -495,7 +495,8 @@ module.exports = { }, collected_by:{ type:"string", - enum:["BAP","BPP"] + enum:["BAP","BPP"], + const: { $data: "/on_select/0/message/order/payments/0/collected_by" }, } }, required: ["type","collected_by"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 284f2a0..7b3912a 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -168,12 +168,8 @@ module.exports = Object.freeze({ "RTO-Disposed", "Cancelled", ], -<<<<<<< HEAD - CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by"], -======= CANCELLATION_TAGS_CODES:["rto_event","precancel_state"], CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by","fulfillment_state","updated_at"], ->>>>>>> patch-reference-implementations-remote/main FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], MANDATORY_ATTRIBUTES: ["brand"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index b0f90a6..1d1624b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -10,11 +10,7 @@ const checkOnCancel = (data, msgIdSet) => { let version = on_cancel.context.core_version; let messageId = on_cancel.context.message_id; const providerId = on_cancel.message?.provider?.id; -<<<<<<< HEAD - -======= let selectedItem; ->>>>>>> patch-reference-implementations-remote/main on_cancel = on_cancel.message.order; let onSearchItemsArr = dao.getValue(`${on_cancel?.provider?.id}itemsArr`); let ffState; @@ -48,16 +44,10 @@ const checkOnCancel = (data, msgIdSet) => { } catch (error) { console.log(error); } -<<<<<<< HEAD - if (onSearchItemsArr) { - let selectedItem = onSearchItemsArr.filter( - (element) => element.parent_item_id === dao.getValue("selectedItem") -======= if (onSearchItemsArr) { selectedItem = onSearchItemsArr.filter( (element) => element?.parent_item_id === dao.getValue("selectedItem") ->>>>>>> patch-reference-implementations-remote/main ); selectedItem = selectedItem[0]; } @@ -84,14 +74,10 @@ const checkOnCancel = (data, msgIdSet) => { } } -<<<<<<< HEAD - if (fulfillment.start.time.timestamp && dao.getValue("pickupTime")) { -======= if ( fulfillment?.start?.time?.timestamp && dao.getValue("pickupTime") ) { ->>>>>>> patch-reference-implementations-remote/main if ( !_.isEqual( dao.getValue("pickupTime"), @@ -106,30 +92,7 @@ const checkOnCancel = (data, msgIdSet) => { if (version === "1.2.0") { if (dao.getValue("rts") === "yes") { if (!fulfillment?.start?.time) { -<<<<<<< HEAD - onCancelObj.msngStrtTime = `Pickup time range (fulfillments/start/time) is missing`; - } - if (!fulfillment?.end?.time) { - onCancelObj.msngDlvryTime = `Delivery time range (fulfillments/end/time) is missing`; - } - } - let fulTags = fulfillment?.tags; - let rtoID; - fulTags.forEach((tag) => { - if (tag.code === "rto_event") { - const lists = tag.list; - lists.forEach((list) => { - if (list.code === "rto_id") { - rtoID = list.value; - - if (rtoID !== selectedItem.fulfillment_id) { - onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; - } - } - }); -======= onCancelObj.msngStrtTime = `Pickup time range (fulfillments/start/time) is missing for fulfillment type - '${fulfillment.type}'`; ->>>>>>> patch-reference-implementations-remote/main } if (!fulfillment?.end?.time) { onCancelObj.msngDlvryTime = `Delivery time range (fulfillments/end/time) is missing for fulfillment type - '${fulfillment.type}'`; From 2c794cb025db6bde50889e75ef2edd98872b3bec Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 19 Feb 2024 10:25:07 +0530 Subject: [PATCH 166/228] minor bug fix --- .../logistics-b2b/log-verification-utility/utils/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 4dcd474..69ad03c 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -199,11 +199,11 @@ const timestampCheck = (date) => { const getVersion = (data,vertical) => { if(vertical==='logistics'){ - if (data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; + if (data?.search && data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; else return "v1.2"; } if(vertical==='b2b'){ - if (data?.search[0]?.context?.version === "2.0.1") return "v1"; + if (data?.search && data?.search[0]?.context?.version === "2.0.1") return "v1"; else return "v2"; } From ef672b6e96386358920fe3cb7aa8bcdbe3bc8a54 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 20 Feb 2024 14:37:16 +0530 Subject: [PATCH 167/228] minor fixes --- .../schema/B2B_json_schema/v2/on_cancel.js | 2 +- .../schema/B2B_json_schema/v2/on_confirm.js | 2 +- .../schema/B2B_json_schema/v2/on_search.js | 12 ++++++------ .../schema/B2B_json_schema/v2/select.js | 9 ++++++--- .../log-verification-utility/utils/utils.js | 4 ++-- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js index 570a209..097447c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js @@ -438,7 +438,7 @@ module.exports = { location: { required: ["address", "gps"] }, }, }, - required: ["type", "location", "time", "contact"], + required: ["type", "location", "contact"], }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 31c6737..cf3c0a3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -426,7 +426,7 @@ module.exports = { required: ["phone"], }, }, - required: ["type", "location", "time", "contact"], + required: ["type", "location", "contact"], }, }, rateable: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 9afe1df..a5d8c44 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -522,7 +522,7 @@ module.exports = { required: ["unit", "value"], }, count: { - type: "string", + type: "integer", }, }, required: ["measure", "count"], @@ -552,7 +552,7 @@ module.exports = { required: ["unit", "value"], }, count: { - type: "string", + type: "integer", }, }, required: ["measure", "count"], @@ -582,7 +582,7 @@ module.exports = { required: ["unit", "value"], }, count: { - type: "string", + type: "integer", }, }, required: ["measure", "count"], @@ -614,7 +614,7 @@ module.exports = { type: "string", }, }, - "add-ons": { + "add_ons": { type: "array", items: { type: "object", @@ -824,10 +824,10 @@ module.exports = { required: ["label", "range"], }, matched: { - type: "string", + type: "boolean", }, recommended: { - type: "string", + type: "boolean", }, tags: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 9c89d02..87ba678 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -124,8 +124,9 @@ module.exports = { format: "duration", }, }, - required: ["id", "locations", "ttl"], - errorMessage: "id, locations are mandatory attributes and ttl is required for RFQ Flow" + required: ["id", "locations"], + errorMessage: + "id, locations are mandatory attributes and ttl is required for RFQ Flow", }, items: { type: "array", @@ -369,7 +370,9 @@ module.exports = { }, }, additionalProperties: false, - required: ["id", "type", "stops"], + if: { properties: { type: { const: "Delivery" } } }, + then: { required: ["id", "type", "stops"] }, + else: { required: ["id", "type"] }, }, }, payments: { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 69ad03c..e6e9502 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -386,12 +386,12 @@ function findDifferencesInArrays(array1, array2) { const differences = []; // Check if arrays have the same length - if (array1.length !== array2.length) { + if (array1?.length !== array2?.length) { return differences; } // Iterate over each item in the arrays - for (let i = 0; i < array1.length; i++) { + for (let i = 0; i < array1?.length; i++) { const item1 = array1[i]; const item2 = array2[i]; From 0a160eb58b364974a70b88c48afa4da9aac6c589 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 20 Feb 2024 15:18:44 +0530 Subject: [PATCH 168/228] bug fix --- .../schema/logistics_api_json_schema/v1.2/onUpdateSchema.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index 0812e7e..55d31d2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -157,11 +157,6 @@ module.exports = { }, duration: { type: "string", -<<<<<<< HEAD - }, - timestamp: { - type: "string", -======= const: { $data: "/on_confirm/0/message/order/items/0/time/duration", @@ -173,7 +168,6 @@ module.exports = { $data: "/on_confirm/0/message/order/items/0/time/timestamp", }, ->>>>>>> patch-reference-implementations-remote/main }, }, required: ["label", "duration", "timestamp"], From 5cd1e123eff30446dba2568637ba834ba1c6240b Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 20 Feb 2024 15:35:26 +0530 Subject: [PATCH 169/228] updated linked order val in on_confirm for logistics --- .../utils/logistics/logOnConfirm.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 5133fd0..822a3ed 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -12,6 +12,7 @@ const checkOnConfirm = (data, msgIdSet) => { on_confirm = on_confirm.message.order; let items= on_confirm.items; let fulfillments = on_confirm.fulfillments; + let linkedOrder = on_confirm["@ondc/org/linked_order"] let rts = dao.getValue("rts"); let p2h2p = dao.getValue("p2h2p") let awbNo= dao.getValue("awbNo"); @@ -51,6 +52,27 @@ const checkOnConfirm = (data, msgIdSet) => { console.log(`Error checking fulfillment object in /on_confirm`); } + try { + console.log("checking linked order in /confirm"); + + const orderWeight =linkedOrder?.order?.weight?.value; + + let totalUnitWeight=0; + + linkedOrder?.items.forEach(item=>{ + const quantity = item?.quantity?.measure?.value + const count = item?.quantity?.count + + const unitWeight = (quantity*count) + totalUnitWeight+=unitWeight; + }) + + if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2)){ + onCnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` + } + } catch (error) { + console.log(error); + } dao.setValue("awbNo",awbNo); return onCnfrmObj; }; From 3ff593c656dd4ee0d2f76b978b90a7acc67e4657 Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Wed, 21 Feb 2024 17:32:49 +0530 Subject: [PATCH 170/228] feat: on_sub java util --- .idea/.gitignore | 3 + .idea/misc.xml | 6 + .idea/modules.xml | 8 + .idea/reference-implementations.iml | 9 + .idea/vcs.xml | 6 + utilities/on_subscibe-service/.DS_Store | Bin 0 -> 6148 bytes utilities/on_subscibe-service/java/.gitignore | 33 ++ .../java/.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 62547 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 + utilities/on_subscibe-service/java/mvnw | 308 ++++++++++++++++++ utilities/on_subscibe-service/java/mvnw.cmd | 205 ++++++++++++ utilities/on_subscibe-service/java/pom.xml | 58 ++++ .../java/com/ondc/onboarding/AppConfig.java | 49 +++ .../com/ondc/onboarding/CryptoKeyPair.java | 38 +++ .../onboarding/OnboardingApplication.java | 20 ++ .../main/java/com/ondc/onboarding/Routes.java | 115 +++++++ .../main/java/com/ondc/onboarding/Utils.java | 68 ++++ .../src/main/resources/application.properties | 1 + .../OnboardingApplicationTests.java | 13 + .../.idea/.gitignore | 3 + .../.idea/compiler.xml | 13 + .../.idea/encodings.xml | 7 + .../.idea/jarRepositories.xml | 20 ++ .../ondc-crypto-utility-master/.idea/misc.xml | 13 + .../ondc-crypto-utility-master/.idea/vcs.xml | 6 + .../test/java/org/ondc/crypto/util/Test.java | 42 +++ .../ondc/crypto/util/CryptoFunctions.class | Bin 0 -> 4741 bytes .../org/ondc/crypto/util/CryptoKeyPair.class | Bin 0 -> 796 bytes .../target/maven-archiver/pom.properties | 4 + .../compile/default-compile/createdFiles.lst | 2 + .../compile/default-compile/inputFiles.lst | 2 + .../default-testCompile/createdFiles.lst | 1 + .../default-testCompile/inputFiles.lst | 1 + .../org/ondc/crypto/util/CryptoTest.class | Bin 0 -> 6543 bytes .../org/ondc/crypto/util/Test.class | Bin 0 -> 1951 bytes 35 files changed, 1056 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/reference-implementations.iml create mode 100644 .idea/vcs.xml create mode 100644 utilities/on_subscibe-service/.DS_Store create mode 100644 utilities/on_subscibe-service/java/.gitignore create mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar create mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties create mode 100755 utilities/on_subscibe-service/java/mvnw create mode 100644 utilities/on_subscibe-service/java/mvnw.cmd create mode 100644 utilities/on_subscibe-service/java/pom.xml create mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java create mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java create mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java create mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java create mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java create mode 100644 utilities/on_subscibe-service/java/src/main/resources/application.properties create mode 100644 utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java create mode 100644 utilities/ondc-crypto-utility-master/.idea/.gitignore create mode 100644 utilities/ondc-crypto-utility-master/.idea/compiler.xml create mode 100644 utilities/ondc-crypto-utility-master/.idea/encodings.xml create mode 100644 utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml create mode 100644 utilities/ondc-crypto-utility-master/.idea/misc.xml create mode 100644 utilities/ondc-crypto-utility-master/.idea/vcs.xml create mode 100644 utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/Test.java create mode 100644 utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class create mode 100644 utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class create mode 100644 utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties create mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst create mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst create mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst create mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst create mode 100644 utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class create mode 100644 utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/Test.class diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..6ff3c25 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4be6c13 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/reference-implementations.iml b/.idea/reference-implementations.iml new file mode 100644 index 0000000..d6ebd48 --- /dev/null +++ b/.idea/reference-implementations.iml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/utilities/on_subscibe-service/.DS_Store b/utilities/on_subscibe-service/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..7664ca874f8f67c84b8f16c9d72cf3a75a514615 GIT binary patch literal 6148 zcmeHK%}T>S5Z-NTn^J@x6nb3nTCleD4=*9s7cim+mDME2W|! z(?`K|I9U#xJLgI!qfk!fIw2fSAmr{Qlw-B@)IyG9o$DKiQ+MjaW^1+T9v`+v@1(zO zi`8kj(-!^S(Ry8XcK7zrE{9Livs7<}NDiE9*|wO$J1DuDUi`U?lzaqxmXpO25(C5l zF+dD#9s~9)a2lIeI#o;z5CcCjfct}hhUi*M4eG4}I=nukzk-MYI=&?kg+YS5%Ju2+V6?8@2Wh3nP9E_68Ku0iUF0b(G}K-mnNc>Z6& zFH`u)&!^Cc7$64z83VjB@CP0gWzW`c<>6T?pgllC!MGF^5YTg%02tst($Y@j7pOy= YYcVy5v!Gq41JXr66G9y^@Cyul0h+E%Z~y=R literal 0 HcmV?d00001 diff --git a/utilities/on_subscibe-service/java/.gitignore b/utilities/on_subscibe-service/java/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/utilities/on_subscibe-service/java/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb28b0e37c7d206feb564310fdeec0927af4123a GIT binary patch literal 62547 zcmb5V1CS=sk~Z9!wr$(CZEL#U=Co~N+O}=mwr$(Cds^S@-Tij=#=rmlVk@E|Dyp8$ z$UKz?`Q$l@GN3=8fq)=^fVx`E)Pern1@-q?PE1vZPD);!LGdpP^)C$aAFx&{CzjH` zpQV9;fd0PyFPNN=yp*_@iYmRFcvOrKbU!1a*o)t$0ex(~3z5?bw11HQYW_uDngyer za60w&wz^`W&Z!0XSH^cLNR&k>%)Vr|$}(wfBzmSbuK^)dy#xr@_NZVszJASn12dw; z-KbI5yz=2awY0>OUF)&crfPu&tVl|!>g*#ur@K=$@8N05<_Mldg}X`N6O<~3|Dpk3 zRWb!e7z<{Mr96 z^C{%ROigEIapRGbFA5g4XoQAe_Y1ii3Ci!KV`?$ zZ2Hy1VP#hVp>OOqe~m|lo@^276Ik<~*6eRSOe;$wn_0@St#cJy}qI#RP= zHVMXyFYYX%T_k3MNbtOX{<*_6Htq*o|7~MkS|A|A|8AqKl!%zTirAJGz;R<3&F7_N z)uC9$9K1M-)g0#}tnM(lO2k~W&4xT7gshgZ1-y2Yo-q9Li7%zguh7W#kGfnjo7Cl6 z!^wTtP392HU0aVB!$cPHjdK}yi7xNMp+KVZy3_u}+lBCloJ&C?#NE@y$_{Uv83*iV zhDOcv`=|CiyQ5)C4fghUmxmwBP0fvuR>aV`bZ3{Q4&6-(M@5sHt0M(}WetqItGB1C zCU-)_n-VD;(6T1%0(@6%U`UgUwgJCCdXvI#f%79Elbg4^yucgfW1^ zNF!|C39SaXsqU9kIimX0vZ`U29)>O|Kfs*hXBXC;Cs9_Zos3%8lu)JGm~c19+j8Va z)~kFfHouwMbfRHJ``%9mLj_bCx!<)O9XNq&uH(>(Q0V7-gom7$kxSpjpPiYGG{IT8 zKdjoDkkMTL9-|vXDuUL=B-K)nVaSFd5TsX0v1C$ETE1Ajnhe9ept?d;xVCWMc$MbR zL{-oP*vjp_3%f0b8h!Qija6rzq~E!#7X~8^ZUb#@rnF~sG0hx^Ok?G9dwmit494OT z_WQzm_sR_#%|I`jx5(6aJYTLv;3U#e@*^jms9#~U`eHOZZEB~yn=4UA(=_U#pYn5e zeeaDmq-$-)&)5Y}h1zDbftv>|?GjQ=)qUw*^CkcAG#o%I8i186AbS@;qrezPCQYWHe=q-5zF>xO*Kk|VTZD;t={XqrKfR|{itr~k71VS?cBc=9zgeFbpeQf*Wad-tAW7(o ze6RbNeu31Uebi}b0>|=7ZjH*J+zSj8fy|+T)+X{N8Vv^d+USG3arWZ?pz)WD)VW}P z0!D>}01W#e@VWTL8w1m|h`D(EnHc*C5#1WK4G|C5ViXO$YzKfJkda# z2c2*qXI-StLW*7_c-%Dws+D#Kkv^gL!_=GMn?Y^0J7*3le!!fTzSux%=1T$O8oy8j z%)PQ9!O+>+y+Dw*r`*}y4SpUa21pWJ$gEDXCZg8L+B!pYWd8X;jRBQkN_b=#tb6Nx zVodM4k?gF&R&P=s`B3d@M5Qvr;1;i_w1AI=*rH(G1kVRMC`_nohm~Ie5^YWYqZMV2<`J* z`i)p799U_mcUjKYn!^T&hu7`Lw$PkddV&W(ni)y|9f}rGr|i-7nnfH6nyB$Q{(*Nv zZz@~rzWM#V@sjT3ewv9c`pP@xM6D!StnV@qCdO${loe(4Gy00NDF5&@Ku;h2P+Vh7 z(X6De$cX5@V}DHXG?K^6mV>XiT768Ee^ye&Cs=2yefVcFn|G zBz$~J(ld&1j@%`sBK^^0Gs$I$q9{R}!HhVu|B@Bhb29PF(%U6#P|T|{ughrfjB@s- zZ)nWbT=6f6aVyk86h(0{NqFg#_d-&q^A@E2l0Iu0(C1@^s6Y-G0r32qll>aW3cHP# zyH`KWu&2?XrIGVB6LOgb+$1zrsW>c2!a(2Y!TnGSAg(|akb#ROpk$~$h}jiY&nWEz zmMxk4&H$8yk(6GKOLQCx$Ji-5H%$Oo4l7~@gbHzNj;iC%_g-+`hCf=YA>Z&F)I1sI z%?Mm27>#i5b5x*U%#QE0wgsN|L73Qf%Mq)QW@O+)a;#mQN?b8e#X%wHbZyA_F+`P%-1SZVnTPPMermk1Rpm#(;z^tMJqwt zDMHw=^c9%?#BcjyPGZFlGOC12RN(i`QAez>VM4#BK&Tm~MZ_!#U8PR->|l+38rIqk zap{3_ei_txm=KL<4p_ukI`9GAEZ+--)Z%)I+9LYO!c|rF=Da5DE@8%g-Zb*O-z8Tv zzbvTzeUcYFgy{b)8Q6+BPl*C}p~DiX%RHMlZf;NmCH;xy=D6Ii;tGU~ zM?k;9X_E?)-wP|VRChb4LrAL*?XD6R2L(MxRFolr6GJ$C>Ihr*nv#lBU>Yklt`-bQ zr;5c(o}R!m4PRz=CnYcQv}m?O=CA(PWBW0?)UY)5d4Kf;8-HU@=xMnA#uw{g`hK{U zB-EQG%T-7FMuUQ;r2xgBi1w69b-Jk8Kujr>`C#&kw-kx_R_GLRC}oum#c{je^h&x9 zoEe)8uUX|SahpME4SEog-5X^wQE0^I!YEHlwawJ|l^^0kD)z{o4^I$Eha$5tzD*A8 zR<*lss4U5N*JCYl;sxBaQkB3M8VT|gXibxFR-NH4Hsmw|{={*Xk)%!$IeqpW&($DQ zuf$~fL+;QIaK?EUfKSX;Gpbm8{<=v#$SrH~P-it--v1kL>3SbJS@>hAE2x_k1-iK# zRN~My-v@dGN3E#c!V1(nOH>vJ{rcOVCx$5s7B?7EKe%B`bbx(8}km#t2a z1A~COG(S4C7~h~k+3;NkxdA4gbB7bRVbm%$DXK0TSBI=Ph6f+PA@$t){_NrRLb`jp zn1u=O0C8%&`rdQgO3kEi#QqiBQcBcbG3wqPrJ8+0r<`L0Co-n8y-NbWbx;}DTq@FD z1b)B$b>Nwx^2;+oIcgW(4I`5DeLE$mWYYc7#tishbd;Y!oQLxI>?6_zq7Ej)92xAZ z!D0mfl|v4EC<3(06V8m+BS)Vx90b=xBSTwTznptIbt5u5KD54$vwl|kp#RpZuJ*k) z>jw52JS&x)9&g3RDXGV zElux37>A=`#5(UuRx&d4qxrV<38_w?#plbw03l9>Nz$Y zZS;fNq6>cGvoASa2y(D&qR9_{@tVrnvduek+riBR#VCG|4Ne^w@mf2Y;-k90%V zpA6dVw|naH;pM~VAwLcQZ|pyTEr;_S2GpkB?7)+?cW{0yE$G43`viTn+^}IPNlDo3 zmE`*)*tFe^=p+a{a5xR;H0r=&!u9y)kYUv@;NUKZ)`u-KFTv0S&FTEQc;D3d|KEKSxirI9TtAWe#hvOXV z>807~TWI~^rL?)WMmi!T!j-vjsw@f11?#jNTu^cmjp!+A1f__Dw!7oqF>&r$V7gc< z?6D92h~Y?faUD+I8V!w~8Z%ws5S{20(AkaTZc>=z`ZK=>ik1td7Op#vAnD;8S zh<>2tmEZiSm-nEjuaWVE)aUXp$BumSS;qw#Xy7-yeq)(<{2G#ap8z)+lTi( ziMb-iig6!==yk zb6{;1hs`#qO5OJQlcJ|62g!?fbI^6v-(`tAQ%Drjcm!`-$%Q#@yw3pf`mXjN>=BSH z(Nftnf50zUUTK;htPt0ONKJq1_d0!a^g>DeNCNpoyZhsnch+s|jXg1!NnEv%li2yw zL}Y=P3u`S%Fj)lhWv0vF4}R;rh4&}2YB8B!|7^}a{#Oac|%oFdMToRrWxEIEN<0CG@_j#R4%R4i0$*6xzzr}^`rI!#y9Xkr{+Rt9G$*@ zQ}XJ+_dl^9@(QYdlXLIMI_Q2uSl>N9g*YXMjddFvVouadTFwyNOT0uG$p!rGF5*`1 z&xsKPj&;t10m&pdPv+LpZd$pyI_v1IJnMD%kWn{vY=O3k1sJRYwPoDV1S4OfVz4FB z$^ygjgHCW=ySKSsoSA&wSlq83JB+O-)s>>e@a{_FjB{@=AlrX7wq>JE=n@}@fba(;n4EG| zge1i)?NE@M@DC5eEv4; z#R~0aNssmFHANL@-eDq2_jFn=MXE9y>1FZH4&v<}vEdB6Kz^l)X%%X@E#4)ahB(KY zx8RH+1*6b|o1$_lRqi^)qoLs;eV5zkKSN;HDwJIx#ceKS!A$ZJ-BpJSc*zl+D~EM2 zm@Kpq2M*kX`;gES_Dd1Y#UH`i!#1HdehqP^{DA-AW^dV(UPu|O@Hvr>?X3^~=1iaRa~AVXbj z-yGL<(5}*)su2Tj#oIt+c6Gh}$0|sUYGGDzNMX+$Oi$e&UJt3&kwu)HX+XP{es(S3 z%9C9y({_fu>^BKjI7k;mZ4DKrdqxw`IM#8{Sh?X(6WE4S6-9M}U0&e32fV$2w{`19 zd=9JfCaYm@J$;nSG3(|byYDqh>c%`JW)W*Y0&K~g6)W?AvVP&DsF_6!fG3i%j^Q>R zR_j5@NguaZB{&XjXF+~6m|utO*pxq$8?0GjW0J-e6Lnf0c@}hvom8KOnirhjOM7!n zP#Iv^0_BqJI?hR5+Dl}p!7X}^NvFOCGvh9y*hgik<&X)3UcEBCdUr$Dt8?0f&LSur ze*n!(V(7umZ%UCS>Hf(g=}39OcvGbf2+D;OZ089m_nUbdCE0PXJfnyrIlLXGh2D!m zK=C#{JmoHY1ws47L0zeWkxxV=A%V8a&E^w%;fBp`PN_ndicD@oN?p?Bu~20>;h;W` ztV=hI*Ts$6JXOwOY?sOk_1xjzNYA#40dD}|js#3V{SLhPEkn5>Ma+cGQi*#`g-*g56Q&@!dg)|1YpLai3Bu8a;l2fnD6&)MZ~hS%&J}k z2p-wG=S|5YGy*Rcnm<9VIVq%~`Q{g(Vq4V)CP257v06=M2W|8AgZO0CC_}HVQ>`VU zy;2LDlG1iwIeMj?l40_`21Qsm?d=1~6f4@_&`lp~pIeXnR)wF0z7FH&wu~L~mfmMr zY4_w6tc{ZP&sa&Ui@UxZ*!UovRT})(p!GtQh~+AMZ6wcqMXM*4r@EaUdt>;Qs2Nt8 zDCJi#^Rwx|T|j_kZi6K!X>Ir%%UxaH>m6I9Yp;Sr;DKJ@{)dz4hpG>jX?>iiXzVQ0 zR$IzL8q11KPvIWIT{hU`TrFyI0YQh`#>J4XE*3;v^07C004~FC7TlRVVC}<}LC4h_ zZjZ)2*#)JyXPHcwte!}{y%i_!{^KwF9qzIRst@oUu~4m;1J_qR;Pz1KSI{rXY5_I_ z%gWC*%bNsb;v?>+TbM$qT`_U8{-g@egY=7+SN#(?RE<2nfrWrOn2OXK!ek7v`aDrH zxCoFHyA&@^@m+#Y(*cohQ4B76me;)(t}{#7?E$_u#1fv)vUE5K;jmlgYI0$Mo!*EA zf?dx$4L(?nyFbv|AF1kB!$P_q)wk1*@L0>mSC(A8f4Rgmv1HG;QDWFj<(1oz)JHr+cP|EPET zSD~QW&W(W?1PF-iZ()b|UrnB(#wG^NR!*X}t~OS-21dpXq)h)YcdA(1A`2nzVFax9rx~WuN=SVt`OIR=eE@$^9&Gx_HCfN= zI(V`)Jn+tJPF~mS?ED7#InwS&6OfH;qDzI_8@t>In6nl zo}q{Ds*cTG*w3CH{Mw9*Zs|iDH^KqmhlLp_+wfwIS24G z{c@fdgqy^Y)RNpI7va^nYr9;18t|j=AYDMpj)j1oNE;8+QQ)ap8O??lv%jbrb*a;} z?OvnGXbtE9zt;TOyWc|$9BeSGQbfNZR`o_C!kMr|mzFvN+5;g2TgFo8DzgS2kkuw@ z=`Gq?xbAPzyf3MQ^ZXp>Gx4GwPD))qv<1EreWT!S@H-IpO{TPP1se8Yv8f@Xw>B}Y z@#;egDL_+0WDA)AuP5@5Dyefuu&0g;P>ro9Qr>@2-VDrb(-whYxmWgkRGE(KC2LwS z;ya>ASBlDMtcZCCD8h+Awq1%A|Hbx)rpn`REck#(J^SbjiHXe-jBp!?>~DC7Wb?mC z_AN+^nOt;3tPnaRZBEpB6s|hCcFouWlA{3QJHP!EPBq1``CIsgMCYD#80(bsKpvwO)0#)1{ zos6v&9c=%W0G-T@9sfSLxeGZvnHk$SnHw57+5X4!u1dvH0YwOvuZ7M^2YOKra0dqR zD`K@MTs(k@h>VeI5UYI%n7#3L_WXVnpu$Vr-g}gEE>Y8ZQQsj_wbl&t6nj{;ga4q8SN#Z6cBZepMoyv7MF-tnnZp*(8jq848yZ zsG_fP$Y-rtCAPPI7QC^nzQjlk;p3tk88!1dJuEFZ!BoB;c!T>L>xSD<#+4X%*;_IB z0bZ%-SLOi5DV7uo{z}YLKHsOHfFIYlu8h(?gRs9@bbzk&dkvw*CWnV;GTAKOZfbY9 z(nKOTQ?fRRs(pr@KsUDq@*P`YUk4j=m?FIoIr)pHUCSE84|Qcf6GucZBRt;6oq_8Z zP^R{LRMo?8>5oaye)Jgg9?H}q?%m@2bBI!XOOP1B0s$%htwA&XuR`=chDc2)ebgna zFWvevD|V882V)@vt|>eeB+@<-L0^6NN%B5BREi8K=GwHVh6X>kCN+R3l{%oJw5g>F zrj$rp$9 zhepggNYDlBLM;Q*CB&%w zW+aY{Mj{=;Rc0dkUw~k)SwgT$RVEn+1QV;%<*FZg!1OcfOcLiF@~k$`IG|E8J0?R2 zk?iDGLR*b|9#WhNLtavx0&=Nx2NII{!@1T78VEA*I#65C`b5)8cGclxKQoVFM$P({ zLwJKo9!9xN4Q8a2F`xL&_>KZfN zOK?5jP%CT{^m4_jZahnn4DrqgTr%(e_({|z2`C2NrR6=v9 z*|55wrjpExm3M&wQ^P?rQPmkI9Z9jlcB~4IfYuLaBV95OGm#E|YwBvj5Z}L~f`&wc zrFo!zLX*C{d2}OGE{YCxyPDNV(%RZ7;;6oM*5a>5LmLy~_NIuhXTy-*>*^oo1L;`o zlY#igc#sXmsfGHA{Vu$lCq$&Ok|9~pSl5Q3csNqZc-!a;O@R$G28a@Sg#&gnrYFsk z&OjZtfIdsr%RV)bh>{>f883aoWuYCPDP{_)%yQhVdYh;6(EOO=;ztX1>n-LcOvCIr zKPLkb`WG2;>r)LTp!~AlXjf-Oe3k`Chvw$l7SB2bA=x3s$;;VTFL0QcHliysKd^*n zg-SNbtPnMAIBX7uiwi&vS)`dunX$}x)f=iwHH;OS6jZ9dYJ^wQ=F#j9U{wJ9eGH^#vzm$HIm->xSO>WQ~nwLYQ8FS|?l!vWL<%j1~P<+07ZMKkTqE0F*Oy1FchM z2(Nx-db%$WC~|loN~e!U`A4)V4@A|gPZh`TA18`yO1{ z(?VA_M6SYp-A#%JEppNHsV~kgW+*Ez=?H?GV!<$F^nOd+SZX(f0IoC#@A=TDv4B2M z%G-laS}yqR0f+qnYW_e7E;5$Q!eO-%XWZML++hz$Xaq@c%2&ognqB2%k;Cs!WA6vl z{6s3fwj*0Q_odHNXd(8234^=Asmc0#8ChzaSyIeCkO(wxqC=R`cZY1|TSK)EYx{W9 z!YXa8GER#Hx<^$eY>{d;u8*+0ocvY0f#D-}KO!`zyDD$%z1*2KI>T+Xmp)%%7c$P< zvTF;ea#Zfzz51>&s<=tS74(t=Hm0dIncn~&zaxiohmQn>6x`R+%vT%~Dhc%RQ=Cj^ z&%gxxQo!zAsu6Z+Ud#P!%3is<%*dJXe!*wZ-yidw|zw|C`cR z`fiF^(yZt?p{ZX|8Ita)UC$=fg6wOve?w+8ww|^7OQ0d zN(3dmJ@mV8>74I$kQl8NM%aC+2l?ZQ2pqkMs{&q(|4hwNM z^xYnjj)q6uAK@m|H$g2ARS2($e9aqGYlEED9sT?~{isH3Sk}kjmZ05Atkgh^M6VNP zX7@!i@k$yRsDK8RA1iqi0}#Phs7y(bKYAQbO9y=~10?8cXtIC4@gF#xZS;y3mAI`h zZ^VmqwJ%W>kisQ!J6R?Zjcgar;Il%$jI*@y)B+fn^53jQd0`)=C~w%Lo?qw!q3fVi{~2arObUM{s=q)hgBn64~)W0tyi?(vlFb z>tCE=B1cbfyY=V38fUGN(#vmn1aY!@v_c70}pa(Lrle-(-SH8Nd!emQF zf3kz0cE~KzB%37B24|e=l4)L}g1AF@v%J*A;5F7li!>I0`lfO9TR+ak`xyqWnj5iwJ$>t_vp(bet2p(jRD;5Q9x2*`|FA4#5cfo8SF@cW zeO{H7C0_YJ*P@_BEvm2dB}pUDYXq@G1^Ee#NY9Q`l`$BUXb01#lmQk^{g3?aaP~(* zD;INgi#8TDZ&*@ZKhx$jA^H-H1Lp`%`O{Y{@_o!+7ST}{Ng^P;X>~Bci{|Qdf1{}p z_kK+zL;>D30r6~R?|h!5NKYOi6X&I5)|ME+NG>d9^`hxKpU^)KBOpZiU^ z;|SzGWtbaclC-%9(zR-|q}kB8H&($nsB1LPAkgcm+Qs@cAov{IXxo5PHrH(8DuEMb z3_R#>7^jjGeS7$!`}m8!8$z|)I~{dhd)SvoH9oR9#LjO{{8O&r7w{d9V1z^syn&E6 z{DG0vlQF_Yb3*|>RzVop^{$mWp|%NDYj@4{d*-@O^<(=L=DMFIQHEp-dtz@1Rumd; zadt^4B#(uUyM6aeUJkGl0GfaULpR!2Ql&q$nEV^+SiDptdPbuJ=VJ)`czZ@&HPUuj zc5dSRB&xk)dI~;6N?wkzI}}4K3i%I=EnlKGpPJ9hu?mNzH7|H0j(mN3(ubdaps3GM z1i+9gk=!$mH=L#LRDf4!mXw0;uxSUIXhl|#h*uK+fQPilJc8RCK9GNPt=X^8`*;3$ zBBo77gkGB5F8a8)*OR10nK&~8CEMPVQyhY>i`PS{L^-*WAz$ljtU%zlG1lm%%U4Zw zms0oZR8b|`>4U1X*9JLQQ>m9MF5%ppoafz^;`7DbmmIENrc$hucekkE4I83WhT%(9 zMaE;f7`g4B#vl(#tNP8$3q{$&oY*oa0HLX6D?xTW3M6f<^{%CK4OE1Pmfue`M6Dh= z&Z-zrq$^xhP%|hU&)(+2KSSpeHgX^0?gRZ5wA8@%%9~@|*Ylux1M{WQ4ekG(T+_b` zb6I)QRGp%fRF)^T?i^j&JDBhfNU9?>Sl6WVMM%S?7< ze|4gaDbPooB=F4Y=>~_+y~Q1{Ox@%q>v+_ZIOfnz5y+qy zhi+^!CE*Lv-}>g^%G=bGLqD(aTN;yHDBH#tOC=X02}QU~Xdme``Wn>N>6{VwgU~Z>g+0 zxv0`>>iSfu$baHMw8(^FL6QWe;}(U>@;8j)t)yHAOj?SdeH;evFx-kpU@nT>lsrUt zqhV}2pD^5bC4786guG1`5|fK@pE6xcT#ns)vR|^?A08G62teHaE&p`ZrCBj_Swt*~dVt=5*RK6Y{% zABqK$X59BnrK3r3u=wxklRnA1uh+q`?T0kE1YhvDWF4OY#<(+V|R@R%tdkq2huF(!Ip+EpZF3zr*|9pmKHPo)Cu z;H+^s&`Ql}u=Jt~ZWj`bAw|i-3#7(2WuRU3DU{BW8`?!O?YO1M$*MMTsaEM!5Jyp~ z!gp6yR4$O%wQ8%dyz43ZPeoJwy;o;yg=S0^Y}%|)to>=N^`!3VMf1~}OZ`Dl$q&|w z9$!i3!i1uAgPTuKSWdBrDr*N$g=E#mdqfj*h;Z}OG`{n245+g;IKfdn!&gF2OtHaD zyGDzj@@d2!P(_Ux)3v;1ABTj__{w*kaRF-1YVU`})Acgk?(T*1YqEve3=5)8bkZK* z!Tus*e$h@^u z>#zV0771Bix~r&h2FJ9)%N{>s>?2tk1$bId)1#G;OKgn-U8jUo^AK;Hu)hQEi}swD(264kAS-SBCD$R(Ro0rh8~Le zzRwxbz_JHDbD+hTX15AWmVw!#rC)-zeZahQQmo6FG1)ah3uuyIuTMof}RO!`Y3^Fxn_-G$23RDOh(@NU?r6`*S?#E50)w zpcsgDZ-iO{;EesgDQq9;p*C#QH(sp~2w^zAJWaUL%@yo)iIL6y8;e_}=dwQc%k%;H zFt5lenH*`}LWd+fPqi;exJeRZgl&nLR%|a!%1x0RQ54cgyWBYrL>sskcAtPxi&8c( zw_K?sI*3n%S;lKiYpveBN08{rgV&-B1NN5Jiu07~%n#%&f!(R(z1)xsxtRBkg#+Lv zh21zX?aYDd_f}qdA`Os*j!eC<5)iUJ&Twj7?*p%vEOGElGhpRZsccM!<k}DeC;TY;rULQs3e}lZyP#UVb=6 zB$Dkm2FaHWUXr7<{R&46sfZ)&(HXxB_=e`%LZci`s7L6c-L7iF&wdmTJz`*^=jD~* zpOZ@jcq8LezVkE^M6D9^QgZqnX&x*mr1_Cf#R9R3&{i3%v#}V$UZzGC;Or*=Dw5SXBC6NV|sGZp^#%RTimyaj@!ZuyJ z6C+r}O1TsAzV9PAa*Gd!9#FQMl)ZLHzTr99biAqA(dz-m9LeIeKny3YB=*+|#-Gq# zaErUR5Z*Wh^e<+wcm70eW;f-g=YTbMiDX)AznDM6B73)T4r%nq+*hKcKF?)#vbv?K zPMe=sFCuC*ZqsBPh-?g!m*O`}6<}Pfj}Y1n9|Y@cUdD5GX_)6Sx9pPfS7 zxkt?g6ZwJ+50C7qrh6dMFmr7qah`FskT_H=GC92vkVh$WfZa2%5L99_DxyM{$#6HQ zx$VR-Wwt!q9JL2{ybEGJr$^?!V4m_BqDqt!mbs=QjHf340+^a{)waVvP0+98(BA$M ztWr&sM=juyYgvf`(SC}+y@QtYgU>0ghJ6VbU}|kEraR&&W%#;!#KI?le%g`e>ZVPiDrneh#&1(Y?uiMo^f5qo@{JEr(p9>8GhDa+PC9yG;lX+D?hQ^fZB&Sdox219zUj_5;+n<0@Wi3@DK`MU8FM!OFJ z8*_mTA-u!Ab#95FRVWTIqAL#BVQGxE_s?>Ql|@0o9vos&r<_4d!+Q6(_270)6#lu$ zV!j$a?_V0I<(3Z=J7C-K0a^Kc1Go9p&T6yQeAD+)dG-$a&%Fo0AOte~_Z&_m2@ue~ z9cKFf-A41Dz31Ooj9FSR`l?H5UtdP?JS=UU$jF#znE1k@0g%K?KQuwZkfDI3Ai)(q z#x_Yo6WR_Y@#6I_02S&NpcP<%sw!!M_3#*8qa+*4rS@x=i{-2K#*Qr)*Q$-{<_(<| z0730e+rubnT38*m;|$-4!1r6u&Ua2kO_s-(7*NGgDTe##%I>_9uW;X__b_k)xlv$; zW%K2hsmr>5e^Z~`tS-eUgWmSF9}Yg8E}qydSVX0nYZMX_x94QK?tw2>^;raVTqstR zIrNAX2`X~|h->dTOb9IrA!i5INpLV}99ES|i0ldzC`;R$FBY5&7+TIy8%GO8SZ37_ zw=^Swk?z+j-&0-cTE|LU0q@IKRa&C6ZlXbSa2vN5r-)*f<3{wLV*uJUw980AFkWN7 zKh{?97GmVu-0rs9FB6ludy|n`gN5p~?y51aJzBg6#+-=0pWdZ2n4xTiQ=&3As-!-6 zFlb|ssAJEJL#s8(=odfz8^9b#@RrvNE4gjuEITzAd7R4+rq$yEJKXP?6D@yM7xZ&^ z@%jnE3}bteJo{p(l`hu`Yvzg9I#~>(T;>c;ufeLfc!m3D&RaQS=gAtEO-WbI+f_#| zaVpq-<%~=27U8*qlVCuI6z9@j)#R!z3{jc>&I(qT-8IBW57_$z5Qm3gVC1TcWJNc% zDk?H3%QHno@fu9nT%L^K)=#sRiRNg|=%M zR;8BE)QA4#Dsg^EakzttRg9pkfIrF3iVYVM#*_+#3X+~qeZc^WQJvEyVlO@9=0pl!ayNOh|{j0j^a z+zi_$_0QKhwArW)sJ$wji;A`?$ecbr?(4x5%2pLgh#wggbt)#T^2R3a9m+>GcrUxU z*u-WTgHAN*e!0;Wa%1k)J_P(Vdp>vwrROTVae@6Wn04q4JL-)g&bWO6PWGuN2Q*s9 zn47Q2bIn4=!P1k0jN_U#+`Ah59zRD??jY?s;U;k@%q87=dM*_yvLN0->qswJWb zImaj{Ah&`)C$u#E0mfZh;iyyWNyEg;w0v%QS5 zGXqad{`>!XZJ%+nT+DiVm;lahOGmZyeqJ-;D&!S3d%CQS4ZFM zkzq5U^O|vIsU_erz_^^$|D0E3(i*&fF-fN}8!k3ugsUmW1{&dgnk!|>z2At?h^^T@ zWN_|`?#UM!FwqmSAgD6Hw%VM|fEAlhIA~^S@d@o<`-sxtE(|<><#76_5^l)Xr|l}Q zd@7Fa8Bj1ICqcy2fKl1rD4TYd84)PG5Ee2W4Nt@NNmpJWvc3q@@*c;~%^Vasf2H`y z+~U-19wtFT?@yIFc4SE_ab?s@wEUfSkOED}+qVjjy>=eac2^S^+|_3%cjH%EUTJ&r znp9q?RbStJcT*Vi{3KDa^jr4>{5x+?!1)8c2SqiCEzE$TQ+`3KPQQnG8_Qk<^)y_o zt1Q^f{#yCUt!1e(3;E6y?>p+7sGAYLp`lA3c~Y`re9q&`c6>0?c0E2Ap5seFv92#X z1Vldj!7A8@8tWr&?%;EBQ_Fwd)8A3!wIx`V!~~h(!$pCy7=&*+*uIzG@*d%*{qG#4 zX0^}}sRN^N=p{w(+yjv%xwb!%lnVTE7l1l6gJwQmq_G83J&Y98$S!r*L8}IiIa2E= zE!0tbOuEDb*No0-KB{zjo1k#_4FHtr{!)>o+Y@bll}Sa6D^xktI0H&l{jKAK)A(iz zB-N00F?~Z}Y7tG+vp)-q*v71(C}65$-=uXx^|R$xx9zZip-V>Hqeyfd(wteM)+!!H z$s+>g4I@+`h2>C|J;PhvtOq)`xm4;CyF}R<)!ma3T{Vf_5|zo;D4YI4ZDBkE(vMeE zb#ZV;n}CgA0w8x!UC2&5Z(K)9bibj#?~>R(72lFx_Am~jS?;7mo~p+05~XGD+(wV4 zEVYnf0N5+-7O+Gc1L!sPGUHv<6=cV8}*m$m`kBs@z zy;goR(?J^JrB7uXXpD00+SD0luk!vK3wwp(N%|X!HmO{xC#OMYQ&a7Yqv-54iEUK4 zVH;)rY6)pUX~ESvQK^w|&}>J{I?YlvOhpMgt-JB}m5Br`Q9X+^8+Xa%S81hO<1t#h zbS+MljFP1J0GGNR1}KwE=cfey%;@n&@Kli+Z5d>daJjbvuO3dW{r$1FT0j zR$c9$t~P50P+NhG^krLH%k}wsQ%mm+@#c;-c9>rYy;8#(jZ|KA8RrmnN2~>w0ciU7 zGiLC?Q^{^Ox-9F()RE^>Xq(MAbGaT0^6jc>M5^*&uc@YGt5Iw4i{6_z5}H$oO`arY z4BT(POK%DnxbH>P$A;OWPb@gYS96F7`jTn6JO@hdM za>_p!1mf?ULJZb1w-+HamqN__2CtI%VK`k^(++Ga0%z*z@k0wYJDqT^)~%|4O299; zh1_iRtc7you(kOK8?Q$R7v-@Qk4+i=8GD2_zI0%{Ra`_prF{+UPW^m5MCA&4ZUpZb z2*!)KA8b--Upp~U%f+rsmCmV~!Y>Gzl#yVvZER2h;f&rkdx{r#9mc8DZMJaQXs?SL zCg3#>xR6ve8&YkP*`Z=lng|Ow+h@t*!Ial*XQg3P;VS8@E1C)VS`?L9N+rxlD7bxC z3@Ag)Vu?#ykY`ND+GvRYTUP&-KDMiqly$Z~uFXt^)4Jjk9RIs*&$?-UPM*d7&m${m zm12kaN3mV1J|c6f$>V+{lvHp~XVW3DU0;cBR>7|)4bo{xa1-ts-lYU-Q-b)_fVVl`EP5X}+J9EzT20x8XIv=m7witdu7!3Lh=KE#OyKpT1GWk{YAo^ny|fvZt<+jmsFs=l*%e& zmRkBt5ccv4O7!HAyv2~rsq*(FmMTm?@TX3&1`nu|7C^F{ad%GLuoX}Rl}6`)uHF_xlx^gVca+mGH4T8u8;q{S*x3=j;kelz^atO~)v!Q_BT z4H6%IA}bvfuk0_vweELeEl8N5w-Q1GF!@f{VKnbyYB2?}d&QvI-j}~RI_+9t9$tC2 z94m=3eLi=sQb^S5;fqP?3aaXc&`}`lq z&M8dOXvxx9Y1^u_ZQHhO+qP}nwkvJhwoz$Mp6Qcq^7M#eWm}!3U@s07hop` zW24|J{t$aB`W>uBTssEvYMyi$hkaOqWh+^(RV_1MYnE0XPgW?7sBDk=Cqs(;$qrPEflqa0ZE?A3cBfW%0RPA235Wb6@=R_d>Sez; z`spwa50bq?-zh+id~Q!T`AYn`$GHzs;jxIw(A1_Ql&f|qP}|bon#H;sjKmSDM!nyn z>bU8l%3DB3F+$}|J^da!!pN|DO!Ndc2J)wMk!+Rr1hes#V}5o(?(yQSphn|9_aU<- zn|nsDS{^x&tweP;Ft`2ur>Koo2IdXJDsr6IN)7vB41Yy-^Wbo9*2th2QA@C zE0-0Gk12YOO?d_Guu6b3&(PIL`d zh4{`k54hu9o%v1K3PGuccez-wdC<&2fp)>`qIIaf)R{5un7-vwm=>LD7ibnJ$|KyE zzw`X*tM0S|V(I3vf454PY{yA5lbE+36_<1kd=&0Xy4jfvUKZ0$Jq!AG4KS7DrE9rph;dK^6*#CIU9qu7 z?)6O`TN&MCWGmUVd1@E2ow2`vZ1A#nGo8_n!dmX77DCgAP1va*ILU+!a&$zdm6Pa6 z4#|*&3dM+r_RJb%!0}7X!An&T4a4@ejqNJ;=1YVQ{J6|oURuj8MBZ8i7l=zz%S4-; zL}=M^wU43lZVwNJgN|#xIfo$aZfY#odZ6~z?aNn=oR1@zDb=a(o3w`IGu&j>6lYxL z&MtqINe4Z>bdsHNkVIu$Dbq0wc#X-xev221e~L zbm8kJ(Xzij$gF4Ij0(yuR?H1hShSy@{WXsHyKtAedk4O!IdpR{E32Oqp{1TD{usJi zGG@{3A$x%R*pp8b$RQo4w&eDhN`&b~iZ2m3U>@9p1o5kXoEVmHX7I6Uw4dn((mFw` zilWrqFd=F5sH$&*(eJB52zaLwRe zz`sruIc=Ck75>v5P5kd>B2u=drvGPg6s&k5^W!%CDxtRO)V6_Y_QP{%7B>E~vyMLG zhrfn8kijyK&bX+rZsnSJ26!j$1x+V!Pyn|ph%sXWr9^f&lf|C;+I^Fi_4;`-LJI&F zr;5O@#4jZX=Yaw0`pUyfF4J8A9wE#7_9!X|_s8~YUzWu&#E^%4NxUA3*jK-F5R3LP2|msHBLmiMIzVpPAEX)2 zLKYjm3VI4r#7|nP^}-}rL+Q4?LqlmBnbL+R8P%8VmV{`wP0=~2)LptW_i682*sUR# z+EifOk_cWVKg-iWr^Qf4cs^3&@BFRC6n0vu{HqZzNqW1{m)3K@gi$i}O(hT`f#bT- z8PqCdSj~FncPNmMKl9i9QPH1OMhvd42zLL~qWVup#nIJRg_?7KQ-g3jGTt5ywN;Qx zwmz4dddJYIOsC8VqC2R%NQ>zm=PJH70kS|EsEB>2Otmtf-18`jUGA6kMZL3vEASDN zNX%?0+=vgsUz!dxZ@~)eU17m4pN3xGC0T;#a@b9Iu0g_v*a3|ck^s_DVA^%yH-wt= zm1)7&q6&Rq#)nc9PQ6DKD{NU=&ul10rTiIe!)x^PS~=K(wX9|?k&{Mv&S$iL9@H7= zG0w~UxKXLF003zJ-H%fGA4Db9{~#p&Bl7ki^SWwv2sfoAlrLMvza)uh;7Aa_@FL4b z4G>`j5Mn9e5JrrN#R$wiB(!6@lU@49(tawM&oma6lB$-^!Pmmo;&j57CDmKi)yesg~P;lJPy9D(!;n;^1ql)$5uYf~f z&GywSWx=ABov_%8pCx=g-gww_u26?5st=rdeExu?5dvj^C?ZZxDv@Si^nX~2qA&K= z2jr;{=L(x~9GLXrIGXs>dehU^D}_NMCMegdtNVWyx)8xHT6Qu!R>?%@RvADs9er;NMkweUBFNrBm1F5e0_>^%CwM6ui}K_MpRqLS0*@lAcj zB6TTCBv>w2qh)qU3*kN+6tPmMQx|5Z0A4n67U-nss90Ec_rDF}r)IR4PE{$8;BSt= zT%6|jyD^(w6a*A5>_|TkMqx~e$n@8{`q?|)Q&Y4UWcI!yP-8AwBQ#P`%M&ib;}pli z9KAPU_9txQ3zOM#(x}*lN8q$2(Tq1yT4RN0!t~|&RdQMXfm!81d0ZuyD}aG3r4+g` z8Aevs3E_ssRAMR+&*Q30M!J5&o%^(3$ZJ=PLZ9<@x^0nb>dm17;8EQJE>hLgR(Wc% zn_LXw|5=b$6%X zS~ClDAZ?wdQrtKcV9>_v1_IXqy)?<@cGGq#!H`DNOE1hb4*P_@tGbMy6r@iCN=NiA zL1jLwuMw&N-e9H(v7>HGwqegSgD{GSzZ@sZ?g5Y`fuZ^X2hL=qeFO(;u|QZl1|HmW zYv+kq#fq_Kzr_LaezT zqIkG6R+ve#k6!xy*}@Kz@jcRaG9g|~j5fAYegGOE0k8+qtF?EgI99h*W}Cw z7TP&T0tz4QxiW!r zF4?|!WiNo=$ZCyrom-ep7y}(MVWOWxL+9?AlhX<>p||=VzvX`lUX(EdR^e5m%Rp_q zim6JL6{>S%OKoX(0FS>c1zY|;&!%i-sSE>ybYX3&^>zb`NPj7?N^ydh=s=0fpyyz% zraFILQ17_9<ettJJt~I+sl=&CPHwz zC9dEb#QFQcY?bk11Y=tEl{t+2IG`QFmYS>ECl;kv=N6&_xJLQt>}ZQiFSf+!D*4Ar zGJ~LFB7e_2AQaxg*h{$!eJ6=smO(d2ZNmwzcy3OG@)kNymCWS44|>fP^7QkJHkE9JmLryhcxFASKb4GYkJ|u^Fj=VdF0%6kgKllkt zC|_ov2R4cJ2QjjYjT6jE#J1J<xaNC>Xm;0SX<`LuW*}*{yQ3c9{Zl=<9NP z^2g5rAdO!-b4XfeBrXa4f{M0&VDrq+ps&2C8FYl@S59?edhp~7ee>GR$zQI4r8ONi zP^OA+8zrTAxOMx5ZBS03RS@J_V`3{QsOxznx6Yt*$IuEd3%R|Ki&zZkjNvrxlPD$m z%K+rwM!`E&Z46ogXCu!3 z8use`FJJ?g_xi?~?MxZYXEu=F=XTC8P3{W*CbG3Wk)^31nD~W>*cJ@W4xg%Qqo7rq z`pUu8wL!6Cm~@niI*YmQ+NbldAlQRh?L!)upVZ)|1{2;0gh38FD&8h#V{7tR&&J}I zX1?;dBqK}5XVyv;l(%?@IVMYj3lL4r)Wx9$<99}{B92UthUfHW3DvGth^Q0-=kcJ1 z!*I9xYAc$5N$~rXV>_VzPVv`6CeX(A_j3*ZkeB~lor#8O-k+0OOYzTkri@PVRRpOP zmBV|NKlJT?y4Q82er)@lK&P%CeLbRw8f+ZC9R)twg5ayJ-Va!hbpPlhs?>297lC8 zvD*WtsmSS{t{}hMPS;JjNf)`_WzqoEt~Pd0T;+_0g*?p=dEQ0#Aemzg_czxPUspzI z^H5oelpi$Z{#zG$emQJ#$q#|K%a0_x5`|;7XGMuQ7lQB9zsnh6b75B9@>ZatHR_6c z0(k}`kfHic{V|@;ghTu>UOZ_jFClp>UT#piDniL(5ZNYXWeW0VRfBerxamg4su5<; z(}Ct2AhR@I-ro0}DdZLRtgI@dm+V`cRZjgV-H+aXm5|Mgz`aZX63i<|oHk-E)cABn z0$NR?(>fla7)Ong28FZSi9Yk0LtYl5lZw5wT!K5=fYT$avgkMKJWx~V#i@7~6_{dM zxDDPIW2l{O2Elv#i^cjYg~lGHRj(W*9gD`(FILKY$R`tL2qo&rtU*c;li!V`O$aV{ z!m|n!FAB2>MR_FVN*Ktv5+2dW4rr3YmfEheyD+48%USM#q6)w%#2}~=5yZE1LLcth zF%VtefH&#AcMx7)JNC$P>~OFuG6sK}F7V$D7m!{ixz&inpAVpFXiu^QruAw@Sc7Y2 z_A^V(2W_+KTGRp2aQSMAgyV#b3@{?5q@hPEP6oF3^}|@8GuD6iKbX;!LI!L=P#Za zL$Zuv#=x3fseRMZ()#SQcXv->xW`C|6quwqL1M&KByBj z2V`}(uL4JB-hUs6304@%QL~S6VF^6ZI=e-Nm9Tc^7gWLd*HM-^S&0d1NuObw-Y3e> zqSXR3>u^~aDQx>tHzn9x?XRk}+__h_LvS~3Fa`#+m*MB9qG(g(GY-^;wO|i#x^?CR zVsOitW{)5m7YV{kb&Z!eXmI}pxP_^kI{}#_ zgjaG)(y7RO*u`io)9E{kXo@kDHrbP;mO`v2Hei32u~HxyuS)acL!R(MUiOKsKCRtv z#H4&dEtrDz|MLy<&(dV!`Pr-J2RVuX1OUME@1%*GzLOchqoc94!9QF$QnrTrRzl`K zYz}h+XD4&p|5Pg33fh+ch;6#w*H5`@6xA;;S5)H>i$}ii2d*l_1qHxY`L3g=t? z!-H0J5>kDt$4DQ{@V3$htxCI;N+$d^K^ad8q~&)NCV6wa5(D${P!Y2w(XF!8d0GpJ zRa=xLRQ;=8`J2+A334};LOIhU`HQ*0v4Upn?w|sciL|{AJSrG_(%-(W9EZb%>EAGG zpDY?z1rQLps`nbCtzqJ#@wxU4}(j!ZQ{`g`g*SXlLah*W9 zyuh)UWoRCknQtd~Lk#BT_qjwj&Kw8U)w=owaJ;A5ae}3)y>{neYNS`|VHJdcSEBF# zBJ6a;T)u;^i#L~LVF-X7!E$SggILXMlsEy~v}K*DM2)f@U~g|Q6I-Pss@)`>fgFWx zsq&7pe!|VA-h;@=fBF{(mR1^{1>ukTYUdyF^#A+(|I_&nm{_xaKn3h4&yMyym2k-wMFg(s@ez=DPmuB%`| z6;e@HQKB(|!PU1sW)W6~x|=8m6rL~4dQ9LTk|RzL-_(_77B4I~ZG=q7K%qHiv!FD8 zmt;Vnhb{ymaydv2V;X-5p zTt2ln?kaB9&(dH_X70^@rrCfz)nwfa9LYTHXO(IPcTEf$QiEhTpl??L+`Eetyqof8 zzl=q)?KdYni!C_9b8Z3xm7r5<5ZG-0uA`u^7Dm7k4mAsQ(rkoWy*^DZJa~#y6+hNG zh?7{D9$a9LS`a@SvZ5?C{JUHovWU9KI}z8YV4pWftx21v*Q;MpU{+b@>Or(}pwO^fu0qA3_k_Bo2}lIxvmMhucG-o>O=+R6YxZ zjs!o%K1AA*q#&bs@~%YA@C;}?!7yIml1`%lT3Cvq4)%A)U0o1)7HM;mm4-ZZK2`Lj zLo?!Kq1G1y1lk>$U~_tOW=%XFoyIui^Cdk511&V}x#n4JeB7>bpQkYIkpGQRHxH$L z%tS=WHC~upIXSem>=TTv?BLsQ37AO88(X+L1bI<;Bt>eY!}wjYoBn#2RGEP49&ZH-Z_}R_JK_ z>o*_y!pOI6?Vf*{x-XT;^(_0}2twfk`*)_lLl0H-g|}BC?dm7CU|^-gNJ~rx z($>97WTKf71$?2|V$Ybpf~Aj@ZZOcb3#uRq51%4^ts-#RMrJhgm|K3QpCsPGW=2dZ zAr5-HYX!D*o#Q&2;jL%X?0{}yH}j*(JC4ck;u%=a_D6CrXyBIM&O#7QWgc?@7MCsY zfH6&xgQmG$U6Miu$iF(*6d8Mq3Z+en_Fi`6VFF=i6L8+;Hr6J zmT=k0A2T{9Ghh9@)|G5R-<3A|qe_a#ipsFs6Yd!}Lcdl8k)I22-)F^4O&GP&1ljl~ z!REpRoer@}YTSWM&mueNci|^H?GbJcfC_Y@?Y+e4Yw?Qoy@VLy_8u2d#0W~C6j(pe zyO6SqpGhB-;)%3lwMGseMkWH0EgErnd9a_pLaxbWJug8$meJoY@o-5kNv&A$MJZ=U z^fXPLqV6m3#x%4V*OYD zUPS&WHikdN<{#Yj|EFQ`UojD4`Zh*CZO4Cv`w^&*FfqBi`iXsWg%%a< zk@*c%j1+xib(4q^nHHO^y5d8iNkvczbqZ5;^ZVu%*PJ!O?X-CoNP*&tOU!5%bwUEw zQN?P*a=KKlu{`7GoA}DE=#nDibRgecw>-*da~7&wgow}|DyCJq!-Lp8a~(zR@tO1 zgu(4s4HptPGn(HmN2ayYs@g+yx1n`nU3KM{tQHhMHBw7f#gwru$=C()`aKZAl^dYc ze7fC)8EZEXOryk6AD&-4L+4cJ&M@3;;{R)mi4=`ti7IZByr^|_HNsjcNFu?mIE)jD za2j)FPwRY!R_YR-P?URm0Pti*e#5jmfK)6EvaKCT{h)kbJl{AGr1Ekt}pG?^e z*botRf-RsB8q10BTroj{ZP**)2zkXTF+{9<4@$aNDreO7%tttKkR3z`3ljd?heAJEe<0%4zYK?};Ur*!a>PbGYFFi(OF-%wyzbKeBdbkjv^i9mn@UocSS z4;J%-Q$l`zb&r*Pb`U;3@qkc=8QaPE9KwmlVwAf01sa*uI2*N`9U^3*1lLsM9dJ(4 zZBkU}os|5YT#Z;PD8xVv!yo$-n{-n4JM5ukjnTciniiT`(cZ6sD6~67e5_?8am%!w zeCLUxq~7x-!Xg#PgKV&caC@7mu<86am{WaXo(lAemt4~I$utSp(URWpYNo$RvU*$N z#%iiA+h`(E;BUg;=I!#EaxO89bUK3*v5Nc3GPmURC5TqzC|))DsFNtJICH6oBW6#q z+B(N{ey+^mk_{!@ z)VhAWXG=_0j|0f9iJ;c404PiIFqK)(AD05Xh`Fk`r$^b`v+>*g+_+h@r)e+ELJ45) z?20~u<}HQyQ5AsBz(teF9!!_GLXnm{5Z0e{Ki*@!=&3x4-RcjBn##DDzHJ|KSZ5(E z9=tFZ)p~-}x%9sCY27)2i>(E-^OiYT?_)a;yXAGR$y+E`myMd;xDA#_Q49t*E}&ql#H~|x z2J2R1_#2lt91NnF!uqW%_=HlbF?A{B{n>}9$g5QF!bh_a7LTU~Jyz}7>W5{_LAov{ zy2_dmGy)d)&7^bJyUjEw%3xj{cuG0Eo zwL*XQB*Oi=r&HIIecC1%lbE;Y-*5|cL955S+2@uR18JDL<0;;Uc2Q9JEyo1R!!sz_ z#BqnkGfbLP#oQJk3y}nwMd(3Tt^PVA#zXnYF7D0W1)#+`i?@cm}fBkKD z+Mpcuim53|v7;8Tv(KraEyOK`HvJq^;rlNzOjIbW&HJDFqW>doN&j7)`RDv#v|PQ+ z03WnB4Y4X@Fe-@%3;He*FjY1MFmkyv0>64Cp~FIDKQTwmFP~_CxZOf{8gPy}I<=JC zo%_bmue&$UU0|GG%%99eI!m#5Y1MD3AsJqG#gt3u{%sj5&tQ&xZpP%fcKdYPtr<3$ zAeqgZ=vdjA;Xi##r%!J+yhK)TDP3%C7Y#J|&N^))dRk&qJSU*b;1W%t1;j#2{l~#{ zo8QYEny2AY>N{z4S6|uBzYp>7nP_tqX#!DfgQfeY6CO7ZRJ10&$5Rc+BEPb{ns!Bi z`y;v{>LQheel`}&OniUiNtQv@;EQP5iR&MitbPCYvoZgL76Tqu#lruAI`#g9F#j!= z^FLRVg0?m$=BCaL`u{ZnNKV>N`O$SuDvY`AoyfIzL9~ zo|bs1ADoXMr{tRGL% zA#cLu%kuMrYQXJq8(&qS|UYUxdCla(;SJLYIdQp)1luCxniVg~duy zUTPo9%ev2~W}Vbm-*=!DKv$%TktO$2rF~7-W-{ODp{sL%yQY_tcupR@HlA0f#^1l8 zbi>MV~o zz)zl1a?sGv)E}kP$4v3CQgTjpSJo?s>_$e>s2i+M^D5EfrwjFAo(8E%(^ROV0vz0o z-cg0jIk24n!wxZainfH)+?MGu@kg$XgaMY-^H}z^vG~XC7z2;p2Kv`b^3S#b5ssMOJ7724v>S36dD zeypxJ<=E~sD4f5wX060RIF-AR0#{Z z=&y$r8A-e6q18lIF{@O9Mi%dYSYT6erw!@zrl=uj>o(3=M*Bg4E$#bLhNUPO+Mn}>+IVN-`>5gM7tT7jre|&*_t;Tpk%PJL z%$qScr*q7OJ6?p&;VjEZ&*A;wHv2GdJ+fE;d(Qj#pmf2WL5#s^ZrXYC8x7)>5vq_7 zMCL}T{jNMA5`}6P5#PaMJDB2~TVt;!yEP)WEDAoi9PUt89S2Cj?+E0V(=_sv4Vn6b z_kS6~X!G;PKK>vZF@gWpg8Zuh%YX^2UYPdCg7?EH#^gkdOWpy(%RnXyyrhmJT~UJw zAR;%Zgb6z(mS+o9MT|Sc6O({!i0pzk;s9?Dq)%tTW3*XdM3zhPn*`z45$Bg!P4xfy zD*{>30*JsSk?bQ-DgG62v>Vw-w`SA}{*Za7%N(d-mr@~xq5&OvPa*F2Q3Mqzzf%Oe z4N$`+<=;f5_$9nBd=PhPRU>9_2N8M`tT<-fcvc&!qkoAo4J{e3&;6(YoF8Wd&A+>; z|MSKXb~83~{=byCWHm57tRs{!AI<5papN(zKssb_p_WT@0kL0T0Z5#KLbz%zfk?f7 zR!vXBs36XaNcq5usS7<>skM_*P$e*^8y1ksiuokbsGFQ_{-8BAMfu!Z6G=88;>Fxt z|F-RU{=9i6obkTa0k~L#g;9ot8GCSxjAsyeN~1;^E=o5`m%u7dO1C*nn1gklHCBUw z;R(LgZ}sHld`c%&=S+Vx%;_I1*36P`WYx%&AboA1W@P;BvuFW+ng*wh?^aH4-b7So zG?9kFs_6ma85@wo!Z`L)B#zQAZz{Mc7S%d<*_4cKYaKRSY`#<{w?}4*Z>f2gvK`P1 zfT~v?LkvzaxnV|3^^P5UZa1I@u*4>TdXADYkent$d1q;jzE~%v?@rFYC~jB;IM5n_U0;r>5Xmdu{;2%zCwa&n>vnRC^&+dUZKy zt=@Lfsb$dsMP}Bn;3sb+u76jBKX(|0P-^P!&CUJ!;M?R?z7)$0DXkMG*ccBLj+xI) zYP=jIl88MY5Jyf@wKN--x@We~_^#kM2#Xg$0yD+2Tu^MZ1w%AIpCToT-qQbctHpc_ z>Z97ECB%ak;R<4hEt6bVqgYm(!~^Yx9?6_FUDqQQVk=HETyWpi!O^`EZ_5AoSv@VbUzsqusIZ;yX!4CsMiznO}S{4e>^0`c<)c~mC#*{90@+T@%EQ~>bovc8n_$bvqkOU7CrYe8uI5~{3O7EijeX`js z-$LNz4pJA7_V5~JA_Wl*uSrQYSh9Wm($%@jowv^fSPW<~kK&M*hAleywHd?7v{`;Y zBhL2+-O+7QK_)7XOJAbdTV-S`!I)t~GE8z+fV7y;wp#!wj75drv;R*UdSh(}u$%{VSd0gLeFp;h6FkiVz%g=EY3G#>RU;alRy;vQmk*| z@x-ba0XKE%IyL4OYw6IXzMiS(q^UDk=t(#XgkuF`{P?=k8k3r)rmhkv`vg@kiWd34 z-~t+1aV3SabTbG=nQYs>3~E<}{5@0g**LAWi*~SfRZhGcgP{e5T!0M7CU}`f@r8xI z0bx%sI!?5);-wG+Mx&S=NRfIi>V-wP(n&$X0Bhd)qI^ch%96s6&u7qpiK8ijA=X_R zk&|9f$GXf-;VgnrxV83Cp-Q!!sHH`5O^o~qZu!xny1t?(Au(EAn)D??v<1Uo;#m7-M@ovk|()C(`o>QMTp}F?> zakm3bHBKUjH-MHXDow7#Z|@wea1X9ePH;%YA)fCZ9-MD)p^(p!2E`aU9nmJlm;CXQ zkx~$WQ`Yq{1h5k>E>Ex{Z=P=)N*0b8_O({IeKg?vqQ)hk=JHe z5iqUKm!~mLP0fnRwkCO(xxTV@&p+o8wdSP$jZofYP}yEkvSc z5yD-^>04{zTP7X44q9Af&-wgt7k|XtncO&L@y-wFFR44RsPu57FRvIBaI^Pqy_*DV z@i13CsaR5@X@xH=NT3}T`_vsy!a02n80eQqya=-p7#YW`Jc0z!QglGg`1zeg6uXwI zsB~hlNMo)kFL(V3Q1<%8yoI6X7ncn-&&Uh3rL@S(6@wKAXt6Wr=a2ObI7}8$D-FoI z>AJA>WsBEMi5ba6JhJ%9EAi&ocd(ZsD|MsXwu@X;2h#|(bSWu@2{+c7soC`%uo{sMYq&Vyufb)?OI59ds)O+kyE8@G z@tlpNr0UO~}qd0HQve6njJ zda2+l$gdX7AvvGhxM6OToCuQ|Zw|9!g1)O+7>~{KNvASjp9#Cqce-or+y5xdzWL3gLWt2oa+T(I+{j(&bF1laUsJB{fOgE-B}qslaS>C z)TjzG8XecbS%a+?yT!0QmTex?E478;D|sL*oS4C-g0Tq(YoH|eyxJ#1j088C|U-w5id`%Sz7X_w#l+U9+)$|2no<}5J zRb_9@0esSr?n}HvVGbD5@$p$8k4?qOe-GNOk3-K^Mw>Xg+drCKi5@$GTeijpI;;IG ziD<&go`ptLC&^<0jw^l0aY?_pUUK+xp#0Bk66iQ29vpR)VBE{JOJ&OL^gKsN<&t<| zCMLTYMSDG5Ie9O>6Dl#T{@cscz%)}?tC#?rj>iwQ0!YUk~R z$rB-k=fa9x&631Z9Mfqj_GRoS1MzqSMEdaZ2!isP19Sr>qG8!yL(WWF)_&{F)r>KnJGSciSp!P0fqHr+G=fGO02Q#9gHK zpwz+yhpC4w*<9JO@#(MdkZcWbdCO5B!H`Z|nV?UtcBo96$BgX+7VYMwp@b-%;BrJu zMd*K!{1txv{kHKPDs9?WZrz_^o1Tq2P=+=|E=Oy4#WE{>9}*9(apqhmE`&AeBzQgQ zELFLCmb~q|6y0FCt|B}*uI*ayZ#6=$BpGtF{Jfye#Q>FZ?BPnk)*Qmd?rNG^tvFUU z_b&antYsZnUR6Q9tQUy81r$&ovT#fy;(Db4F&M*C=KxQgHDrRcVR#d+ z0(D|*9#u`w_%2o3faI{?dNd9$#5nj1PROHNq z7HJ(;7B1ThyM>a@Fo^lJb2ls2lD`}ocREH|5pKN;$>gFyM6k)kZG;lA;@kSJIqUhf zX%dhcN(Jtomz4(rNng&1br3Xx33EvCWz%o8s;SpRiKEUFd+KJ+u|gn|J85dZ)Exc&=V|Ns8Xs#P>qv6PX&VAJXJ(ILZO!WJd0 z`+|f5HrEj~isRN7?dBHotcPI7;6W48*%J(9 zftl1Tr`bKH*WNdFx+h;BZ+`p!qKl~|Zt5izh}#pU9FQKE97#$@*pf38Hr8A+`N+50U3$6h%^!4fBN zjh^cl#8qW5OZbvxCfYzKHuyeKLF4z^@~+oqlz9(Hx8vypIiUlt!(vs}_t#4@nh$s; z>FYERg*KD#Xs+W4q-V-IBQK!)M1)Aa+h+V+is)z!_=gEn&^ci7<DEEmYcoSh?WdXUsP7O4)&lQXA(BVM5jI8s6;mO}94AC0gG(`>|T)yuV1l~i-ejCCt zoejDhX0nrZDP|x9u4zp%S2UeDzV`o#pBGu1tZ-$<9TIbN=ALwhQ0=9S{8#}Uu8n-~ z5~xIvUhLSz@c@0|me$CdZCpZl(vQw@a0Y4^{T0w_>pOkwI^x4KkBf3qGmm)nG|Ps5 z_XTY~^b^mL&_*yjl~RRIi&eS(>y?y}O4-)nWyTEPpQAb#Xz8SnnfIL+nAcNL9nqV9 zRL|eyF)RKI5-kJO6}>Q89XmgY@b1&!JI>g3ryZ@jN2v3vm7O`AL!BTWNouJzV+$+Y zYY}u%i>K6=IYU2O$2TAyVjGt?wgF9xCj;?EK(8fWu!!~48`3u^W$eUlCh*91PLxu1 zRY(F7Q3s7h$Q-p&L$ucN}it*-9KR z_<wHu?!dav0$P+PI3{J8?{+l|n&2YMLV2 z+hRta$A5WpCXl1RNbYBsX8IGX{2v>U|8_I-JD56K|GexW>}F_e_g_1r?08v8Kz{V$ zT=6aGMk>ibvRO@Yrc@ezaD0%ydHkXGHrR{7>q~~tO7ChJflwa4-xL|@#YIJejC5VT zInU4CjQ9V0+lClQY=vh^s4MadwQmk7li{54Y;Ht}gkZOIh9(vfK?3kXLoD72!lHD# zwI-Jg|IhT=Y#s|tso1PWp;|aJ2}M?Y{ETyYG<86woO_b+WVRh<9eJu#i5jxKu(s~3 z4mz+@3=aNl^xt{E2_xewFIsHJfCzEkqQ0<7e|{vT>{;WlICA|DW4c@^A*osWudRAP zJut4A^wh@}XW4*&iFq|rOUqg*x%1F+hu3U6Am;CLXMF&({;q0uEWG2w2lZtg)prt` z=5@!oRH~lpncz1yO4+)?>NkO4NEgP4U~VPmfw~CEWo`!#AeTySp3qOE#{oUW>FwHkZ3rBaFeISHfiVSB7%}M) z=10EZ1Ec&l;4 zG98m5sU!pVqojGEFh8P{2|!ReQ&hfDEH2dmTVkrS;$dN~G2v-qnxn^A2VeHqY@;P} zudZD5vHtVvB*loIDF1M7AEEvS&h0;X`u}!1vj6S-NmdbeL=r{*T2J6^VA7F`S`CDd zY|=AA6|9Tu8>ND6fQhfK4;L3vAdJPBA}d6YOyKP&ZVi%z6{lbkE|VyB*p1_julR^k zqBwjkqmFK=u&e8MfArjW-(Ei8{rWso1vt5NhUdN|zpXqK{ylJ8@}wq-nV~L4bIjtt zt$&(1FTIs+aw}{&0SO4*sa0H2h&7g}VN5uYjfed5h7eGp$2Wu*@m9WIr0kxOc}fX9eOWh zFKfV>+SD$@kESKYm{F*J90XQjr$!<~v(J%&RMuQM+6CkmnYZDGlOUdq}%)VA& zl#acS%XE2KuX~7IamK`og@C`21~*cEEc#PZM6HT*Veb_l&Ej~j0zL7p0Eo`mMu(=X zJ$v;&Lya75I4C^saKROgfi(fdP0C$GM3WyZn%mm3yEI>|S&O(u{{S<}ihUp#`X&_z zmQBma;82#`C;dR5Sx09e07FvtJLhZ{9R~|$FCdU6TDNUwTc9kNct?8e@o2MpQDrkg zN?G+aYtTjiUPA=RX5o{4RYu}6;)ET>TcgL^VpfIpluJ|lQR(_)>6k%L^FZmoK-Wm- zR5qy0P)hm8yvqOL>>Z;k4U}!s?%1~7v7K~m+gh=0c9Ip_9UC3nwr$%^I>yU6`;2kV z-uJ%y-afzA7;BC7jc-=XnpHK+Kf*tcOS>f5ab2&J&5hIOfXzs=&cz|Qmrpu6Z);`R z0%3^dioK5x?o7t~SK7u5m{dyUZ#QUPqBHYn@jETeG>VU=ieZuJ;mm^j>dZM7))cw?a`w8R z%3M0R=kdOt^W^$Kq5Z%aJ(a$(*qFpy^W}Ij$h+Jnmc9eaP(vB@{@8t zz=RQ$x4XYC#enS$fxh@;cSZ|D%7ug;0z{C8I8h{KocN-cyv3UG_nk99UNS4ki^OFkYea`q`rs zG@qdMI;4ogcd5Tr`di1JBg4I*6CFvCID_2SN5&)DZG&wXW{|c+BdQ4)G9_{YGA@A* zaf}o^hQFJCFtzt&*ua~%3NylCjLtqWTfmA-@zw;@*?d&RE3O8G&d;AVC|rZrU}jx# zC-9SF`9;CbQ(?07o8Q9E12vi)EP@tOIYKEKnO@-o!ggkC)^#L-c40iZtb4Y-cS>$I zTn~+>rn*Ts>*y*z^b3-fAlne+M-*%ecrI^rmKAVv23cB`aWD?JDJ5NIafRvRr*~~C z)99Afs`BPK!5BFT)b_^8GyH*{22}yDq;be`GnPl=vW+ITnaqzl(uYOHhXi}S!P+QZ z4SwfEPuu&z4t#?6Zaw}bvN{;|80DfxCTuOdz-}iY%AO}SBj1nx1(*F%3A-zdxU0aj z`zzw9-l?C(2H7rtBA*_)*rea>G?SnBgv#L)17oe57KFyDgzE36&tlDunHKKW$?}ta ztJc>6h<^^#x1@iTYrc}__pe0yf1OnQmoTjWaCG`#Cbdb?g5kXaXd-7;tfx?>Y-gI| zt7_K}yT5WM-2?bD-}ym*?~sZ{FgkQ9tXFSF zls=QGy?fZ=+(@M>P3Y>@O{f44yU^fP>zNzIQ0(&O$JCd_!p?2;} zI6E1j@`DxzgJvqcE@zgapQ?tophO14`=14DUZ*#@%rRi``pi0lkNgidSsHGjXK8gO{drQoNqR&tRjM4>^DtW`)fiRFO4LE=Z+nCBS~|B3gZsh`Y?-$g z@8@Z$D7C!L9l=SWoE;(+*YirPLWvBd$5Ztn3J3EaGM+#pW#@{3%yksGqy(2Bt5PVE zf*fICtPp77%}5j#0G8<=v=)LR>-a3dxja8cy3m$=MZ2#$8mbLvxE%NptMd+L?mG`v zF1cANFv17DqP^P5)AYHDQWHk*s~HFq6OaJ3h#BUqUOMkh)~!(ptZ2WP!_$TBV}!@>Ta#eQS_{ffgpfiRbyw1f)X4S z_iU`lNuTy86;%!sF3yh?$5zjW4F?6E9Ts-TnA zDyx5p1h$Z3IsHv7b*Q{5(bkPc{f`2Wfxg*Z#IvQ;W_q9|GqXGj<@abo)FyPtzI~i25&o zC!cJR%0!}lLf^L2eAfZg7Z69wp{J?D6UhXr%vvAn?%)7Ngct4Hrs@LZqD9qFHYAWy z4l=2LI?ER&$He2n`RiG&nsfLv?8$Cl)&d8a-~-N`I|&EPa@Y=v@>0Gl?jlt>AUY;H z`**5bpS#VGhdp4pKbf3iEF*>-eXg_$bqt5Dc%q0+)R50>zd^l7sN5R5Z)Ut+oz-8_ zJ`Z9HE9(=wRTD)T=%GZTEi9K5naPzlfE$|3GYGLRCLsnqLi8Sc6y&iskqA&Z$#7Ng z7Q@C0)6k;J$TlQ+VKZ5)-Ff_BNoIMm+~!@Cv1yAUI-U!R)LHc@+nSUzo$GlRb+8W< zYPG%NFfr;!(RlnvBbN~~EpT6Xj5*^Z&73tdIQ$LZu`vkfzdTKa5|JJtQ_rm4g$9LO zKtgYVdW=b<2WGM3I_j|Rd8gZ3j;)S#AT(aP^d>9wrtQS_+K>pZDX^?mN!Z>f^jP@1 zlJ;i79_MgOAJa`%S9EdVn>ip{d!k6c5%zizdIoB9Nr!n`*X#%6xP1?vHKc6*6+vKx zmEt|f^02)S_u_wlW_<`7uLQU%{wdH0iojOf_=}2=(krE<*!~kn%==#0Zz`?8v@4gP zPB=-O-W=OO3tD19%eX>PZj3YfrCt0sEjgTd#b$buAgBri#)wW14x7QcHf2Cneuizz z368r7`zpf`YltXY9|2V{stf8VCHgKXVGjv$m!hdDf0gi`(Q!(Pyg~FO28Vr#!BYP| zI)qG2?Ho=1Us9dTml}-ZOR?g5Vk)f+r=dbCN*N1=qNfG>UCLeA8pd3Ub-pRx1b3FA zEn`CIMf`2Mt3>>#3RkE19o}aMzi^C`+Z>8iIPHSdTdmjCdJBtNmd9o0^LrJc9|U9c zD~=FUnSyghk7jScMWT|SHkP(&DK$Z=n&lGm+FDTpGxfoIyKV)H6^nY~INQ#=OtIT! zyB*J=(#oHf=S)MNOncW->!c0r0H#=2QzobO&f@x&Y8sYi-)Ld;83zO$9@nPPhD}yt z{P`*fT@Z(?YAmF{1)C;o?G@dfd2$c+=Av*|;P@Yz1KnclB-Z-fJQ-=+T*g>0B7!g# zQH{dHt_%wj=wlmT&m59)TQ~xK)gB6f^EY$=1zcbGf~Q>p_PzDCHR6lndGmqPY2)&w z$Th^K%1v@KeY-5DpLr4zeJcHqB`HqX0A$e)AIm(Y(hNQk5uqovcuch0v=`DU5YC3y z-5i&?5@i$icVgS3@YrU<+aBw+WUaTr5Ya9$)S>!<@Q?5PsQIz560=q4wGE3Ycs*vK z8@ys>cpbG8Ff74#oVzfy)S@LK27V5-0h|;_~=j1TTZ9_1LrbBUHb?)F4fc)&F7hX1v160!vJc!aRI>vp*bYK=CB(Qbtw7 zDr2O^J%%#zHa7M5hGBh#8(2IBAk}zdhAk$`=QYe^0P6Bb+j5X)Grmi$ z6YH?*kx9hX>KCI04iaM_wzSVD+%EWS)@DR&nWsSBc2VIZ>C(jX((ZiV0=cp}rtTO&|GMvbmE4FpBF5Rd z6ZG=>X&>N3?ZN2^11pXEP4L?XUo`qrwxgQm4X~RCttXmZAhnhu4KDK=VkKq?@@Q_Z za`*xyHrsAEsR zV(7)2+|h)%EHHLD3>Qg{>G|ns_%5g5aSzA#z91R zMDKNuIt@|t?PkPsjCxUy&fu^At*yUYdBV!R_KOyVb?DO&z$GLJh9~b|3ELsysL7U6 zp24`RH+;%C(!bWHtX&*bF!l-jEXsR_|K~XL+9c+$`<11IzZ4>se?JZh1Ds60y#7sW zoh+O!Tuqd}w)1VxzL>W?;A=$xf1Os={m;|NbvBxm+JC@H^Fj$J=?t2XqL|2KWl$3+ zz$K+#_-KW(t)MEg6zBSF8XqU$IUhHj+&VwsZqd7) ztjz$#CZrccfmFdi_1$#&wl~A*RisBaBy~)w|txu1QrvR1?)2mb&m2N$C(5MS%hSX)VJnb@ZGXB5^%(<#1L@ zL^>fBd+dEe`&hxXM<0A9tviIs^BDkByJdc~mtTYr!%F7Q1XnK2$%h$Ob30*hSP$Bt zDd#w{2Z%x^Wpv8!)hm>6u01mY!xmPgwZ#Q0148)SxJc3Udt!-&}eRO^LN ze26pQB!Jhg&Z>#FD>`C`sU44><=v>O>tJdLs!HPpV#AM32^J@Za-9J(CQjKxpzXao zQfRkWP%g9P8XV21MmoHfx{DICLSc*t4qVeQL9t}&Pz0rM}YTba@XsD=XMW@FxFM{QYQJHvM(JsUSa3mcTUl9^qcVA zBveO--fqw%{#QGR1vy;x88+qMcgzmcYc#8U`CPPt6bl?uj%w_`b~9JliftnOa|ziW z|6(q&STs_*0{KNa(Z79@{`X&JY1^+;Xa69b|Dd7D&H!hVf6&hh4NZ5v0pt&DEsMpo zMr0ak4U%PP5+e(ja@sKj)2IONU+B`cVR&53WbXAm5=K>~>@0Qh7kK*=iU^KaC~-ir zYFQA7@!SSrZyYEp95i%GCj*1WgtDId*icG=rKu~O#ZtEB2^+&4+s_Tv1;2OIjh~pG zcfHczxNp>;OeocnVoL-HyKU!i!v0vWF_jJs&O1zm%4%40S7_FVNX1;R4h^c1u9V@f z`YzP6l>w>%a#*jk(Y82xQ@`@L(*zD&H>NY`iH(iyEU5R$qwTKC5jm4>BikQGHp^)u z-RQ`UCa70hJaYQeA=HtU1;fyxkcB2oY&q&->r-G9pis)t$`508$?eDDueFdW=n5hJ z08lH$dKN$y#OEE@k{#|<%GYY=_c~fHfC@pD54KSP9{Ek@T47ez$;m$}iwR}3?)hbkwS$@p2iVH0IM$lB*XYA+#}-re|UNzCE)SOYwy z=Y!fkG4&I%3J(_H#UsV#SjHulRIVcpJ`utDTY{k&6?#fzt~@Om=L(vs6cxAJxkIWI z@H7)f2h%9!jl@C!lm+X4uu;TT6o0pd7 zteFQ(ND@djf#o2kTkjcgT=dHs7ukmP0&l8{f;o3JuHGd2Op*?p7?Ct=jA*tIg{MZk z$2Lsc0e8Tdcwrjx|_Ok?9uB3Il|^2FF%X#ck}WoIvrzQXN%kT$9NI{79Wm~gZ3`8I+O`)`n30feZ( zDO-fl6IG3c^8S;Y_M-)+^CmM0tT^g0?H#>H8!oC8W%oU!~3|DJ?)~LT9*&GAQG13zOGq6gs*={cu|(V7{R$y@{-iV*9q@AD(#Ktb}J&3&k|5Djs$)9WM7!6#EaJ_ilvbfUvyh8c?-{n zfuFrC0u6}UJZ7aj@(cNG_(CKgjQQTA-UK@-MVmick zot}6F%@jhq(*}!rVFp5d6?dg|G}M*moyLriI!PQDI;E1L1eOa6>F9E6&mdLD>^0jJ z09l?1PptuV65gm=)VYiv<5?*<+MH~*G|$~9Z3XEy@B1-M(}o&*Fr9Sv6NYAP#`h{p zbwbUE3xeJ;vD}QMqECN)!yvDHRwb7c1s6IRmW!094`?Fm!l~45w)0X`Hg+6Y0-xf# zSMemBdE)Q=e^58HR{kWrL5-H0X6pDu%o{0=#!KxGp0A;6{N5kI+EoY_eTE%2q|rwm zekNeLY-R?htk!YP2|@dbd8TWG4#G)=bXlE{^ZTb^Q$}Er zz)Fp)ul24tBtQFIegdI37`K$VR3tVdi<(fIsu{#QMx=$&CK9M8oN%3Mk;>ZPd-;Q- zn|sSKSnc-S0yrw#TlA$+p{J~u=u98s>IoL@cNLOxH=+1m?;t1bR$vR=M$US&Z8DO3 z_&zhQuId1$wVNsS=X?&s(ecIi#00o{kuPs6kpYkL$jMyGW8U7mlCVaZeEL=HsIxqm zFRLxWin8B>!Dc#9Z#t0RNQiR-@5J+=;tC7|1D*~rxcwHa5iIVD@99cCFE@BukUC-S z^iJdt?dwU)kH2VY9?|zVShMbZctzFRz5Q4tiXa^>@U%jDYq}$rSyc#p2wXr}mc0qq z^lT>$y)N(Qg0dwmEwTopneoU(y)>Mj+f{iHM0o|>ZtCg-itPj4addYz??aE)Rp&hk z_SI)%XeSf=SjZq18h!Cc>Xy&EynnxdHQ){(x@g|ZA%`3LU^KzX02c5N;F#tEk1)7v z(|V9tO3>?^X|kQ*rRBf4>mWW2$-Lx})|M7z125&VHcxsCqB!<$l1F$zCrJ+nm0f3Z z%Hq^=SKpHyV2@Y*Cu2x>fXC0SscnR*($zEB{KOniJcpn@e`PMH*_Q6*0Z^8RNCEvZ z+UU9!927p9YZ&g=bnUvQUZcdisyn;-4;ACXOe-Xor9K8Qbp{ldE17+G@VQT+9ZJQ*9dZoXfU2ue|mMhrrZk2R7&~YjFW4`BTq45UwVc6JORKU)wBCTanITh0GD}s$`C5pb(9{b9 znwee6j%?-UV)_7opOioCf5@C?@w^@g& z&68+oMmV;5JW@TT63&CSDrfYL2$L)pVseDtAwPwleEM3F^-Ufn3PpfxFmx6o zQ`Wq9x#d$e`VKn5LOXNsrqhGao7~|s(u~drPrZ+;aP!C%z4NskZstCbAibD}O%8Ij zb~C(taxco~WzJLxhL1T}3ctXMbV6}_z=IZN9L0|SxLSe`$X`<)BhM`$1&&)e_}fCh z=idVL<+u6Vn{&ksP*ZLlMo$fC`dtzF_?~L?4Rril2G4%v5^7sUa^&8aMtMX&mtapl zD(dW|cisM3fqMaB`8?QbkyiUl2g>hMB5EoS&IB8TdoC~)b$nT=`%GgU`k-)+8}`)F*~I~DXMaTP%kZftx11~?iALs5J+&Rom#p%Y z>dH}-euH4u=_V3hc6^*2WMtL!9%yRTJ93p}@aV0zdY*?xchFI>m+UivV=;aMFp0P~ zwB8P)wvV6D-GL?6hJ#g7Hy7=2i^&Od#S=j!;Rc_yjO!*4aN7{vqzg2t-R|Dav%_NDk z`H_FVlSi==(~f-#65VmQ{EE92x<03lwo5p)s=ZJ^L7PlS>132Whr zR6v~t(#I+(`usYLCoO;Rt8j&b^5g_xgs*98Gp|N}b>-`HtVm)MscD)71y?(K6DRCZV26RsHPHKk)EKKZA%C99t3$t^B0-k5@?E>A-YMbFe?>ms?J?_guHHNU(;id*>xH zTrtam+Aq?n@-y@uY@A?hy?1qX^eLu_RaH4Ave?A8NapgQF=C%XI7wlcCf4<6BRo_% zBXxxc*A6-3CruF?3i8HOdbc%>N=-iiOF+9HX|ht6SCkz;A^am&qi_I&qk1B(x<=(m z>QG)nswCOLl_1{SZ@_eE#m^qb6#6DoMsB*)`17ui+XvF%(}|J4G$z2G*;E!1ERnAH z@q%=#uV6kBddqy4=g>!VTV)9*1=i{wJ}Ep!I*?)uJdA(LwE?(!?;}_u=^M2NShWC_ z*7l4aBJ=!QVU2-iehgb`$vOI8zkm{W%QO~?xOD;NgI;Iqa3#^$^U5D&McReLe&qs# zR<^@QpR4#W~Laz+QBsPt@3L#KF`Yr8}jgHe;5(cfpQ=;Zjtbt;c%y^#-m=hqOT z;KAYakW+$w0&F}>K10&SiPcD9SrDOuczj@U#W})5jGU-_htU`U6Q%wdy((%?J}y+$ z=$4jw1N nJo)qTxG{D(`3*#8tY|67hJRF;)r6F|#I`Ar6I0aafRa=kr-Z0I^}9xf^u;G5iEQCbpv3b#S#%H|HYHsQaHK$! zU#3Fpz8*^pK%RRmX<_09eIVziB0jOgPgFnI-*QcwEBtBiO#v!>{W1cLNXyw3D9M|A z*oGy(u8BkDA1c;MsXmpK^-~pl=We^RYnhZ4bz*)Q)C2G+E3tgx9PzU0T>c|1ilS!T zyE=bz`=wskDiOi!@!l?Y))#%{FM`}7r~X)i1)1*c6_2Q!_1{)fp%cS|YF+Q-CB%d< z=zYus`Vt@Mx*a7V)=mpLS$-5viaKgNB=+zN657qy0qR94!cTtX-Z%KBCg4OKw7b=t zr=`7q5Ox=lJ%!G5WIyNQC1xpqYU0{!I$hyrk!6%De$gp<_*Gc?ES(OwY8U^)Kjgc{ zSlhpXDb|;{+y9`u{EuMz54rlky2~p6xX2>MV6BZ&k`$q%q7v(xYps2wr9e8^4<;CB zc)eAT~B^rjzO6<4BDDH;il6 zFsM8jL+agQ;zazW(uiQjM%fPf2N~_p{cy29XP11_lQFpt`t#9nlk}>fv((FZt-dBa zuMIc4HmPHW04n0TTG9ug9;&OV9euL$Ib|+M7}}L~z4e%%%b|r~6OQj(S2d7XfYn#xp8;KQ55UYu#gY*De5j6Cc z#R%?rqwpy7I1(kpU7B*Pq=etXeYUn04jg%ZPjYqQNa$==yTG=6KX+=;i2Xg+kjV2T*Gc!(ef z`Q4fR*TA=M5-}z+s%YO+!K{k}S**ic&>o4_Tmv$EQTOp7F6TXPCj-UTXy?OQ=%*y62Qajk{rXbR%jMCOFMiVE3KekQa4xR}B%=iPtd8BXo~q$OX_ zSp910{Ew;m|GATsq_XiJ3w@s(jrj^NDtr(Dp!`Ve!Oq?|EJ9=vY2>IfrV{rT%(jiY zi}W@jA2iqd=?q>s;3%?@oi7~Ndo3Ge-2!zX58j(w&zVlPuXm3rcHb7O0RsM|!Ys(b zh(=*&Aywo3vuJoWZnU!u2_4bNkDTc&&bCYc%T zM~~xYxS#3KXFzQ@OXdc%9QDOxqiTd_> zT;(DX9{5dIuC4pO_xy+3{Ov)1I7j!Z)6&nHUvTRP>VU5dm#849icG)cvl0QOPkCIzG^lOp4#UcNr`VhBp(Ha%8@KPlvT*5u!v_$b#b~%sn3K{mu zaxeD%Q~{;Lw03ZAq(Pc-IVj>n*h3l2{sqioCMGatQY0kx zi`1(WWDQ=;gmLSGptEQ%UFC)th@|71<8eiRtX&Mx@#1q#nMF_BMfQdS>!!Qkx2o}= zuqRi?`UOX5P3fP%M+71Q$ctH4Av}bXED#fQ`KR4!b~60nsAv^*M7c-x`|~B}XIuq% zlqIJOf>WvlhQ@Uw$du|14)tZ?; zPNZ|xZSwp1y+d4sut8E4*l2JWR|~o0A9vD-?zC-w zDc@=wE1YKb*OMSi_Kx}&w;#h3>sHp|8^hnA3w?-WK)X?@Z2dgV7`9Cupf-B2RE4x^ zwlw+~!V9C^tyb`J;m2}ksD`w}G9`yu(^--{SQ+wt^Fu4Li~Fft!3QO`upSkAU?o;# z(1Q%GUVWbbkTK-M=T+ULkk3s6Dc9`G4CO6|=&-S&D+rbJQ$`Y-xL~ol;kc(l)VbU>{&>bV+*?ua;$bnDc29RW+Ig16)Vf6=L|fMR_P2b7>6}0 zdlB#-gj|j*C~M=F^2=K*k~=tl6YM3SXXi&K-`EvEXnWz&4D-^hQRBJI3gKKDj^6|> z*WhHSim1qAffNt60Mve9lfw^+&0bx-AM0%j>QP3%W=S@(l=(nrJ678mRQ(#+sI@d{ zdb#5fo#T;hK7xJ=M58wZf|?DHwD%!OZ3JrTGV5#{cfQwuiMvz%!CQ}CubJ7`z?@rSF<+KHNV2goc)a6hP0oHB@3LLKSH2w{um&J*z1Ka2 zLIR>lvOvh>Oxe%?3A@v<_T|}${zf_&@C~^FCo#jB(W9VLO?DX{)n(BQ0(V0`mI|9Y z#U3WwxixJkU_NTvA>5q(A@r2dnEXJp#6B=pww$XGU}~1~c``UKqQb=^*2P|4Dq*_! zhY^i61Sy%T5$Td0O6^C>h(xVvT!}Y##WeT8+s+Uuz=7)~V$>!zU;%d>H)rm*6^IrsCma%|cifwDLk_ z!^W2voQ)D;I$=v2E>iSaBw!d7aD+|LWl2iD!cBw`Q5p1~fk_xGiPi8e^mY&#viTAk zmaKL8m;JQ4bY(n6uBZt02z#noMMxTfF-RzjKre-c+@B)#J3pN-Zv7F}JtAwNk3j?OkpVCL6W1)Q$FLAj zGI!tX;g`O{%pt=0|q54Jyj##w*4e*|_;Us2Tn?!#^R(>u}|FAw1G_ z#wQsagnj9$TAC`2B_XgB$wNq~Sxgl?#0+QWWcB{G`c6~&SosbtRt}Tukw`TQ!oG1= zYyL(y<;Wh+H24>=E}Gs=Hs2%fg;&Qdvr74{E!R?Bd zIRQ?{{xkLJ_44P@y3^#(Be%(pk%$liKbUUo76wSoVfJmt9iTKL3z{uW6L&?jYg>EY zsx{kRiW@q%<$VZvbS(TKKTO4{Ad6l^IeY(F^3}=mX9|FZmQ`~RErNxlBPl3ast}W$T4V?SW=6kIGn@-^`qJv| zZXwhK4Kl1a4E}nLI`rdOi?^pd6;LZ-|8G&INHgOeC5q{_#s+SXb0r(;5ryHFsoTJD zx$VtNDh=-Tx3t!NTlk=hgAaSM)#U}e>_-Ex(|JoX*hWmBPPdTIa-2(BIOUJ|Iddy| zwY*J%z%W$}*;uSoB!BIJB6N6UhQUIQE_yz_qzI>J^KBi}BY>=s6i!&Tc@qiz!=i?7 zxiX$U`wY+pL|g$eMs`>($`tgd_(wYg79#sL4Fo+aAXig?OQz2#X0Qak(8U8^&8==C z#-0^IygzQfJG4SWwS5vko2aaOJn*kM+f1-)aG{T43VJAgxdP(fJ4&U{XR90*#a)G8+clOwdF?hJ?D) zmxu>0>M|g_QRHe_7G|q6o`C>9x4xd$Gl7lAuR~+FtNid=%DRsnf}YI*yOToWO%xnP zY*1G5yDnTGv{{xg5FhWU65q3-|-(+-rJ2WCeSJn(7Az>ej4Jp9+l-GyZ_| zJ8}>iA4g|}q1AhEEv#uWR&$g&Uyht?fVU(qk(j?^D`))s>oG08pow!f>P1u71P%oL2)UC4GeS87&G?{)NE;D=my1Q9{~;y zJULE=bG6jXE28Y11YmoZoo945`MM*`v%5b=_02*0cwzDve#3(4M}NPt`)?SCa|7*q z-94ks(R6WH-l9fE4m4}10WSu&O`|;ZCIT%vL$_pbABY!}s33@~gIvZ0H4co|=_-T$ zF#lC7r`89_+RL9wYN=E3YwR?2{$^ki(KKd>smX(Wh*^VmQh|Ob5$n_%N{!{9xP~LJO0^=V?BK8AbCEFBhDd$^yih$>U z(o{RReCU{#zHSEavFNdc8Yt<%N9pd1flD{ZVSWQu*ea1t#$J5f6*6;tCx=&;EIN^S}*3s%=M#)`~=nz!&Q0&{EP|9nzWyS<#!QxP;!E8&3D}?QKh^ zqGum|+;xu9QE=F#fe2ws5+y1Igr&l`fLyLKry=1}(W+2W`waeOR`ZXlW1B{|;4sE3 zn^ZVlR11hiV~p<~TaSen8I~ay#7Ql=-_|U@$8yjZsZ=Vi+^`JV2+kn+oiSUi%omO_+7}saXnJ9 z5ETilbag(g#jZPopCgJu+n@(i7g}3EK2@N zd64$77H5a`i%b%a^iRjMaprwzWz(`=7E6QY)o)gek7H)yZ-BLw^6FAoHwTj9nJtWc ztKaytMlWGLg29W{?gr|rx&snb@XyvR_}x3fmC>d=-nQp5ab3*whTw}DfUcKlMDDx` z-%?ek^*|Kqooy#>2lfklZ|jN4X$&n6f)RNNPl(+0S>t(8xSeOGj~X0CGRrWmm(WXT z))DDW_t&y$D#2`9<-+JT0x1==26*gpWPV~IF=rePVF%e-I&y$@5eo~A+>yZ&z6&7> z*INESfBHGNegTWga&d@;n;FSCGyW?}e_Qw#GTLHo*fWxuuG@I~5VA!A1pOdRTiPA~ z^AGe(yo=9bwLJD}@oDf$d+34~=(vIuPtOKiP}obDc|?@hY}J*@V|UynBeAkYa?S{@ z_f$U=K+>deTAi&=a*xv>Ruyw$UsTWY=Yn=xjf;s)6NQu>_niQ_idmzIwuL`Scf)f= zyzK?D5a5)^D@H&qN%F6Zd0JeXX*Knbe~VLe^gi|?JK67&mB4jrapV-$`hCQT;C{%T z*pjxB+Y|~LD9bmMN%Iq}S$F$x1yWU7@GcR91V8h;!O2I5MN_rq*gRx(k8T!1WSDTp zr9eJO4$~H94aG^6k5p8k=kFJ>4lnY0q_Bsa$@vTRW6uY?slH|Qt)Yu6Yun&pfJ zBi!h;6x?FDs&79#PT*HSCEUsKws#s%TFy*=2PAfb`>gEPBn+D-WdfXA?MkB=<8kb_ z1+4D11mdHG0EcAyg4dneLtfJ8)RyHQl@6hWJNe(d_EjyCHf7%Xsd)S4A-4COz{G@% z5xQ!P>AS@H@;4Ws)N91)3A6PleMe2<& z!(zv#%Uc?N`(Xmm)OJPYt)BM`nRjoWA&P0Yxl@c9Y02zlPH1J5l$nhPrMwu=atkz4 z)a-1+OEL;d@ctx=s<<+3Sv1VYy0RYmiji|#hy$66#`5;u~BkH4^$EGZ-Y4xyZ=%3KuaeLYKAUr$xMtIh_5mga> zPz<#G0mQ7IxEw-yO}BueN}RaFlg$RwCDB)vLF$wDu%qZyLYsPKdcbHD23$qn9i#JFqIo#OK?u7db2-$GatzO!On87%}Br};~#}n zziVB;qf_4(K$u>Qyz$ln_kBGS!CD-t4Y}9oxL@7@Sx*?NOAzdeINUD>Hl#*V%pfA; zSA`==YatS*G*crJ3`3ll4)vKss&)UtY#7ZxiVoG%9(4<%`WWcjX2jV(^g7Yhj+h5J z$5=?S=tuCyEt74^6jo@6y|@~N>&cVfFNtaRl=)Gm!vR;Bc$3-;ySCI$%kdmjQ|si` z{$q_YCe6vjy6re9jGN|`43D``)1PODtz0)vhV4XV36nVpOnMx2uM%qZ<3TtcI%>BQ zf0(J`{JqPPJxw>k#&nIvoZ5e9Sno)B2r+E0G} z@&M|zf4E0Q$O*NBR2I;?i7N} z@2^Su#`%qeX}m3cbSojiLk#84kvW1fICNPS`OyT0SpUoA0(s^2m~J<^eKE!dhJx_N zG_T}0&(<*an>oF=@?6?55g&IxSgY3?7|@pmDRE6gJyJNPH6un~%0hZ@?h=hI6O$b^ z)29#<4$E)cE-5IFbRpk9JVrw$$966UDyw;Iym4OY4Fc!&s1ZH4BJ1-$9<)Zt1c)N- zU^&9hsk6z?3%<9kGKHW|6~k;&cghtWz`oz`_YjVuvy;B;T67=L2c6=8`7WyTBv*QH zNv*bo1#KOk{O&)@&pkd*?v+kcJ8tM>AGx$~WMhH{L40_N=bkrVg+^p!H)IqXCQf2_ z0fPig=8CEo>p4vE(nc^DKbZ|9_Xo}$i4zJ`jVh95; z5%aNP3@``=EJ=Vt9U`y+$YtX;%OPzgZ_3+;+mh{p#W&y4-%%Bf`LhOy-*kB0qnB^m z_nBTz_b?-`F$*ymByshU>D)za2g`0j^ioo;A#QeL@x3@|+_!=YXA5f6Xg(Ack&WOg zJ<2i|Fd6OmyH!@YSMVxb;=M)ZDhBt)4`5T*>cUXWPG#%@$&*>K&u3#|`fm2mj*FKVf?du{xZ}WKWETTFhq6_fO$PS5(ItF=3~pFp~*j z!ys1<4EL1)#{`mz@gW|t-FpPkd%pK)n_Rb)F;z7cQ6dym_>YI3&e!=!m006oS3Mjq{q ze%hNzW=G0jpfl2K(x`CDuZCsJV*hm9T~%5n7R_g}VFpk`G((D^MWVMAmRp--T{`P; zwMgD<;e`fm`g3|fPns|6qnd{|FCHY*YAguXH(?%sx%4+Gu|Y)_8mk4EljxmP+MP`* z`SUbI{TCIN2OV+$y#g->Jqv#$wL;}4xJmah#$0`v^ughM_XjTA$B}ux)JZuY5-GW4 zKy440I+w=ZtE-_i+0xImq}vyzD68?8;94-5L~_O6Ty>X3itdA-x?6P(c4jkr+f!H( zUDeqiG>3bn^Sf8(`_YwqPeJ9&-@OCQZm4X{FfRMeBtN4E9Ca@;GVpU*L>lVb;@=PH zTQvTr?^jKyCKh&ZVOI*<y%T*Aw(XCPrFC=39*y$A`FSzxBiQ#W+uW10d8&gYp4{teh;^p@anft+z$5!Hv&@h0X-@xJG>hbTCxjDwMiWK@1b%8wYL6BrV zT41m}tX8g-`P@vj4T!Mlk8F0S!MA`^J=SCy9-jdwDe^hVDa`WwyI^H@ryt=F5y6>b zT8&iI6&j8edAfX^ycgWbnMZQ26Q~`LmdEScKC8|~$Jgyw(>18NAQ$9AwCRmri!96L zp^)b0P2CR-9S%cG$#rU}MXnx21T#031o>2VrDs@sa-FpjfvgLPW>Q&LHUoNOtmkt# zoDZ=5OGp{^vO~=p29^`aXd8K?(+f-bW`N$U;-o;%f?RcR!k02Nod2h^^8ly%Z67#E zC3|IOuj~^YBO=Fklo@3mvd6I{Z*&FZ>iq* zxh|JuJoo2$p8MJ3zO@dQ;%1#~Mrm48 zB0053{1bDi_a@jo<4!@!`w4}B(&Qb`~IeSBh zu+_yIYl2Wgk+?x4pCmAM>x_SqBPUj#c`C`k>_fp@qPlAAwD$!zOxRkL7;=|nu(#ut zyF^;&hm-D_;ji{d6rOloACu5*NkF4IC3@rifMG(|^Skv$H&^YnYL*rpw=UCi;JOuz zN*NX(7wZXS4tF@6PIWAs%*j!$RoL*3sh)}iry%thDvN5AUM888q_(>|Tzt|Yea3AyMYBgm$H_`F^v2%)bux)3s znFIEBDK;-JS5SH|;1?afJb<*=c5puu=w%tv#ihn*R!^Hd$KWAp4$#`joJ*)$kNtZ z2Al6h>Z>(u?3tmzA4^d+jLKx{97!Pb4;CX&u;M||**7zXI7hO6nrdMx*Xa=|-`#1^ zBQ?Ha&7cd7hN=%y4yUp?zl8~Lo;%mQrDe8!ce-W_K94FFMN*g(w8q-_K5S+c0{o29X&PzpV;UJE^!xnFc%b@>kvW4m#xiOj-L*DadC&2N#0Us z;<-(m1WB7$=j6hjcPC6JB)D3T2#IC`ibu#yi!uK7W2!j|Z>~RaJ*&XXy#ytIk2DIp z5?Qd^s90_?ILjU#>ZWk5HXts}grg_!Gmgm!d?eLGR7xEP zvTCrslV~94ym5_i<5oqy(@@?wN}lIdtiY8=?|Ng!XeYnly`@9wCGx2S$3x|0x8T2h zz7A85Vb2>s44rKpI_4Y7_Pnd2^mYj2%^jM|Du>u4`^Psda^JIP%*DK6bo`Vf&f{!% zDTYCwF5Nhi=)QhU2$@eQv&ZzxsX+Hl+gP6kW|e!n9IU2>Vh~cioI{>4WvR}t*4Hpz z%5z?HjLGoka}Q3AbX9AkY|Yjf^M(>@tBAI9JO5pDCQu0R3Nns>)LC#vB2p96C*?K? zvX$un$sBDx$1=+NNj*@Oa@u*b@O*XBr_sg@8sCUq-|LK!MUmC)epklrv}5O_^<{NP zX16|c$9Wtbks3y7geI^tF5oRZJu;v zwkW8j+8Ccxo9stEDOT_Go&j%$KCgVO7pm+^%PKEPBZqbMw%s@732XS{cX+wCSjH1s z5)bc=g**<^NNsroY` z?}fHHlgu^B?2r{^^gQ&j zbF~T((>|Yg&C5WKL8DCnl1}Z3!YHFW2S1|;Xr0`Uz-;=FxEwYc4QpeAtnm7^f~uzX zl;xA!?>MLR?tL80Iudm;mi{!ewL91KhG7Hsa-XepKi<2mc6%zf0GwtbfJ1Zf-<@Xu z#|XWDzv|04t)&9Id!UxAAkN{t5qC%%8-WV3i;3duS19%m2||Y{!3pR1=g|zQYAMqc zff)_2nj-O4wfxy;UNM?|Uieo!^J$A*uDe>@V(NKH;KS;Y_dtE8${p>RdcrW;=2*fj4~d?OG0l-(g?ik}vz} z)5-wDppVts>K-=|@{=!53?=8)Jw#RGpS_FWpbwtn}{v!JEJ$q-sr7F6&OPBuI# zuVNFMPte79XgEu!P&qRq8u4J>r%$l-IQ00Lin90(_KtC)aR_de zxN=pY2<1b29_^AG2WJIGmmX4rv3$!`l15{e(H!1^+x9voZ6;882YAE12q7+lgy+>) zj|s0CyzI9=Mo!R}&LXB`&DYpZ7c?0r(&KNV+~TULd0y^e;G{KVR4nL0KvU9mr8&$^ zxrM-9P8zE`J?aZ(iB~Rz<{vvnk2HaZU#K$aVFfYnbAXVUOLU#As5JvS%+26 zi$sNuPY}dLGUS$0g&;oBqhzv2dY`l3@6Na403M!Sh${B|7(y|_cONa;6BrtUe@ZzV z7SThtHT8k?Rwc)(Z}@BP#H@JJHz&GR&M=E@P9KJ89yQKmRh&I~%vbL1L-K3E>7>CH z)Y!=jXVb1iPrAoAZZ3}3wU*5~nrV!ZjL5zqJ<@NwjHCZC>68Cc<{&E_#S;E*jOdjtg?uKN|l`P8sjz&Qf7a^z9 z;{3-8T+H4y99_zc;JYIvs!sk$G}` z??mt*Mm9Z@glCZb!X?!xXD-21sFDPEpZOK{sbQseQ$%6~b;n+*z0hRoR}0Pe>B|#t z$XrVcXv8M|q*Z8MY&r9J0A=d^1bHpjrUXu)qEj~$%%=gZp`^~%O*lzxUquG^p6;n; z^(3HL+hx4gRP?4N*b2p9!^|2~rcw3!9nQj$vmZusbXYz_x^AVc`3qBFm(jS9ueU5h z^AnNnbswfQ2Jq=W=T+p-V|nQco@bOAH$pLQZ+BKH8E$iM>IDz z3|wc?QP`yI=X5YTlp8h}%p6{Deq?S0QD$Ug>ih1SdPZg237Rl{S~=Ha4~-ckMoIWMn+X@@`V6 z#HHZj>MQbt$Qqp*9T(cjc^lxZ7UO(>PwzF-qEr(wo`vaulxdall|KP`7p4gd`23&Jy=#sAes*0diLB(U$Nx46VQvP)8idSs8^zaV91xw*O-JMH=)FoJshRob|_)O)ojtfP))WHCr(;*2;VMQ75^ zfN@a^f#o<|*9X;3IcGodLUz-3i~FAu+zI4c5h+nW^h_!^)b*B_xw-l4O$TB(ixaqW ziMoa%i=BeS<-F45kMO;Tw|FWa`G2c!SuOA3CbowPhF6csf1|&qqugUrj;UgGHm| z;j^yoH?MZhR;AYOW_XW2Lg2j%%ejL)B@*bUMD`g<#Z${1+fa57r7X82 zcqY-cfPnK%Y^3@szRner zt)bBToYCph6Jv*W+&t?&9FG4(Iu2w46 z4B#AcFy_^J@f*6<{>CN}Sj969*DYV*e7<61U>GoN{tz!Do90+jApFueVY_IW(MQF; zl?4yA_(MvMwN&pWKVyg{3uU_+y6RMdot2vu%mC?st=N0pf-~JZXE?3JFf)j<{1xsU z`2ephz)#HzsWEP!inHm2hI(V(~@W zY7gGU-lO52cHD&SY)>QHgy$=>^X%u0TQZfCizro!*weMyvZC=;MWOawdAx~`3C*W` z%^#^$uRP;gyqEE0<(i8xcQY$oc+6mY#z{-XFxsO1(cN8Y)>p;^q9|5bk`Z*p|c!?(rErw#y;yT(%@c7trQBv6cj)$3>pI z>tz+;IB?D=aQV=s(n)o63*yn8dX1m7#Z4G{%fF@K2o5n3jxR~mU?nzMi#;}8e#(>{ zy{Z4!AI)jZ8TY;nq1aq}tq;~=zzoTv)er06oeX3;9{uP{LWR*2%9cmE%S^`~!BW>X zn3PZFTf3g*dG68~^1*q@#^Ge(_8puPEFLD8OS|0b2a{5e=N4S%;~f3tC>F6UxK#v9 z)N-#Mv8=ePCh1KsUKD1A8jF_%$MPf|_yCN9oy%*@um6D{w*2|4GY zb}gafrSC+f=b*W{)!a!fqwZ9)K>fk=i4qf!4M?0v{CMNTo2A9}mQzV=%3UT&i{3{W z>ulG#M!K7%jPf6Mjff9BMslgQq3zIogY);Cv3v;&b#;^=sh#(Bn%W)H*bHNaLwdpq z85%fUTUJJNjYO_426T2TBj0D{6t zw&S_HZ|C?pI_2q(9Fas&@uJs6nVX;P*5K#6p|#)_(8PM-{L(;2wl`ma{ZAd5gA)?y z>0GSLoK<*FwW+G8@-M3vcffg7I(qm7lzF)n`Q9iCvp*mn7=|CjlpG{x z&r0n}XLWZ!>=lynUr7D`6n`7a_ZgT< zm!i;&?Fb0Q2QmqmCHfZ7ex=_tU~(7b)L?RIvPyEAU=gLIZ-VTAA~WR00yKyTXg^(G zqWLZJs!FnQYMOH3*fN&Tn(IKMLf{Ki?pRo8zZJ6YVyj)y0^)-sR}2-)%mI(Aw2AgT zbbp1T{qB(OSNJd0cVBH^tI>HR(q+#*lmi@LWe*rZz&M2h1L_=50uZ1e*n#E*`6?aw zj`ka&JpceRGe@}Ey1)Q~O}0qHRg4K_u>4e1arvJ7Q9!=t5AuzG`n=a-f0}{+lnCE#zu$`oVn44eS&T?N*wz~t~E&oQDBrB_MSg z_yVrQehWbD0xHX|v-hpselAu;O7s;P*!uAT`dr~}Lie=tknaGoiU?;*8Cwgala-65 zosOB4mATbdXJFujzgA4?UkCKE093A1KM?W&Pw>A?IACqg1z~IZYkdP70EeCfjii(n z3k%ax?4|rY(87N&_vhsyVK1zp@uils|B%`(V4e3%sj5f|i(eIhiSg-fHK1Pb0-mS^ zeh?WA7#{hhNci5e;?n*iVy|)iJiR>|8{TN3!=VBC2dN)~^ISSW_(g<^rHr$)nVrdA z39BMa5wl5q+5F@)4b%5-> zA^-P20l_e^S2PTa&HE2wf3jf)#)2ITVXzndeuMpPo8}kphQKhegB%QO+yBpDpgkcl z1nlPp14#+^bIA7__h16pMFECzKJ3p4`;Rf$gnr%{!5#oG42AH&X8hV8061%4W91ku z`OW_hyI+uBOqYXkVC&BqoKWmv;|{O|4d#Nay<)gkxBr^^N48(VDF7Sj#H1i3>9138 zkhxAU7;M)I18&d!Yw!V9zQA0tp(G4<8U5GX{YoYCQ?p56FxcD-2FwO5fqyx@__=$L zeK6Sg3>XQv)qz1?zW-k$_j`-)tf+yRU_%fXrenc>$^70d1Q-W?T#vy;6#Y-Q-<2)+ z5iTl6MA7j9m&oBhRXTKr*$3gec z3E;zX457RGZwUvD$l&8e42Qb^cbq>zYy@ive8`2N9vk=#6+AQlZZ7qk=?(ap1q0n0 z{B9Fte-{Gi-Tvax1)M+d1}Fyg@9X~sh1m|hsDcZuYOnxriBPN;z)q3<=-yBN2iM6V A?*IS* literal 0 HcmV?d00001 diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..5f0536e --- /dev/null +++ b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/utilities/on_subscibe-service/java/mvnw b/utilities/on_subscibe-service/java/mvnw new file mode 100755 index 0000000..66df285 --- /dev/null +++ b/utilities/on_subscibe-service/java/mvnw @@ -0,0 +1,308 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/utilities/on_subscibe-service/java/mvnw.cmd b/utilities/on_subscibe-service/java/mvnw.cmd new file mode 100644 index 0000000..95ba6f5 --- /dev/null +++ b/utilities/on_subscibe-service/java/mvnw.cmd @@ -0,0 +1,205 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/utilities/on_subscibe-service/java/pom.xml b/utilities/on_subscibe-service/java/pom.xml new file mode 100644 index 0000000..0cdd2bf --- /dev/null +++ b/utilities/on_subscibe-service/java/pom.xml @@ -0,0 +1,58 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.2.2 + + + com.ondc + onboarding + 0.0.1-SNAPSHOT + onboarding + Onboarding Process + + 17 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.bouncycastle + bcprov-jdk15on + 1.69 + + + com.vaadin.external.google + android-json + 0.0.20131108.vaadin1 + compile + + + org.springframework + spring-beans + 6.1.3 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java new file mode 100644 index 0000000..93e2323 --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java @@ -0,0 +1,49 @@ +package com.ondc.onboarding; + +import org.json.JSONException; +import org.json.JSONObject; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import static com.ondc.onboarding.Utils.*; + +@Configuration +public class AppConfig { + @Bean + public Map keys() throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException { + CryptoKeyPair signingKeyPair = generateSigningKeyPair(); + CryptoKeyPair encKeyPair = generateEncDecKey(); + + Map keys = new HashMap<>(); + keys.put("sign_public_key",signingKeyPair.getPublickKey()); + keys.put("sign_private_key",signingKeyPair.getPrivateKey()); + keys.put("enc_public_key", encKeyPair.getPublickKey()); + keys.put("enc_private_key", encKeyPair.getPrivateKey()); + return keys; + } + + @Bean + public String requestId(){ + return ""; + } + + @Bean + public String ondcPublicKey(){ + return "MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM="; + } + + @Bean + public String gatewayUrl(){ + return "https://staging.registry.ondc.org/subscribe"; + } +} \ No newline at end of file diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java new file mode 100644 index 0000000..95219e9 --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java @@ -0,0 +1,38 @@ +/* + * + */ +package com.ondc.onboarding; + + + +public class CryptoKeyPair { + + public CryptoKeyPair(byte[] publicKey, byte[] privateKey){ + this.setPrivateKey(privateKey); + this.setPublicKey(publicKey); + } + + private byte[] privateKey; + + public byte[] getPrivateKey() { + return privateKey; + } + + + public void setPrivateKey(byte[] privateKey) { + this.privateKey = privateKey; + } + + + public byte[] getPublickKey() { + return publicKey; + } + + + public void setPublicKey(byte[] publicKey) { + this.publicKey = publicKey; + } + + private byte[] publicKey; + +} diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java new file mode 100644 index 0000000..e90a518 --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java @@ -0,0 +1,20 @@ +package com.ondc.onboarding; + +import org.json.JSONException; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +@SpringBootApplication +public class OnboardingApplication { + public static void main(String[] args) throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException { + SpringApplication.run(OnboardingApplication.class, args); + } + +} diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java new file mode 100644 index 0000000..2be6ff3 --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java @@ -0,0 +1,115 @@ +package com.ondc.onboarding; + + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.security.*; +import java.security.spec.InvalidKeySpecException; +import java.util.Arrays; +import java.util.Base64; +import java.util.Map; + +import com.fasterxml.jackson.databind.JsonNode; +import org.json.JSONException; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; + + +@RestController +public class Routes extends Utils{ + private String signMessage; + + @Autowired + private Map keys; + + @Autowired + private String ondcPublicKey; + @Autowired + private String requestId; + + @Autowired + private String gatewayUrl; + private Logger logger = LoggerFactory.getLogger(Routes.class);; + + @GetMapping("/get-keys") + public ResponseEntity> getKeys (){ + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(keys); + } + + @PostMapping("/subscribe") + public ResponseEntity subscribe(@RequestBody JsonNode subscribeBody) throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException, IOException, InterruptedException { + + this.requestId = subscribeBody.get("message").get("request_id").asText(); + this.signMessage = sign( + this.keys.get("sign_private_key"), + this.requestId.getBytes()); + + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(gatewayUrl)) + .POST(HttpRequest.BodyPublishers.ofString(subscribeBody.toString())) + .build(); + HttpClient client = HttpClient.newHttpClient(); + HttpResponse httpResponse = client.send(request, HttpResponse.BodyHandlers.ofString()); + JSONObject responseJson = new JSONObject(httpResponse.body()); + + if (responseJson.has("error")){ + this.logger.info(responseJson.getJSONObject("error").toString()); + return ResponseEntity.status(401).contentType(MediaType.APPLICATION_JSON).body(httpResponse.body()); + } + + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(httpResponse.body()); + } + + @GetMapping("/ondc-site-verification.html") + public ResponseEntity htmlVerify() throws JSONException { + + if (this.requestId.isEmpty()){ + return ResponseEntity.internalServerError().body("Please Set Request ID"); + } + + return ResponseEntity.ok().contentType(MediaType.TEXT_HTML).body( + """ + + + + + + + + ONDC Site Verification Page + + + """.formatted(this.signMessage)); + } + + @PostMapping("/on_subscribe") + public ResponseEntity onSubscribe(@RequestBody JsonNode request) throws JSONException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeySpecException, BadPaddingException, NoSuchProviderException, InvalidKeyException, IOException { + logger.info(request.toString()); + byte[] decryptedData = encryptDecrypt( + Cipher.DECRYPT_MODE, + Base64.getDecoder().decode(request.get("challenge").asText()), + keys.get("enc_private_key"), + Base64.getDecoder().decode(this.ondcPublicKey) + ); + JSONObject response = new JSONObject(); + response.put("answer", new String(decryptedData)); + logger.info(response.toString()); + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(response.toString()); + } +} \ No newline at end of file diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java new file mode 100644 index 0000000..b38a821 --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java @@ -0,0 +1,68 @@ +package com.ondc.onboarding; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.math.ec.rfc8032.Ed25519; + +import javax.crypto.*; +import javax.crypto.spec.SecretKeySpec; +import java.security.*; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +import static org.bouncycastle.jcajce.spec.XDHParameterSpec.X25519; + +public class Utils { + public static CryptoKeyPair generateSigningKeyPair() { + SecureRandom RANDOM = new SecureRandom(); + byte[] privateKey = new byte[Ed25519.SECRET_KEY_SIZE]; + byte[] publicKey = new byte[Ed25519.PUBLIC_KEY_SIZE]; + RANDOM.nextBytes(privateKey); + Ed25519.generatePublicKey(privateKey, 0, publicKey, 0); + return new CryptoKeyPair(publicKey,privateKey) ; + } + + public static CryptoKeyPair generateEncDecKey() throws InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + KeyPairGenerator kpg= KeyPairGenerator.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME); + kpg.initialize(256); // 32 Byte or 256 Bits + KeyPair kp = kpg.generateKeyPair(); + return new CryptoKeyPair(kp.getPublic().getEncoded(),kp.getPrivate().getEncoded()); + } + + public static String fromBase64(byte[] src){ + return Base64.getEncoder().encodeToString(src); + } + + public static String sign(byte[] privateKey,byte[] message) { + // initialise signature variable + byte[] signature = new byte[Ed25519.SIGNATURE_SIZE]; + + // sign the received message with given private key + Ed25519.sign(privateKey, 0, message, 0, message.length, signature, 0); + return fromBase64(signature); + } + + public static byte[] encryptDecrypt(int mode, byte[] challenge_string,byte[] privateKey, byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + KeyAgreement keyAgreement=KeyAgreement.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME); + X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey); + PublicKey publickey = KeyFactory.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME) + .generatePublic(x509EncodedKeySpec); + PrivateKey privatekey = KeyFactory.getInstance(X25519, BouncyCastleProvider.PROVIDER_NAME) + .generatePrivate(new PKCS8EncodedKeySpec(privateKey)); + keyAgreement.init(privatekey); + keyAgreement.doPhase(publickey, true); + byte[] secret = keyAgreement.generateSecret(); + SecretKey originalKey = new SecretKeySpec(secret , 0, secret.length, "AES"); + Cipher cipher = Cipher.getInstance("AES", BouncyCastleProvider.PROVIDER_NAME); + cipher.init(mode, originalKey); + return cipher.doFinal(challenge_string); + } + +} diff --git a/utilities/on_subscibe-service/java/src/main/resources/application.properties b/utilities/on_subscibe-service/java/src/main/resources/application.properties new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java b/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java new file mode 100644 index 0000000..162295c --- /dev/null +++ b/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java @@ -0,0 +1,13 @@ +package com.ondc.onboarding; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class OnboardingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/utilities/ondc-crypto-utility-master/.idea/.gitignore b/utilities/ondc-crypto-utility-master/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/utilities/ondc-crypto-utility-master/.idea/compiler.xml b/utilities/ondc-crypto-utility-master/.idea/compiler.xml new file mode 100644 index 0000000..505c2c3 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/.idea/compiler.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/encodings.xml b/utilities/ondc-crypto-utility-master/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/utilities/ondc-crypto-utility-master/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml b/utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/misc.xml b/utilities/ondc-crypto-utility-master/.idea/misc.xml new file mode 100644 index 0000000..897a30e --- /dev/null +++ b/utilities/ondc-crypto-utility-master/.idea/misc.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/vcs.xml b/utilities/ondc-crypto-utility-master/.idea/vcs.xml new file mode 100644 index 0000000..b2bdec2 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/Test.java b/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/Test.java new file mode 100644 index 0000000..289fe59 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/Test.java @@ -0,0 +1,42 @@ +package org.ondc.crypto.util; + +import org.bouncycastle.math.ec.rfc8032.Ed25519; + +import java.security.SecureRandom; +import java.util.Base64; + +public class Test { + + + public static void main(String[] args) { + CryptoKeyPair signingKeyPair=CryptoFunctions.generateSigningKeyPair(); + byte[] privateKey = signingKeyPair.getPrivateKey(); + System.out.printf("Private Key: %s \n",Base64.getEncoder().encodeToString(privateKey)); + System.out.printf("Public Key: %s \n",Base64.getEncoder().encodeToString(signingKeyPair.getPublickKey())); + + byte[] signMessage = Test.sign(privateKey,"IND|ONDC:RET10|sellerApp|std:080|ref-app-seller-staging-v2.ondc.org".getBytes()); + System.out.println(Base64.getEncoder().encodeToString(signMessage)); + } + +// public static void vLookUp(HashMap payload){ +// String message = String.format("%s|%s|%s|%s",) +// payload.get("domain") +// } + public static CryptoKeyPair generateSigningKeyPair() { + SecureRandom RANDOM = new SecureRandom(); + byte[] privateKey = new byte[Ed25519.SECRET_KEY_SIZE]; + byte[] publicKey = new byte[Ed25519.PUBLIC_KEY_SIZE]; + RANDOM.nextBytes(privateKey); + Ed25519.generatePublicKey(privateKey, 0, publicKey, 0); + return new CryptoKeyPair(publicKey,privateKey) ; + } + + public static byte[] sign(byte[] privateKey,byte[] message) { + // initialise signature variable + byte[] signature = new byte[Ed25519.SIGNATURE_SIZE]; + + // sign the received message with given private key + Ed25519.sign(privateKey, 0, message, 0, message.length, signature, 0); + return signature; + } +} diff --git a/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class b/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class new file mode 100644 index 0000000000000000000000000000000000000000..f3523071ff15c9a2308f5eaffd0d183529f16bf4 GIT binary patch literal 4741 zcmb7IX?PRY6+O?gJ+c^sF{{`Dgn&09FmVDlC0N1^jt#ho7#o_p z=t|SHq$KIS?|YN9wINRF-n8kyrcIM3O}e+g+po*lujkE-#*(b0;j=Bxyt(h*d(OS@ z-aCHezYkspa2@^@LInZ}DpgdWTA=QvHmOBYnw5+k8aZj`If3fkre)^#2m~4$2NVPa zRyjghL!YqC+*BkkFO0*Ql}L|=ph$HK1RBzIGBT2$u=FWi%jQx>WL(RQMhrb-pU`)1 z+tC{7O0>4MZQmug)T&sBMFKUJaVi&`${AUKs)pmy#(@w*SgfKRO9U1t4a=~#oY6lq zk}~yPV~RT{)x%%u+A@KS(rVgD=n>tX%H-0KiJX~=#GGr&_iLsd!cwe|a90W_+?}_w zO2uld5va_XNlT#CQ|v02Zmd&r71ooGNy9cz&~{#g=6f2CDcC5`IuG?p-H2rD^rV?E z>`2t%Bj)hY?=1$gNuVMc3t=<1C}>d8h$eyMWk@F50t=ExF27fxrJ-*wWbvGBTFH(^ zcgYV>Ub-WM4G2g(TUA_(2z671FivO(-1M}uB$ z+i<;t8&vGXE`fE$n7n}8{CR zPvnjT=)uhjdR6q{fWV4kb-o-CP+^y)rxQj(B4|7wm7W|@(T^9pPy20il7~cK&3t?A zBVwSzxHNb~U}cFdUnYbB991wVqc=n@q}-|e!J>}Nq-_}EhQ%V$c?F>=tD-}}ae-@! zUCCxxE(Y7S?eYNAW}HhQ9K)^h1TP9<7%x$vNe@TnA)$D;rsvW&PtD#da4_N@fH@6} z_b?JF44e>Hn9q}ZWN#=vIgaO^yYtUuzI+k%sKDkjp!<7c@tviplekrSF{UDg@q%pi z1HSXh-0%ZUa05uI$l#^SDS1R#e@b-`O@}-#1IVh#VS?2&k?tSWvdpx`a>B<-vt4SC z`(LKwluUA;Ms^U}$SJr@;Hsh|b7*v*dSnK1hMlOhD;~lWULljU4PCJ8jRap=FdgOMddYn~CQvUMHD*Jr8Yz=R;xsIGmlu z8&uqZH#(eko0gVhiKNp!y+OQ*buZf2+1u3`-P*RjHH7oHOTk;D%NJNQinHT@kmntDa31%lxL5Z7D%;2!xf;9;Z&&aR74O8m1U5J>SY|q+k7_ob zN8+r|3C&K#+>N73l;KcZdVIR>(Qe3I;OY2%{K(kGG?=4p5Moq%s-1mH1V+W5_zI4PnWw2Q@ zt>sWc4J_8rp~I7-hU&we2lpK!$TcoDKiPOr{5gzrp^SgNIbR%)vKM9Yg@XdOe7pYh(({i-#4rIXxC2{YERz&iU*fw5&mRTof5lja zN2y&O}oC!q1H}gsBlhb2Ovg;>k$Cp#^u)x(t72#kyKB15H zb1EV=1%lu4sHGY3y-FIzwrjlt+)uZDD z8h<#iF?xP_6QnQ7uo{*#_>yfo^D?&^IKVpbkRhuacXC_w@c8j86NHsChO^GtD4>oN z_4L&a_daA&=Qn)vUw>*|Ul!O>60T=y;N0%zA}z9fm+bPV9m?gi*b(%Kiyu_4@zFC% zR&$wMgpf&KQr1|mb0#Q8!9zkJZ-?$RfMvxpF=v_0`5A$x;_~YNn#-j)r;!5o{TGyI zN*gowYgu;pd><`rE-YYdVz$9qGLh|zA`6=#*@LTY^s%Zw| zen-Wp`6(X*Tksivs;&S&i_h_{2KV89uE@=Ipprj8(=3#s8PxRFt$!%kCqE7}HBUor z4zvU=qHY#ThgzCvu>9cG`zT!jX<;250j@`ot*{om_!hVuD{v#%qiEpND=jxsdk`D( z06x#VTCBwv@I~6L$4X4|s)CXgn88KTP{TL8OP*hY)E(fC`ntW+l|XZ#`LgsR+%ji> zp(8O&Dn?KT-Lbdc-Q`%}cG`K+u~$XgvyQzQz9v58S-IJ>qBaqxG;tAYB{CPE%ix&; zy{e-_>Qz0x^2)_ggD;WQ3WwDTL@h(xS%39KT=Os%&SC@EZN7+>qxG$F@w(oo#ezHA zo2Id+Ptr@aqnEH>fENcZ;jkbp%O%)=L-r~L6zriv+=V5$K&tL0t@kj%_c{(Pr@_^H zcf5=*Q*H}$<}3IrVSdfgAeP|kyjVyj-@v!b@EhPKY&MeS8Cj2DNirlGf2dv~))4z;1 z8VUyk;o#-^(=&K^drkdmY4P^=B5Ym)@i(Z8Xx5CN9GuE zljHC7B; literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class b/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class new file mode 100644 index 0000000000000000000000000000000000000000..0e3e6a87407f1cee431c9b9d09644ca7cf96d63b GIT binary patch literal 796 zcmah{%TC)s6g^`cr*REQL!hPf71Tv=s(Jyt0*fHAA!?DRkgBX4W2HmgI5G|rf7MDn zq%Qgad{o7`Vb<#sFdM)cnnWrCCvswIy{VmC_5eHX)w-p5^S4zH$L49b*3&V@Lhef%ojQ(~g zlnE)I3ift-7%Nn}dKiBkfA7cH=dhnJQ}3oxm>h(emh&WO=U?@)!rSiub$p$ z^50#c?6)s4`_nWmajnDVI?uI%3KlR&XPz_jrf9=5UhqT!ag3l6$v}(oOT3zl3AoE$ z$v;Ew2LlTN?wDlL0D48i1W?J(XGS<~v0Ah^e)}A?TWa#I0H12w24S(Nx}oG4A~N{( hR3eRsMAoJf;q#eBr16l*28nF`gGk|xqH7|(c@1Izd0qej literal 0 HcmV?d00001 diff --git a/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties b/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties new file mode 100644 index 0000000..5af20f4 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties @@ -0,0 +1,4 @@ +#Created by Apache Maven 3.9.6 +groupId=org.ondc +artifactId=ondc-crypto-util +version=0.1-GA diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file mode 100644 index 0000000..4c1ad80 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst @@ -0,0 +1,2 @@ +org/ondc/crypto/util/CryptoKeyPair.class +org/ondc/crypto/util/CryptoFunctions.class diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file mode 100644 index 0000000..f9d72a4 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst @@ -0,0 +1,2 @@ +/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java +/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst new file mode 100644 index 0000000..4c3c6df --- /dev/null +++ b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst @@ -0,0 +1 @@ +org/ondc/crypto/util/CryptoTest.class diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst new file mode 100644 index 0000000..8e67e07 --- /dev/null +++ b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst @@ -0,0 +1 @@ +/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java diff --git a/utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class b/utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class new file mode 100644 index 0000000000000000000000000000000000000000..1868aa2d886f69ccbbdea592a9193352792c061f GIT binary patch literal 6543 zcmdT}d3;<|75;8AlQ%ORD1-(`2{43~q@n2mEd`QNY(fjANgA6FDWTMtnVZRLCNtBS zH)&IZDvAqBtAIc&vM(YElqHQoQP~PDi=v>2f~W}MjvJs-zWbJ0vWdT+{z3ceTkbpe z+;h+Q&Uen8?t1V3hXBkI-T+Eas=*V47i9wbtkDPca9mHs!pnQs$cQOWw!laj=0bte z+F4yb_ylIPCo_g=49ZY%Jh?8E>ZnmB~WrmCSP2QUIj67PPyd`f;hnc4SMnCq!z8cDd z*bmc+tnC=em~wzdCbLviVNW%Z;dah5Ia}%jjXvxzaN3Fgvp)eGh)NC9gE$CP0{dC! z7OyFwrIZEn1dXa4yP;WK0UUxuHH3mV4AlZNCUMb{Y$Bq(ni1GPCKEEPo3g|9{4zPz zt{Z8ABWh>0OrpY(qbp`m3Ex7e*ovq&)X)&>UcPLV4@U@08<3fd9+M$68S0T%fMqm* zTFlZ=7sQd6El~ZR7ZTVjCQSxmkhXF;0Z;9$?xq0dAgtl2AdXgw3Q%VUTENF?O+!S3 z^3U8L=HXb*RXF3f+U}_ek~ zI7h>Y0tbu+S5wxAQ#gPHDD~kZwA^3qI-$CuT8%da(TtOs5_&2{%>wn~g>+1m9nEz5 z5`mKH*-F)^K`g~-+>4oXw>*uZ8*LQlv~Y|5YPECS%%)|?vZW2nHM9ruQLJ#?XXR28 zQ)m7>fdJjNI1x#5LjqN<;sTKw&ez5OI&r#&t{^^!GXxH_EEq>nU~g$D?93UwKjSd2 z$!F3ge>H*cL|xhJ!&%JEa{~bdqO*fotpaa>Bij=ih0wIQys-dY z&WK|4^GJ$qGDgBCqc2g6&YX|*$w+@_U7s}j=w(wMNXaxE=q7}bad@6%*+eEAiI6UO zv+?+l51(X?1$;Q4d_QKM%_eR*DnhX=w>y6TTG0rKqervPmjlCA|`E~ zvh(UXfkXV&&P*8{SLOzSo5W>NaJ~ZA^Kas|{MBhEi`$En_7(z&eDO8fmiMj;164Y{ zuDX@m1-y!Yh~RHp)oD15X0C` zj*?EU6;*aOv&dK9;zrK(;Q@ieKL7}Q*g?S@?A+Yz(=&alw_?hzOQ!qz=)<=Ol>$^K z5f$|B2JtW+DL`LST<@2s@~h&Rg6y|L*=Uu}$M~()DfUXVFynR#ROYLojX$-Rj9Tpa zB$x76_ZsPpxjJgZ*t%K6yBRp;%m`b(!ttl+WVJ%5RXJ1bDTlXb1r8efDVNBs6wT~= zOg&+CDdJ=+(9GIKFSHm5*_IvXk?BsoC(e=bmSjYacj;+Ey*q;*v(F$W9yVEPq#97R z2ZyN+)M<)Fbyus~EGA%5scKC7nbvmKHDfZxjudrkPRv-H^^eO4ziiUIl^UW{v+dTRb_%Sn>Ng$@X`eLY(%+YPENz0*-saX zwIw^Uk-kOoSdz2)1`1^VA~172+4gjDknLx>K=f|{b;Y6?mbwBHI`~>3{|`n&$>(U^ zwxV5+MhU_K!FL>cbAn6B+%Y}g6i-I_JB$soK=z+(DvFdg>Cw>|8K%P67O+W~Vu95> zq?Pq#=FhVptdV2f5k3SulG$`bE@44uqUKL|bJVf|!KDcvVVdKrZ6R zKg9EV6L^7YN|c(CUdnhmwE1pKEw32H0qU+fclADkgImVfjhJSVZwf<%@Y4#wo>LmvL|et@Xp`m{4Y=Eu+>QPprI~ zD(jU+lvp)_kI(lgv!eemb9!^;tQyZ8ci(*!tMCkCP4UJpYb!iku(vXDfJWYmDe5uF zN6!e>R;bGe)~QgILWMHH(={*yKFs9l{|KJBYZ=r!j?6|4n}NAF3XM319sOJ^<2lj5 zvFyR-<6azx2ho6CJZ(LP6Y&!)#M?MYRPk)rj76dcO=1n2MUp4F4Lq5hk5k1aYEW>Q zXG6k)OO?prNBA*eQzQEDA~9Klx#BEpe2F&h!ejU;enuF*%$WzEWDnJOH3T%&YM7(p z6{1wb&-rmGC%(%2FR1F58SY5nS2-XKIY8X1+~ET8Tqlg~`$oQh7yw!Rsn!o0Cb!y{ z{B$0Z7x1xkTuct)V1}`S5$q%;PbVh35W*S6%=A4Ahz%%n8)T;2b(j* zpo7h@=y$N$C{{bze10r8FZf{CJdfCXjo2(zBw0F>*wjdpZzybj&cWmtoV$7#EuwV< z7q#$TtCCSi?PiYT*xDj3Z>5LdYiyFevcao%c`G;Y0OqW$^lry(4P|O* z0^a=w^;MSfQcQ=g0e9pKsF`d#ciCdfhRMY4rdYjN?Ow&d#akJn$@aJLIhfxp_GKqY zB!_u6wORO5VjH-Kh`*SKzl4b2gz4B!sY{9c%lP$j%5UL}E6B%JkwLeTf3N0`T-WeN zs_U2+*E1Jxz((ANoA`G(ZpK@<1@H2h7r)2ss!wOn-6w&!>yiQArP$w^@Q~C{yv#Z2Y_zj;*_+#NV zD?>`LR9uTU$=)8W{W5;bCofmujo*>m%PbzB3(p>IhChwlJYEZ-VUuT%xCvTr%%*oT zJRcOt|DG<|hxb3=Pu$#J@pl%ScgJJ?3z=R2aNg%|?1_&FaQ1{kM)6mr*iJ`Bvz1X6zFleNEm%~syi;+R1p!stT?pjj@1e#`WEE zFt!d)rR57WFW8Rle<~2o4DBTmM?ynV$1UgrgJrj1l$|5Xu-x;CUpA_~T{N=6dbR3U zzFl@af$oBIq-**zZxIIN;d+r%+SG70w17DL${6(ar<-oylPBluQTk zk%mDX5Aaan_P-elq-5Z5w@h%9lp<#imTI1Z{Du4Un8A>SVI3nF73ge0j5)3-n#TeQ znGjpOhl9GUuqfthasHvtIO%U!4~w={FHZ^+Iwn=-f}{lJuP9#}j|H-8o68qlo6Fg` zot53mi3?8_i_%@JR4zRKXl`P5;=+~3V`il?7M_fGzF8pQv9qahRe9qqh9qY2M8n5A zW>u8BBEAtP&I~M_`_fBd4)YoobbJEV^qq#Kv@1OpLCj;d3dE@^l|5KeN~!fs8_MSZ1@FTc+n1rBO2d z6GK{tdu+{4Jf1REj;3a2CZDP+YdXHfx(v575~=uNwYsR+tH zL8~?XE6Ws~t9IWZjgVV#dsj*F6?0Ux46P|cmUS!8nzJ3bSuGt(ch@{Da;GC#w#?$5 z>DubMwi)wJY<7Hachewpz$D&Mo;IZCnFZ2m-dWsS-r8V;hM*eejeZi9pnwBawbIS)gz{zj zOfVzm%T?EstF}@pp*WALN)XW39L~XP(eyk?ep;>Tai2vQ;XDRnU_#N%=N`Wdz6IY+ z!&eZ$a1p@^KGiWeh+p!lhX&Zk*ZfN00N-#&U49LYb-s75q2)#{(X#OxogH^#zaz3A zy+-foCGO`h@#uxx9(%VheH(j7T?h}#uEJ=KM-RAYcO$0PRqP$aTVnre^zSvf1+)aH!^RK-M_-h zdRzLpcuqYwh6(bEk?1ICeEAofF3H;OI&@#a+mYIpMUoPL}~hs z6YCKq?OJH1aIm1!jpG1OLQRJnj+f-9aCEdiQ=y|H(UG?*a(?uE#8hB0$kaVT8^?so ljEcfrfp0FjDg;rQ81W>C5`oSA2u|^e? Date: Wed, 21 Feb 2024 17:39:35 +0530 Subject: [PATCH 171/228] feat: on_sub java util --- utilities/on_subscibe-service/java/.gitignore | 3 +++ utilities/on_subscibe-service/java/README.md | 0 2 files changed, 3 insertions(+) create mode 100644 utilities/on_subscibe-service/java/README.md diff --git a/utilities/on_subscibe-service/java/.gitignore b/utilities/on_subscibe-service/java/.gitignore index 549e00a..ea7b7ee 100644 --- a/utilities/on_subscibe-service/java/.gitignore +++ b/utilities/on_subscibe-service/java/.gitignore @@ -18,6 +18,9 @@ target/ *.iws *.iml *.ipr +*.mvn +mvnm +mvnm.cmd ### NetBeans ### /nbproject/private/ diff --git a/utilities/on_subscibe-service/java/README.md b/utilities/on_subscibe-service/java/README.md new file mode 100644 index 0000000..e69de29 From 9d2cbc0a94e806f491a4f8c249bc68364b8b17df Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Wed, 21 Feb 2024 17:42:57 +0530 Subject: [PATCH 172/228] feat: on_sub java util --- .../java/.mvn/wrapper/maven-wrapper.jar | Bin 62547 -> 0 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 - utilities/on_subscibe-service/java/mvnw | 308 ------------------ utilities/on_subscibe-service/java/mvnw.cmd | 205 ------------ 4 files changed, 515 deletions(-) delete mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar delete mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties delete mode 100755 utilities/on_subscibe-service/java/mvnw delete mode 100644 utilities/on_subscibe-service/java/mvnw.cmd diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index cb28b0e37c7d206feb564310fdeec0927af4123a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62547 zcmb5V1CS=sk~Z9!wr$(CZEL#U=Co~N+O}=mwr$(Cds^S@-Tij=#=rmlVk@E|Dyp8$ z$UKz?`Q$l@GN3=8fq)=^fVx`E)Pern1@-q?PE1vZPD);!LGdpP^)C$aAFx&{CzjH` zpQV9;fd0PyFPNN=yp*_@iYmRFcvOrKbU!1a*o)t$0ex(~3z5?bw11HQYW_uDngyer za60w&wz^`W&Z!0XSH^cLNR&k>%)Vr|$}(wfBzmSbuK^)dy#xr@_NZVszJASn12dw; z-KbI5yz=2awY0>OUF)&crfPu&tVl|!>g*#ur@K=$@8N05<_Mldg}X`N6O<~3|Dpk3 zRWb!e7z<{Mr96 z^C{%ROigEIapRGbFA5g4XoQAe_Y1ii3Ci!KV`?$ zZ2Hy1VP#hVp>OOqe~m|lo@^276Ik<~*6eRSOe;$wn_0@St#cJy}qI#RP= zHVMXyFYYX%T_k3MNbtOX{<*_6Htq*o|7~MkS|A|A|8AqKl!%zTirAJGz;R<3&F7_N z)uC9$9K1M-)g0#}tnM(lO2k~W&4xT7gshgZ1-y2Yo-q9Li7%zguh7W#kGfnjo7Cl6 z!^wTtP392HU0aVB!$cPHjdK}yi7xNMp+KVZy3_u}+lBCloJ&C?#NE@y$_{Uv83*iV zhDOcv`=|CiyQ5)C4fghUmxmwBP0fvuR>aV`bZ3{Q4&6-(M@5sHt0M(}WetqItGB1C zCU-)_n-VD;(6T1%0(@6%U`UgUwgJCCdXvI#f%79Elbg4^yucgfW1^ zNF!|C39SaXsqU9kIimX0vZ`U29)>O|Kfs*hXBXC;Cs9_Zos3%8lu)JGm~c19+j8Va z)~kFfHouwMbfRHJ``%9mLj_bCx!<)O9XNq&uH(>(Q0V7-gom7$kxSpjpPiYGG{IT8 zKdjoDkkMTL9-|vXDuUL=B-K)nVaSFd5TsX0v1C$ETE1Ajnhe9ept?d;xVCWMc$MbR zL{-oP*vjp_3%f0b8h!Qija6rzq~E!#7X~8^ZUb#@rnF~sG0hx^Ok?G9dwmit494OT z_WQzm_sR_#%|I`jx5(6aJYTLv;3U#e@*^jms9#~U`eHOZZEB~yn=4UA(=_U#pYn5e zeeaDmq-$-)&)5Y}h1zDbftv>|?GjQ=)qUw*^CkcAG#o%I8i186AbS@;qrezPCQYWHe=q-5zF>xO*Kk|VTZD;t={XqrKfR|{itr~k71VS?cBc=9zgeFbpeQf*Wad-tAW7(o ze6RbNeu31Uebi}b0>|=7ZjH*J+zSj8fy|+T)+X{N8Vv^d+USG3arWZ?pz)WD)VW}P z0!D>}01W#e@VWTL8w1m|h`D(EnHc*C5#1WK4G|C5ViXO$YzKfJkda# z2c2*qXI-StLW*7_c-%Dws+D#Kkv^gL!_=GMn?Y^0J7*3le!!fTzSux%=1T$O8oy8j z%)PQ9!O+>+y+Dw*r`*}y4SpUa21pWJ$gEDXCZg8L+B!pYWd8X;jRBQkN_b=#tb6Nx zVodM4k?gF&R&P=s`B3d@M5Qvr;1;i_w1AI=*rH(G1kVRMC`_nohm~Ie5^YWYqZMV2<`J* z`i)p799U_mcUjKYn!^T&hu7`Lw$PkddV&W(ni)y|9f}rGr|i-7nnfH6nyB$Q{(*Nv zZz@~rzWM#V@sjT3ewv9c`pP@xM6D!StnV@qCdO${loe(4Gy00NDF5&@Ku;h2P+Vh7 z(X6De$cX5@V}DHXG?K^6mV>XiT768Ee^ye&Cs=2yefVcFn|G zBz$~J(ld&1j@%`sBK^^0Gs$I$q9{R}!HhVu|B@Bhb29PF(%U6#P|T|{ughrfjB@s- zZ)nWbT=6f6aVyk86h(0{NqFg#_d-&q^A@E2l0Iu0(C1@^s6Y-G0r32qll>aW3cHP# zyH`KWu&2?XrIGVB6LOgb+$1zrsW>c2!a(2Y!TnGSAg(|akb#ROpk$~$h}jiY&nWEz zmMxk4&H$8yk(6GKOLQCx$Ji-5H%$Oo4l7~@gbHzNj;iC%_g-+`hCf=YA>Z&F)I1sI z%?Mm27>#i5b5x*U%#QE0wgsN|L73Qf%Mq)QW@O+)a;#mQN?b8e#X%wHbZyA_F+`P%-1SZVnTPPMermk1Rpm#(;z^tMJqwt zDMHw=^c9%?#BcjyPGZFlGOC12RN(i`QAez>VM4#BK&Tm~MZ_!#U8PR->|l+38rIqk zap{3_ei_txm=KL<4p_ukI`9GAEZ+--)Z%)I+9LYO!c|rF=Da5DE@8%g-Zb*O-z8Tv zzbvTzeUcYFgy{b)8Q6+BPl*C}p~DiX%RHMlZf;NmCH;xy=D6Ii;tGU~ zM?k;9X_E?)-wP|VRChb4LrAL*?XD6R2L(MxRFolr6GJ$C>Ihr*nv#lBU>Yklt`-bQ zr;5c(o}R!m4PRz=CnYcQv}m?O=CA(PWBW0?)UY)5d4Kf;8-HU@=xMnA#uw{g`hK{U zB-EQG%T-7FMuUQ;r2xgBi1w69b-Jk8Kujr>`C#&kw-kx_R_GLRC}oum#c{je^h&x9 zoEe)8uUX|SahpME4SEog-5X^wQE0^I!YEHlwawJ|l^^0kD)z{o4^I$Eha$5tzD*A8 zR<*lss4U5N*JCYl;sxBaQkB3M8VT|gXibxFR-NH4Hsmw|{={*Xk)%!$IeqpW&($DQ zuf$~fL+;QIaK?EUfKSX;Gpbm8{<=v#$SrH~P-it--v1kL>3SbJS@>hAE2x_k1-iK# zRN~My-v@dGN3E#c!V1(nOH>vJ{rcOVCx$5s7B?7EKe%B`bbx(8}km#t2a z1A~COG(S4C7~h~k+3;NkxdA4gbB7bRVbm%$DXK0TSBI=Ph6f+PA@$t){_NrRLb`jp zn1u=O0C8%&`rdQgO3kEi#QqiBQcBcbG3wqPrJ8+0r<`L0Co-n8y-NbWbx;}DTq@FD z1b)B$b>Nwx^2;+oIcgW(4I`5DeLE$mWYYc7#tishbd;Y!oQLxI>?6_zq7Ej)92xAZ z!D0mfl|v4EC<3(06V8m+BS)Vx90b=xBSTwTznptIbt5u5KD54$vwl|kp#RpZuJ*k) z>jw52JS&x)9&g3RDXGV zElux37>A=`#5(UuRx&d4qxrV<38_w?#plbw03l9>Nz$Y zZS;fNq6>cGvoASa2y(D&qR9_{@tVrnvduek+riBR#VCG|4Ne^w@mf2Y;-k90%V zpA6dVw|naH;pM~VAwLcQZ|pyTEr;_S2GpkB?7)+?cW{0yE$G43`viTn+^}IPNlDo3 zmE`*)*tFe^=p+a{a5xR;H0r=&!u9y)kYUv@;NUKZ)`u-KFTv0S&FTEQc;D3d|KEKSxirI9TtAWe#hvOXV z>807~TWI~^rL?)WMmi!T!j-vjsw@f11?#jNTu^cmjp!+A1f__Dw!7oqF>&r$V7gc< z?6D92h~Y?faUD+I8V!w~8Z%ws5S{20(AkaTZc>=z`ZK=>ik1td7Op#vAnD;8S zh<>2tmEZiSm-nEjuaWVE)aUXp$BumSS;qw#Xy7-yeq)(<{2G#ap8z)+lTi( ziMb-iig6!==yk zb6{;1hs`#qO5OJQlcJ|62g!?fbI^6v-(`tAQ%Drjcm!`-$%Q#@yw3pf`mXjN>=BSH z(Nftnf50zUUTK;htPt0ONKJq1_d0!a^g>DeNCNpoyZhsnch+s|jXg1!NnEv%li2yw zL}Y=P3u`S%Fj)lhWv0vF4}R;rh4&}2YB8B!|7^}a{#Oac|%oFdMToRrWxEIEN<0CG@_j#R4%R4i0$*6xzzr}^`rI!#y9Xkr{+Rt9G$*@ zQ}XJ+_dl^9@(QYdlXLIMI_Q2uSl>N9g*YXMjddFvVouadTFwyNOT0uG$p!rGF5*`1 z&xsKPj&;t10m&pdPv+LpZd$pyI_v1IJnMD%kWn{vY=O3k1sJRYwPoDV1S4OfVz4FB z$^ygjgHCW=ySKSsoSA&wSlq83JB+O-)s>>e@a{_FjB{@=AlrX7wq>JE=n@}@fba(;n4EG| zge1i)?NE@M@DC5eEv4; z#R~0aNssmFHANL@-eDq2_jFn=MXE9y>1FZH4&v<}vEdB6Kz^l)X%%X@E#4)ahB(KY zx8RH+1*6b|o1$_lRqi^)qoLs;eV5zkKSN;HDwJIx#ceKS!A$ZJ-BpJSc*zl+D~EM2 zm@Kpq2M*kX`;gES_Dd1Y#UH`i!#1HdehqP^{DA-AW^dV(UPu|O@Hvr>?X3^~=1iaRa~AVXbj z-yGL<(5}*)su2Tj#oIt+c6Gh}$0|sUYGGDzNMX+$Oi$e&UJt3&kwu)HX+XP{es(S3 z%9C9y({_fu>^BKjI7k;mZ4DKrdqxw`IM#8{Sh?X(6WE4S6-9M}U0&e32fV$2w{`19 zd=9JfCaYm@J$;nSG3(|byYDqh>c%`JW)W*Y0&K~g6)W?AvVP&DsF_6!fG3i%j^Q>R zR_j5@NguaZB{&XjXF+~6m|utO*pxq$8?0GjW0J-e6Lnf0c@}hvom8KOnirhjOM7!n zP#Iv^0_BqJI?hR5+Dl}p!7X}^NvFOCGvh9y*hgik<&X)3UcEBCdUr$Dt8?0f&LSur ze*n!(V(7umZ%UCS>Hf(g=}39OcvGbf2+D;OZ089m_nUbdCE0PXJfnyrIlLXGh2D!m zK=C#{JmoHY1ws47L0zeWkxxV=A%V8a&E^w%;fBp`PN_ndicD@oN?p?Bu~20>;h;W` ztV=hI*Ts$6JXOwOY?sOk_1xjzNYA#40dD}|js#3V{SLhPEkn5>Ma+cGQi*#`g-*g56Q&@!dg)|1YpLai3Bu8a;l2fnD6&)MZ~hS%&J}k z2p-wG=S|5YGy*Rcnm<9VIVq%~`Q{g(Vq4V)CP257v06=M2W|8AgZO0CC_}HVQ>`VU zy;2LDlG1iwIeMj?l40_`21Qsm?d=1~6f4@_&`lp~pIeXnR)wF0z7FH&wu~L~mfmMr zY4_w6tc{ZP&sa&Ui@UxZ*!UovRT})(p!GtQh~+AMZ6wcqMXM*4r@EaUdt>;Qs2Nt8 zDCJi#^Rwx|T|j_kZi6K!X>Ir%%UxaH>m6I9Yp;Sr;DKJ@{)dz4hpG>jX?>iiXzVQ0 zR$IzL8q11KPvIWIT{hU`TrFyI0YQh`#>J4XE*3;v^07C004~FC7TlRVVC}<}LC4h_ zZjZ)2*#)JyXPHcwte!}{y%i_!{^KwF9qzIRst@oUu~4m;1J_qR;Pz1KSI{rXY5_I_ z%gWC*%bNsb;v?>+TbM$qT`_U8{-g@egY=7+SN#(?RE<2nfrWrOn2OXK!ek7v`aDrH zxCoFHyA&@^@m+#Y(*cohQ4B76me;)(t}{#7?E$_u#1fv)vUE5K;jmlgYI0$Mo!*EA zf?dx$4L(?nyFbv|AF1kB!$P_q)wk1*@L0>mSC(A8f4Rgmv1HG;QDWFj<(1oz)JHr+cP|EPET zSD~QW&W(W?1PF-iZ()b|UrnB(#wG^NR!*X}t~OS-21dpXq)h)YcdA(1A`2nzVFax9rx~WuN=SVt`OIR=eE@$^9&Gx_HCfN= zI(V`)Jn+tJPF~mS?ED7#InwS&6OfH;qDzI_8@t>In6nl zo}q{Ds*cTG*w3CH{Mw9*Zs|iDH^KqmhlLp_+wfwIS24G z{c@fdgqy^Y)RNpI7va^nYr9;18t|j=AYDMpj)j1oNE;8+QQ)ap8O??lv%jbrb*a;} z?OvnGXbtE9zt;TOyWc|$9BeSGQbfNZR`o_C!kMr|mzFvN+5;g2TgFo8DzgS2kkuw@ z=`Gq?xbAPzyf3MQ^ZXp>Gx4GwPD))qv<1EreWT!S@H-IpO{TPP1se8Yv8f@Xw>B}Y z@#;egDL_+0WDA)AuP5@5Dyefuu&0g;P>ro9Qr>@2-VDrb(-whYxmWgkRGE(KC2LwS z;ya>ASBlDMtcZCCD8h+Awq1%A|Hbx)rpn`REck#(J^SbjiHXe-jBp!?>~DC7Wb?mC z_AN+^nOt;3tPnaRZBEpB6s|hCcFouWlA{3QJHP!EPBq1``CIsgMCYD#80(bsKpvwO)0#)1{ zos6v&9c=%W0G-T@9sfSLxeGZvnHk$SnHw57+5X4!u1dvH0YwOvuZ7M^2YOKra0dqR zD`K@MTs(k@h>VeI5UYI%n7#3L_WXVnpu$Vr-g}gEE>Y8ZQQsj_wbl&t6nj{;ga4q8SN#Z6cBZepMoyv7MF-tnnZp*(8jq848yZ zsG_fP$Y-rtCAPPI7QC^nzQjlk;p3tk88!1dJuEFZ!BoB;c!T>L>xSD<#+4X%*;_IB z0bZ%-SLOi5DV7uo{z}YLKHsOHfFIYlu8h(?gRs9@bbzk&dkvw*CWnV;GTAKOZfbY9 z(nKOTQ?fRRs(pr@KsUDq@*P`YUk4j=m?FIoIr)pHUCSE84|Qcf6GucZBRt;6oq_8Z zP^R{LRMo?8>5oaye)Jgg9?H}q?%m@2bBI!XOOP1B0s$%htwA&XuR`=chDc2)ebgna zFWvevD|V882V)@vt|>eeB+@<-L0^6NN%B5BREi8K=GwHVh6X>kCN+R3l{%oJw5g>F zrj$rp$9 zhepggNYDlBLM;Q*CB&%w zW+aY{Mj{=;Rc0dkUw~k)SwgT$RVEn+1QV;%<*FZg!1OcfOcLiF@~k$`IG|E8J0?R2 zk?iDGLR*b|9#WhNLtavx0&=Nx2NII{!@1T78VEA*I#65C`b5)8cGclxKQoVFM$P({ zLwJKo9!9xN4Q8a2F`xL&_>KZfN zOK?5jP%CT{^m4_jZahnn4DrqgTr%(e_({|z2`C2NrR6=v9 z*|55wrjpExm3M&wQ^P?rQPmkI9Z9jlcB~4IfYuLaBV95OGm#E|YwBvj5Z}L~f`&wc zrFo!zLX*C{d2}OGE{YCxyPDNV(%RZ7;;6oM*5a>5LmLy~_NIuhXTy-*>*^oo1L;`o zlY#igc#sXmsfGHA{Vu$lCq$&Ok|9~pSl5Q3csNqZc-!a;O@R$G28a@Sg#&gnrYFsk z&OjZtfIdsr%RV)bh>{>f883aoWuYCPDP{_)%yQhVdYh;6(EOO=;ztX1>n-LcOvCIr zKPLkb`WG2;>r)LTp!~AlXjf-Oe3k`Chvw$l7SB2bA=x3s$;;VTFL0QcHliysKd^*n zg-SNbtPnMAIBX7uiwi&vS)`dunX$}x)f=iwHH;OS6jZ9dYJ^wQ=F#j9U{wJ9eGH^#vzm$HIm->xSO>WQ~nwLYQ8FS|?l!vWL<%j1~P<+07ZMKkTqE0F*Oy1FchM z2(Nx-db%$WC~|loN~e!U`A4)V4@A|gPZh`TA18`yO1{ z(?VA_M6SYp-A#%JEppNHsV~kgW+*Ez=?H?GV!<$F^nOd+SZX(f0IoC#@A=TDv4B2M z%G-laS}yqR0f+qnYW_e7E;5$Q!eO-%XWZML++hz$Xaq@c%2&ognqB2%k;Cs!WA6vl z{6s3fwj*0Q_odHNXd(8234^=Asmc0#8ChzaSyIeCkO(wxqC=R`cZY1|TSK)EYx{W9 z!YXa8GER#Hx<^$eY>{d;u8*+0ocvY0f#D-}KO!`zyDD$%z1*2KI>T+Xmp)%%7c$P< zvTF;ea#Zfzz51>&s<=tS74(t=Hm0dIncn~&zaxiohmQn>6x`R+%vT%~Dhc%RQ=Cj^ z&%gxxQo!zAsu6Z+Ud#P!%3is<%*dJXe!*wZ-yidw|zw|C`cR z`fiF^(yZt?p{ZX|8Ita)UC$=fg6wOve?w+8ww|^7OQ0d zN(3dmJ@mV8>74I$kQl8NM%aC+2l?ZQ2pqkMs{&q(|4hwNM z^xYnjj)q6uAK@m|H$g2ARS2($e9aqGYlEED9sT?~{isH3Sk}kjmZ05Atkgh^M6VNP zX7@!i@k$yRsDK8RA1iqi0}#Phs7y(bKYAQbO9y=~10?8cXtIC4@gF#xZS;y3mAI`h zZ^VmqwJ%W>kisQ!J6R?Zjcgar;Il%$jI*@y)B+fn^53jQd0`)=C~w%Lo?qw!q3fVi{~2arObUM{s=q)hgBn64~)W0tyi?(vlFb z>tCE=B1cbfyY=V38fUGN(#vmn1aY!@v_c70}pa(Lrle-(-SH8Nd!emQF zf3kz0cE~KzB%37B24|e=l4)L}g1AF@v%J*A;5F7li!>I0`lfO9TR+ak`xyqWnj5iwJ$>t_vp(bet2p(jRD;5Q9x2*`|FA4#5cfo8SF@cW zeO{H7C0_YJ*P@_BEvm2dB}pUDYXq@G1^Ee#NY9Q`l`$BUXb01#lmQk^{g3?aaP~(* zD;INgi#8TDZ&*@ZKhx$jA^H-H1Lp`%`O{Y{@_o!+7ST}{Ng^P;X>~Bci{|Qdf1{}p z_kK+zL;>D30r6~R?|h!5NKYOi6X&I5)|ME+NG>d9^`hxKpU^)KBOpZiU^ z;|SzGWtbaclC-%9(zR-|q}kB8H&($nsB1LPAkgcm+Qs@cAov{IXxo5PHrH(8DuEMb z3_R#>7^jjGeS7$!`}m8!8$z|)I~{dhd)SvoH9oR9#LjO{{8O&r7w{d9V1z^syn&E6 z{DG0vlQF_Yb3*|>RzVop^{$mWp|%NDYj@4{d*-@O^<(=L=DMFIQHEp-dtz@1Rumd; zadt^4B#(uUyM6aeUJkGl0GfaULpR!2Ql&q$nEV^+SiDptdPbuJ=VJ)`czZ@&HPUuj zc5dSRB&xk)dI~;6N?wkzI}}4K3i%I=EnlKGpPJ9hu?mNzH7|H0j(mN3(ubdaps3GM z1i+9gk=!$mH=L#LRDf4!mXw0;uxSUIXhl|#h*uK+fQPilJc8RCK9GNPt=X^8`*;3$ zBBo77gkGB5F8a8)*OR10nK&~8CEMPVQyhY>i`PS{L^-*WAz$ljtU%zlG1lm%%U4Zw zms0oZR8b|`>4U1X*9JLQQ>m9MF5%ppoafz^;`7DbmmIENrc$hucekkE4I83WhT%(9 zMaE;f7`g4B#vl(#tNP8$3q{$&oY*oa0HLX6D?xTW3M6f<^{%CK4OE1Pmfue`M6Dh= z&Z-zrq$^xhP%|hU&)(+2KSSpeHgX^0?gRZ5wA8@%%9~@|*Ylux1M{WQ4ekG(T+_b` zb6I)QRGp%fRF)^T?i^j&JDBhfNU9?>Sl6WVMM%S?7< ze|4gaDbPooB=F4Y=>~_+y~Q1{Ox@%q>v+_ZIOfnz5y+qy zhi+^!CE*Lv-}>g^%G=bGLqD(aTN;yHDBH#tOC=X02}QU~Xdme``Wn>N>6{VwgU~Z>g+0 zxv0`>>iSfu$baHMw8(^FL6QWe;}(U>@;8j)t)yHAOj?SdeH;evFx-kpU@nT>lsrUt zqhV}2pD^5bC4786guG1`5|fK@pE6xcT#ns)vR|^?A08G62teHaE&p`ZrCBj_Swt*~dVt=5*RK6Y{% zABqK$X59BnrK3r3u=wxklRnA1uh+q`?T0kE1YhvDWF4OY#<(+V|R@R%tdkq2huF(!Ip+EpZF3zr*|9pmKHPo)Cu z;H+^s&`Ql}u=Jt~ZWj`bAw|i-3#7(2WuRU3DU{BW8`?!O?YO1M$*MMTsaEM!5Jyp~ z!gp6yR4$O%wQ8%dyz43ZPeoJwy;o;yg=S0^Y}%|)to>=N^`!3VMf1~}OZ`Dl$q&|w z9$!i3!i1uAgPTuKSWdBrDr*N$g=E#mdqfj*h;Z}OG`{n245+g;IKfdn!&gF2OtHaD zyGDzj@@d2!P(_Ux)3v;1ABTj__{w*kaRF-1YVU`})Acgk?(T*1YqEve3=5)8bkZK* z!Tus*e$h@^u z>#zV0771Bix~r&h2FJ9)%N{>s>?2tk1$bId)1#G;OKgn-U8jUo^AK;Hu)hQEi}swD(264kAS-SBCD$R(Ro0rh8~Le zzRwxbz_JHDbD+hTX15AWmVw!#rC)-zeZahQQmo6FG1)ah3uuyIuTMof}RO!`Y3^Fxn_-G$23RDOh(@NU?r6`*S?#E50)w zpcsgDZ-iO{;EesgDQq9;p*C#QH(sp~2w^zAJWaUL%@yo)iIL6y8;e_}=dwQc%k%;H zFt5lenH*`}LWd+fPqi;exJeRZgl&nLR%|a!%1x0RQ54cgyWBYrL>sskcAtPxi&8c( zw_K?sI*3n%S;lKiYpveBN08{rgV&-B1NN5Jiu07~%n#%&f!(R(z1)xsxtRBkg#+Lv zh21zX?aYDd_f}qdA`Os*j!eC<5)iUJ&Twj7?*p%vEOGElGhpRZsccM!<k}DeC;TY;rULQs3e}lZyP#UVb=6 zB$Dkm2FaHWUXr7<{R&46sfZ)&(HXxB_=e`%LZci`s7L6c-L7iF&wdmTJz`*^=jD~* zpOZ@jcq8LezVkE^M6D9^QgZqnX&x*mr1_Cf#R9R3&{i3%v#}V$UZzGC;Or*=Dw5SXBC6NV|sGZp^#%RTimyaj@!ZuyJ z6C+r}O1TsAzV9PAa*Gd!9#FQMl)ZLHzTr99biAqA(dz-m9LeIeKny3YB=*+|#-Gq# zaErUR5Z*Wh^e<+wcm70eW;f-g=YTbMiDX)AznDM6B73)T4r%nq+*hKcKF?)#vbv?K zPMe=sFCuC*ZqsBPh-?g!m*O`}6<}Pfj}Y1n9|Y@cUdD5GX_)6Sx9pPfS7 zxkt?g6ZwJ+50C7qrh6dMFmr7qah`FskT_H=GC92vkVh$WfZa2%5L99_DxyM{$#6HQ zx$VR-Wwt!q9JL2{ybEGJr$^?!V4m_BqDqt!mbs=QjHf340+^a{)waVvP0+98(BA$M ztWr&sM=juyYgvf`(SC}+y@QtYgU>0ghJ6VbU}|kEraR&&W%#;!#KI?le%g`e>ZVPiDrneh#&1(Y?uiMo^f5qo@{JEr(p9>8GhDa+PC9yG;lX+D?hQ^fZB&Sdox219zUj_5;+n<0@Wi3@DK`MU8FM!OFJ z8*_mTA-u!Ab#95FRVWTIqAL#BVQGxE_s?>Ql|@0o9vos&r<_4d!+Q6(_270)6#lu$ zV!j$a?_V0I<(3Z=J7C-K0a^Kc1Go9p&T6yQeAD+)dG-$a&%Fo0AOte~_Z&_m2@ue~ z9cKFf-A41Dz31Ooj9FSR`l?H5UtdP?JS=UU$jF#znE1k@0g%K?KQuwZkfDI3Ai)(q z#x_Yo6WR_Y@#6I_02S&NpcP<%sw!!M_3#*8qa+*4rS@x=i{-2K#*Qr)*Q$-{<_(<| z0730e+rubnT38*m;|$-4!1r6u&Ua2kO_s-(7*NGgDTe##%I>_9uW;X__b_k)xlv$; zW%K2hsmr>5e^Z~`tS-eUgWmSF9}Yg8E}qydSVX0nYZMX_x94QK?tw2>^;raVTqstR zIrNAX2`X~|h->dTOb9IrA!i5INpLV}99ES|i0ldzC`;R$FBY5&7+TIy8%GO8SZ37_ zw=^Swk?z+j-&0-cTE|LU0q@IKRa&C6ZlXbSa2vN5r-)*f<3{wLV*uJUw980AFkWN7 zKh{?97GmVu-0rs9FB6ludy|n`gN5p~?y51aJzBg6#+-=0pWdZ2n4xTiQ=&3As-!-6 zFlb|ssAJEJL#s8(=odfz8^9b#@RrvNE4gjuEITzAd7R4+rq$yEJKXP?6D@yM7xZ&^ z@%jnE3}bteJo{p(l`hu`Yvzg9I#~>(T;>c;ufeLfc!m3D&RaQS=gAtEO-WbI+f_#| zaVpq-<%~=27U8*qlVCuI6z9@j)#R!z3{jc>&I(qT-8IBW57_$z5Qm3gVC1TcWJNc% zDk?H3%QHno@fu9nT%L^K)=#sRiRNg|=%M zR;8BE)QA4#Dsg^EakzttRg9pkfIrF3iVYVM#*_+#3X+~qeZc^WQJvEyVlO@9=0pl!ayNOh|{j0j^a z+zi_$_0QKhwArW)sJ$wji;A`?$ecbr?(4x5%2pLgh#wggbt)#T^2R3a9m+>GcrUxU z*u-WTgHAN*e!0;Wa%1k)J_P(Vdp>vwrROTVae@6Wn04q4JL-)g&bWO6PWGuN2Q*s9 zn47Q2bIn4=!P1k0jN_U#+`Ah59zRD??jY?s;U;k@%q87=dM*_yvLN0->qswJWb zImaj{Ah&`)C$u#E0mfZh;iyyWNyEg;w0v%QS5 zGXqad{`>!XZJ%+nT+DiVm;lahOGmZyeqJ-;D&!S3d%CQS4ZFM zkzq5U^O|vIsU_erz_^^$|D0E3(i*&fF-fN}8!k3ugsUmW1{&dgnk!|>z2At?h^^T@ zWN_|`?#UM!FwqmSAgD6Hw%VM|fEAlhIA~^S@d@o<`-sxtE(|<><#76_5^l)Xr|l}Q zd@7Fa8Bj1ICqcy2fKl1rD4TYd84)PG5Ee2W4Nt@NNmpJWvc3q@@*c;~%^Vasf2H`y z+~U-19wtFT?@yIFc4SE_ab?s@wEUfSkOED}+qVjjy>=eac2^S^+|_3%cjH%EUTJ&r znp9q?RbStJcT*Vi{3KDa^jr4>{5x+?!1)8c2SqiCEzE$TQ+`3KPQQnG8_Qk<^)y_o zt1Q^f{#yCUt!1e(3;E6y?>p+7sGAYLp`lA3c~Y`re9q&`c6>0?c0E2Ap5seFv92#X z1Vldj!7A8@8tWr&?%;EBQ_Fwd)8A3!wIx`V!~~h(!$pCy7=&*+*uIzG@*d%*{qG#4 zX0^}}sRN^N=p{w(+yjv%xwb!%lnVTE7l1l6gJwQmq_G83J&Y98$S!r*L8}IiIa2E= zE!0tbOuEDb*No0-KB{zjo1k#_4FHtr{!)>o+Y@bll}Sa6D^xktI0H&l{jKAK)A(iz zB-N00F?~Z}Y7tG+vp)-q*v71(C}65$-=uXx^|R$xx9zZip-V>Hqeyfd(wteM)+!!H z$s+>g4I@+`h2>C|J;PhvtOq)`xm4;CyF}R<)!ma3T{Vf_5|zo;D4YI4ZDBkE(vMeE zb#ZV;n}CgA0w8x!UC2&5Z(K)9bibj#?~>R(72lFx_Am~jS?;7mo~p+05~XGD+(wV4 zEVYnf0N5+-7O+Gc1L!sPGUHv<6=cV8}*m$m`kBs@z zy;goR(?J^JrB7uXXpD00+SD0luk!vK3wwp(N%|X!HmO{xC#OMYQ&a7Yqv-54iEUK4 zVH;)rY6)pUX~ESvQK^w|&}>J{I?YlvOhpMgt-JB}m5Br`Q9X+^8+Xa%S81hO<1t#h zbS+MljFP1J0GGNR1}KwE=cfey%;@n&@Kli+Z5d>daJjbvuO3dW{r$1FT0j zR$c9$t~P50P+NhG^krLH%k}wsQ%mm+@#c;-c9>rYy;8#(jZ|KA8RrmnN2~>w0ciU7 zGiLC?Q^{^Ox-9F()RE^>Xq(MAbGaT0^6jc>M5^*&uc@YGt5Iw4i{6_z5}H$oO`arY z4BT(POK%DnxbH>P$A;OWPb@gYS96F7`jTn6JO@hdM za>_p!1mf?ULJZb1w-+HamqN__2CtI%VK`k^(++Ga0%z*z@k0wYJDqT^)~%|4O299; zh1_iRtc7you(kOK8?Q$R7v-@Qk4+i=8GD2_zI0%{Ra`_prF{+UPW^m5MCA&4ZUpZb z2*!)KA8b--Upp~U%f+rsmCmV~!Y>Gzl#yVvZER2h;f&rkdx{r#9mc8DZMJaQXs?SL zCg3#>xR6ve8&YkP*`Z=lng|Ow+h@t*!Ial*XQg3P;VS8@E1C)VS`?L9N+rxlD7bxC z3@Ag)Vu?#ykY`ND+GvRYTUP&-KDMiqly$Z~uFXt^)4Jjk9RIs*&$?-UPM*d7&m${m zm12kaN3mV1J|c6f$>V+{lvHp~XVW3DU0;cBR>7|)4bo{xa1-ts-lYU-Q-b)_fVVl`EP5X}+J9EzT20x8XIv=m7witdu7!3Lh=KE#OyKpT1GWk{YAo^ny|fvZt<+jmsFs=l*%e& zmRkBt5ccv4O7!HAyv2~rsq*(FmMTm?@TX3&1`nu|7C^F{ad%GLuoX}Rl}6`)uHF_xlx^gVca+mGH4T8u8;q{S*x3=j;kelz^atO~)v!Q_BT z4H6%IA}bvfuk0_vweELeEl8N5w-Q1GF!@f{VKnbyYB2?}d&QvI-j}~RI_+9t9$tC2 z94m=3eLi=sQb^S5;fqP?3aaXc&`}`lq z&M8dOXvxx9Y1^u_ZQHhO+qP}nwkvJhwoz$Mp6Qcq^7M#eWm}!3U@s07hop` zW24|J{t$aB`W>uBTssEvYMyi$hkaOqWh+^(RV_1MYnE0XPgW?7sBDk=Cqs(;$qrPEflqa0ZE?A3cBfW%0RPA235Wb6@=R_d>Sez; z`spwa50bq?-zh+id~Q!T`AYn`$GHzs;jxIw(A1_Ql&f|qP}|bon#H;sjKmSDM!nyn z>bU8l%3DB3F+$}|J^da!!pN|DO!Ndc2J)wMk!+Rr1hes#V}5o(?(yQSphn|9_aU<- zn|nsDS{^x&tweP;Ft`2ur>Koo2IdXJDsr6IN)7vB41Yy-^Wbo9*2th2QA@C zE0-0Gk12YOO?d_Guu6b3&(PIL`d zh4{`k54hu9o%v1K3PGuccez-wdC<&2fp)>`qIIaf)R{5un7-vwm=>LD7ibnJ$|KyE zzw`X*tM0S|V(I3vf454PY{yA5lbE+36_<1kd=&0Xy4jfvUKZ0$Jq!AG4KS7DrE9rph;dK^6*#CIU9qu7 z?)6O`TN&MCWGmUVd1@E2ow2`vZ1A#nGo8_n!dmX77DCgAP1va*ILU+!a&$zdm6Pa6 z4#|*&3dM+r_RJb%!0}7X!An&T4a4@ejqNJ;=1YVQ{J6|oURuj8MBZ8i7l=zz%S4-; zL}=M^wU43lZVwNJgN|#xIfo$aZfY#odZ6~z?aNn=oR1@zDb=a(o3w`IGu&j>6lYxL z&MtqINe4Z>bdsHNkVIu$Dbq0wc#X-xev221e~L zbm8kJ(Xzij$gF4Ij0(yuR?H1hShSy@{WXsHyKtAedk4O!IdpR{E32Oqp{1TD{usJi zGG@{3A$x%R*pp8b$RQo4w&eDhN`&b~iZ2m3U>@9p1o5kXoEVmHX7I6Uw4dn((mFw` zilWrqFd=F5sH$&*(eJB52zaLwRe zz`sruIc=Ck75>v5P5kd>B2u=drvGPg6s&k5^W!%CDxtRO)V6_Y_QP{%7B>E~vyMLG zhrfn8kijyK&bX+rZsnSJ26!j$1x+V!Pyn|ph%sXWr9^f&lf|C;+I^Fi_4;`-LJI&F zr;5O@#4jZX=Yaw0`pUyfF4J8A9wE#7_9!X|_s8~YUzWu&#E^%4NxUA3*jK-F5R3LP2|msHBLmiMIzVpPAEX)2 zLKYjm3VI4r#7|nP^}-}rL+Q4?LqlmBnbL+R8P%8VmV{`wP0=~2)LptW_i682*sUR# z+EifOk_cWVKg-iWr^Qf4cs^3&@BFRC6n0vu{HqZzNqW1{m)3K@gi$i}O(hT`f#bT- z8PqCdSj~FncPNmMKl9i9QPH1OMhvd42zLL~qWVup#nIJRg_?7KQ-g3jGTt5ywN;Qx zwmz4dddJYIOsC8VqC2R%NQ>zm=PJH70kS|EsEB>2Otmtf-18`jUGA6kMZL3vEASDN zNX%?0+=vgsUz!dxZ@~)eU17m4pN3xGC0T;#a@b9Iu0g_v*a3|ck^s_DVA^%yH-wt= zm1)7&q6&Rq#)nc9PQ6DKD{NU=&ul10rTiIe!)x^PS~=K(wX9|?k&{Mv&S$iL9@H7= zG0w~UxKXLF003zJ-H%fGA4Db9{~#p&Bl7ki^SWwv2sfoAlrLMvza)uh;7Aa_@FL4b z4G>`j5Mn9e5JrrN#R$wiB(!6@lU@49(tawM&oma6lB$-^!Pmmo;&j57CDmKi)yesg~P;lJPy9D(!;n;^1ql)$5uYf~f z&GywSWx=ABov_%8pCx=g-gww_u26?5st=rdeExu?5dvj^C?ZZxDv@Si^nX~2qA&K= z2jr;{=L(x~9GLXrIGXs>dehU^D}_NMCMegdtNVWyx)8xHT6Qu!R>?%@RvADs9er;NMkweUBFNrBm1F5e0_>^%CwM6ui}K_MpRqLS0*@lAcj zB6TTCBv>w2qh)qU3*kN+6tPmMQx|5Z0A4n67U-nss90Ec_rDF}r)IR4PE{$8;BSt= zT%6|jyD^(w6a*A5>_|TkMqx~e$n@8{`q?|)Q&Y4UWcI!yP-8AwBQ#P`%M&ib;}pli z9KAPU_9txQ3zOM#(x}*lN8q$2(Tq1yT4RN0!t~|&RdQMXfm!81d0ZuyD}aG3r4+g` z8Aevs3E_ssRAMR+&*Q30M!J5&o%^(3$ZJ=PLZ9<@x^0nb>dm17;8EQJE>hLgR(Wc% zn_LXw|5=b$6%X zS~ClDAZ?wdQrtKcV9>_v1_IXqy)?<@cGGq#!H`DNOE1hb4*P_@tGbMy6r@iCN=NiA zL1jLwuMw&N-e9H(v7>HGwqegSgD{GSzZ@sZ?g5Y`fuZ^X2hL=qeFO(;u|QZl1|HmW zYv+kq#fq_Kzr_LaezT zqIkG6R+ve#k6!xy*}@Kz@jcRaG9g|~j5fAYegGOE0k8+qtF?EgI99h*W}Cw z7TP&T0tz4QxiW!r zF4?|!WiNo=$ZCyrom-ep7y}(MVWOWxL+9?AlhX<>p||=VzvX`lUX(EdR^e5m%Rp_q zim6JL6{>S%OKoX(0FS>c1zY|;&!%i-sSE>ybYX3&^>zb`NPj7?N^ydh=s=0fpyyz% zraFILQ17_9<ettJJt~I+sl=&CPHwz zC9dEb#QFQcY?bk11Y=tEl{t+2IG`QFmYS>ECl;kv=N6&_xJLQt>}ZQiFSf+!D*4Ar zGJ~LFB7e_2AQaxg*h{$!eJ6=smO(d2ZNmwzcy3OG@)kNymCWS44|>fP^7QkJHkE9JmLryhcxFASKb4GYkJ|u^Fj=VdF0%6kgKllkt zC|_ov2R4cJ2QjjYjT6jE#J1J<xaNC>Xm;0SX<`LuW*}*{yQ3c9{Zl=<9NP z^2g5rAdO!-b4XfeBrXa4f{M0&VDrq+ps&2C8FYl@S59?edhp~7ee>GR$zQI4r8ONi zP^OA+8zrTAxOMx5ZBS03RS@J_V`3{QsOxznx6Yt*$IuEd3%R|Ki&zZkjNvrxlPD$m z%K+rwM!`E&Z46ogXCu!3 z8use`FJJ?g_xi?~?MxZYXEu=F=XTC8P3{W*CbG3Wk)^31nD~W>*cJ@W4xg%Qqo7rq z`pUu8wL!6Cm~@niI*YmQ+NbldAlQRh?L!)upVZ)|1{2;0gh38FD&8h#V{7tR&&J}I zX1?;dBqK}5XVyv;l(%?@IVMYj3lL4r)Wx9$<99}{B92UthUfHW3DvGth^Q0-=kcJ1 z!*I9xYAc$5N$~rXV>_VzPVv`6CeX(A_j3*ZkeB~lor#8O-k+0OOYzTkri@PVRRpOP zmBV|NKlJT?y4Q82er)@lK&P%CeLbRw8f+ZC9R)twg5ayJ-Va!hbpPlhs?>297lC8 zvD*WtsmSS{t{}hMPS;JjNf)`_WzqoEt~Pd0T;+_0g*?p=dEQ0#Aemzg_czxPUspzI z^H5oelpi$Z{#zG$emQJ#$q#|K%a0_x5`|;7XGMuQ7lQB9zsnh6b75B9@>ZatHR_6c z0(k}`kfHic{V|@;ghTu>UOZ_jFClp>UT#piDniL(5ZNYXWeW0VRfBerxamg4su5<; z(}Ct2AhR@I-ro0}DdZLRtgI@dm+V`cRZjgV-H+aXm5|Mgz`aZX63i<|oHk-E)cABn z0$NR?(>fla7)Ong28FZSi9Yk0LtYl5lZw5wT!K5=fYT$avgkMKJWx~V#i@7~6_{dM zxDDPIW2l{O2Elv#i^cjYg~lGHRj(W*9gD`(FILKY$R`tL2qo&rtU*c;li!V`O$aV{ z!m|n!FAB2>MR_FVN*Ktv5+2dW4rr3YmfEheyD+48%USM#q6)w%#2}~=5yZE1LLcth zF%VtefH&#AcMx7)JNC$P>~OFuG6sK}F7V$D7m!{ixz&inpAVpFXiu^QruAw@Sc7Y2 z_A^V(2W_+KTGRp2aQSMAgyV#b3@{?5q@hPEP6oF3^}|@8GuD6iKbX;!LI!L=P#Za zL$Zuv#=x3fseRMZ()#SQcXv->xW`C|6quwqL1M&KByBj z2V`}(uL4JB-hUs6304@%QL~S6VF^6ZI=e-Nm9Tc^7gWLd*HM-^S&0d1NuObw-Y3e> zqSXR3>u^~aDQx>tHzn9x?XRk}+__h_LvS~3Fa`#+m*MB9qG(g(GY-^;wO|i#x^?CR zVsOitW{)5m7YV{kb&Z!eXmI}pxP_^kI{}#_ zgjaG)(y7RO*u`io)9E{kXo@kDHrbP;mO`v2Hei32u~HxyuS)acL!R(MUiOKsKCRtv z#H4&dEtrDz|MLy<&(dV!`Pr-J2RVuX1OUME@1%*GzLOchqoc94!9QF$QnrTrRzl`K zYz}h+XD4&p|5Pg33fh+ch;6#w*H5`@6xA;;S5)H>i$}ii2d*l_1qHxY`L3g=t? z!-H0J5>kDt$4DQ{@V3$htxCI;N+$d^K^ad8q~&)NCV6wa5(D${P!Y2w(XF!8d0GpJ zRa=xLRQ;=8`J2+A334};LOIhU`HQ*0v4Upn?w|sciL|{AJSrG_(%-(W9EZb%>EAGG zpDY?z1rQLps`nbCtzqJ#@wxU4}(j!ZQ{`g`g*SXlLah*W9 zyuh)UWoRCknQtd~Lk#BT_qjwj&Kw8U)w=owaJ;A5ae}3)y>{neYNS`|VHJdcSEBF# zBJ6a;T)u;^i#L~LVF-X7!E$SggILXMlsEy~v}K*DM2)f@U~g|Q6I-Pss@)`>fgFWx zsq&7pe!|VA-h;@=fBF{(mR1^{1>ukTYUdyF^#A+(|I_&nm{_xaKn3h4&yMyym2k-wMFg(s@ez=DPmuB%`| z6;e@HQKB(|!PU1sW)W6~x|=8m6rL~4dQ9LTk|RzL-_(_77B4I~ZG=q7K%qHiv!FD8 zmt;Vnhb{ymaydv2V;X-5p zTt2ln?kaB9&(dH_X70^@rrCfz)nwfa9LYTHXO(IPcTEf$QiEhTpl??L+`Eetyqof8 zzl=q)?KdYni!C_9b8Z3xm7r5<5ZG-0uA`u^7Dm7k4mAsQ(rkoWy*^DZJa~#y6+hNG zh?7{D9$a9LS`a@SvZ5?C{JUHovWU9KI}z8YV4pWftx21v*Q;MpU{+b@>Or(}pwO^fu0qA3_k_Bo2}lIxvmMhucG-o>O=+R6YxZ zjs!o%K1AA*q#&bs@~%YA@C;}?!7yIml1`%lT3Cvq4)%A)U0o1)7HM;mm4-ZZK2`Lj zLo?!Kq1G1y1lk>$U~_tOW=%XFoyIui^Cdk511&V}x#n4JeB7>bpQkYIkpGQRHxH$L z%tS=WHC~upIXSem>=TTv?BLsQ37AO88(X+L1bI<;Bt>eY!}wjYoBn#2RGEP49&ZH-Z_}R_JK_ z>o*_y!pOI6?Vf*{x-XT;^(_0}2twfk`*)_lLl0H-g|}BC?dm7CU|^-gNJ~rx z($>97WTKf71$?2|V$Ybpf~Aj@ZZOcb3#uRq51%4^ts-#RMrJhgm|K3QpCsPGW=2dZ zAr5-HYX!D*o#Q&2;jL%X?0{}yH}j*(JC4ck;u%=a_D6CrXyBIM&O#7QWgc?@7MCsY zfH6&xgQmG$U6Miu$iF(*6d8Mq3Z+en_Fi`6VFF=i6L8+;Hr6J zmT=k0A2T{9Ghh9@)|G5R-<3A|qe_a#ipsFs6Yd!}Lcdl8k)I22-)F^4O&GP&1ljl~ z!REpRoer@}YTSWM&mueNci|^H?GbJcfC_Y@?Y+e4Yw?Qoy@VLy_8u2d#0W~C6j(pe zyO6SqpGhB-;)%3lwMGseMkWH0EgErnd9a_pLaxbWJug8$meJoY@o-5kNv&A$MJZ=U z^fXPLqV6m3#x%4V*OYD zUPS&WHikdN<{#Yj|EFQ`UojD4`Zh*CZO4Cv`w^&*FfqBi`iXsWg%%a< zk@*c%j1+xib(4q^nHHO^y5d8iNkvczbqZ5;^ZVu%*PJ!O?X-CoNP*&tOU!5%bwUEw zQN?P*a=KKlu{`7GoA}DE=#nDibRgecw>-*da~7&wgow}|DyCJq!-Lp8a~(zR@tO1 zgu(4s4HptPGn(HmN2ayYs@g+yx1n`nU3KM{tQHhMHBw7f#gwru$=C()`aKZAl^dYc ze7fC)8EZEXOryk6AD&-4L+4cJ&M@3;;{R)mi4=`ti7IZByr^|_HNsjcNFu?mIE)jD za2j)FPwRY!R_YR-P?URm0Pti*e#5jmfK)6EvaKCT{h)kbJl{AGr1Ekt}pG?^e z*botRf-RsB8q10BTroj{ZP**)2zkXTF+{9<4@$aNDreO7%tttKkR3z`3ljd?heAJEe<0%4zYK?};Ur*!a>PbGYFFi(OF-%wyzbKeBdbkjv^i9mn@UocSS z4;J%-Q$l`zb&r*Pb`U;3@qkc=8QaPE9KwmlVwAf01sa*uI2*N`9U^3*1lLsM9dJ(4 zZBkU}os|5YT#Z;PD8xVv!yo$-n{-n4JM5ukjnTciniiT`(cZ6sD6~67e5_?8am%!w zeCLUxq~7x-!Xg#PgKV&caC@7mu<86am{WaXo(lAemt4~I$utSp(URWpYNo$RvU*$N z#%iiA+h`(E;BUg;=I!#EaxO89bUK3*v5Nc3GPmURC5TqzC|))DsFNtJICH6oBW6#q z+B(N{ey+^mk_{!@ z)VhAWXG=_0j|0f9iJ;c404PiIFqK)(AD05Xh`Fk`r$^b`v+>*g+_+h@r)e+ELJ45) z?20~u<}HQyQ5AsBz(teF9!!_GLXnm{5Z0e{Ki*@!=&3x4-RcjBn##DDzHJ|KSZ5(E z9=tFZ)p~-}x%9sCY27)2i>(E-^OiYT?_)a;yXAGR$y+E`myMd;xDA#_Q49t*E}&ql#H~|x z2J2R1_#2lt91NnF!uqW%_=HlbF?A{B{n>}9$g5QF!bh_a7LTU~Jyz}7>W5{_LAov{ zy2_dmGy)d)&7^bJyUjEw%3xj{cuG0Eo zwL*XQB*Oi=r&HIIecC1%lbE;Y-*5|cL955S+2@uR18JDL<0;;Uc2Q9JEyo1R!!sz_ z#BqnkGfbLP#oQJk3y}nwMd(3Tt^PVA#zXnYF7D0W1)#+`i?@cm}fBkKD z+Mpcuim53|v7;8Tv(KraEyOK`HvJq^;rlNzOjIbW&HJDFqW>doN&j7)`RDv#v|PQ+ z03WnB4Y4X@Fe-@%3;He*FjY1MFmkyv0>64Cp~FIDKQTwmFP~_CxZOf{8gPy}I<=JC zo%_bmue&$UU0|GG%%99eI!m#5Y1MD3AsJqG#gt3u{%sj5&tQ&xZpP%fcKdYPtr<3$ zAeqgZ=vdjA;Xi##r%!J+yhK)TDP3%C7Y#J|&N^))dRk&qJSU*b;1W%t1;j#2{l~#{ zo8QYEny2AY>N{z4S6|uBzYp>7nP_tqX#!DfgQfeY6CO7ZRJ10&$5Rc+BEPb{ns!Bi z`y;v{>LQheel`}&OniUiNtQv@;EQP5iR&MitbPCYvoZgL76Tqu#lruAI`#g9F#j!= z^FLRVg0?m$=BCaL`u{ZnNKV>N`O$SuDvY`AoyfIzL9~ zo|bs1ADoXMr{tRGL% zA#cLu%kuMrYQXJq8(&qS|UYUxdCla(;SJLYIdQp)1luCxniVg~duy zUTPo9%ev2~W}Vbm-*=!DKv$%TktO$2rF~7-W-{ODp{sL%yQY_tcupR@HlA0f#^1l8 zbi>MV~o zz)zl1a?sGv)E}kP$4v3CQgTjpSJo?s>_$e>s2i+M^D5EfrwjFAo(8E%(^ROV0vz0o z-cg0jIk24n!wxZainfH)+?MGu@kg$XgaMY-^H}z^vG~XC7z2;p2Kv`b^3S#b5ssMOJ7724v>S36dD zeypxJ<=E~sD4f5wX060RIF-AR0#{Z z=&y$r8A-e6q18lIF{@O9Mi%dYSYT6erw!@zrl=uj>o(3=M*Bg4E$#bLhNUPO+Mn}>+IVN-`>5gM7tT7jre|&*_t;Tpk%PJL z%$qScr*q7OJ6?p&;VjEZ&*A;wHv2GdJ+fE;d(Qj#pmf2WL5#s^ZrXYC8x7)>5vq_7 zMCL}T{jNMA5`}6P5#PaMJDB2~TVt;!yEP)WEDAoi9PUt89S2Cj?+E0V(=_sv4Vn6b z_kS6~X!G;PKK>vZF@gWpg8Zuh%YX^2UYPdCg7?EH#^gkdOWpy(%RnXyyrhmJT~UJw zAR;%Zgb6z(mS+o9MT|Sc6O({!i0pzk;s9?Dq)%tTW3*XdM3zhPn*`z45$Bg!P4xfy zD*{>30*JsSk?bQ-DgG62v>Vw-w`SA}{*Za7%N(d-mr@~xq5&OvPa*F2Q3Mqzzf%Oe z4N$`+<=;f5_$9nBd=PhPRU>9_2N8M`tT<-fcvc&!qkoAo4J{e3&;6(YoF8Wd&A+>; z|MSKXb~83~{=byCWHm57tRs{!AI<5papN(zKssb_p_WT@0kL0T0Z5#KLbz%zfk?f7 zR!vXBs36XaNcq5usS7<>skM_*P$e*^8y1ksiuokbsGFQ_{-8BAMfu!Z6G=88;>Fxt z|F-RU{=9i6obkTa0k~L#g;9ot8GCSxjAsyeN~1;^E=o5`m%u7dO1C*nn1gklHCBUw z;R(LgZ}sHld`c%&=S+Vx%;_I1*36P`WYx%&AboA1W@P;BvuFW+ng*wh?^aH4-b7So zG?9kFs_6ma85@wo!Z`L)B#zQAZz{Mc7S%d<*_4cKYaKRSY`#<{w?}4*Z>f2gvK`P1 zfT~v?LkvzaxnV|3^^P5UZa1I@u*4>TdXADYkent$d1q;jzE~%v?@rFYC~jB;IM5n_U0;r>5Xmdu{;2%zCwa&n>vnRC^&+dUZKy zt=@Lfsb$dsMP}Bn;3sb+u76jBKX(|0P-^P!&CUJ!;M?R?z7)$0DXkMG*ccBLj+xI) zYP=jIl88MY5Jyf@wKN--x@We~_^#kM2#Xg$0yD+2Tu^MZ1w%AIpCToT-qQbctHpc_ z>Z97ECB%ak;R<4hEt6bVqgYm(!~^Yx9?6_FUDqQQVk=HETyWpi!O^`EZ_5AoSv@VbUzsqusIZ;yX!4CsMiznO}S{4e>^0`c<)c~mC#*{90@+T@%EQ~>bovc8n_$bvqkOU7CrYe8uI5~{3O7EijeX`js z-$LNz4pJA7_V5~JA_Wl*uSrQYSh9Wm($%@jowv^fSPW<~kK&M*hAleywHd?7v{`;Y zBhL2+-O+7QK_)7XOJAbdTV-S`!I)t~GE8z+fV7y;wp#!wj75drv;R*UdSh(}u$%{VSd0gLeFp;h6FkiVz%g=EY3G#>RU;alRy;vQmk*| z@x-ba0XKE%IyL4OYw6IXzMiS(q^UDk=t(#XgkuF`{P?=k8k3r)rmhkv`vg@kiWd34 z-~t+1aV3SabTbG=nQYs>3~E<}{5@0g**LAWi*~SfRZhGcgP{e5T!0M7CU}`f@r8xI z0bx%sI!?5);-wG+Mx&S=NRfIi>V-wP(n&$X0Bhd)qI^ch%96s6&u7qpiK8ijA=X_R zk&|9f$GXf-;VgnrxV83Cp-Q!!sHH`5O^o~qZu!xny1t?(Au(EAn)D??v<1Uo;#m7-M@ovk|()C(`o>QMTp}F?> zakm3bHBKUjH-MHXDow7#Z|@wea1X9ePH;%YA)fCZ9-MD)p^(p!2E`aU9nmJlm;CXQ zkx~$WQ`Yq{1h5k>E>Ex{Z=P=)N*0b8_O({IeKg?vqQ)hk=JHe z5iqUKm!~mLP0fnRwkCO(xxTV@&p+o8wdSP$jZofYP}yEkvSc z5yD-^>04{zTP7X44q9Af&-wgt7k|XtncO&L@y-wFFR44RsPu57FRvIBaI^Pqy_*DV z@i13CsaR5@X@xH=NT3}T`_vsy!a02n80eQqya=-p7#YW`Jc0z!QglGg`1zeg6uXwI zsB~hlNMo)kFL(V3Q1<%8yoI6X7ncn-&&Uh3rL@S(6@wKAXt6Wr=a2ObI7}8$D-FoI z>AJA>WsBEMi5ba6JhJ%9EAi&ocd(ZsD|MsXwu@X;2h#|(bSWu@2{+c7soC`%uo{sMYq&Vyufb)?OI59ds)O+kyE8@G z@tlpNr0UO~}qd0HQve6njJ zda2+l$gdX7AvvGhxM6OToCuQ|Zw|9!g1)O+7>~{KNvASjp9#Cqce-or+y5xdzWL3gLWt2oa+T(I+{j(&bF1laUsJB{fOgE-B}qslaS>C z)TjzG8XecbS%a+?yT!0QmTex?E478;D|sL*oS4C-g0Tq(YoH|eyxJ#1j088C|U-w5id`%Sz7X_w#l+U9+)$|2no<}5J zRb_9@0esSr?n}HvVGbD5@$p$8k4?qOe-GNOk3-K^Mw>Xg+drCKi5@$GTeijpI;;IG ziD<&go`ptLC&^<0jw^l0aY?_pUUK+xp#0Bk66iQ29vpR)VBE{JOJ&OL^gKsN<&t<| zCMLTYMSDG5Ie9O>6Dl#T{@cscz%)}?tC#?rj>iwQ0!YUk~R z$rB-k=fa9x&631Z9Mfqj_GRoS1MzqSMEdaZ2!isP19Sr>qG8!yL(WWF)_&{F)r>KnJGSciSp!P0fqHr+G=fGO02Q#9gHK zpwz+yhpC4w*<9JO@#(MdkZcWbdCO5B!H`Z|nV?UtcBo96$BgX+7VYMwp@b-%;BrJu zMd*K!{1txv{kHKPDs9?WZrz_^o1Tq2P=+=|E=Oy4#WE{>9}*9(apqhmE`&AeBzQgQ zELFLCmb~q|6y0FCt|B}*uI*ayZ#6=$BpGtF{Jfye#Q>FZ?BPnk)*Qmd?rNG^tvFUU z_b&antYsZnUR6Q9tQUy81r$&ovT#fy;(Db4F&M*C=KxQgHDrRcVR#d+ z0(D|*9#u`w_%2o3faI{?dNd9$#5nj1PROHNq z7HJ(;7B1ThyM>a@Fo^lJb2ls2lD`}ocREH|5pKN;$>gFyM6k)kZG;lA;@kSJIqUhf zX%dhcN(Jtomz4(rNng&1br3Xx33EvCWz%o8s;SpRiKEUFd+KJ+u|gn|J85dZ)Exc&=V|Ns8Xs#P>qv6PX&VAJXJ(ILZO!WJd0 z`+|f5HrEj~isRN7?dBHotcPI7;6W48*%J(9 zftl1Tr`bKH*WNdFx+h;BZ+`p!qKl~|Zt5izh}#pU9FQKE97#$@*pf38Hr8A+`N+50U3$6h%^!4fBN zjh^cl#8qW5OZbvxCfYzKHuyeKLF4z^@~+oqlz9(Hx8vypIiUlt!(vs}_t#4@nh$s; z>FYERg*KD#Xs+W4q-V-IBQK!)M1)Aa+h+V+is)z!_=gEn&^ci7<DEEmYcoSh?WdXUsP7O4)&lQXA(BVM5jI8s6;mO}94AC0gG(`>|T)yuV1l~i-ejCCt zoejDhX0nrZDP|x9u4zp%S2UeDzV`o#pBGu1tZ-$<9TIbN=ALwhQ0=9S{8#}Uu8n-~ z5~xIvUhLSz@c@0|me$CdZCpZl(vQw@a0Y4^{T0w_>pOkwI^x4KkBf3qGmm)nG|Ps5 z_XTY~^b^mL&_*yjl~RRIi&eS(>y?y}O4-)nWyTEPpQAb#Xz8SnnfIL+nAcNL9nqV9 zRL|eyF)RKI5-kJO6}>Q89XmgY@b1&!JI>g3ryZ@jN2v3vm7O`AL!BTWNouJzV+$+Y zYY}u%i>K6=IYU2O$2TAyVjGt?wgF9xCj;?EK(8fWu!!~48`3u^W$eUlCh*91PLxu1 zRY(F7Q3s7h$Q-p&L$ucN}it*-9KR z_<wHu?!dav0$P+PI3{J8?{+l|n&2YMLV2 z+hRta$A5WpCXl1RNbYBsX8IGX{2v>U|8_I-JD56K|GexW>}F_e_g_1r?08v8Kz{V$ zT=6aGMk>ibvRO@Yrc@ezaD0%ydHkXGHrR{7>q~~tO7ChJflwa4-xL|@#YIJejC5VT zInU4CjQ9V0+lClQY=vh^s4MadwQmk7li{54Y;Ht}gkZOIh9(vfK?3kXLoD72!lHD# zwI-Jg|IhT=Y#s|tso1PWp;|aJ2}M?Y{ETyYG<86woO_b+WVRh<9eJu#i5jxKu(s~3 z4mz+@3=aNl^xt{E2_xewFIsHJfCzEkqQ0<7e|{vT>{;WlICA|DW4c@^A*osWudRAP zJut4A^wh@}XW4*&iFq|rOUqg*x%1F+hu3U6Am;CLXMF&({;q0uEWG2w2lZtg)prt` z=5@!oRH~lpncz1yO4+)?>NkO4NEgP4U~VPmfw~CEWo`!#AeTySp3qOE#{oUW>FwHkZ3rBaFeISHfiVSB7%}M) z=10EZ1Ec&l;4 zG98m5sU!pVqojGEFh8P{2|!ReQ&hfDEH2dmTVkrS;$dN~G2v-qnxn^A2VeHqY@;P} zudZD5vHtVvB*loIDF1M7AEEvS&h0;X`u}!1vj6S-NmdbeL=r{*T2J6^VA7F`S`CDd zY|=AA6|9Tu8>ND6fQhfK4;L3vAdJPBA}d6YOyKP&ZVi%z6{lbkE|VyB*p1_julR^k zqBwjkqmFK=u&e8MfArjW-(Ei8{rWso1vt5NhUdN|zpXqK{ylJ8@}wq-nV~L4bIjtt zt$&(1FTIs+aw}{&0SO4*sa0H2h&7g}VN5uYjfed5h7eGp$2Wu*@m9WIr0kxOc}fX9eOWh zFKfV>+SD$@kESKYm{F*J90XQjr$!<~v(J%&RMuQM+6CkmnYZDGlOUdq}%)VA& zl#acS%XE2KuX~7IamK`og@C`21~*cEEc#PZM6HT*Veb_l&Ej~j0zL7p0Eo`mMu(=X zJ$v;&Lya75I4C^saKROgfi(fdP0C$GM3WyZn%mm3yEI>|S&O(u{{S<}ihUp#`X&_z zmQBma;82#`C;dR5Sx09e07FvtJLhZ{9R~|$FCdU6TDNUwTc9kNct?8e@o2MpQDrkg zN?G+aYtTjiUPA=RX5o{4RYu}6;)ET>TcgL^VpfIpluJ|lQR(_)>6k%L^FZmoK-Wm- zR5qy0P)hm8yvqOL>>Z;k4U}!s?%1~7v7K~m+gh=0c9Ip_9UC3nwr$%^I>yU6`;2kV z-uJ%y-afzA7;BC7jc-=XnpHK+Kf*tcOS>f5ab2&J&5hIOfXzs=&cz|Qmrpu6Z);`R z0%3^dioK5x?o7t~SK7u5m{dyUZ#QUPqBHYn@jETeG>VU=ieZuJ;mm^j>dZM7))cw?a`w8R z%3M0R=kdOt^W^$Kq5Z%aJ(a$(*qFpy^W}Ij$h+Jnmc9eaP(vB@{@8t zz=RQ$x4XYC#enS$fxh@;cSZ|D%7ug;0z{C8I8h{KocN-cyv3UG_nk99UNS4ki^OFkYea`q`rs zG@qdMI;4ogcd5Tr`di1JBg4I*6CFvCID_2SN5&)DZG&wXW{|c+BdQ4)G9_{YGA@A* zaf}o^hQFJCFtzt&*ua~%3NylCjLtqWTfmA-@zw;@*?d&RE3O8G&d;AVC|rZrU}jx# zC-9SF`9;CbQ(?07o8Q9E12vi)EP@tOIYKEKnO@-o!ggkC)^#L-c40iZtb4Y-cS>$I zTn~+>rn*Ts>*y*z^b3-fAlne+M-*%ecrI^rmKAVv23cB`aWD?JDJ5NIafRvRr*~~C z)99Afs`BPK!5BFT)b_^8GyH*{22}yDq;be`GnPl=vW+ITnaqzl(uYOHhXi}S!P+QZ z4SwfEPuu&z4t#?6Zaw}bvN{;|80DfxCTuOdz-}iY%AO}SBj1nx1(*F%3A-zdxU0aj z`zzw9-l?C(2H7rtBA*_)*rea>G?SnBgv#L)17oe57KFyDgzE36&tlDunHKKW$?}ta ztJc>6h<^^#x1@iTYrc}__pe0yf1OnQmoTjWaCG`#Cbdb?g5kXaXd-7;tfx?>Y-gI| zt7_K}yT5WM-2?bD-}ym*?~sZ{FgkQ9tXFSF zls=QGy?fZ=+(@M>P3Y>@O{f44yU^fP>zNzIQ0(&O$JCd_!p?2;} zI6E1j@`DxzgJvqcE@zgapQ?tophO14`=14DUZ*#@%rRi``pi0lkNgidSsHGjXK8gO{drQoNqR&tRjM4>^DtW`)fiRFO4LE=Z+nCBS~|B3gZsh`Y?-$g z@8@Z$D7C!L9l=SWoE;(+*YirPLWvBd$5Ztn3J3EaGM+#pW#@{3%yksGqy(2Bt5PVE zf*fICtPp77%}5j#0G8<=v=)LR>-a3dxja8cy3m$=MZ2#$8mbLvxE%NptMd+L?mG`v zF1cANFv17DqP^P5)AYHDQWHk*s~HFq6OaJ3h#BUqUOMkh)~!(ptZ2WP!_$TBV}!@>Ta#eQS_{ffgpfiRbyw1f)X4S z_iU`lNuTy86;%!sF3yh?$5zjW4F?6E9Ts-TnA zDyx5p1h$Z3IsHv7b*Q{5(bkPc{f`2Wfxg*Z#IvQ;W_q9|GqXGj<@abo)FyPtzI~i25&o zC!cJR%0!}lLf^L2eAfZg7Z69wp{J?D6UhXr%vvAn?%)7Ngct4Hrs@LZqD9qFHYAWy z4l=2LI?ER&$He2n`RiG&nsfLv?8$Cl)&d8a-~-N`I|&EPa@Y=v@>0Gl?jlt>AUY;H z`**5bpS#VGhdp4pKbf3iEF*>-eXg_$bqt5Dc%q0+)R50>zd^l7sN5R5Z)Ut+oz-8_ zJ`Z9HE9(=wRTD)T=%GZTEi9K5naPzlfE$|3GYGLRCLsnqLi8Sc6y&iskqA&Z$#7Ng z7Q@C0)6k;J$TlQ+VKZ5)-Ff_BNoIMm+~!@Cv1yAUI-U!R)LHc@+nSUzo$GlRb+8W< zYPG%NFfr;!(RlnvBbN~~EpT6Xj5*^Z&73tdIQ$LZu`vkfzdTKa5|JJtQ_rm4g$9LO zKtgYVdW=b<2WGM3I_j|Rd8gZ3j;)S#AT(aP^d>9wrtQS_+K>pZDX^?mN!Z>f^jP@1 zlJ;i79_MgOAJa`%S9EdVn>ip{d!k6c5%zizdIoB9Nr!n`*X#%6xP1?vHKc6*6+vKx zmEt|f^02)S_u_wlW_<`7uLQU%{wdH0iojOf_=}2=(krE<*!~kn%==#0Zz`?8v@4gP zPB=-O-W=OO3tD19%eX>PZj3YfrCt0sEjgTd#b$buAgBri#)wW14x7QcHf2Cneuizz z368r7`zpf`YltXY9|2V{stf8VCHgKXVGjv$m!hdDf0gi`(Q!(Pyg~FO28Vr#!BYP| zI)qG2?Ho=1Us9dTml}-ZOR?g5Vk)f+r=dbCN*N1=qNfG>UCLeA8pd3Ub-pRx1b3FA zEn`CIMf`2Mt3>>#3RkE19o}aMzi^C`+Z>8iIPHSdTdmjCdJBtNmd9o0^LrJc9|U9c zD~=FUnSyghk7jScMWT|SHkP(&DK$Z=n&lGm+FDTpGxfoIyKV)H6^nY~INQ#=OtIT! zyB*J=(#oHf=S)MNOncW->!c0r0H#=2QzobO&f@x&Y8sYi-)Ld;83zO$9@nPPhD}yt z{P`*fT@Z(?YAmF{1)C;o?G@dfd2$c+=Av*|;P@Yz1KnclB-Z-fJQ-=+T*g>0B7!g# zQH{dHt_%wj=wlmT&m59)TQ~xK)gB6f^EY$=1zcbGf~Q>p_PzDCHR6lndGmqPY2)&w z$Th^K%1v@KeY-5DpLr4zeJcHqB`HqX0A$e)AIm(Y(hNQk5uqovcuch0v=`DU5YC3y z-5i&?5@i$icVgS3@YrU<+aBw+WUaTr5Ya9$)S>!<@Q?5PsQIz560=q4wGE3Ycs*vK z8@ys>cpbG8Ff74#oVzfy)S@LK27V5-0h|;_~=j1TTZ9_1LrbBUHb?)F4fc)&F7hX1v160!vJc!aRI>vp*bYK=CB(Qbtw7 zDr2O^J%%#zHa7M5hGBh#8(2IBAk}zdhAk$`=QYe^0P6Bb+j5X)Grmi$ z6YH?*kx9hX>KCI04iaM_wzSVD+%EWS)@DR&nWsSBc2VIZ>C(jX((ZiV0=cp}rtTO&|GMvbmE4FpBF5Rd z6ZG=>X&>N3?ZN2^11pXEP4L?XUo`qrwxgQm4X~RCttXmZAhnhu4KDK=VkKq?@@Q_Z za`*xyHrsAEsR zV(7)2+|h)%EHHLD3>Qg{>G|ns_%5g5aSzA#z91R zMDKNuIt@|t?PkPsjCxUy&fu^At*yUYdBV!R_KOyVb?DO&z$GLJh9~b|3ELsysL7U6 zp24`RH+;%C(!bWHtX&*bF!l-jEXsR_|K~XL+9c+$`<11IzZ4>se?JZh1Ds60y#7sW zoh+O!Tuqd}w)1VxzL>W?;A=$xf1Os={m;|NbvBxm+JC@H^Fj$J=?t2XqL|2KWl$3+ zz$K+#_-KW(t)MEg6zBSF8XqU$IUhHj+&VwsZqd7) ztjz$#CZrccfmFdi_1$#&wl~A*RisBaBy~)w|txu1QrvR1?)2mb&m2N$C(5MS%hSX)VJnb@ZGXB5^%(<#1L@ zL^>fBd+dEe`&hxXM<0A9tviIs^BDkByJdc~mtTYr!%F7Q1XnK2$%h$Ob30*hSP$Bt zDd#w{2Z%x^Wpv8!)hm>6u01mY!xmPgwZ#Q0148)SxJc3Udt!-&}eRO^LN ze26pQB!Jhg&Z>#FD>`C`sU44><=v>O>tJdLs!HPpV#AM32^J@Za-9J(CQjKxpzXao zQfRkWP%g9P8XV21MmoHfx{DICLSc*t4qVeQL9t}&Pz0rM}YTba@XsD=XMW@FxFM{QYQJHvM(JsUSa3mcTUl9^qcVA zBveO--fqw%{#QGR1vy;x88+qMcgzmcYc#8U`CPPt6bl?uj%w_`b~9JliftnOa|ziW z|6(q&STs_*0{KNa(Z79@{`X&JY1^+;Xa69b|Dd7D&H!hVf6&hh4NZ5v0pt&DEsMpo zMr0ak4U%PP5+e(ja@sKj)2IONU+B`cVR&53WbXAm5=K>~>@0Qh7kK*=iU^KaC~-ir zYFQA7@!SSrZyYEp95i%GCj*1WgtDId*icG=rKu~O#ZtEB2^+&4+s_Tv1;2OIjh~pG zcfHczxNp>;OeocnVoL-HyKU!i!v0vWF_jJs&O1zm%4%40S7_FVNX1;R4h^c1u9V@f z`YzP6l>w>%a#*jk(Y82xQ@`@L(*zD&H>NY`iH(iyEU5R$qwTKC5jm4>BikQGHp^)u z-RQ`UCa70hJaYQeA=HtU1;fyxkcB2oY&q&->r-G9pis)t$`508$?eDDueFdW=n5hJ z08lH$dKN$y#OEE@k{#|<%GYY=_c~fHfC@pD54KSP9{Ek@T47ez$;m$}iwR}3?)hbkwS$@p2iVH0IM$lB*XYA+#}-re|UNzCE)SOYwy z=Y!fkG4&I%3J(_H#UsV#SjHulRIVcpJ`utDTY{k&6?#fzt~@Om=L(vs6cxAJxkIWI z@H7)f2h%9!jl@C!lm+X4uu;TT6o0pd7 zteFQ(ND@djf#o2kTkjcgT=dHs7ukmP0&l8{f;o3JuHGd2Op*?p7?Ct=jA*tIg{MZk z$2Lsc0e8Tdcwrjx|_Ok?9uB3Il|^2FF%X#ck}WoIvrzQXN%kT$9NI{79Wm~gZ3`8I+O`)`n30feZ( zDO-fl6IG3c^8S;Y_M-)+^CmM0tT^g0?H#>H8!oC8W%oU!~3|DJ?)~LT9*&GAQG13zOGq6gs*={cu|(V7{R$y@{-iV*9q@AD(#Ktb}J&3&k|5Djs$)9WM7!6#EaJ_ilvbfUvyh8c?-{n zfuFrC0u6}UJZ7aj@(cNG_(CKgjQQTA-UK@-MVmick zot}6F%@jhq(*}!rVFp5d6?dg|G}M*moyLriI!PQDI;E1L1eOa6>F9E6&mdLD>^0jJ z09l?1PptuV65gm=)VYiv<5?*<+MH~*G|$~9Z3XEy@B1-M(}o&*Fr9Sv6NYAP#`h{p zbwbUE3xeJ;vD}QMqECN)!yvDHRwb7c1s6IRmW!094`?Fm!l~45w)0X`Hg+6Y0-xf# zSMemBdE)Q=e^58HR{kWrL5-H0X6pDu%o{0=#!KxGp0A;6{N5kI+EoY_eTE%2q|rwm zekNeLY-R?htk!YP2|@dbd8TWG4#G)=bXlE{^ZTb^Q$}Er zz)Fp)ul24tBtQFIegdI37`K$VR3tVdi<(fIsu{#QMx=$&CK9M8oN%3Mk;>ZPd-;Q- zn|sSKSnc-S0yrw#TlA$+p{J~u=u98s>IoL@cNLOxH=+1m?;t1bR$vR=M$US&Z8DO3 z_&zhQuId1$wVNsS=X?&s(ecIi#00o{kuPs6kpYkL$jMyGW8U7mlCVaZeEL=HsIxqm zFRLxWin8B>!Dc#9Z#t0RNQiR-@5J+=;tC7|1D*~rxcwHa5iIVD@99cCFE@BukUC-S z^iJdt?dwU)kH2VY9?|zVShMbZctzFRz5Q4tiXa^>@U%jDYq}$rSyc#p2wXr}mc0qq z^lT>$y)N(Qg0dwmEwTopneoU(y)>Mj+f{iHM0o|>ZtCg-itPj4addYz??aE)Rp&hk z_SI)%XeSf=SjZq18h!Cc>Xy&EynnxdHQ){(x@g|ZA%`3LU^KzX02c5N;F#tEk1)7v z(|V9tO3>?^X|kQ*rRBf4>mWW2$-Lx})|M7z125&VHcxsCqB!<$l1F$zCrJ+nm0f3Z z%Hq^=SKpHyV2@Y*Cu2x>fXC0SscnR*($zEB{KOniJcpn@e`PMH*_Q6*0Z^8RNCEvZ z+UU9!927p9YZ&g=bnUvQUZcdisyn;-4;ACXOe-Xor9K8Qbp{ldE17+G@VQT+9ZJQ*9dZoXfU2ue|mMhrrZk2R7&~YjFW4`BTq45UwVc6JORKU)wBCTanITh0GD}s$`C5pb(9{b9 znwee6j%?-UV)_7opOioCf5@C?@w^@g& z&68+oMmV;5JW@TT63&CSDrfYL2$L)pVseDtAwPwleEM3F^-Ufn3PpfxFmx6o zQ`Wq9x#d$e`VKn5LOXNsrqhGao7~|s(u~drPrZ+;aP!C%z4NskZstCbAibD}O%8Ij zb~C(taxco~WzJLxhL1T}3ctXMbV6}_z=IZN9L0|SxLSe`$X`<)BhM`$1&&)e_}fCh z=idVL<+u6Vn{&ksP*ZLlMo$fC`dtzF_?~L?4Rril2G4%v5^7sUa^&8aMtMX&mtapl zD(dW|cisM3fqMaB`8?QbkyiUl2g>hMB5EoS&IB8TdoC~)b$nT=`%GgU`k-)+8}`)F*~I~DXMaTP%kZftx11~?iALs5J+&Rom#p%Y z>dH}-euH4u=_V3hc6^*2WMtL!9%yRTJ93p}@aV0zdY*?xchFI>m+UivV=;aMFp0P~ zwB8P)wvV6D-GL?6hJ#g7Hy7=2i^&Od#S=j!;Rc_yjO!*4aN7{vqzg2t-R|Dav%_NDk z`H_FVlSi==(~f-#65VmQ{EE92x<03lwo5p)s=ZJ^L7PlS>132Whr zR6v~t(#I+(`usYLCoO;Rt8j&b^5g_xgs*98Gp|N}b>-`HtVm)MscD)71y?(K6DRCZV26RsHPHKk)EKKZA%C99t3$t^B0-k5@?E>A-YMbFe?>ms?J?_guHHNU(;id*>xH zTrtam+Aq?n@-y@uY@A?hy?1qX^eLu_RaH4Ave?A8NapgQF=C%XI7wlcCf4<6BRo_% zBXxxc*A6-3CruF?3i8HOdbc%>N=-iiOF+9HX|ht6SCkz;A^am&qi_I&qk1B(x<=(m z>QG)nswCOLl_1{SZ@_eE#m^qb6#6DoMsB*)`17ui+XvF%(}|J4G$z2G*;E!1ERnAH z@q%=#uV6kBddqy4=g>!VTV)9*1=i{wJ}Ep!I*?)uJdA(LwE?(!?;}_u=^M2NShWC_ z*7l4aBJ=!QVU2-iehgb`$vOI8zkm{W%QO~?xOD;NgI;Iqa3#^$^U5D&McReLe&qs# zR<^@QpR4#W~Laz+QBsPt@3L#KF`Yr8}jgHe;5(cfpQ=;Zjtbt;c%y^#-m=hqOT z;KAYakW+$w0&F}>K10&SiPcD9SrDOuczj@U#W})5jGU-_htU`U6Q%wdy((%?J}y+$ z=$4jw1N nJo)qTxG{D(`3*#8tY|67hJRF;)r6F|#I`Ar6I0aafRa=kr-Z0I^}9xf^u;G5iEQCbpv3b#S#%H|HYHsQaHK$! zU#3Fpz8*^pK%RRmX<_09eIVziB0jOgPgFnI-*QcwEBtBiO#v!>{W1cLNXyw3D9M|A z*oGy(u8BkDA1c;MsXmpK^-~pl=We^RYnhZ4bz*)Q)C2G+E3tgx9PzU0T>c|1ilS!T zyE=bz`=wskDiOi!@!l?Y))#%{FM`}7r~X)i1)1*c6_2Q!_1{)fp%cS|YF+Q-CB%d< z=zYus`Vt@Mx*a7V)=mpLS$-5viaKgNB=+zN657qy0qR94!cTtX-Z%KBCg4OKw7b=t zr=`7q5Ox=lJ%!G5WIyNQC1xpqYU0{!I$hyrk!6%De$gp<_*Gc?ES(OwY8U^)Kjgc{ zSlhpXDb|;{+y9`u{EuMz54rlky2~p6xX2>MV6BZ&k`$q%q7v(xYps2wr9e8^4<;CB zc)eAT~B^rjzO6<4BDDH;il6 zFsM8jL+agQ;zazW(uiQjM%fPf2N~_p{cy29XP11_lQFpt`t#9nlk}>fv((FZt-dBa zuMIc4HmPHW04n0TTG9ug9;&OV9euL$Ib|+M7}}L~z4e%%%b|r~6OQj(S2d7XfYn#xp8;KQ55UYu#gY*De5j6Cc z#R%?rqwpy7I1(kpU7B*Pq=etXeYUn04jg%ZPjYqQNa$==yTG=6KX+=;i2Xg+kjV2T*Gc!(ef z`Q4fR*TA=M5-}z+s%YO+!K{k}S**ic&>o4_Tmv$EQTOp7F6TXPCj-UTXy?OQ=%*y62Qajk{rXbR%jMCOFMiVE3KekQa4xR}B%=iPtd8BXo~q$OX_ zSp910{Ew;m|GATsq_XiJ3w@s(jrj^NDtr(Dp!`Ve!Oq?|EJ9=vY2>IfrV{rT%(jiY zi}W@jA2iqd=?q>s;3%?@oi7~Ndo3Ge-2!zX58j(w&zVlPuXm3rcHb7O0RsM|!Ys(b zh(=*&Aywo3vuJoWZnU!u2_4bNkDTc&&bCYc%T zM~~xYxS#3KXFzQ@OXdc%9QDOxqiTd_> zT;(DX9{5dIuC4pO_xy+3{Ov)1I7j!Z)6&nHUvTRP>VU5dm#849icG)cvl0QOPkCIzG^lOp4#UcNr`VhBp(Ha%8@KPlvT*5u!v_$b#b~%sn3K{mu zaxeD%Q~{;Lw03ZAq(Pc-IVj>n*h3l2{sqioCMGatQY0kx zi`1(WWDQ=;gmLSGptEQ%UFC)th@|71<8eiRtX&Mx@#1q#nMF_BMfQdS>!!Qkx2o}= zuqRi?`UOX5P3fP%M+71Q$ctH4Av}bXED#fQ`KR4!b~60nsAv^*M7c-x`|~B}XIuq% zlqIJOf>WvlhQ@Uw$du|14)tZ?; zPNZ|xZSwp1y+d4sut8E4*l2JWR|~o0A9vD-?zC-w zDc@=wE1YKb*OMSi_Kx}&w;#h3>sHp|8^hnA3w?-WK)X?@Z2dgV7`9Cupf-B2RE4x^ zwlw+~!V9C^tyb`J;m2}ksD`w}G9`yu(^--{SQ+wt^Fu4Li~Fft!3QO`upSkAU?o;# z(1Q%GUVWbbkTK-M=T+ULkk3s6Dc9`G4CO6|=&-S&D+rbJQ$`Y-xL~ol;kc(l)VbU>{&>bV+*?ua;$bnDc29RW+Ig16)Vf6=L|fMR_P2b7>6}0 zdlB#-gj|j*C~M=F^2=K*k~=tl6YM3SXXi&K-`EvEXnWz&4D-^hQRBJI3gKKDj^6|> z*WhHSim1qAffNt60Mve9lfw^+&0bx-AM0%j>QP3%W=S@(l=(nrJ678mRQ(#+sI@d{ zdb#5fo#T;hK7xJ=M58wZf|?DHwD%!OZ3JrTGV5#{cfQwuiMvz%!CQ}CubJ7`z?@rSF<+KHNV2goc)a6hP0oHB@3LLKSH2w{um&J*z1Ka2 zLIR>lvOvh>Oxe%?3A@v<_T|}${zf_&@C~^FCo#jB(W9VLO?DX{)n(BQ0(V0`mI|9Y z#U3WwxixJkU_NTvA>5q(A@r2dnEXJp#6B=pww$XGU}~1~c``UKqQb=^*2P|4Dq*_! zhY^i61Sy%T5$Td0O6^C>h(xVvT!}Y##WeT8+s+Uuz=7)~V$>!zU;%d>H)rm*6^IrsCma%|cifwDLk_ z!^W2voQ)D;I$=v2E>iSaBw!d7aD+|LWl2iD!cBw`Q5p1~fk_xGiPi8e^mY&#viTAk zmaKL8m;JQ4bY(n6uBZt02z#noMMxTfF-RzjKre-c+@B)#J3pN-Zv7F}JtAwNk3j?OkpVCL6W1)Q$FLAj zGI!tX;g`O{%pt=0|q54Jyj##w*4e*|_;Us2Tn?!#^R(>u}|FAw1G_ z#wQsagnj9$TAC`2B_XgB$wNq~Sxgl?#0+QWWcB{G`c6~&SosbtRt}Tukw`TQ!oG1= zYyL(y<;Wh+H24>=E}Gs=Hs2%fg;&Qdvr74{E!R?Bd zIRQ?{{xkLJ_44P@y3^#(Be%(pk%$liKbUUo76wSoVfJmt9iTKL3z{uW6L&?jYg>EY zsx{kRiW@q%<$VZvbS(TKKTO4{Ad6l^IeY(F^3}=mX9|FZmQ`~RErNxlBPl3ast}W$T4V?SW=6kIGn@-^`qJv| zZXwhK4Kl1a4E}nLI`rdOi?^pd6;LZ-|8G&INHgOeC5q{_#s+SXb0r(;5ryHFsoTJD zx$VtNDh=-Tx3t!NTlk=hgAaSM)#U}e>_-Ex(|JoX*hWmBPPdTIa-2(BIOUJ|Iddy| zwY*J%z%W$}*;uSoB!BIJB6N6UhQUIQE_yz_qzI>J^KBi}BY>=s6i!&Tc@qiz!=i?7 zxiX$U`wY+pL|g$eMs`>($`tgd_(wYg79#sL4Fo+aAXig?OQz2#X0Qak(8U8^&8==C z#-0^IygzQfJG4SWwS5vko2aaOJn*kM+f1-)aG{T43VJAgxdP(fJ4&U{XR90*#a)G8+clOwdF?hJ?D) zmxu>0>M|g_QRHe_7G|q6o`C>9x4xd$Gl7lAuR~+FtNid=%DRsnf}YI*yOToWO%xnP zY*1G5yDnTGv{{xg5FhWU65q3-|-(+-rJ2WCeSJn(7Az>ej4Jp9+l-GyZ_| zJ8}>iA4g|}q1AhEEv#uWR&$g&Uyht?fVU(qk(j?^D`))s>oG08pow!f>P1u71P%oL2)UC4GeS87&G?{)NE;D=my1Q9{~;y zJULE=bG6jXE28Y11YmoZoo945`MM*`v%5b=_02*0cwzDve#3(4M}NPt`)?SCa|7*q z-94ks(R6WH-l9fE4m4}10WSu&O`|;ZCIT%vL$_pbABY!}s33@~gIvZ0H4co|=_-T$ zF#lC7r`89_+RL9wYN=E3YwR?2{$^ki(KKd>smX(Wh*^VmQh|Ob5$n_%N{!{9xP~LJO0^=V?BK8AbCEFBhDd$^yih$>U z(o{RReCU{#zHSEavFNdc8Yt<%N9pd1flD{ZVSWQu*ea1t#$J5f6*6;tCx=&;EIN^S}*3s%=M#)`~=nz!&Q0&{EP|9nzWyS<#!QxP;!E8&3D}?QKh^ zqGum|+;xu9QE=F#fe2ws5+y1Igr&l`fLyLKry=1}(W+2W`waeOR`ZXlW1B{|;4sE3 zn^ZVlR11hiV~p<~TaSen8I~ay#7Ql=-_|U@$8yjZsZ=Vi+^`JV2+kn+oiSUi%omO_+7}saXnJ9 z5ETilbag(g#jZPopCgJu+n@(i7g}3EK2@N zd64$77H5a`i%b%a^iRjMaprwzWz(`=7E6QY)o)gek7H)yZ-BLw^6FAoHwTj9nJtWc ztKaytMlWGLg29W{?gr|rx&snb@XyvR_}x3fmC>d=-nQp5ab3*whTw}DfUcKlMDDx` z-%?ek^*|Kqooy#>2lfklZ|jN4X$&n6f)RNNPl(+0S>t(8xSeOGj~X0CGRrWmm(WXT z))DDW_t&y$D#2`9<-+JT0x1==26*gpWPV~IF=rePVF%e-I&y$@5eo~A+>yZ&z6&7> z*INESfBHGNegTWga&d@;n;FSCGyW?}e_Qw#GTLHo*fWxuuG@I~5VA!A1pOdRTiPA~ z^AGe(yo=9bwLJD}@oDf$d+34~=(vIuPtOKiP}obDc|?@hY}J*@V|UynBeAkYa?S{@ z_f$U=K+>deTAi&=a*xv>Ruyw$UsTWY=Yn=xjf;s)6NQu>_niQ_idmzIwuL`Scf)f= zyzK?D5a5)^D@H&qN%F6Zd0JeXX*Knbe~VLe^gi|?JK67&mB4jrapV-$`hCQT;C{%T z*pjxB+Y|~LD9bmMN%Iq}S$F$x1yWU7@GcR91V8h;!O2I5MN_rq*gRx(k8T!1WSDTp zr9eJO4$~H94aG^6k5p8k=kFJ>4lnY0q_Bsa$@vTRW6uY?slH|Qt)Yu6Yun&pfJ zBi!h;6x?FDs&79#PT*HSCEUsKws#s%TFy*=2PAfb`>gEPBn+D-WdfXA?MkB=<8kb_ z1+4D11mdHG0EcAyg4dneLtfJ8)RyHQl@6hWJNe(d_EjyCHf7%Xsd)S4A-4COz{G@% z5xQ!P>AS@H@;4Ws)N91)3A6PleMe2<& z!(zv#%Uc?N`(Xmm)OJPYt)BM`nRjoWA&P0Yxl@c9Y02zlPH1J5l$nhPrMwu=atkz4 z)a-1+OEL;d@ctx=s<<+3Sv1VYy0RYmiji|#hy$66#`5;u~BkH4^$EGZ-Y4xyZ=%3KuaeLYKAUr$xMtIh_5mga> zPz<#G0mQ7IxEw-yO}BueN}RaFlg$RwCDB)vLF$wDu%qZyLYsPKdcbHD23$qn9i#JFqIo#OK?u7db2-$GatzO!On87%}Br};~#}n zziVB;qf_4(K$u>Qyz$ln_kBGS!CD-t4Y}9oxL@7@Sx*?NOAzdeINUD>Hl#*V%pfA; zSA`==YatS*G*crJ3`3ll4)vKss&)UtY#7ZxiVoG%9(4<%`WWcjX2jV(^g7Yhj+h5J z$5=?S=tuCyEt74^6jo@6y|@~N>&cVfFNtaRl=)Gm!vR;Bc$3-;ySCI$%kdmjQ|si` z{$q_YCe6vjy6re9jGN|`43D``)1PODtz0)vhV4XV36nVpOnMx2uM%qZ<3TtcI%>BQ zf0(J`{JqPPJxw>k#&nIvoZ5e9Sno)B2r+E0G} z@&M|zf4E0Q$O*NBR2I;?i7N} z@2^Su#`%qeX}m3cbSojiLk#84kvW1fICNPS`OyT0SpUoA0(s^2m~J<^eKE!dhJx_N zG_T}0&(<*an>oF=@?6?55g&IxSgY3?7|@pmDRE6gJyJNPH6un~%0hZ@?h=hI6O$b^ z)29#<4$E)cE-5IFbRpk9JVrw$$966UDyw;Iym4OY4Fc!&s1ZH4BJ1-$9<)Zt1c)N- zU^&9hsk6z?3%<9kGKHW|6~k;&cghtWz`oz`_YjVuvy;B;T67=L2c6=8`7WyTBv*QH zNv*bo1#KOk{O&)@&pkd*?v+kcJ8tM>AGx$~WMhH{L40_N=bkrVg+^p!H)IqXCQf2_ z0fPig=8CEo>p4vE(nc^DKbZ|9_Xo}$i4zJ`jVh95; z5%aNP3@``=EJ=Vt9U`y+$YtX;%OPzgZ_3+;+mh{p#W&y4-%%Bf`LhOy-*kB0qnB^m z_nBTz_b?-`F$*ymByshU>D)za2g`0j^ioo;A#QeL@x3@|+_!=YXA5f6Xg(Ack&WOg zJ<2i|Fd6OmyH!@YSMVxb;=M)ZDhBt)4`5T*>cUXWPG#%@$&*>K&u3#|`fm2mj*FKVf?du{xZ}WKWETTFhq6_fO$PS5(ItF=3~pFp~*j z!ys1<4EL1)#{`mz@gW|t-FpPkd%pK)n_Rb)F;z7cQ6dym_>YI3&e!=!m006oS3Mjq{q ze%hNzW=G0jpfl2K(x`CDuZCsJV*hm9T~%5n7R_g}VFpk`G((D^MWVMAmRp--T{`P; zwMgD<;e`fm`g3|fPns|6qnd{|FCHY*YAguXH(?%sx%4+Gu|Y)_8mk4EljxmP+MP`* z`SUbI{TCIN2OV+$y#g->Jqv#$wL;}4xJmah#$0`v^ughM_XjTA$B}ux)JZuY5-GW4 zKy440I+w=ZtE-_i+0xImq}vyzD68?8;94-5L~_O6Ty>X3itdA-x?6P(c4jkr+f!H( zUDeqiG>3bn^Sf8(`_YwqPeJ9&-@OCQZm4X{FfRMeBtN4E9Ca@;GVpU*L>lVb;@=PH zTQvTr?^jKyCKh&ZVOI*<y%T*Aw(XCPrFC=39*y$A`FSzxBiQ#W+uW10d8&gYp4{teh;^p@anft+z$5!Hv&@h0X-@xJG>hbTCxjDwMiWK@1b%8wYL6BrV zT41m}tX8g-`P@vj4T!Mlk8F0S!MA`^J=SCy9-jdwDe^hVDa`WwyI^H@ryt=F5y6>b zT8&iI6&j8edAfX^ycgWbnMZQ26Q~`LmdEScKC8|~$Jgyw(>18NAQ$9AwCRmri!96L zp^)b0P2CR-9S%cG$#rU}MXnx21T#031o>2VrDs@sa-FpjfvgLPW>Q&LHUoNOtmkt# zoDZ=5OGp{^vO~=p29^`aXd8K?(+f-bW`N$U;-o;%f?RcR!k02Nod2h^^8ly%Z67#E zC3|IOuj~^YBO=Fklo@3mvd6I{Z*&FZ>iq* zxh|JuJoo2$p8MJ3zO@dQ;%1#~Mrm48 zB0053{1bDi_a@jo<4!@!`w4}B(&Qb`~IeSBh zu+_yIYl2Wgk+?x4pCmAM>x_SqBPUj#c`C`k>_fp@qPlAAwD$!zOxRkL7;=|nu(#ut zyF^;&hm-D_;ji{d6rOloACu5*NkF4IC3@rifMG(|^Skv$H&^YnYL*rpw=UCi;JOuz zN*NX(7wZXS4tF@6PIWAs%*j!$RoL*3sh)}iry%thDvN5AUM888q_(>|Tzt|Yea3AyMYBgm$H_`F^v2%)bux)3s znFIEBDK;-JS5SH|;1?afJb<*=c5puu=w%tv#ihn*R!^Hd$KWAp4$#`joJ*)$kNtZ z2Al6h>Z>(u?3tmzA4^d+jLKx{97!Pb4;CX&u;M||**7zXI7hO6nrdMx*Xa=|-`#1^ zBQ?Ha&7cd7hN=%y4yUp?zl8~Lo;%mQrDe8!ce-W_K94FFMN*g(w8q-_K5S+c0{o29X&PzpV;UJE^!xnFc%b@>kvW4m#xiOj-L*DadC&2N#0Us z;<-(m1WB7$=j6hjcPC6JB)D3T2#IC`ibu#yi!uK7W2!j|Z>~RaJ*&XXy#ytIk2DIp z5?Qd^s90_?ILjU#>ZWk5HXts}grg_!Gmgm!d?eLGR7xEP zvTCrslV~94ym5_i<5oqy(@@?wN}lIdtiY8=?|Ng!XeYnly`@9wCGx2S$3x|0x8T2h zz7A85Vb2>s44rKpI_4Y7_Pnd2^mYj2%^jM|Du>u4`^Psda^JIP%*DK6bo`Vf&f{!% zDTYCwF5Nhi=)QhU2$@eQv&ZzxsX+Hl+gP6kW|e!n9IU2>Vh~cioI{>4WvR}t*4Hpz z%5z?HjLGoka}Q3AbX9AkY|Yjf^M(>@tBAI9JO5pDCQu0R3Nns>)LC#vB2p96C*?K? zvX$un$sBDx$1=+NNj*@Oa@u*b@O*XBr_sg@8sCUq-|LK!MUmC)epklrv}5O_^<{NP zX16|c$9Wtbks3y7geI^tF5oRZJu;v zwkW8j+8Ccxo9stEDOT_Go&j%$KCgVO7pm+^%PKEPBZqbMw%s@732XS{cX+wCSjH1s z5)bc=g**<^NNsroY` z?}fHHlgu^B?2r{^^gQ&j zbF~T((>|Yg&C5WKL8DCnl1}Z3!YHFW2S1|;Xr0`Uz-;=FxEwYc4QpeAtnm7^f~uzX zl;xA!?>MLR?tL80Iudm;mi{!ewL91KhG7Hsa-XepKi<2mc6%zf0GwtbfJ1Zf-<@Xu z#|XWDzv|04t)&9Id!UxAAkN{t5qC%%8-WV3i;3duS19%m2||Y{!3pR1=g|zQYAMqc zff)_2nj-O4wfxy;UNM?|Uieo!^J$A*uDe>@V(NKH;KS;Y_dtE8${p>RdcrW;=2*fj4~d?OG0l-(g?ik}vz} z)5-wDppVts>K-=|@{=!53?=8)Jw#RGpS_FWpbwtn}{v!JEJ$q-sr7F6&OPBuI# zuVNFMPte79XgEu!P&qRq8u4J>r%$l-IQ00Lin90(_KtC)aR_de zxN=pY2<1b29_^AG2WJIGmmX4rv3$!`l15{e(H!1^+x9voZ6;882YAE12q7+lgy+>) zj|s0CyzI9=Mo!R}&LXB`&DYpZ7c?0r(&KNV+~TULd0y^e;G{KVR4nL0KvU9mr8&$^ zxrM-9P8zE`J?aZ(iB~Rz<{vvnk2HaZU#K$aVFfYnbAXVUOLU#As5JvS%+26 zi$sNuPY}dLGUS$0g&;oBqhzv2dY`l3@6Na403M!Sh${B|7(y|_cONa;6BrtUe@ZzV z7SThtHT8k?Rwc)(Z}@BP#H@JJHz&GR&M=E@P9KJ89yQKmRh&I~%vbL1L-K3E>7>CH z)Y!=jXVb1iPrAoAZZ3}3wU*5~nrV!ZjL5zqJ<@NwjHCZC>68Cc<{&E_#S;E*jOdjtg?uKN|l`P8sjz&Qf7a^z9 z;{3-8T+H4y99_zc;JYIvs!sk$G}` z??mt*Mm9Z@glCZb!X?!xXD-21sFDPEpZOK{sbQseQ$%6~b;n+*z0hRoR}0Pe>B|#t z$XrVcXv8M|q*Z8MY&r9J0A=d^1bHpjrUXu)qEj~$%%=gZp`^~%O*lzxUquG^p6;n; z^(3HL+hx4gRP?4N*b2p9!^|2~rcw3!9nQj$vmZusbXYz_x^AVc`3qBFm(jS9ueU5h z^AnNnbswfQ2Jq=W=T+p-V|nQco@bOAH$pLQZ+BKH8E$iM>IDz z3|wc?QP`yI=X5YTlp8h}%p6{Deq?S0QD$Ug>ih1SdPZg237Rl{S~=Ha4~-ckMoIWMn+X@@`V6 z#HHZj>MQbt$Qqp*9T(cjc^lxZ7UO(>PwzF-qEr(wo`vaulxdall|KP`7p4gd`23&Jy=#sAes*0diLB(U$Nx46VQvP)8idSs8^zaV91xw*O-JMH=)FoJshRob|_)O)ojtfP))WHCr(;*2;VMQ75^ zfN@a^f#o<|*9X;3IcGodLUz-3i~FAu+zI4c5h+nW^h_!^)b*B_xw-l4O$TB(ixaqW ziMoa%i=BeS<-F45kMO;Tw|FWa`G2c!SuOA3CbowPhF6csf1|&qqugUrj;UgGHm| z;j^yoH?MZhR;AYOW_XW2Lg2j%%ejL)B@*bUMD`g<#Z${1+fa57r7X82 zcqY-cfPnK%Y^3@szRner zt)bBToYCph6Jv*W+&t?&9FG4(Iu2w46 z4B#AcFy_^J@f*6<{>CN}Sj969*DYV*e7<61U>GoN{tz!Do90+jApFueVY_IW(MQF; zl?4yA_(MvMwN&pWKVyg{3uU_+y6RMdot2vu%mC?st=N0pf-~JZXE?3JFf)j<{1xsU z`2ephz)#HzsWEP!inHm2hI(V(~@W zY7gGU-lO52cHD&SY)>QHgy$=>^X%u0TQZfCizro!*weMyvZC=;MWOawdAx~`3C*W` z%^#^$uRP;gyqEE0<(i8xcQY$oc+6mY#z{-XFxsO1(cN8Y)>p;^q9|5bk`Z*p|c!?(rErw#y;yT(%@c7trQBv6cj)$3>pI z>tz+;IB?D=aQV=s(n)o63*yn8dX1m7#Z4G{%fF@K2o5n3jxR~mU?nzMi#;}8e#(>{ zy{Z4!AI)jZ8TY;nq1aq}tq;~=zzoTv)er06oeX3;9{uP{LWR*2%9cmE%S^`~!BW>X zn3PZFTf3g*dG68~^1*q@#^Ge(_8puPEFLD8OS|0b2a{5e=N4S%;~f3tC>F6UxK#v9 z)N-#Mv8=ePCh1KsUKD1A8jF_%$MPf|_yCN9oy%*@um6D{w*2|4GY zb}gafrSC+f=b*W{)!a!fqwZ9)K>fk=i4qf!4M?0v{CMNTo2A9}mQzV=%3UT&i{3{W z>ulG#M!K7%jPf6Mjff9BMslgQq3zIogY);Cv3v;&b#;^=sh#(Bn%W)H*bHNaLwdpq z85%fUTUJJNjYO_426T2TBj0D{6t zw&S_HZ|C?pI_2q(9Fas&@uJs6nVX;P*5K#6p|#)_(8PM-{L(;2wl`ma{ZAd5gA)?y z>0GSLoK<*FwW+G8@-M3vcffg7I(qm7lzF)n`Q9iCvp*mn7=|CjlpG{x z&r0n}XLWZ!>=lynUr7D`6n`7a_ZgT< zm!i;&?Fb0Q2QmqmCHfZ7ex=_tU~(7b)L?RIvPyEAU=gLIZ-VTAA~WR00yKyTXg^(G zqWLZJs!FnQYMOH3*fN&Tn(IKMLf{Ki?pRo8zZJ6YVyj)y0^)-sR}2-)%mI(Aw2AgT zbbp1T{qB(OSNJd0cVBH^tI>HR(q+#*lmi@LWe*rZz&M2h1L_=50uZ1e*n#E*`6?aw zj`ka&JpceRGe@}Ey1)Q~O}0qHRg4K_u>4e1arvJ7Q9!=t5AuzG`n=a-f0}{+lnCE#zu$`oVn44eS&T?N*wz~t~E&oQDBrB_MSg z_yVrQehWbD0xHX|v-hpselAu;O7s;P*!uAT`dr~}Lie=tknaGoiU?;*8Cwgala-65 zosOB4mATbdXJFujzgA4?UkCKE093A1KM?W&Pw>A?IACqg1z~IZYkdP70EeCfjii(n z3k%ax?4|rY(87N&_vhsyVK1zp@uils|B%`(V4e3%sj5f|i(eIhiSg-fHK1Pb0-mS^ zeh?WA7#{hhNci5e;?n*iVy|)iJiR>|8{TN3!=VBC2dN)~^ISSW_(g<^rHr$)nVrdA z39BMa5wl5q+5F@)4b%5-> zA^-P20l_e^S2PTa&HE2wf3jf)#)2ITVXzndeuMpPo8}kphQKhegB%QO+yBpDpgkcl z1nlPp14#+^bIA7__h16pMFECzKJ3p4`;Rf$gnr%{!5#oG42AH&X8hV8061%4W91ku z`OW_hyI+uBOqYXkVC&BqoKWmv;|{O|4d#Nay<)gkxBr^^N48(VDF7Sj#H1i3>9138 zkhxAU7;M)I18&d!Yw!V9zQA0tp(G4<8U5GX{YoYCQ?p56FxcD-2FwO5fqyx@__=$L zeK6Sg3>XQv)qz1?zW-k$_j`-)tf+yRU_%fXrenc>$^70d1Q-W?T#vy;6#Y-Q-<2)+ z5iTl6MA7j9m&oBhRXTKr*$3gec z3E;zX457RGZwUvD$l&8e42Qb^cbq>zYy@ive8`2N9vk=#6+AQlZZ7qk=?(ap1q0n0 z{B9Fte-{Gi-Tvax1)M+d1}Fyg@9X~sh1m|hsDcZuYOnxriBPN;z)q3<=-yBN2iM6V A?*IS* diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 5f0536e..0000000 --- a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,2 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/utilities/on_subscibe-service/java/mvnw b/utilities/on_subscibe-service/java/mvnw deleted file mode 100755 index 66df285..0000000 --- a/utilities/on_subscibe-service/java/mvnw +++ /dev/null @@ -1,308 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.2.0 -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /usr/local/etc/mavenrc ] ; then - . /usr/local/etc/mavenrc - fi - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "$(uname)" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME - else - JAVA_HOME="/Library/Java/Home"; export JAVA_HOME - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=$(java-config --jre-home) - fi -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --unix "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --unix "$CLASSPATH") -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && - JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="$(which javac)" - if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=$(which readlink) - if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then - if $darwin ; then - javaHome="$(dirname "\"$javaExecutable\"")" - javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" - else - javaExecutable="$(readlink -f "\"$javaExecutable\"")" - fi - javaHome="$(dirname "\"$javaExecutable\"")" - javaHome=$(expr "$javaHome" : '\(.*\)/bin') - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=$(cd "$wdir/.." || exit 1; pwd) - fi - # end of workaround - done - printf '%s' "$(cd "$basedir" || exit 1; pwd)" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - # Remove \r in case we run on Windows within Git Bash - # and check out the repository with auto CRLF management - # enabled. Otherwise, we may read lines that are delimited with - # \r\n and produce $'-Xarg\r' rather than -Xarg due to word - # splitting rules. - tr -s '\r\n' ' ' < "$1" - fi -} - -log() { - if [ "$MVNW_VERBOSE" = true ]; then - printf '%s\n' "$1" - fi -} - -BASE_DIR=$(find_maven_basedir "$(dirname "$0")") -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR -log "$MAVEN_PROJECTBASEDIR" - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" -if [ -r "$wrapperJarPath" ]; then - log "Found $wrapperJarPath" -else - log "Couldn't find $wrapperJarPath, downloading it ..." - - if [ -n "$MVNW_REPOURL" ]; then - wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - else - wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - fi - while IFS="=" read -r key value; do - # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) - safeValue=$(echo "$value" | tr -d '\r') - case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; - esac - done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" - log "Downloading from: $wrapperUrl" - - if $cygwin; then - wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") - fi - - if command -v wget > /dev/null; then - log "Found wget ... using wget" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - else - wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - log "Found curl ... using curl" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - else - curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - fi - else - log "Falling back to using Java to download" - javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" - javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaSource=$(cygpath --path --windows "$javaSource") - javaClass=$(cygpath --path --windows "$javaClass") - fi - if [ -e "$javaSource" ]; then - if [ ! -e "$javaClass" ]; then - log " - Compiling MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/javac" "$javaSource") - fi - if [ -e "$javaClass" ]; then - log " - Running MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -# If specified, validate the SHA-256 sum of the Maven wrapper jar file -wrapperSha256Sum="" -while IFS="=" read -r key value; do - case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; - esac -done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" -if [ -n "$wrapperSha256Sum" ]; then - wrapperSha256Result=false - if command -v sha256sum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - elif command -v shasum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." - echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." - exit 1 - fi - if [ $wrapperSha256Result = false ]; then - echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 - echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 - echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 - exit 1 - fi -fi - -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --windows "$CLASSPATH") - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -# shellcheck disable=SC2086 # safe args -exec "$JAVACMD" \ - $MAVEN_OPTS \ - $MAVEN_DEBUG_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/utilities/on_subscibe-service/java/mvnw.cmd b/utilities/on_subscibe-service/java/mvnw.cmd deleted file mode 100644 index 95ba6f5..0000000 --- a/utilities/on_subscibe-service/java/mvnw.cmd +++ /dev/null @@ -1,205 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM https://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Apache Maven Wrapper startup batch script, version 3.2.0 -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM set title of command window -title %0 -@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* -if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" -set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %WRAPPER_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file -SET WRAPPER_SHA_256_SUM="" -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B -) -IF NOT %WRAPPER_SHA_256_SUM%=="" ( - powershell -Command "&{"^ - "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ - "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ - " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ - " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ - " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ - " exit 1;"^ - "}"^ - "}" - if ERRORLEVEL 1 goto error -) - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% ^ - %JVM_CONFIG_MAVEN_PROPS% ^ - %MAVEN_OPTS% ^ - %MAVEN_DEBUG_OPTS% ^ - -classpath %WRAPPER_JAR% ^ - "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ - %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" -if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%"=="on" pause - -if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% - -cmd /C exit /B %ERROR_CODE% From 806f81255631fccace693d0299343da98ca30436 Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Wed, 21 Feb 2024 17:44:34 +0530 Subject: [PATCH 173/228] feat: on_sub java util --- .../.idea/.gitignore | 3 --- .../.idea/compiler.xml | 13 ------------ .../.idea/encodings.xml | 7 ------- .../.idea/jarRepositories.xml | 20 ------------------- .../ondc-crypto-utility-master/.idea/misc.xml | 13 ------------ .../ondc-crypto-utility-master/.idea/vcs.xml | 6 ------ 6 files changed, 62 deletions(-) delete mode 100644 utilities/ondc-crypto-utility-master/.idea/.gitignore delete mode 100644 utilities/ondc-crypto-utility-master/.idea/compiler.xml delete mode 100644 utilities/ondc-crypto-utility-master/.idea/encodings.xml delete mode 100644 utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml delete mode 100644 utilities/ondc-crypto-utility-master/.idea/misc.xml delete mode 100644 utilities/ondc-crypto-utility-master/.idea/vcs.xml diff --git a/utilities/ondc-crypto-utility-master/.idea/.gitignore b/utilities/ondc-crypto-utility-master/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/utilities/ondc-crypto-utility-master/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/utilities/ondc-crypto-utility-master/.idea/compiler.xml b/utilities/ondc-crypto-utility-master/.idea/compiler.xml deleted file mode 100644 index 505c2c3..0000000 --- a/utilities/ondc-crypto-utility-master/.idea/compiler.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/encodings.xml b/utilities/ondc-crypto-utility-master/.idea/encodings.xml deleted file mode 100644 index aa00ffa..0000000 --- a/utilities/ondc-crypto-utility-master/.idea/encodings.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml b/utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml deleted file mode 100644 index 712ab9d..0000000 --- a/utilities/ondc-crypto-utility-master/.idea/jarRepositories.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/misc.xml b/utilities/ondc-crypto-utility-master/.idea/misc.xml deleted file mode 100644 index 897a30e..0000000 --- a/utilities/ondc-crypto-utility-master/.idea/misc.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/utilities/ondc-crypto-utility-master/.idea/vcs.xml b/utilities/ondc-crypto-utility-master/.idea/vcs.xml deleted file mode 100644 index b2bdec2..0000000 --- a/utilities/ondc-crypto-utility-master/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 86f0ba63b73054291f5b45a58464ac8bb5cc69b8 Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Wed, 21 Feb 2024 17:44:56 +0530 Subject: [PATCH 174/228] feat: on_sub java util --- .idea/.gitignore | 3 --- .idea/misc.xml | 6 ------ .idea/modules.xml | 8 -------- .idea/reference-implementations.iml | 9 --------- .idea/vcs.xml | 6 ------ 5 files changed, 32 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/reference-implementations.iml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 6ff3c25..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 4be6c13..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/reference-implementations.iml b/.idea/reference-implementations.iml deleted file mode 100644 index d6ebd48..0000000 --- a/.idea/reference-implementations.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file From 22519a06c8dc80e402df7a3a80df0fd29e21cefe Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Wed, 21 Feb 2024 17:46:48 +0530 Subject: [PATCH 175/228] feat: on_sub java util --- .../org/ondc/crypto/util/CryptoFunctions.class | Bin 4741 -> 0 bytes .../org/ondc/crypto/util/CryptoKeyPair.class | Bin 796 -> 0 bytes .../target/maven-archiver/pom.properties | 4 ---- .../compile/default-compile/createdFiles.lst | 2 -- .../compile/default-compile/inputFiles.lst | 2 -- .../default-testCompile/createdFiles.lst | 1 - .../default-testCompile/inputFiles.lst | 1 - .../org/ondc/crypto/util/CryptoTest.class | Bin 6543 -> 0 bytes .../test-classes/org/ondc/crypto/util/Test.class | Bin 1951 -> 0 bytes 9 files changed, 10 deletions(-) delete mode 100644 utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class delete mode 100644 utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class delete mode 100644 utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/Test.class diff --git a/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class b/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class deleted file mode 100644 index f3523071ff15c9a2308f5eaffd0d183529f16bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4741 zcmb7IX?PRY6+O?gJ+c^sF{{`Dgn&09FmVDlC0N1^jt#ho7#o_p z=t|SHq$KIS?|YN9wINRF-n8kyrcIM3O}e+g+po*lujkE-#*(b0;j=Bxyt(h*d(OS@ z-aCHezYkspa2@^@LInZ}DpgdWTA=QvHmOBYnw5+k8aZj`If3fkre)^#2m~4$2NVPa zRyjghL!YqC+*BkkFO0*Ql}L|=ph$HK1RBzIGBT2$u=FWi%jQx>WL(RQMhrb-pU`)1 z+tC{7O0>4MZQmug)T&sBMFKUJaVi&`${AUKs)pmy#(@w*SgfKRO9U1t4a=~#oY6lq zk}~yPV~RT{)x%%u+A@KS(rVgD=n>tX%H-0KiJX~=#GGr&_iLsd!cwe|a90W_+?}_w zO2uld5va_XNlT#CQ|v02Zmd&r71ooGNy9cz&~{#g=6f2CDcC5`IuG?p-H2rD^rV?E z>`2t%Bj)hY?=1$gNuVMc3t=<1C}>d8h$eyMWk@F50t=ExF27fxrJ-*wWbvGBTFH(^ zcgYV>Ub-WM4G2g(TUA_(2z671FivO(-1M}uB$ z+i<;t8&vGXE`fE$n7n}8{CR zPvnjT=)uhjdR6q{fWV4kb-o-CP+^y)rxQj(B4|7wm7W|@(T^9pPy20il7~cK&3t?A zBVwSzxHNb~U}cFdUnYbB991wVqc=n@q}-|e!J>}Nq-_}EhQ%V$c?F>=tD-}}ae-@! zUCCxxE(Y7S?eYNAW}HhQ9K)^h1TP9<7%x$vNe@TnA)$D;rsvW&PtD#da4_N@fH@6} z_b?JF44e>Hn9q}ZWN#=vIgaO^yYtUuzI+k%sKDkjp!<7c@tviplekrSF{UDg@q%pi z1HSXh-0%ZUa05uI$l#^SDS1R#e@b-`O@}-#1IVh#VS?2&k?tSWvdpx`a>B<-vt4SC z`(LKwluUA;Ms^U}$SJr@;Hsh|b7*v*dSnK1hMlOhD;~lWULljU4PCJ8jRap=FdgOMddYn~CQvUMHD*Jr8Yz=R;xsIGmlu z8&uqZH#(eko0gVhiKNp!y+OQ*buZf2+1u3`-P*RjHH7oHOTk;D%NJNQinHT@kmntDa31%lxL5Z7D%;2!xf;9;Z&&aR74O8m1U5J>SY|q+k7_ob zN8+r|3C&K#+>N73l;KcZdVIR>(Qe3I;OY2%{K(kGG?=4p5Moq%s-1mH1V+W5_zI4PnWw2Q@ zt>sWc4J_8rp~I7-hU&we2lpK!$TcoDKiPOr{5gzrp^SgNIbR%)vKM9Yg@XdOe7pYh(({i-#4rIXxC2{YERz&iU*fw5&mRTof5lja zN2y&O}oC!q1H}gsBlhb2Ovg;>k$Cp#^u)x(t72#kyKB15H zb1EV=1%lu4sHGY3y-FIzwrjlt+)uZDD z8h<#iF?xP_6QnQ7uo{*#_>yfo^D?&^IKVpbkRhuacXC_w@c8j86NHsChO^GtD4>oN z_4L&a_daA&=Qn)vUw>*|Ul!O>60T=y;N0%zA}z9fm+bPV9m?gi*b(%Kiyu_4@zFC% zR&$wMgpf&KQr1|mb0#Q8!9zkJZ-?$RfMvxpF=v_0`5A$x;_~YNn#-j)r;!5o{TGyI zN*gowYgu;pd><`rE-YYdVz$9qGLh|zA`6=#*@LTY^s%Zw| zen-Wp`6(X*Tksivs;&S&i_h_{2KV89uE@=Ipprj8(=3#s8PxRFt$!%kCqE7}HBUor z4zvU=qHY#ThgzCvu>9cG`zT!jX<;250j@`ot*{om_!hVuD{v#%qiEpND=jxsdk`D( z06x#VTCBwv@I~6L$4X4|s)CXgn88KTP{TL8OP*hY)E(fC`ntW+l|XZ#`LgsR+%ji> zp(8O&Dn?KT-Lbdc-Q`%}cG`K+u~$XgvyQzQz9v58S-IJ>qBaqxG;tAYB{CPE%ix&; zy{e-_>Qz0x^2)_ggD;WQ3WwDTL@h(xS%39KT=Os%&SC@EZN7+>qxG$F@w(oo#ezHA zo2Id+Ptr@aqnEH>fENcZ;jkbp%O%)=L-r~L6zriv+=V5$K&tL0t@kj%_c{(Pr@_^H zcf5=*Q*H}$<}3IrVSdfgAeP|kyjVyj-@v!b@EhPKY&MeS8Cj2DNirlGf2dv~))4z;1 z8VUyk;o#-^(=&K^drkdmY4P^=B5Ym)@i(Z8Xx5CN9GuE zljHC7B; diff --git a/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class b/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class deleted file mode 100644 index 0e3e6a87407f1cee431c9b9d09644ca7cf96d63b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 796 zcmah{%TC)s6g^`cr*REQL!hPf71Tv=s(Jyt0*fHAA!?DRkgBX4W2HmgI5G|rf7MDn zq%Qgad{o7`Vb<#sFdM)cnnWrCCvswIy{VmC_5eHX)w-p5^S4zH$L49b*3&V@Lhef%ojQ(~g zlnE)I3ift-7%Nn}dKiBkfA7cH=dhnJQ}3oxm>h(emh&WO=U?@)!rSiub$p$ z^50#c?6)s4`_nWmajnDVI?uI%3KlR&XPz_jrf9=5UhqT!ag3l6$v}(oOT3zl3AoE$ z$v;Ew2LlTN?wDlL0D48i1W?J(XGS<~v0Ah^e)}A?TWa#I0H12w24S(Nx}oG4A~N{( hR3eRsMAoJf;q#eBr16l*28nF`gGk|xqH7|(c@1Izd0qej diff --git a/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties b/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties deleted file mode 100644 index 5af20f4..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Created by Apache Maven 3.9.6 -groupId=org.ondc -artifactId=ondc-crypto-util -version=0.1-GA diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index 4c1ad80..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,2 +0,0 @@ -org/ondc/crypto/util/CryptoKeyPair.class -org/ondc/crypto/util/CryptoFunctions.class diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index f9d72a4..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,2 +0,0 @@ -/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java -/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst deleted file mode 100644 index 4c3c6df..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +++ /dev/null @@ -1 +0,0 @@ -org/ondc/crypto/util/CryptoTest.class diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst deleted file mode 100644 index 8e67e07..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +++ /dev/null @@ -1 +0,0 @@ -/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java diff --git a/utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class b/utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class deleted file mode 100644 index 1868aa2d886f69ccbbdea592a9193352792c061f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6543 zcmdT}d3;<|75;8AlQ%ORD1-(`2{43~q@n2mEd`QNY(fjANgA6FDWTMtnVZRLCNtBS zH)&IZDvAqBtAIc&vM(YElqHQoQP~PDi=v>2f~W}MjvJs-zWbJ0vWdT+{z3ceTkbpe z+;h+Q&Uen8?t1V3hXBkI-T+Eas=*V47i9wbtkDPca9mHs!pnQs$cQOWw!laj=0bte z+F4yb_ylIPCo_g=49ZY%Jh?8E>ZnmB~WrmCSP2QUIj67PPyd`f;hnc4SMnCq!z8cDd z*bmc+tnC=em~wzdCbLviVNW%Z;dah5Ia}%jjXvxzaN3Fgvp)eGh)NC9gE$CP0{dC! z7OyFwrIZEn1dXa4yP;WK0UUxuHH3mV4AlZNCUMb{Y$Bq(ni1GPCKEEPo3g|9{4zPz zt{Z8ABWh>0OrpY(qbp`m3Ex7e*ovq&)X)&>UcPLV4@U@08<3fd9+M$68S0T%fMqm* zTFlZ=7sQd6El~ZR7ZTVjCQSxmkhXF;0Z;9$?xq0dAgtl2AdXgw3Q%VUTENF?O+!S3 z^3U8L=HXb*RXF3f+U}_ek~ zI7h>Y0tbu+S5wxAQ#gPHDD~kZwA^3qI-$CuT8%da(TtOs5_&2{%>wn~g>+1m9nEz5 z5`mKH*-F)^K`g~-+>4oXw>*uZ8*LQlv~Y|5YPECS%%)|?vZW2nHM9ruQLJ#?XXR28 zQ)m7>fdJjNI1x#5LjqN<;sTKw&ez5OI&r#&t{^^!GXxH_EEq>nU~g$D?93UwKjSd2 z$!F3ge>H*cL|xhJ!&%JEa{~bdqO*fotpaa>Bij=ih0wIQys-dY z&WK|4^GJ$qGDgBCqc2g6&YX|*$w+@_U7s}j=w(wMNXaxE=q7}bad@6%*+eEAiI6UO zv+?+l51(X?1$;Q4d_QKM%_eR*DnhX=w>y6TTG0rKqervPmjlCA|`E~ zvh(UXfkXV&&P*8{SLOzSo5W>NaJ~ZA^Kas|{MBhEi`$En_7(z&eDO8fmiMj;164Y{ zuDX@m1-y!Yh~RHp)oD15X0C` zj*?EU6;*aOv&dK9;zrK(;Q@ieKL7}Q*g?S@?A+Yz(=&alw_?hzOQ!qz=)<=Ol>$^K z5f$|B2JtW+DL`LST<@2s@~h&Rg6y|L*=Uu}$M~()DfUXVFynR#ROYLojX$-Rj9Tpa zB$x76_ZsPpxjJgZ*t%K6yBRp;%m`b(!ttl+WVJ%5RXJ1bDTlXb1r8efDVNBs6wT~= zOg&+CDdJ=+(9GIKFSHm5*_IvXk?BsoC(e=bmSjYacj;+Ey*q;*v(F$W9yVEPq#97R z2ZyN+)M<)Fbyus~EGA%5scKC7nbvmKHDfZxjudrkPRv-H^^eO4ziiUIl^UW{v+dTRb_%Sn>Ng$@X`eLY(%+YPENz0*-saX zwIw^Uk-kOoSdz2)1`1^VA~172+4gjDknLx>K=f|{b;Y6?mbwBHI`~>3{|`n&$>(U^ zwxV5+MhU_K!FL>cbAn6B+%Y}g6i-I_JB$soK=z+(DvFdg>Cw>|8K%P67O+W~Vu95> zq?Pq#=FhVptdV2f5k3SulG$`bE@44uqUKL|bJVf|!KDcvVVdKrZ6R zKg9EV6L^7YN|c(CUdnhmwE1pKEw32H0qU+fclADkgImVfjhJSVZwf<%@Y4#wo>LmvL|et@Xp`m{4Y=Eu+>QPprI~ zD(jU+lvp)_kI(lgv!eemb9!^;tQyZ8ci(*!tMCkCP4UJpYb!iku(vXDfJWYmDe5uF zN6!e>R;bGe)~QgILWMHH(={*yKFs9l{|KJBYZ=r!j?6|4n}NAF3XM319sOJ^<2lj5 zvFyR-<6azx2ho6CJZ(LP6Y&!)#M?MYRPk)rj76dcO=1n2MUp4F4Lq5hk5k1aYEW>Q zXG6k)OO?prNBA*eQzQEDA~9Klx#BEpe2F&h!ejU;enuF*%$WzEWDnJOH3T%&YM7(p z6{1wb&-rmGC%(%2FR1F58SY5nS2-XKIY8X1+~ET8Tqlg~`$oQh7yw!Rsn!o0Cb!y{ z{B$0Z7x1xkTuct)V1}`S5$q%;PbVh35W*S6%=A4Ahz%%n8)T;2b(j* zpo7h@=y$N$C{{bze10r8FZf{CJdfCXjo2(zBw0F>*wjdpZzybj&cWmtoV$7#EuwV< z7q#$TtCCSi?PiYT*xDj3Z>5LdYiyFevcao%c`G;Y0OqW$^lry(4P|O* z0^a=w^;MSfQcQ=g0e9pKsF`d#ciCdfhRMY4rdYjN?Ow&d#akJn$@aJLIhfxp_GKqY zB!_u6wORO5VjH-Kh`*SKzl4b2gz4B!sY{9c%lP$j%5UL}E6B%JkwLeTf3N0`T-WeN zs_U2+*E1Jxz((ANoA`G(ZpK@<1@H2h7r)2ss!wOn-6w&!>yiQArP$w^@Q~C{yv#Z2Y_zj;*_+#NV zD?>`LR9uTU$=)8W{W5;bCofmujo*>m%PbzB3(p>IhChwlJYEZ-VUuT%xCvTr%%*oT zJRcOt|DG<|hxb3=Pu$#J@pl%ScgJJ?3z=R2aNg%|?1_&FaQ1{kM)6mr*iJ`Bvz1X6zFleNEm%~syi;+R1p!stT?pjj@1e#`WEE zFt!d)rR57WFW8Rle<~2o4DBTmM?ynV$1UgrgJrj1l$|5Xu-x;CUpA_~T{N=6dbR3U zzFl@af$oBIq-**zZxIIN;d+r%+SG70w17DL${6(ar<-oylPBluQTk zk%mDX5Aaan_P-elq-5Z5w@h%9lp<#imTI1Z{Du4Un8A>SVI3nF73ge0j5)3-n#TeQ znGjpOhl9GUuqfthasHvtIO%U!4~w={FHZ^+Iwn=-f}{lJuP9#}j|H-8o68qlo6Fg` zot53mi3?8_i_%@JR4zRKXl`P5;=+~3V`il?7M_fGzF8pQv9qahRe9qqh9qY2M8n5A zW>u8BBEAtP&I~M_`_fBd4)YoobbJEV^qq#Kv@1OpLCj;d3dE@^l|5KeN~!fs8_MSZ1@FTc+n1rBO2d z6GK{tdu+{4Jf1REj;3a2CZDP+YdXHfx(v575~=uNwYsR+tH zL8~?XE6Ws~t9IWZjgVV#dsj*F6?0Ux46P|cmUS!8nzJ3bSuGt(ch@{Da;GC#w#?$5 z>DubMwi)wJY<7Hachewpz$D&Mo;IZCnFZ2m-dWsS-r8V;hM*eejeZi9pnwBawbIS)gz{zj zOfVzm%T?EstF}@pp*WALN)XW39L~XP(eyk?ep;>Tai2vQ;XDRnU_#N%=N`Wdz6IY+ z!&eZ$a1p@^KGiWeh+p!lhX&Zk*ZfN00N-#&U49LYb-s75q2)#{(X#OxogH^#zaz3A zy+-foCGO`h@#uxx9(%VheH(j7T?h}#uEJ=KM-RAYcO$0PRqP$aTVnre^zSvf1+)aH!^RK-M_-h zdRzLpcuqYwh6(bEk?1ICeEAofF3H;OI&@#a+mYIpMUoPL}~hs z6YCKq?OJH1aIm1!jpG1OLQRJnj+f-9aCEdiQ=y|H(UG?*a(?uE#8hB0$kaVT8^?so ljEcfrfp0FjDg;rQ81W>C5`oSA2u|^e? Date: Wed, 21 Feb 2024 18:19:59 +0530 Subject: [PATCH 176/228] feat: on_sub java util --- utilities/on_subscibe-service/.idea/misc.xml | 6 + .../on_subscibe-service/.idea/workspace.xml | 106 ++++++ utilities/on_subscibe-service/java/.DS_Store | Bin 0 -> 6148 bytes utilities/on_subscibe-service/java/.gitignore | 3 - .../java/.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 62547 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 + utilities/on_subscibe-service/java/README.md | 0 utilities/on_subscibe-service/java/mvnw | 308 ++++++++++++++++++ utilities/on_subscibe-service/java/mvnw.cmd | 205 ++++++++++++ utilities/on_subscibe-service/java/pom.xml | 26 +- .../onboarding/OnboardingApplication.java | 20 -- .../onboarding/utility}/AppConfig.java | 7 +- .../onboarding/utility}/CryptoKeyPair.java | 2 +- .../onboarding/utility}/Routes.java | 2 +- .../utility/UtilityApplication.java | 13 + .../onboarding/utility}/Utils.java | 2 +- .../utility/UtilityApplicationTests.java} | 4 +- 17 files changed, 661 insertions(+), 45 deletions(-) create mode 100644 utilities/on_subscibe-service/.idea/misc.xml create mode 100644 utilities/on_subscibe-service/.idea/workspace.xml create mode 100644 utilities/on_subscibe-service/java/.DS_Store create mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar create mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties delete mode 100644 utilities/on_subscibe-service/java/README.md create mode 100755 utilities/on_subscibe-service/java/mvnw create mode 100644 utilities/on_subscibe-service/java/mvnw.cmd delete mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/AppConfig.java (90%) rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/CryptoKeyPair.java (94%) rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/Routes.java (99%) create mode 100644 utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/Utils.java (99%) rename utilities/on_subscibe-service/java/src/test/java/{com/ondc/onboarding/OnboardingApplicationTests.java => ondc/onboarding/utility/UtilityApplicationTests.java} (69%) diff --git a/utilities/on_subscibe-service/.idea/misc.xml b/utilities/on_subscibe-service/.idea/misc.xml new file mode 100644 index 0000000..6ff3c25 --- /dev/null +++ b/utilities/on_subscibe-service/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/utilities/on_subscibe-service/.idea/workspace.xml b/utilities/on_subscibe-service/.idea/workspace.xml new file mode 100644 index 0000000..823ccae --- /dev/null +++ b/utilities/on_subscibe-service/.idea/workspace.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1708517273278 + + + + \ No newline at end of file diff --git a/utilities/on_subscibe-service/java/.DS_Store b/utilities/on_subscibe-service/java/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6c38c6e8111e2ce84d56208c041c5125fd3006f4 GIT binary patch literal 6148 zcmeHKy-EW?5S}qX4s3!pmRsB94bE_O7D8%4lSoqJxS+AWMjI_`d=Z~O5MRKz@Fm1= zc1E+Or=^I_!0xvJd?fA;_|55mC3A*34OqEIInaaaAr_Qv6<( z?7c&0bV}p-G~NH;X=N#^q8QDq5j5G|%g*)I!{cshoqS_m%+jnk2%~jc(lIJd>4cVP zRlc~o|7cHZ@83QjZffmDjr-%1R^0mIRihyz$@9~ BNmT#< literal 0 HcmV?d00001 diff --git a/utilities/on_subscibe-service/java/.gitignore b/utilities/on_subscibe-service/java/.gitignore index ea7b7ee..549e00a 100644 --- a/utilities/on_subscibe-service/java/.gitignore +++ b/utilities/on_subscibe-service/java/.gitignore @@ -18,9 +18,6 @@ target/ *.iws *.iml *.ipr -*.mvn -mvnm -mvnm.cmd ### NetBeans ### /nbproject/private/ diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb28b0e37c7d206feb564310fdeec0927af4123a GIT binary patch literal 62547 zcmb5V1CS=sk~Z9!wr$(CZEL#U=Co~N+O}=mwr$(Cds^S@-Tij=#=rmlVk@E|Dyp8$ z$UKz?`Q$l@GN3=8fq)=^fVx`E)Pern1@-q?PE1vZPD);!LGdpP^)C$aAFx&{CzjH` zpQV9;fd0PyFPNN=yp*_@iYmRFcvOrKbU!1a*o)t$0ex(~3z5?bw11HQYW_uDngyer za60w&wz^`W&Z!0XSH^cLNR&k>%)Vr|$}(wfBzmSbuK^)dy#xr@_NZVszJASn12dw; z-KbI5yz=2awY0>OUF)&crfPu&tVl|!>g*#ur@K=$@8N05<_Mldg}X`N6O<~3|Dpk3 zRWb!e7z<{Mr96 z^C{%ROigEIapRGbFA5g4XoQAe_Y1ii3Ci!KV`?$ zZ2Hy1VP#hVp>OOqe~m|lo@^276Ik<~*6eRSOe;$wn_0@St#cJy}qI#RP= zHVMXyFYYX%T_k3MNbtOX{<*_6Htq*o|7~MkS|A|A|8AqKl!%zTirAJGz;R<3&F7_N z)uC9$9K1M-)g0#}tnM(lO2k~W&4xT7gshgZ1-y2Yo-q9Li7%zguh7W#kGfnjo7Cl6 z!^wTtP392HU0aVB!$cPHjdK}yi7xNMp+KVZy3_u}+lBCloJ&C?#NE@y$_{Uv83*iV zhDOcv`=|CiyQ5)C4fghUmxmwBP0fvuR>aV`bZ3{Q4&6-(M@5sHt0M(}WetqItGB1C zCU-)_n-VD;(6T1%0(@6%U`UgUwgJCCdXvI#f%79Elbg4^yucgfW1^ zNF!|C39SaXsqU9kIimX0vZ`U29)>O|Kfs*hXBXC;Cs9_Zos3%8lu)JGm~c19+j8Va z)~kFfHouwMbfRHJ``%9mLj_bCx!<)O9XNq&uH(>(Q0V7-gom7$kxSpjpPiYGG{IT8 zKdjoDkkMTL9-|vXDuUL=B-K)nVaSFd5TsX0v1C$ETE1Ajnhe9ept?d;xVCWMc$MbR zL{-oP*vjp_3%f0b8h!Qija6rzq~E!#7X~8^ZUb#@rnF~sG0hx^Ok?G9dwmit494OT z_WQzm_sR_#%|I`jx5(6aJYTLv;3U#e@*^jms9#~U`eHOZZEB~yn=4UA(=_U#pYn5e zeeaDmq-$-)&)5Y}h1zDbftv>|?GjQ=)qUw*^CkcAG#o%I8i186AbS@;qrezPCQYWHe=q-5zF>xO*Kk|VTZD;t={XqrKfR|{itr~k71VS?cBc=9zgeFbpeQf*Wad-tAW7(o ze6RbNeu31Uebi}b0>|=7ZjH*J+zSj8fy|+T)+X{N8Vv^d+USG3arWZ?pz)WD)VW}P z0!D>}01W#e@VWTL8w1m|h`D(EnHc*C5#1WK4G|C5ViXO$YzKfJkda# z2c2*qXI-StLW*7_c-%Dws+D#Kkv^gL!_=GMn?Y^0J7*3le!!fTzSux%=1T$O8oy8j z%)PQ9!O+>+y+Dw*r`*}y4SpUa21pWJ$gEDXCZg8L+B!pYWd8X;jRBQkN_b=#tb6Nx zVodM4k?gF&R&P=s`B3d@M5Qvr;1;i_w1AI=*rH(G1kVRMC`_nohm~Ie5^YWYqZMV2<`J* z`i)p799U_mcUjKYn!^T&hu7`Lw$PkddV&W(ni)y|9f}rGr|i-7nnfH6nyB$Q{(*Nv zZz@~rzWM#V@sjT3ewv9c`pP@xM6D!StnV@qCdO${loe(4Gy00NDF5&@Ku;h2P+Vh7 z(X6De$cX5@V}DHXG?K^6mV>XiT768Ee^ye&Cs=2yefVcFn|G zBz$~J(ld&1j@%`sBK^^0Gs$I$q9{R}!HhVu|B@Bhb29PF(%U6#P|T|{ughrfjB@s- zZ)nWbT=6f6aVyk86h(0{NqFg#_d-&q^A@E2l0Iu0(C1@^s6Y-G0r32qll>aW3cHP# zyH`KWu&2?XrIGVB6LOgb+$1zrsW>c2!a(2Y!TnGSAg(|akb#ROpk$~$h}jiY&nWEz zmMxk4&H$8yk(6GKOLQCx$Ji-5H%$Oo4l7~@gbHzNj;iC%_g-+`hCf=YA>Z&F)I1sI z%?Mm27>#i5b5x*U%#QE0wgsN|L73Qf%Mq)QW@O+)a;#mQN?b8e#X%wHbZyA_F+`P%-1SZVnTPPMermk1Rpm#(;z^tMJqwt zDMHw=^c9%?#BcjyPGZFlGOC12RN(i`QAez>VM4#BK&Tm~MZ_!#U8PR->|l+38rIqk zap{3_ei_txm=KL<4p_ukI`9GAEZ+--)Z%)I+9LYO!c|rF=Da5DE@8%g-Zb*O-z8Tv zzbvTzeUcYFgy{b)8Q6+BPl*C}p~DiX%RHMlZf;NmCH;xy=D6Ii;tGU~ zM?k;9X_E?)-wP|VRChb4LrAL*?XD6R2L(MxRFolr6GJ$C>Ihr*nv#lBU>Yklt`-bQ zr;5c(o}R!m4PRz=CnYcQv}m?O=CA(PWBW0?)UY)5d4Kf;8-HU@=xMnA#uw{g`hK{U zB-EQG%T-7FMuUQ;r2xgBi1w69b-Jk8Kujr>`C#&kw-kx_R_GLRC}oum#c{je^h&x9 zoEe)8uUX|SahpME4SEog-5X^wQE0^I!YEHlwawJ|l^^0kD)z{o4^I$Eha$5tzD*A8 zR<*lss4U5N*JCYl;sxBaQkB3M8VT|gXibxFR-NH4Hsmw|{={*Xk)%!$IeqpW&($DQ zuf$~fL+;QIaK?EUfKSX;Gpbm8{<=v#$SrH~P-it--v1kL>3SbJS@>hAE2x_k1-iK# zRN~My-v@dGN3E#c!V1(nOH>vJ{rcOVCx$5s7B?7EKe%B`bbx(8}km#t2a z1A~COG(S4C7~h~k+3;NkxdA4gbB7bRVbm%$DXK0TSBI=Ph6f+PA@$t){_NrRLb`jp zn1u=O0C8%&`rdQgO3kEi#QqiBQcBcbG3wqPrJ8+0r<`L0Co-n8y-NbWbx;}DTq@FD z1b)B$b>Nwx^2;+oIcgW(4I`5DeLE$mWYYc7#tishbd;Y!oQLxI>?6_zq7Ej)92xAZ z!D0mfl|v4EC<3(06V8m+BS)Vx90b=xBSTwTznptIbt5u5KD54$vwl|kp#RpZuJ*k) z>jw52JS&x)9&g3RDXGV zElux37>A=`#5(UuRx&d4qxrV<38_w?#plbw03l9>Nz$Y zZS;fNq6>cGvoASa2y(D&qR9_{@tVrnvduek+riBR#VCG|4Ne^w@mf2Y;-k90%V zpA6dVw|naH;pM~VAwLcQZ|pyTEr;_S2GpkB?7)+?cW{0yE$G43`viTn+^}IPNlDo3 zmE`*)*tFe^=p+a{a5xR;H0r=&!u9y)kYUv@;NUKZ)`u-KFTv0S&FTEQc;D3d|KEKSxirI9TtAWe#hvOXV z>807~TWI~^rL?)WMmi!T!j-vjsw@f11?#jNTu^cmjp!+A1f__Dw!7oqF>&r$V7gc< z?6D92h~Y?faUD+I8V!w~8Z%ws5S{20(AkaTZc>=z`ZK=>ik1td7Op#vAnD;8S zh<>2tmEZiSm-nEjuaWVE)aUXp$BumSS;qw#Xy7-yeq)(<{2G#ap8z)+lTi( ziMb-iig6!==yk zb6{;1hs`#qO5OJQlcJ|62g!?fbI^6v-(`tAQ%Drjcm!`-$%Q#@yw3pf`mXjN>=BSH z(Nftnf50zUUTK;htPt0ONKJq1_d0!a^g>DeNCNpoyZhsnch+s|jXg1!NnEv%li2yw zL}Y=P3u`S%Fj)lhWv0vF4}R;rh4&}2YB8B!|7^}a{#Oac|%oFdMToRrWxEIEN<0CG@_j#R4%R4i0$*6xzzr}^`rI!#y9Xkr{+Rt9G$*@ zQ}XJ+_dl^9@(QYdlXLIMI_Q2uSl>N9g*YXMjddFvVouadTFwyNOT0uG$p!rGF5*`1 z&xsKPj&;t10m&pdPv+LpZd$pyI_v1IJnMD%kWn{vY=O3k1sJRYwPoDV1S4OfVz4FB z$^ygjgHCW=ySKSsoSA&wSlq83JB+O-)s>>e@a{_FjB{@=AlrX7wq>JE=n@}@fba(;n4EG| zge1i)?NE@M@DC5eEv4; z#R~0aNssmFHANL@-eDq2_jFn=MXE9y>1FZH4&v<}vEdB6Kz^l)X%%X@E#4)ahB(KY zx8RH+1*6b|o1$_lRqi^)qoLs;eV5zkKSN;HDwJIx#ceKS!A$ZJ-BpJSc*zl+D~EM2 zm@Kpq2M*kX`;gES_Dd1Y#UH`i!#1HdehqP^{DA-AW^dV(UPu|O@Hvr>?X3^~=1iaRa~AVXbj z-yGL<(5}*)su2Tj#oIt+c6Gh}$0|sUYGGDzNMX+$Oi$e&UJt3&kwu)HX+XP{es(S3 z%9C9y({_fu>^BKjI7k;mZ4DKrdqxw`IM#8{Sh?X(6WE4S6-9M}U0&e32fV$2w{`19 zd=9JfCaYm@J$;nSG3(|byYDqh>c%`JW)W*Y0&K~g6)W?AvVP&DsF_6!fG3i%j^Q>R zR_j5@NguaZB{&XjXF+~6m|utO*pxq$8?0GjW0J-e6Lnf0c@}hvom8KOnirhjOM7!n zP#Iv^0_BqJI?hR5+Dl}p!7X}^NvFOCGvh9y*hgik<&X)3UcEBCdUr$Dt8?0f&LSur ze*n!(V(7umZ%UCS>Hf(g=}39OcvGbf2+D;OZ089m_nUbdCE0PXJfnyrIlLXGh2D!m zK=C#{JmoHY1ws47L0zeWkxxV=A%V8a&E^w%;fBp`PN_ndicD@oN?p?Bu~20>;h;W` ztV=hI*Ts$6JXOwOY?sOk_1xjzNYA#40dD}|js#3V{SLhPEkn5>Ma+cGQi*#`g-*g56Q&@!dg)|1YpLai3Bu8a;l2fnD6&)MZ~hS%&J}k z2p-wG=S|5YGy*Rcnm<9VIVq%~`Q{g(Vq4V)CP257v06=M2W|8AgZO0CC_}HVQ>`VU zy;2LDlG1iwIeMj?l40_`21Qsm?d=1~6f4@_&`lp~pIeXnR)wF0z7FH&wu~L~mfmMr zY4_w6tc{ZP&sa&Ui@UxZ*!UovRT})(p!GtQh~+AMZ6wcqMXM*4r@EaUdt>;Qs2Nt8 zDCJi#^Rwx|T|j_kZi6K!X>Ir%%UxaH>m6I9Yp;Sr;DKJ@{)dz4hpG>jX?>iiXzVQ0 zR$IzL8q11KPvIWIT{hU`TrFyI0YQh`#>J4XE*3;v^07C004~FC7TlRVVC}<}LC4h_ zZjZ)2*#)JyXPHcwte!}{y%i_!{^KwF9qzIRst@oUu~4m;1J_qR;Pz1KSI{rXY5_I_ z%gWC*%bNsb;v?>+TbM$qT`_U8{-g@egY=7+SN#(?RE<2nfrWrOn2OXK!ek7v`aDrH zxCoFHyA&@^@m+#Y(*cohQ4B76me;)(t}{#7?E$_u#1fv)vUE5K;jmlgYI0$Mo!*EA zf?dx$4L(?nyFbv|AF1kB!$P_q)wk1*@L0>mSC(A8f4Rgmv1HG;QDWFj<(1oz)JHr+cP|EPET zSD~QW&W(W?1PF-iZ()b|UrnB(#wG^NR!*X}t~OS-21dpXq)h)YcdA(1A`2nzVFax9rx~WuN=SVt`OIR=eE@$^9&Gx_HCfN= zI(V`)Jn+tJPF~mS?ED7#InwS&6OfH;qDzI_8@t>In6nl zo}q{Ds*cTG*w3CH{Mw9*Zs|iDH^KqmhlLp_+wfwIS24G z{c@fdgqy^Y)RNpI7va^nYr9;18t|j=AYDMpj)j1oNE;8+QQ)ap8O??lv%jbrb*a;} z?OvnGXbtE9zt;TOyWc|$9BeSGQbfNZR`o_C!kMr|mzFvN+5;g2TgFo8DzgS2kkuw@ z=`Gq?xbAPzyf3MQ^ZXp>Gx4GwPD))qv<1EreWT!S@H-IpO{TPP1se8Yv8f@Xw>B}Y z@#;egDL_+0WDA)AuP5@5Dyefuu&0g;P>ro9Qr>@2-VDrb(-whYxmWgkRGE(KC2LwS z;ya>ASBlDMtcZCCD8h+Awq1%A|Hbx)rpn`REck#(J^SbjiHXe-jBp!?>~DC7Wb?mC z_AN+^nOt;3tPnaRZBEpB6s|hCcFouWlA{3QJHP!EPBq1``CIsgMCYD#80(bsKpvwO)0#)1{ zos6v&9c=%W0G-T@9sfSLxeGZvnHk$SnHw57+5X4!u1dvH0YwOvuZ7M^2YOKra0dqR zD`K@MTs(k@h>VeI5UYI%n7#3L_WXVnpu$Vr-g}gEE>Y8ZQQsj_wbl&t6nj{;ga4q8SN#Z6cBZepMoyv7MF-tnnZp*(8jq848yZ zsG_fP$Y-rtCAPPI7QC^nzQjlk;p3tk88!1dJuEFZ!BoB;c!T>L>xSD<#+4X%*;_IB z0bZ%-SLOi5DV7uo{z}YLKHsOHfFIYlu8h(?gRs9@bbzk&dkvw*CWnV;GTAKOZfbY9 z(nKOTQ?fRRs(pr@KsUDq@*P`YUk4j=m?FIoIr)pHUCSE84|Qcf6GucZBRt;6oq_8Z zP^R{LRMo?8>5oaye)Jgg9?H}q?%m@2bBI!XOOP1B0s$%htwA&XuR`=chDc2)ebgna zFWvevD|V882V)@vt|>eeB+@<-L0^6NN%B5BREi8K=GwHVh6X>kCN+R3l{%oJw5g>F zrj$rp$9 zhepggNYDlBLM;Q*CB&%w zW+aY{Mj{=;Rc0dkUw~k)SwgT$RVEn+1QV;%<*FZg!1OcfOcLiF@~k$`IG|E8J0?R2 zk?iDGLR*b|9#WhNLtavx0&=Nx2NII{!@1T78VEA*I#65C`b5)8cGclxKQoVFM$P({ zLwJKo9!9xN4Q8a2F`xL&_>KZfN zOK?5jP%CT{^m4_jZahnn4DrqgTr%(e_({|z2`C2NrR6=v9 z*|55wrjpExm3M&wQ^P?rQPmkI9Z9jlcB~4IfYuLaBV95OGm#E|YwBvj5Z}L~f`&wc zrFo!zLX*C{d2}OGE{YCxyPDNV(%RZ7;;6oM*5a>5LmLy~_NIuhXTy-*>*^oo1L;`o zlY#igc#sXmsfGHA{Vu$lCq$&Ok|9~pSl5Q3csNqZc-!a;O@R$G28a@Sg#&gnrYFsk z&OjZtfIdsr%RV)bh>{>f883aoWuYCPDP{_)%yQhVdYh;6(EOO=;ztX1>n-LcOvCIr zKPLkb`WG2;>r)LTp!~AlXjf-Oe3k`Chvw$l7SB2bA=x3s$;;VTFL0QcHliysKd^*n zg-SNbtPnMAIBX7uiwi&vS)`dunX$}x)f=iwHH;OS6jZ9dYJ^wQ=F#j9U{wJ9eGH^#vzm$HIm->xSO>WQ~nwLYQ8FS|?l!vWL<%j1~P<+07ZMKkTqE0F*Oy1FchM z2(Nx-db%$WC~|loN~e!U`A4)V4@A|gPZh`TA18`yO1{ z(?VA_M6SYp-A#%JEppNHsV~kgW+*Ez=?H?GV!<$F^nOd+SZX(f0IoC#@A=TDv4B2M z%G-laS}yqR0f+qnYW_e7E;5$Q!eO-%XWZML++hz$Xaq@c%2&ognqB2%k;Cs!WA6vl z{6s3fwj*0Q_odHNXd(8234^=Asmc0#8ChzaSyIeCkO(wxqC=R`cZY1|TSK)EYx{W9 z!YXa8GER#Hx<^$eY>{d;u8*+0ocvY0f#D-}KO!`zyDD$%z1*2KI>T+Xmp)%%7c$P< zvTF;ea#Zfzz51>&s<=tS74(t=Hm0dIncn~&zaxiohmQn>6x`R+%vT%~Dhc%RQ=Cj^ z&%gxxQo!zAsu6Z+Ud#P!%3is<%*dJXe!*wZ-yidw|zw|C`cR z`fiF^(yZt?p{ZX|8Ita)UC$=fg6wOve?w+8ww|^7OQ0d zN(3dmJ@mV8>74I$kQl8NM%aC+2l?ZQ2pqkMs{&q(|4hwNM z^xYnjj)q6uAK@m|H$g2ARS2($e9aqGYlEED9sT?~{isH3Sk}kjmZ05Atkgh^M6VNP zX7@!i@k$yRsDK8RA1iqi0}#Phs7y(bKYAQbO9y=~10?8cXtIC4@gF#xZS;y3mAI`h zZ^VmqwJ%W>kisQ!J6R?Zjcgar;Il%$jI*@y)B+fn^53jQd0`)=C~w%Lo?qw!q3fVi{~2arObUM{s=q)hgBn64~)W0tyi?(vlFb z>tCE=B1cbfyY=V38fUGN(#vmn1aY!@v_c70}pa(Lrle-(-SH8Nd!emQF zf3kz0cE~KzB%37B24|e=l4)L}g1AF@v%J*A;5F7li!>I0`lfO9TR+ak`xyqWnj5iwJ$>t_vp(bet2p(jRD;5Q9x2*`|FA4#5cfo8SF@cW zeO{H7C0_YJ*P@_BEvm2dB}pUDYXq@G1^Ee#NY9Q`l`$BUXb01#lmQk^{g3?aaP~(* zD;INgi#8TDZ&*@ZKhx$jA^H-H1Lp`%`O{Y{@_o!+7ST}{Ng^P;X>~Bci{|Qdf1{}p z_kK+zL;>D30r6~R?|h!5NKYOi6X&I5)|ME+NG>d9^`hxKpU^)KBOpZiU^ z;|SzGWtbaclC-%9(zR-|q}kB8H&($nsB1LPAkgcm+Qs@cAov{IXxo5PHrH(8DuEMb z3_R#>7^jjGeS7$!`}m8!8$z|)I~{dhd)SvoH9oR9#LjO{{8O&r7w{d9V1z^syn&E6 z{DG0vlQF_Yb3*|>RzVop^{$mWp|%NDYj@4{d*-@O^<(=L=DMFIQHEp-dtz@1Rumd; zadt^4B#(uUyM6aeUJkGl0GfaULpR!2Ql&q$nEV^+SiDptdPbuJ=VJ)`czZ@&HPUuj zc5dSRB&xk)dI~;6N?wkzI}}4K3i%I=EnlKGpPJ9hu?mNzH7|H0j(mN3(ubdaps3GM z1i+9gk=!$mH=L#LRDf4!mXw0;uxSUIXhl|#h*uK+fQPilJc8RCK9GNPt=X^8`*;3$ zBBo77gkGB5F8a8)*OR10nK&~8CEMPVQyhY>i`PS{L^-*WAz$ljtU%zlG1lm%%U4Zw zms0oZR8b|`>4U1X*9JLQQ>m9MF5%ppoafz^;`7DbmmIENrc$hucekkE4I83WhT%(9 zMaE;f7`g4B#vl(#tNP8$3q{$&oY*oa0HLX6D?xTW3M6f<^{%CK4OE1Pmfue`M6Dh= z&Z-zrq$^xhP%|hU&)(+2KSSpeHgX^0?gRZ5wA8@%%9~@|*Ylux1M{WQ4ekG(T+_b` zb6I)QRGp%fRF)^T?i^j&JDBhfNU9?>Sl6WVMM%S?7< ze|4gaDbPooB=F4Y=>~_+y~Q1{Ox@%q>v+_ZIOfnz5y+qy zhi+^!CE*Lv-}>g^%G=bGLqD(aTN;yHDBH#tOC=X02}QU~Xdme``Wn>N>6{VwgU~Z>g+0 zxv0`>>iSfu$baHMw8(^FL6QWe;}(U>@;8j)t)yHAOj?SdeH;evFx-kpU@nT>lsrUt zqhV}2pD^5bC4786guG1`5|fK@pE6xcT#ns)vR|^?A08G62teHaE&p`ZrCBj_Swt*~dVt=5*RK6Y{% zABqK$X59BnrK3r3u=wxklRnA1uh+q`?T0kE1YhvDWF4OY#<(+V|R@R%tdkq2huF(!Ip+EpZF3zr*|9pmKHPo)Cu z;H+^s&`Ql}u=Jt~ZWj`bAw|i-3#7(2WuRU3DU{BW8`?!O?YO1M$*MMTsaEM!5Jyp~ z!gp6yR4$O%wQ8%dyz43ZPeoJwy;o;yg=S0^Y}%|)to>=N^`!3VMf1~}OZ`Dl$q&|w z9$!i3!i1uAgPTuKSWdBrDr*N$g=E#mdqfj*h;Z}OG`{n245+g;IKfdn!&gF2OtHaD zyGDzj@@d2!P(_Ux)3v;1ABTj__{w*kaRF-1YVU`})Acgk?(T*1YqEve3=5)8bkZK* z!Tus*e$h@^u z>#zV0771Bix~r&h2FJ9)%N{>s>?2tk1$bId)1#G;OKgn-U8jUo^AK;Hu)hQEi}swD(264kAS-SBCD$R(Ro0rh8~Le zzRwxbz_JHDbD+hTX15AWmVw!#rC)-zeZahQQmo6FG1)ah3uuyIuTMof}RO!`Y3^Fxn_-G$23RDOh(@NU?r6`*S?#E50)w zpcsgDZ-iO{;EesgDQq9;p*C#QH(sp~2w^zAJWaUL%@yo)iIL6y8;e_}=dwQc%k%;H zFt5lenH*`}LWd+fPqi;exJeRZgl&nLR%|a!%1x0RQ54cgyWBYrL>sskcAtPxi&8c( zw_K?sI*3n%S;lKiYpveBN08{rgV&-B1NN5Jiu07~%n#%&f!(R(z1)xsxtRBkg#+Lv zh21zX?aYDd_f}qdA`Os*j!eC<5)iUJ&Twj7?*p%vEOGElGhpRZsccM!<k}DeC;TY;rULQs3e}lZyP#UVb=6 zB$Dkm2FaHWUXr7<{R&46sfZ)&(HXxB_=e`%LZci`s7L6c-L7iF&wdmTJz`*^=jD~* zpOZ@jcq8LezVkE^M6D9^QgZqnX&x*mr1_Cf#R9R3&{i3%v#}V$UZzGC;Or*=Dw5SXBC6NV|sGZp^#%RTimyaj@!ZuyJ z6C+r}O1TsAzV9PAa*Gd!9#FQMl)ZLHzTr99biAqA(dz-m9LeIeKny3YB=*+|#-Gq# zaErUR5Z*Wh^e<+wcm70eW;f-g=YTbMiDX)AznDM6B73)T4r%nq+*hKcKF?)#vbv?K zPMe=sFCuC*ZqsBPh-?g!m*O`}6<}Pfj}Y1n9|Y@cUdD5GX_)6Sx9pPfS7 zxkt?g6ZwJ+50C7qrh6dMFmr7qah`FskT_H=GC92vkVh$WfZa2%5L99_DxyM{$#6HQ zx$VR-Wwt!q9JL2{ybEGJr$^?!V4m_BqDqt!mbs=QjHf340+^a{)waVvP0+98(BA$M ztWr&sM=juyYgvf`(SC}+y@QtYgU>0ghJ6VbU}|kEraR&&W%#;!#KI?le%g`e>ZVPiDrneh#&1(Y?uiMo^f5qo@{JEr(p9>8GhDa+PC9yG;lX+D?hQ^fZB&Sdox219zUj_5;+n<0@Wi3@DK`MU8FM!OFJ z8*_mTA-u!Ab#95FRVWTIqAL#BVQGxE_s?>Ql|@0o9vos&r<_4d!+Q6(_270)6#lu$ zV!j$a?_V0I<(3Z=J7C-K0a^Kc1Go9p&T6yQeAD+)dG-$a&%Fo0AOte~_Z&_m2@ue~ z9cKFf-A41Dz31Ooj9FSR`l?H5UtdP?JS=UU$jF#znE1k@0g%K?KQuwZkfDI3Ai)(q z#x_Yo6WR_Y@#6I_02S&NpcP<%sw!!M_3#*8qa+*4rS@x=i{-2K#*Qr)*Q$-{<_(<| z0730e+rubnT38*m;|$-4!1r6u&Ua2kO_s-(7*NGgDTe##%I>_9uW;X__b_k)xlv$; zW%K2hsmr>5e^Z~`tS-eUgWmSF9}Yg8E}qydSVX0nYZMX_x94QK?tw2>^;raVTqstR zIrNAX2`X~|h->dTOb9IrA!i5INpLV}99ES|i0ldzC`;R$FBY5&7+TIy8%GO8SZ37_ zw=^Swk?z+j-&0-cTE|LU0q@IKRa&C6ZlXbSa2vN5r-)*f<3{wLV*uJUw980AFkWN7 zKh{?97GmVu-0rs9FB6ludy|n`gN5p~?y51aJzBg6#+-=0pWdZ2n4xTiQ=&3As-!-6 zFlb|ssAJEJL#s8(=odfz8^9b#@RrvNE4gjuEITzAd7R4+rq$yEJKXP?6D@yM7xZ&^ z@%jnE3}bteJo{p(l`hu`Yvzg9I#~>(T;>c;ufeLfc!m3D&RaQS=gAtEO-WbI+f_#| zaVpq-<%~=27U8*qlVCuI6z9@j)#R!z3{jc>&I(qT-8IBW57_$z5Qm3gVC1TcWJNc% zDk?H3%QHno@fu9nT%L^K)=#sRiRNg|=%M zR;8BE)QA4#Dsg^EakzttRg9pkfIrF3iVYVM#*_+#3X+~qeZc^WQJvEyVlO@9=0pl!ayNOh|{j0j^a z+zi_$_0QKhwArW)sJ$wji;A`?$ecbr?(4x5%2pLgh#wggbt)#T^2R3a9m+>GcrUxU z*u-WTgHAN*e!0;Wa%1k)J_P(Vdp>vwrROTVae@6Wn04q4JL-)g&bWO6PWGuN2Q*s9 zn47Q2bIn4=!P1k0jN_U#+`Ah59zRD??jY?s;U;k@%q87=dM*_yvLN0->qswJWb zImaj{Ah&`)C$u#E0mfZh;iyyWNyEg;w0v%QS5 zGXqad{`>!XZJ%+nT+DiVm;lahOGmZyeqJ-;D&!S3d%CQS4ZFM zkzq5U^O|vIsU_erz_^^$|D0E3(i*&fF-fN}8!k3ugsUmW1{&dgnk!|>z2At?h^^T@ zWN_|`?#UM!FwqmSAgD6Hw%VM|fEAlhIA~^S@d@o<`-sxtE(|<><#76_5^l)Xr|l}Q zd@7Fa8Bj1ICqcy2fKl1rD4TYd84)PG5Ee2W4Nt@NNmpJWvc3q@@*c;~%^Vasf2H`y z+~U-19wtFT?@yIFc4SE_ab?s@wEUfSkOED}+qVjjy>=eac2^S^+|_3%cjH%EUTJ&r znp9q?RbStJcT*Vi{3KDa^jr4>{5x+?!1)8c2SqiCEzE$TQ+`3KPQQnG8_Qk<^)y_o zt1Q^f{#yCUt!1e(3;E6y?>p+7sGAYLp`lA3c~Y`re9q&`c6>0?c0E2Ap5seFv92#X z1Vldj!7A8@8tWr&?%;EBQ_Fwd)8A3!wIx`V!~~h(!$pCy7=&*+*uIzG@*d%*{qG#4 zX0^}}sRN^N=p{w(+yjv%xwb!%lnVTE7l1l6gJwQmq_G83J&Y98$S!r*L8}IiIa2E= zE!0tbOuEDb*No0-KB{zjo1k#_4FHtr{!)>o+Y@bll}Sa6D^xktI0H&l{jKAK)A(iz zB-N00F?~Z}Y7tG+vp)-q*v71(C}65$-=uXx^|R$xx9zZip-V>Hqeyfd(wteM)+!!H z$s+>g4I@+`h2>C|J;PhvtOq)`xm4;CyF}R<)!ma3T{Vf_5|zo;D4YI4ZDBkE(vMeE zb#ZV;n}CgA0w8x!UC2&5Z(K)9bibj#?~>R(72lFx_Am~jS?;7mo~p+05~XGD+(wV4 zEVYnf0N5+-7O+Gc1L!sPGUHv<6=cV8}*m$m`kBs@z zy;goR(?J^JrB7uXXpD00+SD0luk!vK3wwp(N%|X!HmO{xC#OMYQ&a7Yqv-54iEUK4 zVH;)rY6)pUX~ESvQK^w|&}>J{I?YlvOhpMgt-JB}m5Br`Q9X+^8+Xa%S81hO<1t#h zbS+MljFP1J0GGNR1}KwE=cfey%;@n&@Kli+Z5d>daJjbvuO3dW{r$1FT0j zR$c9$t~P50P+NhG^krLH%k}wsQ%mm+@#c;-c9>rYy;8#(jZ|KA8RrmnN2~>w0ciU7 zGiLC?Q^{^Ox-9F()RE^>Xq(MAbGaT0^6jc>M5^*&uc@YGt5Iw4i{6_z5}H$oO`arY z4BT(POK%DnxbH>P$A;OWPb@gYS96F7`jTn6JO@hdM za>_p!1mf?ULJZb1w-+HamqN__2CtI%VK`k^(++Ga0%z*z@k0wYJDqT^)~%|4O299; zh1_iRtc7you(kOK8?Q$R7v-@Qk4+i=8GD2_zI0%{Ra`_prF{+UPW^m5MCA&4ZUpZb z2*!)KA8b--Upp~U%f+rsmCmV~!Y>Gzl#yVvZER2h;f&rkdx{r#9mc8DZMJaQXs?SL zCg3#>xR6ve8&YkP*`Z=lng|Ow+h@t*!Ial*XQg3P;VS8@E1C)VS`?L9N+rxlD7bxC z3@Ag)Vu?#ykY`ND+GvRYTUP&-KDMiqly$Z~uFXt^)4Jjk9RIs*&$?-UPM*d7&m${m zm12kaN3mV1J|c6f$>V+{lvHp~XVW3DU0;cBR>7|)4bo{xa1-ts-lYU-Q-b)_fVVl`EP5X}+J9EzT20x8XIv=m7witdu7!3Lh=KE#OyKpT1GWk{YAo^ny|fvZt<+jmsFs=l*%e& zmRkBt5ccv4O7!HAyv2~rsq*(FmMTm?@TX3&1`nu|7C^F{ad%GLuoX}Rl}6`)uHF_xlx^gVca+mGH4T8u8;q{S*x3=j;kelz^atO~)v!Q_BT z4H6%IA}bvfuk0_vweELeEl8N5w-Q1GF!@f{VKnbyYB2?}d&QvI-j}~RI_+9t9$tC2 z94m=3eLi=sQb^S5;fqP?3aaXc&`}`lq z&M8dOXvxx9Y1^u_ZQHhO+qP}nwkvJhwoz$Mp6Qcq^7M#eWm}!3U@s07hop` zW24|J{t$aB`W>uBTssEvYMyi$hkaOqWh+^(RV_1MYnE0XPgW?7sBDk=Cqs(;$qrPEflqa0ZE?A3cBfW%0RPA235Wb6@=R_d>Sez; z`spwa50bq?-zh+id~Q!T`AYn`$GHzs;jxIw(A1_Ql&f|qP}|bon#H;sjKmSDM!nyn z>bU8l%3DB3F+$}|J^da!!pN|DO!Ndc2J)wMk!+Rr1hes#V}5o(?(yQSphn|9_aU<- zn|nsDS{^x&tweP;Ft`2ur>Koo2IdXJDsr6IN)7vB41Yy-^Wbo9*2th2QA@C zE0-0Gk12YOO?d_Guu6b3&(PIL`d zh4{`k54hu9o%v1K3PGuccez-wdC<&2fp)>`qIIaf)R{5un7-vwm=>LD7ibnJ$|KyE zzw`X*tM0S|V(I3vf454PY{yA5lbE+36_<1kd=&0Xy4jfvUKZ0$Jq!AG4KS7DrE9rph;dK^6*#CIU9qu7 z?)6O`TN&MCWGmUVd1@E2ow2`vZ1A#nGo8_n!dmX77DCgAP1va*ILU+!a&$zdm6Pa6 z4#|*&3dM+r_RJb%!0}7X!An&T4a4@ejqNJ;=1YVQ{J6|oURuj8MBZ8i7l=zz%S4-; zL}=M^wU43lZVwNJgN|#xIfo$aZfY#odZ6~z?aNn=oR1@zDb=a(o3w`IGu&j>6lYxL z&MtqINe4Z>bdsHNkVIu$Dbq0wc#X-xev221e~L zbm8kJ(Xzij$gF4Ij0(yuR?H1hShSy@{WXsHyKtAedk4O!IdpR{E32Oqp{1TD{usJi zGG@{3A$x%R*pp8b$RQo4w&eDhN`&b~iZ2m3U>@9p1o5kXoEVmHX7I6Uw4dn((mFw` zilWrqFd=F5sH$&*(eJB52zaLwRe zz`sruIc=Ck75>v5P5kd>B2u=drvGPg6s&k5^W!%CDxtRO)V6_Y_QP{%7B>E~vyMLG zhrfn8kijyK&bX+rZsnSJ26!j$1x+V!Pyn|ph%sXWr9^f&lf|C;+I^Fi_4;`-LJI&F zr;5O@#4jZX=Yaw0`pUyfF4J8A9wE#7_9!X|_s8~YUzWu&#E^%4NxUA3*jK-F5R3LP2|msHBLmiMIzVpPAEX)2 zLKYjm3VI4r#7|nP^}-}rL+Q4?LqlmBnbL+R8P%8VmV{`wP0=~2)LptW_i682*sUR# z+EifOk_cWVKg-iWr^Qf4cs^3&@BFRC6n0vu{HqZzNqW1{m)3K@gi$i}O(hT`f#bT- z8PqCdSj~FncPNmMKl9i9QPH1OMhvd42zLL~qWVup#nIJRg_?7KQ-g3jGTt5ywN;Qx zwmz4dddJYIOsC8VqC2R%NQ>zm=PJH70kS|EsEB>2Otmtf-18`jUGA6kMZL3vEASDN zNX%?0+=vgsUz!dxZ@~)eU17m4pN3xGC0T;#a@b9Iu0g_v*a3|ck^s_DVA^%yH-wt= zm1)7&q6&Rq#)nc9PQ6DKD{NU=&ul10rTiIe!)x^PS~=K(wX9|?k&{Mv&S$iL9@H7= zG0w~UxKXLF003zJ-H%fGA4Db9{~#p&Bl7ki^SWwv2sfoAlrLMvza)uh;7Aa_@FL4b z4G>`j5Mn9e5JrrN#R$wiB(!6@lU@49(tawM&oma6lB$-^!Pmmo;&j57CDmKi)yesg~P;lJPy9D(!;n;^1ql)$5uYf~f z&GywSWx=ABov_%8pCx=g-gww_u26?5st=rdeExu?5dvj^C?ZZxDv@Si^nX~2qA&K= z2jr;{=L(x~9GLXrIGXs>dehU^D}_NMCMegdtNVWyx)8xHT6Qu!R>?%@RvADs9er;NMkweUBFNrBm1F5e0_>^%CwM6ui}K_MpRqLS0*@lAcj zB6TTCBv>w2qh)qU3*kN+6tPmMQx|5Z0A4n67U-nss90Ec_rDF}r)IR4PE{$8;BSt= zT%6|jyD^(w6a*A5>_|TkMqx~e$n@8{`q?|)Q&Y4UWcI!yP-8AwBQ#P`%M&ib;}pli z9KAPU_9txQ3zOM#(x}*lN8q$2(Tq1yT4RN0!t~|&RdQMXfm!81d0ZuyD}aG3r4+g` z8Aevs3E_ssRAMR+&*Q30M!J5&o%^(3$ZJ=PLZ9<@x^0nb>dm17;8EQJE>hLgR(Wc% zn_LXw|5=b$6%X zS~ClDAZ?wdQrtKcV9>_v1_IXqy)?<@cGGq#!H`DNOE1hb4*P_@tGbMy6r@iCN=NiA zL1jLwuMw&N-e9H(v7>HGwqegSgD{GSzZ@sZ?g5Y`fuZ^X2hL=qeFO(;u|QZl1|HmW zYv+kq#fq_Kzr_LaezT zqIkG6R+ve#k6!xy*}@Kz@jcRaG9g|~j5fAYegGOE0k8+qtF?EgI99h*W}Cw z7TP&T0tz4QxiW!r zF4?|!WiNo=$ZCyrom-ep7y}(MVWOWxL+9?AlhX<>p||=VzvX`lUX(EdR^e5m%Rp_q zim6JL6{>S%OKoX(0FS>c1zY|;&!%i-sSE>ybYX3&^>zb`NPj7?N^ydh=s=0fpyyz% zraFILQ17_9<ettJJt~I+sl=&CPHwz zC9dEb#QFQcY?bk11Y=tEl{t+2IG`QFmYS>ECl;kv=N6&_xJLQt>}ZQiFSf+!D*4Ar zGJ~LFB7e_2AQaxg*h{$!eJ6=smO(d2ZNmwzcy3OG@)kNymCWS44|>fP^7QkJHkE9JmLryhcxFASKb4GYkJ|u^Fj=VdF0%6kgKllkt zC|_ov2R4cJ2QjjYjT6jE#J1J<xaNC>Xm;0SX<`LuW*}*{yQ3c9{Zl=<9NP z^2g5rAdO!-b4XfeBrXa4f{M0&VDrq+ps&2C8FYl@S59?edhp~7ee>GR$zQI4r8ONi zP^OA+8zrTAxOMx5ZBS03RS@J_V`3{QsOxznx6Yt*$IuEd3%R|Ki&zZkjNvrxlPD$m z%K+rwM!`E&Z46ogXCu!3 z8use`FJJ?g_xi?~?MxZYXEu=F=XTC8P3{W*CbG3Wk)^31nD~W>*cJ@W4xg%Qqo7rq z`pUu8wL!6Cm~@niI*YmQ+NbldAlQRh?L!)upVZ)|1{2;0gh38FD&8h#V{7tR&&J}I zX1?;dBqK}5XVyv;l(%?@IVMYj3lL4r)Wx9$<99}{B92UthUfHW3DvGth^Q0-=kcJ1 z!*I9xYAc$5N$~rXV>_VzPVv`6CeX(A_j3*ZkeB~lor#8O-k+0OOYzTkri@PVRRpOP zmBV|NKlJT?y4Q82er)@lK&P%CeLbRw8f+ZC9R)twg5ayJ-Va!hbpPlhs?>297lC8 zvD*WtsmSS{t{}hMPS;JjNf)`_WzqoEt~Pd0T;+_0g*?p=dEQ0#Aemzg_czxPUspzI z^H5oelpi$Z{#zG$emQJ#$q#|K%a0_x5`|;7XGMuQ7lQB9zsnh6b75B9@>ZatHR_6c z0(k}`kfHic{V|@;ghTu>UOZ_jFClp>UT#piDniL(5ZNYXWeW0VRfBerxamg4su5<; z(}Ct2AhR@I-ro0}DdZLRtgI@dm+V`cRZjgV-H+aXm5|Mgz`aZX63i<|oHk-E)cABn z0$NR?(>fla7)Ong28FZSi9Yk0LtYl5lZw5wT!K5=fYT$avgkMKJWx~V#i@7~6_{dM zxDDPIW2l{O2Elv#i^cjYg~lGHRj(W*9gD`(FILKY$R`tL2qo&rtU*c;li!V`O$aV{ z!m|n!FAB2>MR_FVN*Ktv5+2dW4rr3YmfEheyD+48%USM#q6)w%#2}~=5yZE1LLcth zF%VtefH&#AcMx7)JNC$P>~OFuG6sK}F7V$D7m!{ixz&inpAVpFXiu^QruAw@Sc7Y2 z_A^V(2W_+KTGRp2aQSMAgyV#b3@{?5q@hPEP6oF3^}|@8GuD6iKbX;!LI!L=P#Za zL$Zuv#=x3fseRMZ()#SQcXv->xW`C|6quwqL1M&KByBj z2V`}(uL4JB-hUs6304@%QL~S6VF^6ZI=e-Nm9Tc^7gWLd*HM-^S&0d1NuObw-Y3e> zqSXR3>u^~aDQx>tHzn9x?XRk}+__h_LvS~3Fa`#+m*MB9qG(g(GY-^;wO|i#x^?CR zVsOitW{)5m7YV{kb&Z!eXmI}pxP_^kI{}#_ zgjaG)(y7RO*u`io)9E{kXo@kDHrbP;mO`v2Hei32u~HxyuS)acL!R(MUiOKsKCRtv z#H4&dEtrDz|MLy<&(dV!`Pr-J2RVuX1OUME@1%*GzLOchqoc94!9QF$QnrTrRzl`K zYz}h+XD4&p|5Pg33fh+ch;6#w*H5`@6xA;;S5)H>i$}ii2d*l_1qHxY`L3g=t? z!-H0J5>kDt$4DQ{@V3$htxCI;N+$d^K^ad8q~&)NCV6wa5(D${P!Y2w(XF!8d0GpJ zRa=xLRQ;=8`J2+A334};LOIhU`HQ*0v4Upn?w|sciL|{AJSrG_(%-(W9EZb%>EAGG zpDY?z1rQLps`nbCtzqJ#@wxU4}(j!ZQ{`g`g*SXlLah*W9 zyuh)UWoRCknQtd~Lk#BT_qjwj&Kw8U)w=owaJ;A5ae}3)y>{neYNS`|VHJdcSEBF# zBJ6a;T)u;^i#L~LVF-X7!E$SggILXMlsEy~v}K*DM2)f@U~g|Q6I-Pss@)`>fgFWx zsq&7pe!|VA-h;@=fBF{(mR1^{1>ukTYUdyF^#A+(|I_&nm{_xaKn3h4&yMyym2k-wMFg(s@ez=DPmuB%`| z6;e@HQKB(|!PU1sW)W6~x|=8m6rL~4dQ9LTk|RzL-_(_77B4I~ZG=q7K%qHiv!FD8 zmt;Vnhb{ymaydv2V;X-5p zTt2ln?kaB9&(dH_X70^@rrCfz)nwfa9LYTHXO(IPcTEf$QiEhTpl??L+`Eetyqof8 zzl=q)?KdYni!C_9b8Z3xm7r5<5ZG-0uA`u^7Dm7k4mAsQ(rkoWy*^DZJa~#y6+hNG zh?7{D9$a9LS`a@SvZ5?C{JUHovWU9KI}z8YV4pWftx21v*Q;MpU{+b@>Or(}pwO^fu0qA3_k_Bo2}lIxvmMhucG-o>O=+R6YxZ zjs!o%K1AA*q#&bs@~%YA@C;}?!7yIml1`%lT3Cvq4)%A)U0o1)7HM;mm4-ZZK2`Lj zLo?!Kq1G1y1lk>$U~_tOW=%XFoyIui^Cdk511&V}x#n4JeB7>bpQkYIkpGQRHxH$L z%tS=WHC~upIXSem>=TTv?BLsQ37AO88(X+L1bI<;Bt>eY!}wjYoBn#2RGEP49&ZH-Z_}R_JK_ z>o*_y!pOI6?Vf*{x-XT;^(_0}2twfk`*)_lLl0H-g|}BC?dm7CU|^-gNJ~rx z($>97WTKf71$?2|V$Ybpf~Aj@ZZOcb3#uRq51%4^ts-#RMrJhgm|K3QpCsPGW=2dZ zAr5-HYX!D*o#Q&2;jL%X?0{}yH}j*(JC4ck;u%=a_D6CrXyBIM&O#7QWgc?@7MCsY zfH6&xgQmG$U6Miu$iF(*6d8Mq3Z+en_Fi`6VFF=i6L8+;Hr6J zmT=k0A2T{9Ghh9@)|G5R-<3A|qe_a#ipsFs6Yd!}Lcdl8k)I22-)F^4O&GP&1ljl~ z!REpRoer@}YTSWM&mueNci|^H?GbJcfC_Y@?Y+e4Yw?Qoy@VLy_8u2d#0W~C6j(pe zyO6SqpGhB-;)%3lwMGseMkWH0EgErnd9a_pLaxbWJug8$meJoY@o-5kNv&A$MJZ=U z^fXPLqV6m3#x%4V*OYD zUPS&WHikdN<{#Yj|EFQ`UojD4`Zh*CZO4Cv`w^&*FfqBi`iXsWg%%a< zk@*c%j1+xib(4q^nHHO^y5d8iNkvczbqZ5;^ZVu%*PJ!O?X-CoNP*&tOU!5%bwUEw zQN?P*a=KKlu{`7GoA}DE=#nDibRgecw>-*da~7&wgow}|DyCJq!-Lp8a~(zR@tO1 zgu(4s4HptPGn(HmN2ayYs@g+yx1n`nU3KM{tQHhMHBw7f#gwru$=C()`aKZAl^dYc ze7fC)8EZEXOryk6AD&-4L+4cJ&M@3;;{R)mi4=`ti7IZByr^|_HNsjcNFu?mIE)jD za2j)FPwRY!R_YR-P?URm0Pti*e#5jmfK)6EvaKCT{h)kbJl{AGr1Ekt}pG?^e z*botRf-RsB8q10BTroj{ZP**)2zkXTF+{9<4@$aNDreO7%tttKkR3z`3ljd?heAJEe<0%4zYK?};Ur*!a>PbGYFFi(OF-%wyzbKeBdbkjv^i9mn@UocSS z4;J%-Q$l`zb&r*Pb`U;3@qkc=8QaPE9KwmlVwAf01sa*uI2*N`9U^3*1lLsM9dJ(4 zZBkU}os|5YT#Z;PD8xVv!yo$-n{-n4JM5ukjnTciniiT`(cZ6sD6~67e5_?8am%!w zeCLUxq~7x-!Xg#PgKV&caC@7mu<86am{WaXo(lAemt4~I$utSp(URWpYNo$RvU*$N z#%iiA+h`(E;BUg;=I!#EaxO89bUK3*v5Nc3GPmURC5TqzC|))DsFNtJICH6oBW6#q z+B(N{ey+^mk_{!@ z)VhAWXG=_0j|0f9iJ;c404PiIFqK)(AD05Xh`Fk`r$^b`v+>*g+_+h@r)e+ELJ45) z?20~u<}HQyQ5AsBz(teF9!!_GLXnm{5Z0e{Ki*@!=&3x4-RcjBn##DDzHJ|KSZ5(E z9=tFZ)p~-}x%9sCY27)2i>(E-^OiYT?_)a;yXAGR$y+E`myMd;xDA#_Q49t*E}&ql#H~|x z2J2R1_#2lt91NnF!uqW%_=HlbF?A{B{n>}9$g5QF!bh_a7LTU~Jyz}7>W5{_LAov{ zy2_dmGy)d)&7^bJyUjEw%3xj{cuG0Eo zwL*XQB*Oi=r&HIIecC1%lbE;Y-*5|cL955S+2@uR18JDL<0;;Uc2Q9JEyo1R!!sz_ z#BqnkGfbLP#oQJk3y}nwMd(3Tt^PVA#zXnYF7D0W1)#+`i?@cm}fBkKD z+Mpcuim53|v7;8Tv(KraEyOK`HvJq^;rlNzOjIbW&HJDFqW>doN&j7)`RDv#v|PQ+ z03WnB4Y4X@Fe-@%3;He*FjY1MFmkyv0>64Cp~FIDKQTwmFP~_CxZOf{8gPy}I<=JC zo%_bmue&$UU0|GG%%99eI!m#5Y1MD3AsJqG#gt3u{%sj5&tQ&xZpP%fcKdYPtr<3$ zAeqgZ=vdjA;Xi##r%!J+yhK)TDP3%C7Y#J|&N^))dRk&qJSU*b;1W%t1;j#2{l~#{ zo8QYEny2AY>N{z4S6|uBzYp>7nP_tqX#!DfgQfeY6CO7ZRJ10&$5Rc+BEPb{ns!Bi z`y;v{>LQheel`}&OniUiNtQv@;EQP5iR&MitbPCYvoZgL76Tqu#lruAI`#g9F#j!= z^FLRVg0?m$=BCaL`u{ZnNKV>N`O$SuDvY`AoyfIzL9~ zo|bs1ADoXMr{tRGL% zA#cLu%kuMrYQXJq8(&qS|UYUxdCla(;SJLYIdQp)1luCxniVg~duy zUTPo9%ev2~W}Vbm-*=!DKv$%TktO$2rF~7-W-{ODp{sL%yQY_tcupR@HlA0f#^1l8 zbi>MV~o zz)zl1a?sGv)E}kP$4v3CQgTjpSJo?s>_$e>s2i+M^D5EfrwjFAo(8E%(^ROV0vz0o z-cg0jIk24n!wxZainfH)+?MGu@kg$XgaMY-^H}z^vG~XC7z2;p2Kv`b^3S#b5ssMOJ7724v>S36dD zeypxJ<=E~sD4f5wX060RIF-AR0#{Z z=&y$r8A-e6q18lIF{@O9Mi%dYSYT6erw!@zrl=uj>o(3=M*Bg4E$#bLhNUPO+Mn}>+IVN-`>5gM7tT7jre|&*_t;Tpk%PJL z%$qScr*q7OJ6?p&;VjEZ&*A;wHv2GdJ+fE;d(Qj#pmf2WL5#s^ZrXYC8x7)>5vq_7 zMCL}T{jNMA5`}6P5#PaMJDB2~TVt;!yEP)WEDAoi9PUt89S2Cj?+E0V(=_sv4Vn6b z_kS6~X!G;PKK>vZF@gWpg8Zuh%YX^2UYPdCg7?EH#^gkdOWpy(%RnXyyrhmJT~UJw zAR;%Zgb6z(mS+o9MT|Sc6O({!i0pzk;s9?Dq)%tTW3*XdM3zhPn*`z45$Bg!P4xfy zD*{>30*JsSk?bQ-DgG62v>Vw-w`SA}{*Za7%N(d-mr@~xq5&OvPa*F2Q3Mqzzf%Oe z4N$`+<=;f5_$9nBd=PhPRU>9_2N8M`tT<-fcvc&!qkoAo4J{e3&;6(YoF8Wd&A+>; z|MSKXb~83~{=byCWHm57tRs{!AI<5papN(zKssb_p_WT@0kL0T0Z5#KLbz%zfk?f7 zR!vXBs36XaNcq5usS7<>skM_*P$e*^8y1ksiuokbsGFQ_{-8BAMfu!Z6G=88;>Fxt z|F-RU{=9i6obkTa0k~L#g;9ot8GCSxjAsyeN~1;^E=o5`m%u7dO1C*nn1gklHCBUw z;R(LgZ}sHld`c%&=S+Vx%;_I1*36P`WYx%&AboA1W@P;BvuFW+ng*wh?^aH4-b7So zG?9kFs_6ma85@wo!Z`L)B#zQAZz{Mc7S%d<*_4cKYaKRSY`#<{w?}4*Z>f2gvK`P1 zfT~v?LkvzaxnV|3^^P5UZa1I@u*4>TdXADYkent$d1q;jzE~%v?@rFYC~jB;IM5n_U0;r>5Xmdu{;2%zCwa&n>vnRC^&+dUZKy zt=@Lfsb$dsMP}Bn;3sb+u76jBKX(|0P-^P!&CUJ!;M?R?z7)$0DXkMG*ccBLj+xI) zYP=jIl88MY5Jyf@wKN--x@We~_^#kM2#Xg$0yD+2Tu^MZ1w%AIpCToT-qQbctHpc_ z>Z97ECB%ak;R<4hEt6bVqgYm(!~^Yx9?6_FUDqQQVk=HETyWpi!O^`EZ_5AoSv@VbUzsqusIZ;yX!4CsMiznO}S{4e>^0`c<)c~mC#*{90@+T@%EQ~>bovc8n_$bvqkOU7CrYe8uI5~{3O7EijeX`js z-$LNz4pJA7_V5~JA_Wl*uSrQYSh9Wm($%@jowv^fSPW<~kK&M*hAleywHd?7v{`;Y zBhL2+-O+7QK_)7XOJAbdTV-S`!I)t~GE8z+fV7y;wp#!wj75drv;R*UdSh(}u$%{VSd0gLeFp;h6FkiVz%g=EY3G#>RU;alRy;vQmk*| z@x-ba0XKE%IyL4OYw6IXzMiS(q^UDk=t(#XgkuF`{P?=k8k3r)rmhkv`vg@kiWd34 z-~t+1aV3SabTbG=nQYs>3~E<}{5@0g**LAWi*~SfRZhGcgP{e5T!0M7CU}`f@r8xI z0bx%sI!?5);-wG+Mx&S=NRfIi>V-wP(n&$X0Bhd)qI^ch%96s6&u7qpiK8ijA=X_R zk&|9f$GXf-;VgnrxV83Cp-Q!!sHH`5O^o~qZu!xny1t?(Au(EAn)D??v<1Uo;#m7-M@ovk|()C(`o>QMTp}F?> zakm3bHBKUjH-MHXDow7#Z|@wea1X9ePH;%YA)fCZ9-MD)p^(p!2E`aU9nmJlm;CXQ zkx~$WQ`Yq{1h5k>E>Ex{Z=P=)N*0b8_O({IeKg?vqQ)hk=JHe z5iqUKm!~mLP0fnRwkCO(xxTV@&p+o8wdSP$jZofYP}yEkvSc z5yD-^>04{zTP7X44q9Af&-wgt7k|XtncO&L@y-wFFR44RsPu57FRvIBaI^Pqy_*DV z@i13CsaR5@X@xH=NT3}T`_vsy!a02n80eQqya=-p7#YW`Jc0z!QglGg`1zeg6uXwI zsB~hlNMo)kFL(V3Q1<%8yoI6X7ncn-&&Uh3rL@S(6@wKAXt6Wr=a2ObI7}8$D-FoI z>AJA>WsBEMi5ba6JhJ%9EAi&ocd(ZsD|MsXwu@X;2h#|(bSWu@2{+c7soC`%uo{sMYq&Vyufb)?OI59ds)O+kyE8@G z@tlpNr0UO~}qd0HQve6njJ zda2+l$gdX7AvvGhxM6OToCuQ|Zw|9!g1)O+7>~{KNvASjp9#Cqce-or+y5xdzWL3gLWt2oa+T(I+{j(&bF1laUsJB{fOgE-B}qslaS>C z)TjzG8XecbS%a+?yT!0QmTex?E478;D|sL*oS4C-g0Tq(YoH|eyxJ#1j088C|U-w5id`%Sz7X_w#l+U9+)$|2no<}5J zRb_9@0esSr?n}HvVGbD5@$p$8k4?qOe-GNOk3-K^Mw>Xg+drCKi5@$GTeijpI;;IG ziD<&go`ptLC&^<0jw^l0aY?_pUUK+xp#0Bk66iQ29vpR)VBE{JOJ&OL^gKsN<&t<| zCMLTYMSDG5Ie9O>6Dl#T{@cscz%)}?tC#?rj>iwQ0!YUk~R z$rB-k=fa9x&631Z9Mfqj_GRoS1MzqSMEdaZ2!isP19Sr>qG8!yL(WWF)_&{F)r>KnJGSciSp!P0fqHr+G=fGO02Q#9gHK zpwz+yhpC4w*<9JO@#(MdkZcWbdCO5B!H`Z|nV?UtcBo96$BgX+7VYMwp@b-%;BrJu zMd*K!{1txv{kHKPDs9?WZrz_^o1Tq2P=+=|E=Oy4#WE{>9}*9(apqhmE`&AeBzQgQ zELFLCmb~q|6y0FCt|B}*uI*ayZ#6=$BpGtF{Jfye#Q>FZ?BPnk)*Qmd?rNG^tvFUU z_b&antYsZnUR6Q9tQUy81r$&ovT#fy;(Db4F&M*C=KxQgHDrRcVR#d+ z0(D|*9#u`w_%2o3faI{?dNd9$#5nj1PROHNq z7HJ(;7B1ThyM>a@Fo^lJb2ls2lD`}ocREH|5pKN;$>gFyM6k)kZG;lA;@kSJIqUhf zX%dhcN(Jtomz4(rNng&1br3Xx33EvCWz%o8s;SpRiKEUFd+KJ+u|gn|J85dZ)Exc&=V|Ns8Xs#P>qv6PX&VAJXJ(ILZO!WJd0 z`+|f5HrEj~isRN7?dBHotcPI7;6W48*%J(9 zftl1Tr`bKH*WNdFx+h;BZ+`p!qKl~|Zt5izh}#pU9FQKE97#$@*pf38Hr8A+`N+50U3$6h%^!4fBN zjh^cl#8qW5OZbvxCfYzKHuyeKLF4z^@~+oqlz9(Hx8vypIiUlt!(vs}_t#4@nh$s; z>FYERg*KD#Xs+W4q-V-IBQK!)M1)Aa+h+V+is)z!_=gEn&^ci7<DEEmYcoSh?WdXUsP7O4)&lQXA(BVM5jI8s6;mO}94AC0gG(`>|T)yuV1l~i-ejCCt zoejDhX0nrZDP|x9u4zp%S2UeDzV`o#pBGu1tZ-$<9TIbN=ALwhQ0=9S{8#}Uu8n-~ z5~xIvUhLSz@c@0|me$CdZCpZl(vQw@a0Y4^{T0w_>pOkwI^x4KkBf3qGmm)nG|Ps5 z_XTY~^b^mL&_*yjl~RRIi&eS(>y?y}O4-)nWyTEPpQAb#Xz8SnnfIL+nAcNL9nqV9 zRL|eyF)RKI5-kJO6}>Q89XmgY@b1&!JI>g3ryZ@jN2v3vm7O`AL!BTWNouJzV+$+Y zYY}u%i>K6=IYU2O$2TAyVjGt?wgF9xCj;?EK(8fWu!!~48`3u^W$eUlCh*91PLxu1 zRY(F7Q3s7h$Q-p&L$ucN}it*-9KR z_<wHu?!dav0$P+PI3{J8?{+l|n&2YMLV2 z+hRta$A5WpCXl1RNbYBsX8IGX{2v>U|8_I-JD56K|GexW>}F_e_g_1r?08v8Kz{V$ zT=6aGMk>ibvRO@Yrc@ezaD0%ydHkXGHrR{7>q~~tO7ChJflwa4-xL|@#YIJejC5VT zInU4CjQ9V0+lClQY=vh^s4MadwQmk7li{54Y;Ht}gkZOIh9(vfK?3kXLoD72!lHD# zwI-Jg|IhT=Y#s|tso1PWp;|aJ2}M?Y{ETyYG<86woO_b+WVRh<9eJu#i5jxKu(s~3 z4mz+@3=aNl^xt{E2_xewFIsHJfCzEkqQ0<7e|{vT>{;WlICA|DW4c@^A*osWudRAP zJut4A^wh@}XW4*&iFq|rOUqg*x%1F+hu3U6Am;CLXMF&({;q0uEWG2w2lZtg)prt` z=5@!oRH~lpncz1yO4+)?>NkO4NEgP4U~VPmfw~CEWo`!#AeTySp3qOE#{oUW>FwHkZ3rBaFeISHfiVSB7%}M) z=10EZ1Ec&l;4 zG98m5sU!pVqojGEFh8P{2|!ReQ&hfDEH2dmTVkrS;$dN~G2v-qnxn^A2VeHqY@;P} zudZD5vHtVvB*loIDF1M7AEEvS&h0;X`u}!1vj6S-NmdbeL=r{*T2J6^VA7F`S`CDd zY|=AA6|9Tu8>ND6fQhfK4;L3vAdJPBA}d6YOyKP&ZVi%z6{lbkE|VyB*p1_julR^k zqBwjkqmFK=u&e8MfArjW-(Ei8{rWso1vt5NhUdN|zpXqK{ylJ8@}wq-nV~L4bIjtt zt$&(1FTIs+aw}{&0SO4*sa0H2h&7g}VN5uYjfed5h7eGp$2Wu*@m9WIr0kxOc}fX9eOWh zFKfV>+SD$@kESKYm{F*J90XQjr$!<~v(J%&RMuQM+6CkmnYZDGlOUdq}%)VA& zl#acS%XE2KuX~7IamK`og@C`21~*cEEc#PZM6HT*Veb_l&Ej~j0zL7p0Eo`mMu(=X zJ$v;&Lya75I4C^saKROgfi(fdP0C$GM3WyZn%mm3yEI>|S&O(u{{S<}ihUp#`X&_z zmQBma;82#`C;dR5Sx09e07FvtJLhZ{9R~|$FCdU6TDNUwTc9kNct?8e@o2MpQDrkg zN?G+aYtTjiUPA=RX5o{4RYu}6;)ET>TcgL^VpfIpluJ|lQR(_)>6k%L^FZmoK-Wm- zR5qy0P)hm8yvqOL>>Z;k4U}!s?%1~7v7K~m+gh=0c9Ip_9UC3nwr$%^I>yU6`;2kV z-uJ%y-afzA7;BC7jc-=XnpHK+Kf*tcOS>f5ab2&J&5hIOfXzs=&cz|Qmrpu6Z);`R z0%3^dioK5x?o7t~SK7u5m{dyUZ#QUPqBHYn@jETeG>VU=ieZuJ;mm^j>dZM7))cw?a`w8R z%3M0R=kdOt^W^$Kq5Z%aJ(a$(*qFpy^W}Ij$h+Jnmc9eaP(vB@{@8t zz=RQ$x4XYC#enS$fxh@;cSZ|D%7ug;0z{C8I8h{KocN-cyv3UG_nk99UNS4ki^OFkYea`q`rs zG@qdMI;4ogcd5Tr`di1JBg4I*6CFvCID_2SN5&)DZG&wXW{|c+BdQ4)G9_{YGA@A* zaf}o^hQFJCFtzt&*ua~%3NylCjLtqWTfmA-@zw;@*?d&RE3O8G&d;AVC|rZrU}jx# zC-9SF`9;CbQ(?07o8Q9E12vi)EP@tOIYKEKnO@-o!ggkC)^#L-c40iZtb4Y-cS>$I zTn~+>rn*Ts>*y*z^b3-fAlne+M-*%ecrI^rmKAVv23cB`aWD?JDJ5NIafRvRr*~~C z)99Afs`BPK!5BFT)b_^8GyH*{22}yDq;be`GnPl=vW+ITnaqzl(uYOHhXi}S!P+QZ z4SwfEPuu&z4t#?6Zaw}bvN{;|80DfxCTuOdz-}iY%AO}SBj1nx1(*F%3A-zdxU0aj z`zzw9-l?C(2H7rtBA*_)*rea>G?SnBgv#L)17oe57KFyDgzE36&tlDunHKKW$?}ta ztJc>6h<^^#x1@iTYrc}__pe0yf1OnQmoTjWaCG`#Cbdb?g5kXaXd-7;tfx?>Y-gI| zt7_K}yT5WM-2?bD-}ym*?~sZ{FgkQ9tXFSF zls=QGy?fZ=+(@M>P3Y>@O{f44yU^fP>zNzIQ0(&O$JCd_!p?2;} zI6E1j@`DxzgJvqcE@zgapQ?tophO14`=14DUZ*#@%rRi``pi0lkNgidSsHGjXK8gO{drQoNqR&tRjM4>^DtW`)fiRFO4LE=Z+nCBS~|B3gZsh`Y?-$g z@8@Z$D7C!L9l=SWoE;(+*YirPLWvBd$5Ztn3J3EaGM+#pW#@{3%yksGqy(2Bt5PVE zf*fICtPp77%}5j#0G8<=v=)LR>-a3dxja8cy3m$=MZ2#$8mbLvxE%NptMd+L?mG`v zF1cANFv17DqP^P5)AYHDQWHk*s~HFq6OaJ3h#BUqUOMkh)~!(ptZ2WP!_$TBV}!@>Ta#eQS_{ffgpfiRbyw1f)X4S z_iU`lNuTy86;%!sF3yh?$5zjW4F?6E9Ts-TnA zDyx5p1h$Z3IsHv7b*Q{5(bkPc{f`2Wfxg*Z#IvQ;W_q9|GqXGj<@abo)FyPtzI~i25&o zC!cJR%0!}lLf^L2eAfZg7Z69wp{J?D6UhXr%vvAn?%)7Ngct4Hrs@LZqD9qFHYAWy z4l=2LI?ER&$He2n`RiG&nsfLv?8$Cl)&d8a-~-N`I|&EPa@Y=v@>0Gl?jlt>AUY;H z`**5bpS#VGhdp4pKbf3iEF*>-eXg_$bqt5Dc%q0+)R50>zd^l7sN5R5Z)Ut+oz-8_ zJ`Z9HE9(=wRTD)T=%GZTEi9K5naPzlfE$|3GYGLRCLsnqLi8Sc6y&iskqA&Z$#7Ng z7Q@C0)6k;J$TlQ+VKZ5)-Ff_BNoIMm+~!@Cv1yAUI-U!R)LHc@+nSUzo$GlRb+8W< zYPG%NFfr;!(RlnvBbN~~EpT6Xj5*^Z&73tdIQ$LZu`vkfzdTKa5|JJtQ_rm4g$9LO zKtgYVdW=b<2WGM3I_j|Rd8gZ3j;)S#AT(aP^d>9wrtQS_+K>pZDX^?mN!Z>f^jP@1 zlJ;i79_MgOAJa`%S9EdVn>ip{d!k6c5%zizdIoB9Nr!n`*X#%6xP1?vHKc6*6+vKx zmEt|f^02)S_u_wlW_<`7uLQU%{wdH0iojOf_=}2=(krE<*!~kn%==#0Zz`?8v@4gP zPB=-O-W=OO3tD19%eX>PZj3YfrCt0sEjgTd#b$buAgBri#)wW14x7QcHf2Cneuizz z368r7`zpf`YltXY9|2V{stf8VCHgKXVGjv$m!hdDf0gi`(Q!(Pyg~FO28Vr#!BYP| zI)qG2?Ho=1Us9dTml}-ZOR?g5Vk)f+r=dbCN*N1=qNfG>UCLeA8pd3Ub-pRx1b3FA zEn`CIMf`2Mt3>>#3RkE19o}aMzi^C`+Z>8iIPHSdTdmjCdJBtNmd9o0^LrJc9|U9c zD~=FUnSyghk7jScMWT|SHkP(&DK$Z=n&lGm+FDTpGxfoIyKV)H6^nY~INQ#=OtIT! zyB*J=(#oHf=S)MNOncW->!c0r0H#=2QzobO&f@x&Y8sYi-)Ld;83zO$9@nPPhD}yt z{P`*fT@Z(?YAmF{1)C;o?G@dfd2$c+=Av*|;P@Yz1KnclB-Z-fJQ-=+T*g>0B7!g# zQH{dHt_%wj=wlmT&m59)TQ~xK)gB6f^EY$=1zcbGf~Q>p_PzDCHR6lndGmqPY2)&w z$Th^K%1v@KeY-5DpLr4zeJcHqB`HqX0A$e)AIm(Y(hNQk5uqovcuch0v=`DU5YC3y z-5i&?5@i$icVgS3@YrU<+aBw+WUaTr5Ya9$)S>!<@Q?5PsQIz560=q4wGE3Ycs*vK z8@ys>cpbG8Ff74#oVzfy)S@LK27V5-0h|;_~=j1TTZ9_1LrbBUHb?)F4fc)&F7hX1v160!vJc!aRI>vp*bYK=CB(Qbtw7 zDr2O^J%%#zHa7M5hGBh#8(2IBAk}zdhAk$`=QYe^0P6Bb+j5X)Grmi$ z6YH?*kx9hX>KCI04iaM_wzSVD+%EWS)@DR&nWsSBc2VIZ>C(jX((ZiV0=cp}rtTO&|GMvbmE4FpBF5Rd z6ZG=>X&>N3?ZN2^11pXEP4L?XUo`qrwxgQm4X~RCttXmZAhnhu4KDK=VkKq?@@Q_Z za`*xyHrsAEsR zV(7)2+|h)%EHHLD3>Qg{>G|ns_%5g5aSzA#z91R zMDKNuIt@|t?PkPsjCxUy&fu^At*yUYdBV!R_KOyVb?DO&z$GLJh9~b|3ELsysL7U6 zp24`RH+;%C(!bWHtX&*bF!l-jEXsR_|K~XL+9c+$`<11IzZ4>se?JZh1Ds60y#7sW zoh+O!Tuqd}w)1VxzL>W?;A=$xf1Os={m;|NbvBxm+JC@H^Fj$J=?t2XqL|2KWl$3+ zz$K+#_-KW(t)MEg6zBSF8XqU$IUhHj+&VwsZqd7) ztjz$#CZrccfmFdi_1$#&wl~A*RisBaBy~)w|txu1QrvR1?)2mb&m2N$C(5MS%hSX)VJnb@ZGXB5^%(<#1L@ zL^>fBd+dEe`&hxXM<0A9tviIs^BDkByJdc~mtTYr!%F7Q1XnK2$%h$Ob30*hSP$Bt zDd#w{2Z%x^Wpv8!)hm>6u01mY!xmPgwZ#Q0148)SxJc3Udt!-&}eRO^LN ze26pQB!Jhg&Z>#FD>`C`sU44><=v>O>tJdLs!HPpV#AM32^J@Za-9J(CQjKxpzXao zQfRkWP%g9P8XV21MmoHfx{DICLSc*t4qVeQL9t}&Pz0rM}YTba@XsD=XMW@FxFM{QYQJHvM(JsUSa3mcTUl9^qcVA zBveO--fqw%{#QGR1vy;x88+qMcgzmcYc#8U`CPPt6bl?uj%w_`b~9JliftnOa|ziW z|6(q&STs_*0{KNa(Z79@{`X&JY1^+;Xa69b|Dd7D&H!hVf6&hh4NZ5v0pt&DEsMpo zMr0ak4U%PP5+e(ja@sKj)2IONU+B`cVR&53WbXAm5=K>~>@0Qh7kK*=iU^KaC~-ir zYFQA7@!SSrZyYEp95i%GCj*1WgtDId*icG=rKu~O#ZtEB2^+&4+s_Tv1;2OIjh~pG zcfHczxNp>;OeocnVoL-HyKU!i!v0vWF_jJs&O1zm%4%40S7_FVNX1;R4h^c1u9V@f z`YzP6l>w>%a#*jk(Y82xQ@`@L(*zD&H>NY`iH(iyEU5R$qwTKC5jm4>BikQGHp^)u z-RQ`UCa70hJaYQeA=HtU1;fyxkcB2oY&q&->r-G9pis)t$`508$?eDDueFdW=n5hJ z08lH$dKN$y#OEE@k{#|<%GYY=_c~fHfC@pD54KSP9{Ek@T47ez$;m$}iwR}3?)hbkwS$@p2iVH0IM$lB*XYA+#}-re|UNzCE)SOYwy z=Y!fkG4&I%3J(_H#UsV#SjHulRIVcpJ`utDTY{k&6?#fzt~@Om=L(vs6cxAJxkIWI z@H7)f2h%9!jl@C!lm+X4uu;TT6o0pd7 zteFQ(ND@djf#o2kTkjcgT=dHs7ukmP0&l8{f;o3JuHGd2Op*?p7?Ct=jA*tIg{MZk z$2Lsc0e8Tdcwrjx|_Ok?9uB3Il|^2FF%X#ck}WoIvrzQXN%kT$9NI{79Wm~gZ3`8I+O`)`n30feZ( zDO-fl6IG3c^8S;Y_M-)+^CmM0tT^g0?H#>H8!oC8W%oU!~3|DJ?)~LT9*&GAQG13zOGq6gs*={cu|(V7{R$y@{-iV*9q@AD(#Ktb}J&3&k|5Djs$)9WM7!6#EaJ_ilvbfUvyh8c?-{n zfuFrC0u6}UJZ7aj@(cNG_(CKgjQQTA-UK@-MVmick zot}6F%@jhq(*}!rVFp5d6?dg|G}M*moyLriI!PQDI;E1L1eOa6>F9E6&mdLD>^0jJ z09l?1PptuV65gm=)VYiv<5?*<+MH~*G|$~9Z3XEy@B1-M(}o&*Fr9Sv6NYAP#`h{p zbwbUE3xeJ;vD}QMqECN)!yvDHRwb7c1s6IRmW!094`?Fm!l~45w)0X`Hg+6Y0-xf# zSMemBdE)Q=e^58HR{kWrL5-H0X6pDu%o{0=#!KxGp0A;6{N5kI+EoY_eTE%2q|rwm zekNeLY-R?htk!YP2|@dbd8TWG4#G)=bXlE{^ZTb^Q$}Er zz)Fp)ul24tBtQFIegdI37`K$VR3tVdi<(fIsu{#QMx=$&CK9M8oN%3Mk;>ZPd-;Q- zn|sSKSnc-S0yrw#TlA$+p{J~u=u98s>IoL@cNLOxH=+1m?;t1bR$vR=M$US&Z8DO3 z_&zhQuId1$wVNsS=X?&s(ecIi#00o{kuPs6kpYkL$jMyGW8U7mlCVaZeEL=HsIxqm zFRLxWin8B>!Dc#9Z#t0RNQiR-@5J+=;tC7|1D*~rxcwHa5iIVD@99cCFE@BukUC-S z^iJdt?dwU)kH2VY9?|zVShMbZctzFRz5Q4tiXa^>@U%jDYq}$rSyc#p2wXr}mc0qq z^lT>$y)N(Qg0dwmEwTopneoU(y)>Mj+f{iHM0o|>ZtCg-itPj4addYz??aE)Rp&hk z_SI)%XeSf=SjZq18h!Cc>Xy&EynnxdHQ){(x@g|ZA%`3LU^KzX02c5N;F#tEk1)7v z(|V9tO3>?^X|kQ*rRBf4>mWW2$-Lx})|M7z125&VHcxsCqB!<$l1F$zCrJ+nm0f3Z z%Hq^=SKpHyV2@Y*Cu2x>fXC0SscnR*($zEB{KOniJcpn@e`PMH*_Q6*0Z^8RNCEvZ z+UU9!927p9YZ&g=bnUvQUZcdisyn;-4;ACXOe-Xor9K8Qbp{ldE17+G@VQT+9ZJQ*9dZoXfU2ue|mMhrrZk2R7&~YjFW4`BTq45UwVc6JORKU)wBCTanITh0GD}s$`C5pb(9{b9 znwee6j%?-UV)_7opOioCf5@C?@w^@g& z&68+oMmV;5JW@TT63&CSDrfYL2$L)pVseDtAwPwleEM3F^-Ufn3PpfxFmx6o zQ`Wq9x#d$e`VKn5LOXNsrqhGao7~|s(u~drPrZ+;aP!C%z4NskZstCbAibD}O%8Ij zb~C(taxco~WzJLxhL1T}3ctXMbV6}_z=IZN9L0|SxLSe`$X`<)BhM`$1&&)e_}fCh z=idVL<+u6Vn{&ksP*ZLlMo$fC`dtzF_?~L?4Rril2G4%v5^7sUa^&8aMtMX&mtapl zD(dW|cisM3fqMaB`8?QbkyiUl2g>hMB5EoS&IB8TdoC~)b$nT=`%GgU`k-)+8}`)F*~I~DXMaTP%kZftx11~?iALs5J+&Rom#p%Y z>dH}-euH4u=_V3hc6^*2WMtL!9%yRTJ93p}@aV0zdY*?xchFI>m+UivV=;aMFp0P~ zwB8P)wvV6D-GL?6hJ#g7Hy7=2i^&Od#S=j!;Rc_yjO!*4aN7{vqzg2t-R|Dav%_NDk z`H_FVlSi==(~f-#65VmQ{EE92x<03lwo5p)s=ZJ^L7PlS>132Whr zR6v~t(#I+(`usYLCoO;Rt8j&b^5g_xgs*98Gp|N}b>-`HtVm)MscD)71y?(K6DRCZV26RsHPHKk)EKKZA%C99t3$t^B0-k5@?E>A-YMbFe?>ms?J?_guHHNU(;id*>xH zTrtam+Aq?n@-y@uY@A?hy?1qX^eLu_RaH4Ave?A8NapgQF=C%XI7wlcCf4<6BRo_% zBXxxc*A6-3CruF?3i8HOdbc%>N=-iiOF+9HX|ht6SCkz;A^am&qi_I&qk1B(x<=(m z>QG)nswCOLl_1{SZ@_eE#m^qb6#6DoMsB*)`17ui+XvF%(}|J4G$z2G*;E!1ERnAH z@q%=#uV6kBddqy4=g>!VTV)9*1=i{wJ}Ep!I*?)uJdA(LwE?(!?;}_u=^M2NShWC_ z*7l4aBJ=!QVU2-iehgb`$vOI8zkm{W%QO~?xOD;NgI;Iqa3#^$^U5D&McReLe&qs# zR<^@QpR4#W~Laz+QBsPt@3L#KF`Yr8}jgHe;5(cfpQ=;Zjtbt;c%y^#-m=hqOT z;KAYakW+$w0&F}>K10&SiPcD9SrDOuczj@U#W})5jGU-_htU`U6Q%wdy((%?J}y+$ z=$4jw1N nJo)qTxG{D(`3*#8tY|67hJRF;)r6F|#I`Ar6I0aafRa=kr-Z0I^}9xf^u;G5iEQCbpv3b#S#%H|HYHsQaHK$! zU#3Fpz8*^pK%RRmX<_09eIVziB0jOgPgFnI-*QcwEBtBiO#v!>{W1cLNXyw3D9M|A z*oGy(u8BkDA1c;MsXmpK^-~pl=We^RYnhZ4bz*)Q)C2G+E3tgx9PzU0T>c|1ilS!T zyE=bz`=wskDiOi!@!l?Y))#%{FM`}7r~X)i1)1*c6_2Q!_1{)fp%cS|YF+Q-CB%d< z=zYus`Vt@Mx*a7V)=mpLS$-5viaKgNB=+zN657qy0qR94!cTtX-Z%KBCg4OKw7b=t zr=`7q5Ox=lJ%!G5WIyNQC1xpqYU0{!I$hyrk!6%De$gp<_*Gc?ES(OwY8U^)Kjgc{ zSlhpXDb|;{+y9`u{EuMz54rlky2~p6xX2>MV6BZ&k`$q%q7v(xYps2wr9e8^4<;CB zc)eAT~B^rjzO6<4BDDH;il6 zFsM8jL+agQ;zazW(uiQjM%fPf2N~_p{cy29XP11_lQFpt`t#9nlk}>fv((FZt-dBa zuMIc4HmPHW04n0TTG9ug9;&OV9euL$Ib|+M7}}L~z4e%%%b|r~6OQj(S2d7XfYn#xp8;KQ55UYu#gY*De5j6Cc z#R%?rqwpy7I1(kpU7B*Pq=etXeYUn04jg%ZPjYqQNa$==yTG=6KX+=;i2Xg+kjV2T*Gc!(ef z`Q4fR*TA=M5-}z+s%YO+!K{k}S**ic&>o4_Tmv$EQTOp7F6TXPCj-UTXy?OQ=%*y62Qajk{rXbR%jMCOFMiVE3KekQa4xR}B%=iPtd8BXo~q$OX_ zSp910{Ew;m|GATsq_XiJ3w@s(jrj^NDtr(Dp!`Ve!Oq?|EJ9=vY2>IfrV{rT%(jiY zi}W@jA2iqd=?q>s;3%?@oi7~Ndo3Ge-2!zX58j(w&zVlPuXm3rcHb7O0RsM|!Ys(b zh(=*&Aywo3vuJoWZnU!u2_4bNkDTc&&bCYc%T zM~~xYxS#3KXFzQ@OXdc%9QDOxqiTd_> zT;(DX9{5dIuC4pO_xy+3{Ov)1I7j!Z)6&nHUvTRP>VU5dm#849icG)cvl0QOPkCIzG^lOp4#UcNr`VhBp(Ha%8@KPlvT*5u!v_$b#b~%sn3K{mu zaxeD%Q~{;Lw03ZAq(Pc-IVj>n*h3l2{sqioCMGatQY0kx zi`1(WWDQ=;gmLSGptEQ%UFC)th@|71<8eiRtX&Mx@#1q#nMF_BMfQdS>!!Qkx2o}= zuqRi?`UOX5P3fP%M+71Q$ctH4Av}bXED#fQ`KR4!b~60nsAv^*M7c-x`|~B}XIuq% zlqIJOf>WvlhQ@Uw$du|14)tZ?; zPNZ|xZSwp1y+d4sut8E4*l2JWR|~o0A9vD-?zC-w zDc@=wE1YKb*OMSi_Kx}&w;#h3>sHp|8^hnA3w?-WK)X?@Z2dgV7`9Cupf-B2RE4x^ zwlw+~!V9C^tyb`J;m2}ksD`w}G9`yu(^--{SQ+wt^Fu4Li~Fft!3QO`upSkAU?o;# z(1Q%GUVWbbkTK-M=T+ULkk3s6Dc9`G4CO6|=&-S&D+rbJQ$`Y-xL~ol;kc(l)VbU>{&>bV+*?ua;$bnDc29RW+Ig16)Vf6=L|fMR_P2b7>6}0 zdlB#-gj|j*C~M=F^2=K*k~=tl6YM3SXXi&K-`EvEXnWz&4D-^hQRBJI3gKKDj^6|> z*WhHSim1qAffNt60Mve9lfw^+&0bx-AM0%j>QP3%W=S@(l=(nrJ678mRQ(#+sI@d{ zdb#5fo#T;hK7xJ=M58wZf|?DHwD%!OZ3JrTGV5#{cfQwuiMvz%!CQ}CubJ7`z?@rSF<+KHNV2goc)a6hP0oHB@3LLKSH2w{um&J*z1Ka2 zLIR>lvOvh>Oxe%?3A@v<_T|}${zf_&@C~^FCo#jB(W9VLO?DX{)n(BQ0(V0`mI|9Y z#U3WwxixJkU_NTvA>5q(A@r2dnEXJp#6B=pww$XGU}~1~c``UKqQb=^*2P|4Dq*_! zhY^i61Sy%T5$Td0O6^C>h(xVvT!}Y##WeT8+s+Uuz=7)~V$>!zU;%d>H)rm*6^IrsCma%|cifwDLk_ z!^W2voQ)D;I$=v2E>iSaBw!d7aD+|LWl2iD!cBw`Q5p1~fk_xGiPi8e^mY&#viTAk zmaKL8m;JQ4bY(n6uBZt02z#noMMxTfF-RzjKre-c+@B)#J3pN-Zv7F}JtAwNk3j?OkpVCL6W1)Q$FLAj zGI!tX;g`O{%pt=0|q54Jyj##w*4e*|_;Us2Tn?!#^R(>u}|FAw1G_ z#wQsagnj9$TAC`2B_XgB$wNq~Sxgl?#0+QWWcB{G`c6~&SosbtRt}Tukw`TQ!oG1= zYyL(y<;Wh+H24>=E}Gs=Hs2%fg;&Qdvr74{E!R?Bd zIRQ?{{xkLJ_44P@y3^#(Be%(pk%$liKbUUo76wSoVfJmt9iTKL3z{uW6L&?jYg>EY zsx{kRiW@q%<$VZvbS(TKKTO4{Ad6l^IeY(F^3}=mX9|FZmQ`~RErNxlBPl3ast}W$T4V?SW=6kIGn@-^`qJv| zZXwhK4Kl1a4E}nLI`rdOi?^pd6;LZ-|8G&INHgOeC5q{_#s+SXb0r(;5ryHFsoTJD zx$VtNDh=-Tx3t!NTlk=hgAaSM)#U}e>_-Ex(|JoX*hWmBPPdTIa-2(BIOUJ|Iddy| zwY*J%z%W$}*;uSoB!BIJB6N6UhQUIQE_yz_qzI>J^KBi}BY>=s6i!&Tc@qiz!=i?7 zxiX$U`wY+pL|g$eMs`>($`tgd_(wYg79#sL4Fo+aAXig?OQz2#X0Qak(8U8^&8==C z#-0^IygzQfJG4SWwS5vko2aaOJn*kM+f1-)aG{T43VJAgxdP(fJ4&U{XR90*#a)G8+clOwdF?hJ?D) zmxu>0>M|g_QRHe_7G|q6o`C>9x4xd$Gl7lAuR~+FtNid=%DRsnf}YI*yOToWO%xnP zY*1G5yDnTGv{{xg5FhWU65q3-|-(+-rJ2WCeSJn(7Az>ej4Jp9+l-GyZ_| zJ8}>iA4g|}q1AhEEv#uWR&$g&Uyht?fVU(qk(j?^D`))s>oG08pow!f>P1u71P%oL2)UC4GeS87&G?{)NE;D=my1Q9{~;y zJULE=bG6jXE28Y11YmoZoo945`MM*`v%5b=_02*0cwzDve#3(4M}NPt`)?SCa|7*q z-94ks(R6WH-l9fE4m4}10WSu&O`|;ZCIT%vL$_pbABY!}s33@~gIvZ0H4co|=_-T$ zF#lC7r`89_+RL9wYN=E3YwR?2{$^ki(KKd>smX(Wh*^VmQh|Ob5$n_%N{!{9xP~LJO0^=V?BK8AbCEFBhDd$^yih$>U z(o{RReCU{#zHSEavFNdc8Yt<%N9pd1flD{ZVSWQu*ea1t#$J5f6*6;tCx=&;EIN^S}*3s%=M#)`~=nz!&Q0&{EP|9nzWyS<#!QxP;!E8&3D}?QKh^ zqGum|+;xu9QE=F#fe2ws5+y1Igr&l`fLyLKry=1}(W+2W`waeOR`ZXlW1B{|;4sE3 zn^ZVlR11hiV~p<~TaSen8I~ay#7Ql=-_|U@$8yjZsZ=Vi+^`JV2+kn+oiSUi%omO_+7}saXnJ9 z5ETilbag(g#jZPopCgJu+n@(i7g}3EK2@N zd64$77H5a`i%b%a^iRjMaprwzWz(`=7E6QY)o)gek7H)yZ-BLw^6FAoHwTj9nJtWc ztKaytMlWGLg29W{?gr|rx&snb@XyvR_}x3fmC>d=-nQp5ab3*whTw}DfUcKlMDDx` z-%?ek^*|Kqooy#>2lfklZ|jN4X$&n6f)RNNPl(+0S>t(8xSeOGj~X0CGRrWmm(WXT z))DDW_t&y$D#2`9<-+JT0x1==26*gpWPV~IF=rePVF%e-I&y$@5eo~A+>yZ&z6&7> z*INESfBHGNegTWga&d@;n;FSCGyW?}e_Qw#GTLHo*fWxuuG@I~5VA!A1pOdRTiPA~ z^AGe(yo=9bwLJD}@oDf$d+34~=(vIuPtOKiP}obDc|?@hY}J*@V|UynBeAkYa?S{@ z_f$U=K+>deTAi&=a*xv>Ruyw$UsTWY=Yn=xjf;s)6NQu>_niQ_idmzIwuL`Scf)f= zyzK?D5a5)^D@H&qN%F6Zd0JeXX*Knbe~VLe^gi|?JK67&mB4jrapV-$`hCQT;C{%T z*pjxB+Y|~LD9bmMN%Iq}S$F$x1yWU7@GcR91V8h;!O2I5MN_rq*gRx(k8T!1WSDTp zr9eJO4$~H94aG^6k5p8k=kFJ>4lnY0q_Bsa$@vTRW6uY?slH|Qt)Yu6Yun&pfJ zBi!h;6x?FDs&79#PT*HSCEUsKws#s%TFy*=2PAfb`>gEPBn+D-WdfXA?MkB=<8kb_ z1+4D11mdHG0EcAyg4dneLtfJ8)RyHQl@6hWJNe(d_EjyCHf7%Xsd)S4A-4COz{G@% z5xQ!P>AS@H@;4Ws)N91)3A6PleMe2<& z!(zv#%Uc?N`(Xmm)OJPYt)BM`nRjoWA&P0Yxl@c9Y02zlPH1J5l$nhPrMwu=atkz4 z)a-1+OEL;d@ctx=s<<+3Sv1VYy0RYmiji|#hy$66#`5;u~BkH4^$EGZ-Y4xyZ=%3KuaeLYKAUr$xMtIh_5mga> zPz<#G0mQ7IxEw-yO}BueN}RaFlg$RwCDB)vLF$wDu%qZyLYsPKdcbHD23$qn9i#JFqIo#OK?u7db2-$GatzO!On87%}Br};~#}n zziVB;qf_4(K$u>Qyz$ln_kBGS!CD-t4Y}9oxL@7@Sx*?NOAzdeINUD>Hl#*V%pfA; zSA`==YatS*G*crJ3`3ll4)vKss&)UtY#7ZxiVoG%9(4<%`WWcjX2jV(^g7Yhj+h5J z$5=?S=tuCyEt74^6jo@6y|@~N>&cVfFNtaRl=)Gm!vR;Bc$3-;ySCI$%kdmjQ|si` z{$q_YCe6vjy6re9jGN|`43D``)1PODtz0)vhV4XV36nVpOnMx2uM%qZ<3TtcI%>BQ zf0(J`{JqPPJxw>k#&nIvoZ5e9Sno)B2r+E0G} z@&M|zf4E0Q$O*NBR2I;?i7N} z@2^Su#`%qeX}m3cbSojiLk#84kvW1fICNPS`OyT0SpUoA0(s^2m~J<^eKE!dhJx_N zG_T}0&(<*an>oF=@?6?55g&IxSgY3?7|@pmDRE6gJyJNPH6un~%0hZ@?h=hI6O$b^ z)29#<4$E)cE-5IFbRpk9JVrw$$966UDyw;Iym4OY4Fc!&s1ZH4BJ1-$9<)Zt1c)N- zU^&9hsk6z?3%<9kGKHW|6~k;&cghtWz`oz`_YjVuvy;B;T67=L2c6=8`7WyTBv*QH zNv*bo1#KOk{O&)@&pkd*?v+kcJ8tM>AGx$~WMhH{L40_N=bkrVg+^p!H)IqXCQf2_ z0fPig=8CEo>p4vE(nc^DKbZ|9_Xo}$i4zJ`jVh95; z5%aNP3@``=EJ=Vt9U`y+$YtX;%OPzgZ_3+;+mh{p#W&y4-%%Bf`LhOy-*kB0qnB^m z_nBTz_b?-`F$*ymByshU>D)za2g`0j^ioo;A#QeL@x3@|+_!=YXA5f6Xg(Ack&WOg zJ<2i|Fd6OmyH!@YSMVxb;=M)ZDhBt)4`5T*>cUXWPG#%@$&*>K&u3#|`fm2mj*FKVf?du{xZ}WKWETTFhq6_fO$PS5(ItF=3~pFp~*j z!ys1<4EL1)#{`mz@gW|t-FpPkd%pK)n_Rb)F;z7cQ6dym_>YI3&e!=!m006oS3Mjq{q ze%hNzW=G0jpfl2K(x`CDuZCsJV*hm9T~%5n7R_g}VFpk`G((D^MWVMAmRp--T{`P; zwMgD<;e`fm`g3|fPns|6qnd{|FCHY*YAguXH(?%sx%4+Gu|Y)_8mk4EljxmP+MP`* z`SUbI{TCIN2OV+$y#g->Jqv#$wL;}4xJmah#$0`v^ughM_XjTA$B}ux)JZuY5-GW4 zKy440I+w=ZtE-_i+0xImq}vyzD68?8;94-5L~_O6Ty>X3itdA-x?6P(c4jkr+f!H( zUDeqiG>3bn^Sf8(`_YwqPeJ9&-@OCQZm4X{FfRMeBtN4E9Ca@;GVpU*L>lVb;@=PH zTQvTr?^jKyCKh&ZVOI*<y%T*Aw(XCPrFC=39*y$A`FSzxBiQ#W+uW10d8&gYp4{teh;^p@anft+z$5!Hv&@h0X-@xJG>hbTCxjDwMiWK@1b%8wYL6BrV zT41m}tX8g-`P@vj4T!Mlk8F0S!MA`^J=SCy9-jdwDe^hVDa`WwyI^H@ryt=F5y6>b zT8&iI6&j8edAfX^ycgWbnMZQ26Q~`LmdEScKC8|~$Jgyw(>18NAQ$9AwCRmri!96L zp^)b0P2CR-9S%cG$#rU}MXnx21T#031o>2VrDs@sa-FpjfvgLPW>Q&LHUoNOtmkt# zoDZ=5OGp{^vO~=p29^`aXd8K?(+f-bW`N$U;-o;%f?RcR!k02Nod2h^^8ly%Z67#E zC3|IOuj~^YBO=Fklo@3mvd6I{Z*&FZ>iq* zxh|JuJoo2$p8MJ3zO@dQ;%1#~Mrm48 zB0053{1bDi_a@jo<4!@!`w4}B(&Qb`~IeSBh zu+_yIYl2Wgk+?x4pCmAM>x_SqBPUj#c`C`k>_fp@qPlAAwD$!zOxRkL7;=|nu(#ut zyF^;&hm-D_;ji{d6rOloACu5*NkF4IC3@rifMG(|^Skv$H&^YnYL*rpw=UCi;JOuz zN*NX(7wZXS4tF@6PIWAs%*j!$RoL*3sh)}iry%thDvN5AUM888q_(>|Tzt|Yea3AyMYBgm$H_`F^v2%)bux)3s znFIEBDK;-JS5SH|;1?afJb<*=c5puu=w%tv#ihn*R!^Hd$KWAp4$#`joJ*)$kNtZ z2Al6h>Z>(u?3tmzA4^d+jLKx{97!Pb4;CX&u;M||**7zXI7hO6nrdMx*Xa=|-`#1^ zBQ?Ha&7cd7hN=%y4yUp?zl8~Lo;%mQrDe8!ce-W_K94FFMN*g(w8q-_K5S+c0{o29X&PzpV;UJE^!xnFc%b@>kvW4m#xiOj-L*DadC&2N#0Us z;<-(m1WB7$=j6hjcPC6JB)D3T2#IC`ibu#yi!uK7W2!j|Z>~RaJ*&XXy#ytIk2DIp z5?Qd^s90_?ILjU#>ZWk5HXts}grg_!Gmgm!d?eLGR7xEP zvTCrslV~94ym5_i<5oqy(@@?wN}lIdtiY8=?|Ng!XeYnly`@9wCGx2S$3x|0x8T2h zz7A85Vb2>s44rKpI_4Y7_Pnd2^mYj2%^jM|Du>u4`^Psda^JIP%*DK6bo`Vf&f{!% zDTYCwF5Nhi=)QhU2$@eQv&ZzxsX+Hl+gP6kW|e!n9IU2>Vh~cioI{>4WvR}t*4Hpz z%5z?HjLGoka}Q3AbX9AkY|Yjf^M(>@tBAI9JO5pDCQu0R3Nns>)LC#vB2p96C*?K? zvX$un$sBDx$1=+NNj*@Oa@u*b@O*XBr_sg@8sCUq-|LK!MUmC)epklrv}5O_^<{NP zX16|c$9Wtbks3y7geI^tF5oRZJu;v zwkW8j+8Ccxo9stEDOT_Go&j%$KCgVO7pm+^%PKEPBZqbMw%s@732XS{cX+wCSjH1s z5)bc=g**<^NNsroY` z?}fHHlgu^B?2r{^^gQ&j zbF~T((>|Yg&C5WKL8DCnl1}Z3!YHFW2S1|;Xr0`Uz-;=FxEwYc4QpeAtnm7^f~uzX zl;xA!?>MLR?tL80Iudm;mi{!ewL91KhG7Hsa-XepKi<2mc6%zf0GwtbfJ1Zf-<@Xu z#|XWDzv|04t)&9Id!UxAAkN{t5qC%%8-WV3i;3duS19%m2||Y{!3pR1=g|zQYAMqc zff)_2nj-O4wfxy;UNM?|Uieo!^J$A*uDe>@V(NKH;KS;Y_dtE8${p>RdcrW;=2*fj4~d?OG0l-(g?ik}vz} z)5-wDppVts>K-=|@{=!53?=8)Jw#RGpS_FWpbwtn}{v!JEJ$q-sr7F6&OPBuI# zuVNFMPte79XgEu!P&qRq8u4J>r%$l-IQ00Lin90(_KtC)aR_de zxN=pY2<1b29_^AG2WJIGmmX4rv3$!`l15{e(H!1^+x9voZ6;882YAE12q7+lgy+>) zj|s0CyzI9=Mo!R}&LXB`&DYpZ7c?0r(&KNV+~TULd0y^e;G{KVR4nL0KvU9mr8&$^ zxrM-9P8zE`J?aZ(iB~Rz<{vvnk2HaZU#K$aVFfYnbAXVUOLU#As5JvS%+26 zi$sNuPY}dLGUS$0g&;oBqhzv2dY`l3@6Na403M!Sh${B|7(y|_cONa;6BrtUe@ZzV z7SThtHT8k?Rwc)(Z}@BP#H@JJHz&GR&M=E@P9KJ89yQKmRh&I~%vbL1L-K3E>7>CH z)Y!=jXVb1iPrAoAZZ3}3wU*5~nrV!ZjL5zqJ<@NwjHCZC>68Cc<{&E_#S;E*jOdjtg?uKN|l`P8sjz&Qf7a^z9 z;{3-8T+H4y99_zc;JYIvs!sk$G}` z??mt*Mm9Z@glCZb!X?!xXD-21sFDPEpZOK{sbQseQ$%6~b;n+*z0hRoR}0Pe>B|#t z$XrVcXv8M|q*Z8MY&r9J0A=d^1bHpjrUXu)qEj~$%%=gZp`^~%O*lzxUquG^p6;n; z^(3HL+hx4gRP?4N*b2p9!^|2~rcw3!9nQj$vmZusbXYz_x^AVc`3qBFm(jS9ueU5h z^AnNnbswfQ2Jq=W=T+p-V|nQco@bOAH$pLQZ+BKH8E$iM>IDz z3|wc?QP`yI=X5YTlp8h}%p6{Deq?S0QD$Ug>ih1SdPZg237Rl{S~=Ha4~-ckMoIWMn+X@@`V6 z#HHZj>MQbt$Qqp*9T(cjc^lxZ7UO(>PwzF-qEr(wo`vaulxdall|KP`7p4gd`23&Jy=#sAes*0diLB(U$Nx46VQvP)8idSs8^zaV91xw*O-JMH=)FoJshRob|_)O)ojtfP))WHCr(;*2;VMQ75^ zfN@a^f#o<|*9X;3IcGodLUz-3i~FAu+zI4c5h+nW^h_!^)b*B_xw-l4O$TB(ixaqW ziMoa%i=BeS<-F45kMO;Tw|FWa`G2c!SuOA3CbowPhF6csf1|&qqugUrj;UgGHm| z;j^yoH?MZhR;AYOW_XW2Lg2j%%ejL)B@*bUMD`g<#Z${1+fa57r7X82 zcqY-cfPnK%Y^3@szRner zt)bBToYCph6Jv*W+&t?&9FG4(Iu2w46 z4B#AcFy_^J@f*6<{>CN}Sj969*DYV*e7<61U>GoN{tz!Do90+jApFueVY_IW(MQF; zl?4yA_(MvMwN&pWKVyg{3uU_+y6RMdot2vu%mC?st=N0pf-~JZXE?3JFf)j<{1xsU z`2ephz)#HzsWEP!inHm2hI(V(~@W zY7gGU-lO52cHD&SY)>QHgy$=>^X%u0TQZfCizro!*weMyvZC=;MWOawdAx~`3C*W` z%^#^$uRP;gyqEE0<(i8xcQY$oc+6mY#z{-XFxsO1(cN8Y)>p;^q9|5bk`Z*p|c!?(rErw#y;yT(%@c7trQBv6cj)$3>pI z>tz+;IB?D=aQV=s(n)o63*yn8dX1m7#Z4G{%fF@K2o5n3jxR~mU?nzMi#;}8e#(>{ zy{Z4!AI)jZ8TY;nq1aq}tq;~=zzoTv)er06oeX3;9{uP{LWR*2%9cmE%S^`~!BW>X zn3PZFTf3g*dG68~^1*q@#^Ge(_8puPEFLD8OS|0b2a{5e=N4S%;~f3tC>F6UxK#v9 z)N-#Mv8=ePCh1KsUKD1A8jF_%$MPf|_yCN9oy%*@um6D{w*2|4GY zb}gafrSC+f=b*W{)!a!fqwZ9)K>fk=i4qf!4M?0v{CMNTo2A9}mQzV=%3UT&i{3{W z>ulG#M!K7%jPf6Mjff9BMslgQq3zIogY);Cv3v;&b#;^=sh#(Bn%W)H*bHNaLwdpq z85%fUTUJJNjYO_426T2TBj0D{6t zw&S_HZ|C?pI_2q(9Fas&@uJs6nVX;P*5K#6p|#)_(8PM-{L(;2wl`ma{ZAd5gA)?y z>0GSLoK<*FwW+G8@-M3vcffg7I(qm7lzF)n`Q9iCvp*mn7=|CjlpG{x z&r0n}XLWZ!>=lynUr7D`6n`7a_ZgT< zm!i;&?Fb0Q2QmqmCHfZ7ex=_tU~(7b)L?RIvPyEAU=gLIZ-VTAA~WR00yKyTXg^(G zqWLZJs!FnQYMOH3*fN&Tn(IKMLf{Ki?pRo8zZJ6YVyj)y0^)-sR}2-)%mI(Aw2AgT zbbp1T{qB(OSNJd0cVBH^tI>HR(q+#*lmi@LWe*rZz&M2h1L_=50uZ1e*n#E*`6?aw zj`ka&JpceRGe@}Ey1)Q~O}0qHRg4K_u>4e1arvJ7Q9!=t5AuzG`n=a-f0}{+lnCE#zu$`oVn44eS&T?N*wz~t~E&oQDBrB_MSg z_yVrQehWbD0xHX|v-hpselAu;O7s;P*!uAT`dr~}Lie=tknaGoiU?;*8Cwgala-65 zosOB4mATbdXJFujzgA4?UkCKE093A1KM?W&Pw>A?IACqg1z~IZYkdP70EeCfjii(n z3k%ax?4|rY(87N&_vhsyVK1zp@uils|B%`(V4e3%sj5f|i(eIhiSg-fHK1Pb0-mS^ zeh?WA7#{hhNci5e;?n*iVy|)iJiR>|8{TN3!=VBC2dN)~^ISSW_(g<^rHr$)nVrdA z39BMa5wl5q+5F@)4b%5-> zA^-P20l_e^S2PTa&HE2wf3jf)#)2ITVXzndeuMpPo8}kphQKhegB%QO+yBpDpgkcl z1nlPp14#+^bIA7__h16pMFECzKJ3p4`;Rf$gnr%{!5#oG42AH&X8hV8061%4W91ku z`OW_hyI+uBOqYXkVC&BqoKWmv;|{O|4d#Nay<)gkxBr^^N48(VDF7Sj#H1i3>9138 zkhxAU7;M)I18&d!Yw!V9zQA0tp(G4<8U5GX{YoYCQ?p56FxcD-2FwO5fqyx@__=$L zeK6Sg3>XQv)qz1?zW-k$_j`-)tf+yRU_%fXrenc>$^70d1Q-W?T#vy;6#Y-Q-<2)+ z5iTl6MA7j9m&oBhRXTKr*$3gec z3E;zX457RGZwUvD$l&8e42Qb^cbq>zYy@ive8`2N9vk=#6+AQlZZ7qk=?(ap1q0n0 z{B9Fte-{Gi-Tvax1)M+d1}Fyg@9X~sh1m|hsDcZuYOnxriBPN;z)q3<=-yBN2iM6V A?*IS* literal 0 HcmV?d00001 diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..5f0536e --- /dev/null +++ b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/utilities/on_subscibe-service/java/README.md b/utilities/on_subscibe-service/java/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/utilities/on_subscibe-service/java/mvnw b/utilities/on_subscibe-service/java/mvnw new file mode 100755 index 0000000..66df285 --- /dev/null +++ b/utilities/on_subscibe-service/java/mvnw @@ -0,0 +1,308 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/utilities/on_subscibe-service/java/mvnw.cmd b/utilities/on_subscibe-service/java/mvnw.cmd new file mode 100644 index 0000000..95ba6f5 --- /dev/null +++ b/utilities/on_subscibe-service/java/mvnw.cmd @@ -0,0 +1,205 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/utilities/on_subscibe-service/java/pom.xml b/utilities/on_subscibe-service/java/pom.xml index 0cdd2bf..34edd41 100644 --- a/utilities/on_subscibe-service/java/pom.xml +++ b/utilities/on_subscibe-service/java/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.boot @@ -33,18 +33,18 @@ bcprov-jdk15on 1.69 - - com.vaadin.external.google - android-json - 0.0.20131108.vaadin1 - compile - - - org.springframework - spring-beans - 6.1.3 - - + + com.vaadin.external.google + android-json + 0.0.20131108.vaadin1 + compile + + + org.springframework + spring-beans + 6.1.3 + + diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java deleted file mode 100644 index e90a518..0000000 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ondc.onboarding; - -import org.json.JSONException; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; - -@SpringBootApplication -public class OnboardingApplication { - public static void main(String[] args) throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException { - SpringApplication.run(OnboardingApplication.class, args); - } - -} diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java similarity index 90% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java index 93e2323..3c7c55d 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java @@ -1,7 +1,6 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import org.json.JSONException; -import org.json.JSONObject; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -11,11 +10,11 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import static com.ondc.onboarding.Utils.*; +import static ondc.onboarding.utility.Utils.generateEncDecKey; +import static ondc.onboarding.utility.Utils.generateSigningKeyPair; @Configuration public class AppConfig { diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/CryptoKeyPair.java similarity index 94% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/CryptoKeyPair.java index 95219e9..21e6d37 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/CryptoKeyPair.java @@ -1,7 +1,7 @@ /* * */ -package com.ondc.onboarding; +package ondc.onboarding.utility; diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java similarity index 99% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java index 2be6ff3..9d8c9d5 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java @@ -1,4 +1,4 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import java.io.IOException; diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java new file mode 100644 index 0000000..e7d354d --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java @@ -0,0 +1,13 @@ +package ondc.onboarding.utility; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UtilityApplication { + + public static void main(String[] args) { + SpringApplication.run(UtilityApplication.class, args); + } + +} diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java similarity index 99% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java index b38a821..063a9e7 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java @@ -1,4 +1,4 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.math.ec.rfc8032.Ed25519; diff --git a/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java b/utilities/on_subscibe-service/java/src/test/java/ondc/onboarding/utility/UtilityApplicationTests.java similarity index 69% rename from utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java rename to utilities/on_subscibe-service/java/src/test/java/ondc/onboarding/utility/UtilityApplicationTests.java index 162295c..89d667e 100644 --- a/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java +++ b/utilities/on_subscibe-service/java/src/test/java/ondc/onboarding/utility/UtilityApplicationTests.java @@ -1,10 +1,10 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class OnboardingApplicationTests { +class UtilityApplicationTests { @Test void contextLoads() { From 5822584578205db22c9079f61eff0cb99e0aae7e Mon Sep 17 00:00:00 2001 From: Pratik Mazumdar ONDC <150436777+pratikmazumdar@users.noreply.github.com> Date: Wed, 21 Feb 2024 18:36:23 +0530 Subject: [PATCH 177/228] Create Readme.md --- utilities/on_subscibe-service/java/Readme.md | 69 ++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 utilities/on_subscibe-service/java/Readme.md diff --git a/utilities/on_subscibe-service/java/Readme.md b/utilities/on_subscibe-service/java/Readme.md new file mode 100644 index 0000000..b79b032 --- /dev/null +++ b/utilities/on_subscibe-service/java/Readme.md @@ -0,0 +1,69 @@ +### Java Util for Subscribing and Key Generation + +- Clone the repo +- You are required to have Java 17 and Maven. +- Go to the ```main.java.ondc.onboarding.utility.AppConfig``` requestId(java file) should match with message.request_id(subscribe payload) that you will be sending in the subscribe payload. +- Run ```./mvnw spring-boot:run``` +- Hit ```https://subscriber_id/get-keys``` to generate the keys. + ``` + "enc_private_key": "MFECAQEwBQYDK2VuBCIEIPjSJTWFXeb0AH5L5d36q5yknfKGAthnOlsmREO/vBVAgSEAHjjX+uHubKwSOINetLeSedFoWXIaWybDQYON8pXewGQ=", + "sign_private_key": "zeiPflZ2GHCX1bkzm4C4HfOoWclVKdZi9qYXgEnv89g=", + "sign_public_key": "3fdeC79Oqcsb26JLPA8aZSyjWytVR+CdRVtkaneijPk=", + "enc_public_key": "MCowBQYDK2VuAyEAHjjX+uHubKwSOINetLeSedFoWXIaWybDQYON8pXewGQ=" + ``` +- Kindly change the ```message.key_pair.encryption_public_key and signing_public_key``` with the above values. +- Hit ```https://subscriber_id/subscribe``` to subscribe. + ``` + curl --location 'localhost:8080/subscribe' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "context": { + "operation": { + "ops_no": 2 + } + }, + "message": { + "request_id": "ccfce272-13c3-4ca4-a070-64769f5df2a66", + "timestamp": "2024-02-21T13:02:09.814Z", + "entity": { + "gst": { + "legal_entity_name": "ABC Incorporates", + "business_address": "Trade World, Mansarpur, Coorg, Karnataka 333333", + "city_code": [ + "std:080" + ], + "gst_no": "07AAACN2082N4Z7" + }, + "pan": { + "name_as_per_pan": "ABC Incorporates", + "pan_no": "ASDFP7657Q", + "date_of_incorporation": "23/06/1982" + }, + "name_of_authorised_signatory": "Anand Sharma", + "address_of_authorised_signatory": "405, Pinnacle House, Kandiwali, Mumbai 400001", + "email_id": "anand.sharma@abc.com", + "mobile_no": 9912332199, + "country": "IND", + "subscriber_id": "your.app.com", + "unique_key_id": "ccfce174-17c1-4ca4-a070-7419f5df2a66", + "callback_url": "/", + "key_pair": { + "signing_public_key":"Od5jWsddCTo2bG04iT8jWirXBll5hTgt5v9WJVAyZWM=", + "encryption_public_key": "MCowBQYDK2VuAyEAtixcps5Wt84F4sq90IPFr5ZjuUqPE93nGui7ROr2zzk=", + "valid_from": "2024-02-21T13:02:09.814Z", + "valid_until": "2024-10-20T18:00:15.071Z" + } + }, + "network_participant": [ + { + "subscriber_url": "/", + "domain": "ONDC:RET10", + "type": "sellerApp", + "msn": false, + "city_code": [ + "std:080" + ] + } + ] + } +}'``` From f4c6ef65290b087a54e88d566e0d9f3eda4d2576 Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Thu, 22 Feb 2024 10:17:30 +0530 Subject: [PATCH 178/228] feat: on_sub java util --- .idea/.gitignore | 3 - .idea/misc.xml | 6 - .idea/modules.xml | 8 - .idea/reference-implementations.iml | 9 - .idea/vcs.xml | 6 - utilities/on_subscibe-service/java/.DS_Store | Bin 0 -> 6148 bytes utilities/on_subscibe-service/java/.gitignore | 3 - .../java/.mvn/wrapper/maven-wrapper.jar | Bin 0 -> 62547 bytes .../.mvn/wrapper/maven-wrapper.properties | 2 + utilities/on_subscibe-service/java/README.md | 0 utilities/on_subscibe-service/java/Readme.md | 69 ++++ utilities/on_subscibe-service/java/mvnw | 308 ++++++++++++++++++ utilities/on_subscibe-service/java/mvnw.cmd | 205 ++++++++++++ utilities/on_subscibe-service/java/pom.xml | 26 +- .../onboarding/OnboardingApplication.java | 20 -- .../onboarding/utility}/AppConfig.java | 7 +- .../onboarding/utility}/CryptoKeyPair.java | 2 +- .../onboarding/utility}/Routes.java | 2 +- .../utility/UtilityApplication.java | 13 + .../onboarding/utility}/Utils.java | 2 +- .../utility/UtilityApplicationTests.java} | 4 +- .../ondc/crypto/util/CryptoFunctions.class | Bin 4741 -> 0 bytes .../org/ondc/crypto/util/CryptoKeyPair.class | Bin 796 -> 0 bytes .../target/maven-archiver/pom.properties | 4 - .../compile/default-compile/createdFiles.lst | 2 - .../compile/default-compile/inputFiles.lst | 2 - .../default-testCompile/createdFiles.lst | 1 - .../default-testCompile/inputFiles.lst | 1 - .../org/ondc/crypto/util/CryptoTest.class | Bin 6543 -> 0 bytes .../org/ondc/crypto/util/Test.class | Bin 1951 -> 0 bytes 30 files changed, 618 insertions(+), 87 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/misc.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/reference-implementations.iml delete mode 100644 .idea/vcs.xml create mode 100644 utilities/on_subscibe-service/java/.DS_Store create mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar create mode 100644 utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties delete mode 100644 utilities/on_subscibe-service/java/README.md create mode 100644 utilities/on_subscibe-service/java/Readme.md create mode 100755 utilities/on_subscibe-service/java/mvnw create mode 100644 utilities/on_subscibe-service/java/mvnw.cmd delete mode 100644 utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/AppConfig.java (90%) rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/CryptoKeyPair.java (94%) rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/Routes.java (99%) create mode 100644 utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java rename utilities/on_subscibe-service/java/src/main/java/{com/ondc/onboarding => ondc/onboarding/utility}/Utils.java (99%) rename utilities/on_subscibe-service/java/src/test/java/{com/ondc/onboarding/OnboardingApplicationTests.java => ondc/onboarding/utility/UtilityApplicationTests.java} (69%) delete mode 100644 utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class delete mode 100644 utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst delete mode 100644 utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class delete mode 100644 utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/Test.class diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 26d3352..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 6ff3c25..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 4be6c13..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/reference-implementations.iml b/.idea/reference-implementations.iml deleted file mode 100644 index d6ebd48..0000000 --- a/.idea/reference-implementations.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/utilities/on_subscibe-service/java/.DS_Store b/utilities/on_subscibe-service/java/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6c38c6e8111e2ce84d56208c041c5125fd3006f4 GIT binary patch literal 6148 zcmeHKy-EW?5S}qX4s3!pmRsB94bE_O7D8%4lSoqJxS+AWMjI_`d=Z~O5MRKz@Fm1= zc1E+Or=^I_!0xvJd?fA;_|55mC3A*34OqEIInaaaAr_Qv6<( z?7c&0bV}p-G~NH;X=N#^q8QDq5j5G|%g*)I!{cshoqS_m%+jnk2%~jc(lIJd>4cVP zRlc~o|7cHZ@83QjZffmDjr-%1R^0mIRihyz$@9~ BNmT#< literal 0 HcmV?d00001 diff --git a/utilities/on_subscibe-service/java/.gitignore b/utilities/on_subscibe-service/java/.gitignore index ea7b7ee..549e00a 100644 --- a/utilities/on_subscibe-service/java/.gitignore +++ b/utilities/on_subscibe-service/java/.gitignore @@ -18,9 +18,6 @@ target/ *.iws *.iml *.ipr -*.mvn -mvnm -mvnm.cmd ### NetBeans ### /nbproject/private/ diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..cb28b0e37c7d206feb564310fdeec0927af4123a GIT binary patch literal 62547 zcmb5V1CS=sk~Z9!wr$(CZEL#U=Co~N+O}=mwr$(Cds^S@-Tij=#=rmlVk@E|Dyp8$ z$UKz?`Q$l@GN3=8fq)=^fVx`E)Pern1@-q?PE1vZPD);!LGdpP^)C$aAFx&{CzjH` zpQV9;fd0PyFPNN=yp*_@iYmRFcvOrKbU!1a*o)t$0ex(~3z5?bw11HQYW_uDngyer za60w&wz^`W&Z!0XSH^cLNR&k>%)Vr|$}(wfBzmSbuK^)dy#xr@_NZVszJASn12dw; z-KbI5yz=2awY0>OUF)&crfPu&tVl|!>g*#ur@K=$@8N05<_Mldg}X`N6O<~3|Dpk3 zRWb!e7z<{Mr96 z^C{%ROigEIapRGbFA5g4XoQAe_Y1ii3Ci!KV`?$ zZ2Hy1VP#hVp>OOqe~m|lo@^276Ik<~*6eRSOe;$wn_0@St#cJy}qI#RP= zHVMXyFYYX%T_k3MNbtOX{<*_6Htq*o|7~MkS|A|A|8AqKl!%zTirAJGz;R<3&F7_N z)uC9$9K1M-)g0#}tnM(lO2k~W&4xT7gshgZ1-y2Yo-q9Li7%zguh7W#kGfnjo7Cl6 z!^wTtP392HU0aVB!$cPHjdK}yi7xNMp+KVZy3_u}+lBCloJ&C?#NE@y$_{Uv83*iV zhDOcv`=|CiyQ5)C4fghUmxmwBP0fvuR>aV`bZ3{Q4&6-(M@5sHt0M(}WetqItGB1C zCU-)_n-VD;(6T1%0(@6%U`UgUwgJCCdXvI#f%79Elbg4^yucgfW1^ zNF!|C39SaXsqU9kIimX0vZ`U29)>O|Kfs*hXBXC;Cs9_Zos3%8lu)JGm~c19+j8Va z)~kFfHouwMbfRHJ``%9mLj_bCx!<)O9XNq&uH(>(Q0V7-gom7$kxSpjpPiYGG{IT8 zKdjoDkkMTL9-|vXDuUL=B-K)nVaSFd5TsX0v1C$ETE1Ajnhe9ept?d;xVCWMc$MbR zL{-oP*vjp_3%f0b8h!Qija6rzq~E!#7X~8^ZUb#@rnF~sG0hx^Ok?G9dwmit494OT z_WQzm_sR_#%|I`jx5(6aJYTLv;3U#e@*^jms9#~U`eHOZZEB~yn=4UA(=_U#pYn5e zeeaDmq-$-)&)5Y}h1zDbftv>|?GjQ=)qUw*^CkcAG#o%I8i186AbS@;qrezPCQYWHe=q-5zF>xO*Kk|VTZD;t={XqrKfR|{itr~k71VS?cBc=9zgeFbpeQf*Wad-tAW7(o ze6RbNeu31Uebi}b0>|=7ZjH*J+zSj8fy|+T)+X{N8Vv^d+USG3arWZ?pz)WD)VW}P z0!D>}01W#e@VWTL8w1m|h`D(EnHc*C5#1WK4G|C5ViXO$YzKfJkda# z2c2*qXI-StLW*7_c-%Dws+D#Kkv^gL!_=GMn?Y^0J7*3le!!fTzSux%=1T$O8oy8j z%)PQ9!O+>+y+Dw*r`*}y4SpUa21pWJ$gEDXCZg8L+B!pYWd8X;jRBQkN_b=#tb6Nx zVodM4k?gF&R&P=s`B3d@M5Qvr;1;i_w1AI=*rH(G1kVRMC`_nohm~Ie5^YWYqZMV2<`J* z`i)p799U_mcUjKYn!^T&hu7`Lw$PkddV&W(ni)y|9f}rGr|i-7nnfH6nyB$Q{(*Nv zZz@~rzWM#V@sjT3ewv9c`pP@xM6D!StnV@qCdO${loe(4Gy00NDF5&@Ku;h2P+Vh7 z(X6De$cX5@V}DHXG?K^6mV>XiT768Ee^ye&Cs=2yefVcFn|G zBz$~J(ld&1j@%`sBK^^0Gs$I$q9{R}!HhVu|B@Bhb29PF(%U6#P|T|{ughrfjB@s- zZ)nWbT=6f6aVyk86h(0{NqFg#_d-&q^A@E2l0Iu0(C1@^s6Y-G0r32qll>aW3cHP# zyH`KWu&2?XrIGVB6LOgb+$1zrsW>c2!a(2Y!TnGSAg(|akb#ROpk$~$h}jiY&nWEz zmMxk4&H$8yk(6GKOLQCx$Ji-5H%$Oo4l7~@gbHzNj;iC%_g-+`hCf=YA>Z&F)I1sI z%?Mm27>#i5b5x*U%#QE0wgsN|L73Qf%Mq)QW@O+)a;#mQN?b8e#X%wHbZyA_F+`P%-1SZVnTPPMermk1Rpm#(;z^tMJqwt zDMHw=^c9%?#BcjyPGZFlGOC12RN(i`QAez>VM4#BK&Tm~MZ_!#U8PR->|l+38rIqk zap{3_ei_txm=KL<4p_ukI`9GAEZ+--)Z%)I+9LYO!c|rF=Da5DE@8%g-Zb*O-z8Tv zzbvTzeUcYFgy{b)8Q6+BPl*C}p~DiX%RHMlZf;NmCH;xy=D6Ii;tGU~ zM?k;9X_E?)-wP|VRChb4LrAL*?XD6R2L(MxRFolr6GJ$C>Ihr*nv#lBU>Yklt`-bQ zr;5c(o}R!m4PRz=CnYcQv}m?O=CA(PWBW0?)UY)5d4Kf;8-HU@=xMnA#uw{g`hK{U zB-EQG%T-7FMuUQ;r2xgBi1w69b-Jk8Kujr>`C#&kw-kx_R_GLRC}oum#c{je^h&x9 zoEe)8uUX|SahpME4SEog-5X^wQE0^I!YEHlwawJ|l^^0kD)z{o4^I$Eha$5tzD*A8 zR<*lss4U5N*JCYl;sxBaQkB3M8VT|gXibxFR-NH4Hsmw|{={*Xk)%!$IeqpW&($DQ zuf$~fL+;QIaK?EUfKSX;Gpbm8{<=v#$SrH~P-it--v1kL>3SbJS@>hAE2x_k1-iK# zRN~My-v@dGN3E#c!V1(nOH>vJ{rcOVCx$5s7B?7EKe%B`bbx(8}km#t2a z1A~COG(S4C7~h~k+3;NkxdA4gbB7bRVbm%$DXK0TSBI=Ph6f+PA@$t){_NrRLb`jp zn1u=O0C8%&`rdQgO3kEi#QqiBQcBcbG3wqPrJ8+0r<`L0Co-n8y-NbWbx;}DTq@FD z1b)B$b>Nwx^2;+oIcgW(4I`5DeLE$mWYYc7#tishbd;Y!oQLxI>?6_zq7Ej)92xAZ z!D0mfl|v4EC<3(06V8m+BS)Vx90b=xBSTwTznptIbt5u5KD54$vwl|kp#RpZuJ*k) z>jw52JS&x)9&g3RDXGV zElux37>A=`#5(UuRx&d4qxrV<38_w?#plbw03l9>Nz$Y zZS;fNq6>cGvoASa2y(D&qR9_{@tVrnvduek+riBR#VCG|4Ne^w@mf2Y;-k90%V zpA6dVw|naH;pM~VAwLcQZ|pyTEr;_S2GpkB?7)+?cW{0yE$G43`viTn+^}IPNlDo3 zmE`*)*tFe^=p+a{a5xR;H0r=&!u9y)kYUv@;NUKZ)`u-KFTv0S&FTEQc;D3d|KEKSxirI9TtAWe#hvOXV z>807~TWI~^rL?)WMmi!T!j-vjsw@f11?#jNTu^cmjp!+A1f__Dw!7oqF>&r$V7gc< z?6D92h~Y?faUD+I8V!w~8Z%ws5S{20(AkaTZc>=z`ZK=>ik1td7Op#vAnD;8S zh<>2tmEZiSm-nEjuaWVE)aUXp$BumSS;qw#Xy7-yeq)(<{2G#ap8z)+lTi( ziMb-iig6!==yk zb6{;1hs`#qO5OJQlcJ|62g!?fbI^6v-(`tAQ%Drjcm!`-$%Q#@yw3pf`mXjN>=BSH z(Nftnf50zUUTK;htPt0ONKJq1_d0!a^g>DeNCNpoyZhsnch+s|jXg1!NnEv%li2yw zL}Y=P3u`S%Fj)lhWv0vF4}R;rh4&}2YB8B!|7^}a{#Oac|%oFdMToRrWxEIEN<0CG@_j#R4%R4i0$*6xzzr}^`rI!#y9Xkr{+Rt9G$*@ zQ}XJ+_dl^9@(QYdlXLIMI_Q2uSl>N9g*YXMjddFvVouadTFwyNOT0uG$p!rGF5*`1 z&xsKPj&;t10m&pdPv+LpZd$pyI_v1IJnMD%kWn{vY=O3k1sJRYwPoDV1S4OfVz4FB z$^ygjgHCW=ySKSsoSA&wSlq83JB+O-)s>>e@a{_FjB{@=AlrX7wq>JE=n@}@fba(;n4EG| zge1i)?NE@M@DC5eEv4; z#R~0aNssmFHANL@-eDq2_jFn=MXE9y>1FZH4&v<}vEdB6Kz^l)X%%X@E#4)ahB(KY zx8RH+1*6b|o1$_lRqi^)qoLs;eV5zkKSN;HDwJIx#ceKS!A$ZJ-BpJSc*zl+D~EM2 zm@Kpq2M*kX`;gES_Dd1Y#UH`i!#1HdehqP^{DA-AW^dV(UPu|O@Hvr>?X3^~=1iaRa~AVXbj z-yGL<(5}*)su2Tj#oIt+c6Gh}$0|sUYGGDzNMX+$Oi$e&UJt3&kwu)HX+XP{es(S3 z%9C9y({_fu>^BKjI7k;mZ4DKrdqxw`IM#8{Sh?X(6WE4S6-9M}U0&e32fV$2w{`19 zd=9JfCaYm@J$;nSG3(|byYDqh>c%`JW)W*Y0&K~g6)W?AvVP&DsF_6!fG3i%j^Q>R zR_j5@NguaZB{&XjXF+~6m|utO*pxq$8?0GjW0J-e6Lnf0c@}hvom8KOnirhjOM7!n zP#Iv^0_BqJI?hR5+Dl}p!7X}^NvFOCGvh9y*hgik<&X)3UcEBCdUr$Dt8?0f&LSur ze*n!(V(7umZ%UCS>Hf(g=}39OcvGbf2+D;OZ089m_nUbdCE0PXJfnyrIlLXGh2D!m zK=C#{JmoHY1ws47L0zeWkxxV=A%V8a&E^w%;fBp`PN_ndicD@oN?p?Bu~20>;h;W` ztV=hI*Ts$6JXOwOY?sOk_1xjzNYA#40dD}|js#3V{SLhPEkn5>Ma+cGQi*#`g-*g56Q&@!dg)|1YpLai3Bu8a;l2fnD6&)MZ~hS%&J}k z2p-wG=S|5YGy*Rcnm<9VIVq%~`Q{g(Vq4V)CP257v06=M2W|8AgZO0CC_}HVQ>`VU zy;2LDlG1iwIeMj?l40_`21Qsm?d=1~6f4@_&`lp~pIeXnR)wF0z7FH&wu~L~mfmMr zY4_w6tc{ZP&sa&Ui@UxZ*!UovRT})(p!GtQh~+AMZ6wcqMXM*4r@EaUdt>;Qs2Nt8 zDCJi#^Rwx|T|j_kZi6K!X>Ir%%UxaH>m6I9Yp;Sr;DKJ@{)dz4hpG>jX?>iiXzVQ0 zR$IzL8q11KPvIWIT{hU`TrFyI0YQh`#>J4XE*3;v^07C004~FC7TlRVVC}<}LC4h_ zZjZ)2*#)JyXPHcwte!}{y%i_!{^KwF9qzIRst@oUu~4m;1J_qR;Pz1KSI{rXY5_I_ z%gWC*%bNsb;v?>+TbM$qT`_U8{-g@egY=7+SN#(?RE<2nfrWrOn2OXK!ek7v`aDrH zxCoFHyA&@^@m+#Y(*cohQ4B76me;)(t}{#7?E$_u#1fv)vUE5K;jmlgYI0$Mo!*EA zf?dx$4L(?nyFbv|AF1kB!$P_q)wk1*@L0>mSC(A8f4Rgmv1HG;QDWFj<(1oz)JHr+cP|EPET zSD~QW&W(W?1PF-iZ()b|UrnB(#wG^NR!*X}t~OS-21dpXq)h)YcdA(1A`2nzVFax9rx~WuN=SVt`OIR=eE@$^9&Gx_HCfN= zI(V`)Jn+tJPF~mS?ED7#InwS&6OfH;qDzI_8@t>In6nl zo}q{Ds*cTG*w3CH{Mw9*Zs|iDH^KqmhlLp_+wfwIS24G z{c@fdgqy^Y)RNpI7va^nYr9;18t|j=AYDMpj)j1oNE;8+QQ)ap8O??lv%jbrb*a;} z?OvnGXbtE9zt;TOyWc|$9BeSGQbfNZR`o_C!kMr|mzFvN+5;g2TgFo8DzgS2kkuw@ z=`Gq?xbAPzyf3MQ^ZXp>Gx4GwPD))qv<1EreWT!S@H-IpO{TPP1se8Yv8f@Xw>B}Y z@#;egDL_+0WDA)AuP5@5Dyefuu&0g;P>ro9Qr>@2-VDrb(-whYxmWgkRGE(KC2LwS z;ya>ASBlDMtcZCCD8h+Awq1%A|Hbx)rpn`REck#(J^SbjiHXe-jBp!?>~DC7Wb?mC z_AN+^nOt;3tPnaRZBEpB6s|hCcFouWlA{3QJHP!EPBq1``CIsgMCYD#80(bsKpvwO)0#)1{ zos6v&9c=%W0G-T@9sfSLxeGZvnHk$SnHw57+5X4!u1dvH0YwOvuZ7M^2YOKra0dqR zD`K@MTs(k@h>VeI5UYI%n7#3L_WXVnpu$Vr-g}gEE>Y8ZQQsj_wbl&t6nj{;ga4q8SN#Z6cBZepMoyv7MF-tnnZp*(8jq848yZ zsG_fP$Y-rtCAPPI7QC^nzQjlk;p3tk88!1dJuEFZ!BoB;c!T>L>xSD<#+4X%*;_IB z0bZ%-SLOi5DV7uo{z}YLKHsOHfFIYlu8h(?gRs9@bbzk&dkvw*CWnV;GTAKOZfbY9 z(nKOTQ?fRRs(pr@KsUDq@*P`YUk4j=m?FIoIr)pHUCSE84|Qcf6GucZBRt;6oq_8Z zP^R{LRMo?8>5oaye)Jgg9?H}q?%m@2bBI!XOOP1B0s$%htwA&XuR`=chDc2)ebgna zFWvevD|V882V)@vt|>eeB+@<-L0^6NN%B5BREi8K=GwHVh6X>kCN+R3l{%oJw5g>F zrj$rp$9 zhepggNYDlBLM;Q*CB&%w zW+aY{Mj{=;Rc0dkUw~k)SwgT$RVEn+1QV;%<*FZg!1OcfOcLiF@~k$`IG|E8J0?R2 zk?iDGLR*b|9#WhNLtavx0&=Nx2NII{!@1T78VEA*I#65C`b5)8cGclxKQoVFM$P({ zLwJKo9!9xN4Q8a2F`xL&_>KZfN zOK?5jP%CT{^m4_jZahnn4DrqgTr%(e_({|z2`C2NrR6=v9 z*|55wrjpExm3M&wQ^P?rQPmkI9Z9jlcB~4IfYuLaBV95OGm#E|YwBvj5Z}L~f`&wc zrFo!zLX*C{d2}OGE{YCxyPDNV(%RZ7;;6oM*5a>5LmLy~_NIuhXTy-*>*^oo1L;`o zlY#igc#sXmsfGHA{Vu$lCq$&Ok|9~pSl5Q3csNqZc-!a;O@R$G28a@Sg#&gnrYFsk z&OjZtfIdsr%RV)bh>{>f883aoWuYCPDP{_)%yQhVdYh;6(EOO=;ztX1>n-LcOvCIr zKPLkb`WG2;>r)LTp!~AlXjf-Oe3k`Chvw$l7SB2bA=x3s$;;VTFL0QcHliysKd^*n zg-SNbtPnMAIBX7uiwi&vS)`dunX$}x)f=iwHH;OS6jZ9dYJ^wQ=F#j9U{wJ9eGH^#vzm$HIm->xSO>WQ~nwLYQ8FS|?l!vWL<%j1~P<+07ZMKkTqE0F*Oy1FchM z2(Nx-db%$WC~|loN~e!U`A4)V4@A|gPZh`TA18`yO1{ z(?VA_M6SYp-A#%JEppNHsV~kgW+*Ez=?H?GV!<$F^nOd+SZX(f0IoC#@A=TDv4B2M z%G-laS}yqR0f+qnYW_e7E;5$Q!eO-%XWZML++hz$Xaq@c%2&ognqB2%k;Cs!WA6vl z{6s3fwj*0Q_odHNXd(8234^=Asmc0#8ChzaSyIeCkO(wxqC=R`cZY1|TSK)EYx{W9 z!YXa8GER#Hx<^$eY>{d;u8*+0ocvY0f#D-}KO!`zyDD$%z1*2KI>T+Xmp)%%7c$P< zvTF;ea#Zfzz51>&s<=tS74(t=Hm0dIncn~&zaxiohmQn>6x`R+%vT%~Dhc%RQ=Cj^ z&%gxxQo!zAsu6Z+Ud#P!%3is<%*dJXe!*wZ-yidw|zw|C`cR z`fiF^(yZt?p{ZX|8Ita)UC$=fg6wOve?w+8ww|^7OQ0d zN(3dmJ@mV8>74I$kQl8NM%aC+2l?ZQ2pqkMs{&q(|4hwNM z^xYnjj)q6uAK@m|H$g2ARS2($e9aqGYlEED9sT?~{isH3Sk}kjmZ05Atkgh^M6VNP zX7@!i@k$yRsDK8RA1iqi0}#Phs7y(bKYAQbO9y=~10?8cXtIC4@gF#xZS;y3mAI`h zZ^VmqwJ%W>kisQ!J6R?Zjcgar;Il%$jI*@y)B+fn^53jQd0`)=C~w%Lo?qw!q3fVi{~2arObUM{s=q)hgBn64~)W0tyi?(vlFb z>tCE=B1cbfyY=V38fUGN(#vmn1aY!@v_c70}pa(Lrle-(-SH8Nd!emQF zf3kz0cE~KzB%37B24|e=l4)L}g1AF@v%J*A;5F7li!>I0`lfO9TR+ak`xyqWnj5iwJ$>t_vp(bet2p(jRD;5Q9x2*`|FA4#5cfo8SF@cW zeO{H7C0_YJ*P@_BEvm2dB}pUDYXq@G1^Ee#NY9Q`l`$BUXb01#lmQk^{g3?aaP~(* zD;INgi#8TDZ&*@ZKhx$jA^H-H1Lp`%`O{Y{@_o!+7ST}{Ng^P;X>~Bci{|Qdf1{}p z_kK+zL;>D30r6~R?|h!5NKYOi6X&I5)|ME+NG>d9^`hxKpU^)KBOpZiU^ z;|SzGWtbaclC-%9(zR-|q}kB8H&($nsB1LPAkgcm+Qs@cAov{IXxo5PHrH(8DuEMb z3_R#>7^jjGeS7$!`}m8!8$z|)I~{dhd)SvoH9oR9#LjO{{8O&r7w{d9V1z^syn&E6 z{DG0vlQF_Yb3*|>RzVop^{$mWp|%NDYj@4{d*-@O^<(=L=DMFIQHEp-dtz@1Rumd; zadt^4B#(uUyM6aeUJkGl0GfaULpR!2Ql&q$nEV^+SiDptdPbuJ=VJ)`czZ@&HPUuj zc5dSRB&xk)dI~;6N?wkzI}}4K3i%I=EnlKGpPJ9hu?mNzH7|H0j(mN3(ubdaps3GM z1i+9gk=!$mH=L#LRDf4!mXw0;uxSUIXhl|#h*uK+fQPilJc8RCK9GNPt=X^8`*;3$ zBBo77gkGB5F8a8)*OR10nK&~8CEMPVQyhY>i`PS{L^-*WAz$ljtU%zlG1lm%%U4Zw zms0oZR8b|`>4U1X*9JLQQ>m9MF5%ppoafz^;`7DbmmIENrc$hucekkE4I83WhT%(9 zMaE;f7`g4B#vl(#tNP8$3q{$&oY*oa0HLX6D?xTW3M6f<^{%CK4OE1Pmfue`M6Dh= z&Z-zrq$^xhP%|hU&)(+2KSSpeHgX^0?gRZ5wA8@%%9~@|*Ylux1M{WQ4ekG(T+_b` zb6I)QRGp%fRF)^T?i^j&JDBhfNU9?>Sl6WVMM%S?7< ze|4gaDbPooB=F4Y=>~_+y~Q1{Ox@%q>v+_ZIOfnz5y+qy zhi+^!CE*Lv-}>g^%G=bGLqD(aTN;yHDBH#tOC=X02}QU~Xdme``Wn>N>6{VwgU~Z>g+0 zxv0`>>iSfu$baHMw8(^FL6QWe;}(U>@;8j)t)yHAOj?SdeH;evFx-kpU@nT>lsrUt zqhV}2pD^5bC4786guG1`5|fK@pE6xcT#ns)vR|^?A08G62teHaE&p`ZrCBj_Swt*~dVt=5*RK6Y{% zABqK$X59BnrK3r3u=wxklRnA1uh+q`?T0kE1YhvDWF4OY#<(+V|R@R%tdkq2huF(!Ip+EpZF3zr*|9pmKHPo)Cu z;H+^s&`Ql}u=Jt~ZWj`bAw|i-3#7(2WuRU3DU{BW8`?!O?YO1M$*MMTsaEM!5Jyp~ z!gp6yR4$O%wQ8%dyz43ZPeoJwy;o;yg=S0^Y}%|)to>=N^`!3VMf1~}OZ`Dl$q&|w z9$!i3!i1uAgPTuKSWdBrDr*N$g=E#mdqfj*h;Z}OG`{n245+g;IKfdn!&gF2OtHaD zyGDzj@@d2!P(_Ux)3v;1ABTj__{w*kaRF-1YVU`})Acgk?(T*1YqEve3=5)8bkZK* z!Tus*e$h@^u z>#zV0771Bix~r&h2FJ9)%N{>s>?2tk1$bId)1#G;OKgn-U8jUo^AK;Hu)hQEi}swD(264kAS-SBCD$R(Ro0rh8~Le zzRwxbz_JHDbD+hTX15AWmVw!#rC)-zeZahQQmo6FG1)ah3uuyIuTMof}RO!`Y3^Fxn_-G$23RDOh(@NU?r6`*S?#E50)w zpcsgDZ-iO{;EesgDQq9;p*C#QH(sp~2w^zAJWaUL%@yo)iIL6y8;e_}=dwQc%k%;H zFt5lenH*`}LWd+fPqi;exJeRZgl&nLR%|a!%1x0RQ54cgyWBYrL>sskcAtPxi&8c( zw_K?sI*3n%S;lKiYpveBN08{rgV&-B1NN5Jiu07~%n#%&f!(R(z1)xsxtRBkg#+Lv zh21zX?aYDd_f}qdA`Os*j!eC<5)iUJ&Twj7?*p%vEOGElGhpRZsccM!<k}DeC;TY;rULQs3e}lZyP#UVb=6 zB$Dkm2FaHWUXr7<{R&46sfZ)&(HXxB_=e`%LZci`s7L6c-L7iF&wdmTJz`*^=jD~* zpOZ@jcq8LezVkE^M6D9^QgZqnX&x*mr1_Cf#R9R3&{i3%v#}V$UZzGC;Or*=Dw5SXBC6NV|sGZp^#%RTimyaj@!ZuyJ z6C+r}O1TsAzV9PAa*Gd!9#FQMl)ZLHzTr99biAqA(dz-m9LeIeKny3YB=*+|#-Gq# zaErUR5Z*Wh^e<+wcm70eW;f-g=YTbMiDX)AznDM6B73)T4r%nq+*hKcKF?)#vbv?K zPMe=sFCuC*ZqsBPh-?g!m*O`}6<}Pfj}Y1n9|Y@cUdD5GX_)6Sx9pPfS7 zxkt?g6ZwJ+50C7qrh6dMFmr7qah`FskT_H=GC92vkVh$WfZa2%5L99_DxyM{$#6HQ zx$VR-Wwt!q9JL2{ybEGJr$^?!V4m_BqDqt!mbs=QjHf340+^a{)waVvP0+98(BA$M ztWr&sM=juyYgvf`(SC}+y@QtYgU>0ghJ6VbU}|kEraR&&W%#;!#KI?le%g`e>ZVPiDrneh#&1(Y?uiMo^f5qo@{JEr(p9>8GhDa+PC9yG;lX+D?hQ^fZB&Sdox219zUj_5;+n<0@Wi3@DK`MU8FM!OFJ z8*_mTA-u!Ab#95FRVWTIqAL#BVQGxE_s?>Ql|@0o9vos&r<_4d!+Q6(_270)6#lu$ zV!j$a?_V0I<(3Z=J7C-K0a^Kc1Go9p&T6yQeAD+)dG-$a&%Fo0AOte~_Z&_m2@ue~ z9cKFf-A41Dz31Ooj9FSR`l?H5UtdP?JS=UU$jF#znE1k@0g%K?KQuwZkfDI3Ai)(q z#x_Yo6WR_Y@#6I_02S&NpcP<%sw!!M_3#*8qa+*4rS@x=i{-2K#*Qr)*Q$-{<_(<| z0730e+rubnT38*m;|$-4!1r6u&Ua2kO_s-(7*NGgDTe##%I>_9uW;X__b_k)xlv$; zW%K2hsmr>5e^Z~`tS-eUgWmSF9}Yg8E}qydSVX0nYZMX_x94QK?tw2>^;raVTqstR zIrNAX2`X~|h->dTOb9IrA!i5INpLV}99ES|i0ldzC`;R$FBY5&7+TIy8%GO8SZ37_ zw=^Swk?z+j-&0-cTE|LU0q@IKRa&C6ZlXbSa2vN5r-)*f<3{wLV*uJUw980AFkWN7 zKh{?97GmVu-0rs9FB6ludy|n`gN5p~?y51aJzBg6#+-=0pWdZ2n4xTiQ=&3As-!-6 zFlb|ssAJEJL#s8(=odfz8^9b#@RrvNE4gjuEITzAd7R4+rq$yEJKXP?6D@yM7xZ&^ z@%jnE3}bteJo{p(l`hu`Yvzg9I#~>(T;>c;ufeLfc!m3D&RaQS=gAtEO-WbI+f_#| zaVpq-<%~=27U8*qlVCuI6z9@j)#R!z3{jc>&I(qT-8IBW57_$z5Qm3gVC1TcWJNc% zDk?H3%QHno@fu9nT%L^K)=#sRiRNg|=%M zR;8BE)QA4#Dsg^EakzttRg9pkfIrF3iVYVM#*_+#3X+~qeZc^WQJvEyVlO@9=0pl!ayNOh|{j0j^a z+zi_$_0QKhwArW)sJ$wji;A`?$ecbr?(4x5%2pLgh#wggbt)#T^2R3a9m+>GcrUxU z*u-WTgHAN*e!0;Wa%1k)J_P(Vdp>vwrROTVae@6Wn04q4JL-)g&bWO6PWGuN2Q*s9 zn47Q2bIn4=!P1k0jN_U#+`Ah59zRD??jY?s;U;k@%q87=dM*_yvLN0->qswJWb zImaj{Ah&`)C$u#E0mfZh;iyyWNyEg;w0v%QS5 zGXqad{`>!XZJ%+nT+DiVm;lahOGmZyeqJ-;D&!S3d%CQS4ZFM zkzq5U^O|vIsU_erz_^^$|D0E3(i*&fF-fN}8!k3ugsUmW1{&dgnk!|>z2At?h^^T@ zWN_|`?#UM!FwqmSAgD6Hw%VM|fEAlhIA~^S@d@o<`-sxtE(|<><#76_5^l)Xr|l}Q zd@7Fa8Bj1ICqcy2fKl1rD4TYd84)PG5Ee2W4Nt@NNmpJWvc3q@@*c;~%^Vasf2H`y z+~U-19wtFT?@yIFc4SE_ab?s@wEUfSkOED}+qVjjy>=eac2^S^+|_3%cjH%EUTJ&r znp9q?RbStJcT*Vi{3KDa^jr4>{5x+?!1)8c2SqiCEzE$TQ+`3KPQQnG8_Qk<^)y_o zt1Q^f{#yCUt!1e(3;E6y?>p+7sGAYLp`lA3c~Y`re9q&`c6>0?c0E2Ap5seFv92#X z1Vldj!7A8@8tWr&?%;EBQ_Fwd)8A3!wIx`V!~~h(!$pCy7=&*+*uIzG@*d%*{qG#4 zX0^}}sRN^N=p{w(+yjv%xwb!%lnVTE7l1l6gJwQmq_G83J&Y98$S!r*L8}IiIa2E= zE!0tbOuEDb*No0-KB{zjo1k#_4FHtr{!)>o+Y@bll}Sa6D^xktI0H&l{jKAK)A(iz zB-N00F?~Z}Y7tG+vp)-q*v71(C}65$-=uXx^|R$xx9zZip-V>Hqeyfd(wteM)+!!H z$s+>g4I@+`h2>C|J;PhvtOq)`xm4;CyF}R<)!ma3T{Vf_5|zo;D4YI4ZDBkE(vMeE zb#ZV;n}CgA0w8x!UC2&5Z(K)9bibj#?~>R(72lFx_Am~jS?;7mo~p+05~XGD+(wV4 zEVYnf0N5+-7O+Gc1L!sPGUHv<6=cV8}*m$m`kBs@z zy;goR(?J^JrB7uXXpD00+SD0luk!vK3wwp(N%|X!HmO{xC#OMYQ&a7Yqv-54iEUK4 zVH;)rY6)pUX~ESvQK^w|&}>J{I?YlvOhpMgt-JB}m5Br`Q9X+^8+Xa%S81hO<1t#h zbS+MljFP1J0GGNR1}KwE=cfey%;@n&@Kli+Z5d>daJjbvuO3dW{r$1FT0j zR$c9$t~P50P+NhG^krLH%k}wsQ%mm+@#c;-c9>rYy;8#(jZ|KA8RrmnN2~>w0ciU7 zGiLC?Q^{^Ox-9F()RE^>Xq(MAbGaT0^6jc>M5^*&uc@YGt5Iw4i{6_z5}H$oO`arY z4BT(POK%DnxbH>P$A;OWPb@gYS96F7`jTn6JO@hdM za>_p!1mf?ULJZb1w-+HamqN__2CtI%VK`k^(++Ga0%z*z@k0wYJDqT^)~%|4O299; zh1_iRtc7you(kOK8?Q$R7v-@Qk4+i=8GD2_zI0%{Ra`_prF{+UPW^m5MCA&4ZUpZb z2*!)KA8b--Upp~U%f+rsmCmV~!Y>Gzl#yVvZER2h;f&rkdx{r#9mc8DZMJaQXs?SL zCg3#>xR6ve8&YkP*`Z=lng|Ow+h@t*!Ial*XQg3P;VS8@E1C)VS`?L9N+rxlD7bxC z3@Ag)Vu?#ykY`ND+GvRYTUP&-KDMiqly$Z~uFXt^)4Jjk9RIs*&$?-UPM*d7&m${m zm12kaN3mV1J|c6f$>V+{lvHp~XVW3DU0;cBR>7|)4bo{xa1-ts-lYU-Q-b)_fVVl`EP5X}+J9EzT20x8XIv=m7witdu7!3Lh=KE#OyKpT1GWk{YAo^ny|fvZt<+jmsFs=l*%e& zmRkBt5ccv4O7!HAyv2~rsq*(FmMTm?@TX3&1`nu|7C^F{ad%GLuoX}Rl}6`)uHF_xlx^gVca+mGH4T8u8;q{S*x3=j;kelz^atO~)v!Q_BT z4H6%IA}bvfuk0_vweELeEl8N5w-Q1GF!@f{VKnbyYB2?}d&QvI-j}~RI_+9t9$tC2 z94m=3eLi=sQb^S5;fqP?3aaXc&`}`lq z&M8dOXvxx9Y1^u_ZQHhO+qP}nwkvJhwoz$Mp6Qcq^7M#eWm}!3U@s07hop` zW24|J{t$aB`W>uBTssEvYMyi$hkaOqWh+^(RV_1MYnE0XPgW?7sBDk=Cqs(;$qrPEflqa0ZE?A3cBfW%0RPA235Wb6@=R_d>Sez; z`spwa50bq?-zh+id~Q!T`AYn`$GHzs;jxIw(A1_Ql&f|qP}|bon#H;sjKmSDM!nyn z>bU8l%3DB3F+$}|J^da!!pN|DO!Ndc2J)wMk!+Rr1hes#V}5o(?(yQSphn|9_aU<- zn|nsDS{^x&tweP;Ft`2ur>Koo2IdXJDsr6IN)7vB41Yy-^Wbo9*2th2QA@C zE0-0Gk12YOO?d_Guu6b3&(PIL`d zh4{`k54hu9o%v1K3PGuccez-wdC<&2fp)>`qIIaf)R{5un7-vwm=>LD7ibnJ$|KyE zzw`X*tM0S|V(I3vf454PY{yA5lbE+36_<1kd=&0Xy4jfvUKZ0$Jq!AG4KS7DrE9rph;dK^6*#CIU9qu7 z?)6O`TN&MCWGmUVd1@E2ow2`vZ1A#nGo8_n!dmX77DCgAP1va*ILU+!a&$zdm6Pa6 z4#|*&3dM+r_RJb%!0}7X!An&T4a4@ejqNJ;=1YVQ{J6|oURuj8MBZ8i7l=zz%S4-; zL}=M^wU43lZVwNJgN|#xIfo$aZfY#odZ6~z?aNn=oR1@zDb=a(o3w`IGu&j>6lYxL z&MtqINe4Z>bdsHNkVIu$Dbq0wc#X-xev221e~L zbm8kJ(Xzij$gF4Ij0(yuR?H1hShSy@{WXsHyKtAedk4O!IdpR{E32Oqp{1TD{usJi zGG@{3A$x%R*pp8b$RQo4w&eDhN`&b~iZ2m3U>@9p1o5kXoEVmHX7I6Uw4dn((mFw` zilWrqFd=F5sH$&*(eJB52zaLwRe zz`sruIc=Ck75>v5P5kd>B2u=drvGPg6s&k5^W!%CDxtRO)V6_Y_QP{%7B>E~vyMLG zhrfn8kijyK&bX+rZsnSJ26!j$1x+V!Pyn|ph%sXWr9^f&lf|C;+I^Fi_4;`-LJI&F zr;5O@#4jZX=Yaw0`pUyfF4J8A9wE#7_9!X|_s8~YUzWu&#E^%4NxUA3*jK-F5R3LP2|msHBLmiMIzVpPAEX)2 zLKYjm3VI4r#7|nP^}-}rL+Q4?LqlmBnbL+R8P%8VmV{`wP0=~2)LptW_i682*sUR# z+EifOk_cWVKg-iWr^Qf4cs^3&@BFRC6n0vu{HqZzNqW1{m)3K@gi$i}O(hT`f#bT- z8PqCdSj~FncPNmMKl9i9QPH1OMhvd42zLL~qWVup#nIJRg_?7KQ-g3jGTt5ywN;Qx zwmz4dddJYIOsC8VqC2R%NQ>zm=PJH70kS|EsEB>2Otmtf-18`jUGA6kMZL3vEASDN zNX%?0+=vgsUz!dxZ@~)eU17m4pN3xGC0T;#a@b9Iu0g_v*a3|ck^s_DVA^%yH-wt= zm1)7&q6&Rq#)nc9PQ6DKD{NU=&ul10rTiIe!)x^PS~=K(wX9|?k&{Mv&S$iL9@H7= zG0w~UxKXLF003zJ-H%fGA4Db9{~#p&Bl7ki^SWwv2sfoAlrLMvza)uh;7Aa_@FL4b z4G>`j5Mn9e5JrrN#R$wiB(!6@lU@49(tawM&oma6lB$-^!Pmmo;&j57CDmKi)yesg~P;lJPy9D(!;n;^1ql)$5uYf~f z&GywSWx=ABov_%8pCx=g-gww_u26?5st=rdeExu?5dvj^C?ZZxDv@Si^nX~2qA&K= z2jr;{=L(x~9GLXrIGXs>dehU^D}_NMCMegdtNVWyx)8xHT6Qu!R>?%@RvADs9er;NMkweUBFNrBm1F5e0_>^%CwM6ui}K_MpRqLS0*@lAcj zB6TTCBv>w2qh)qU3*kN+6tPmMQx|5Z0A4n67U-nss90Ec_rDF}r)IR4PE{$8;BSt= zT%6|jyD^(w6a*A5>_|TkMqx~e$n@8{`q?|)Q&Y4UWcI!yP-8AwBQ#P`%M&ib;}pli z9KAPU_9txQ3zOM#(x}*lN8q$2(Tq1yT4RN0!t~|&RdQMXfm!81d0ZuyD}aG3r4+g` z8Aevs3E_ssRAMR+&*Q30M!J5&o%^(3$ZJ=PLZ9<@x^0nb>dm17;8EQJE>hLgR(Wc% zn_LXw|5=b$6%X zS~ClDAZ?wdQrtKcV9>_v1_IXqy)?<@cGGq#!H`DNOE1hb4*P_@tGbMy6r@iCN=NiA zL1jLwuMw&N-e9H(v7>HGwqegSgD{GSzZ@sZ?g5Y`fuZ^X2hL=qeFO(;u|QZl1|HmW zYv+kq#fq_Kzr_LaezT zqIkG6R+ve#k6!xy*}@Kz@jcRaG9g|~j5fAYegGOE0k8+qtF?EgI99h*W}Cw z7TP&T0tz4QxiW!r zF4?|!WiNo=$ZCyrom-ep7y}(MVWOWxL+9?AlhX<>p||=VzvX`lUX(EdR^e5m%Rp_q zim6JL6{>S%OKoX(0FS>c1zY|;&!%i-sSE>ybYX3&^>zb`NPj7?N^ydh=s=0fpyyz% zraFILQ17_9<ettJJt~I+sl=&CPHwz zC9dEb#QFQcY?bk11Y=tEl{t+2IG`QFmYS>ECl;kv=N6&_xJLQt>}ZQiFSf+!D*4Ar zGJ~LFB7e_2AQaxg*h{$!eJ6=smO(d2ZNmwzcy3OG@)kNymCWS44|>fP^7QkJHkE9JmLryhcxFASKb4GYkJ|u^Fj=VdF0%6kgKllkt zC|_ov2R4cJ2QjjYjT6jE#J1J<xaNC>Xm;0SX<`LuW*}*{yQ3c9{Zl=<9NP z^2g5rAdO!-b4XfeBrXa4f{M0&VDrq+ps&2C8FYl@S59?edhp~7ee>GR$zQI4r8ONi zP^OA+8zrTAxOMx5ZBS03RS@J_V`3{QsOxznx6Yt*$IuEd3%R|Ki&zZkjNvrxlPD$m z%K+rwM!`E&Z46ogXCu!3 z8use`FJJ?g_xi?~?MxZYXEu=F=XTC8P3{W*CbG3Wk)^31nD~W>*cJ@W4xg%Qqo7rq z`pUu8wL!6Cm~@niI*YmQ+NbldAlQRh?L!)upVZ)|1{2;0gh38FD&8h#V{7tR&&J}I zX1?;dBqK}5XVyv;l(%?@IVMYj3lL4r)Wx9$<99}{B92UthUfHW3DvGth^Q0-=kcJ1 z!*I9xYAc$5N$~rXV>_VzPVv`6CeX(A_j3*ZkeB~lor#8O-k+0OOYzTkri@PVRRpOP zmBV|NKlJT?y4Q82er)@lK&P%CeLbRw8f+ZC9R)twg5ayJ-Va!hbpPlhs?>297lC8 zvD*WtsmSS{t{}hMPS;JjNf)`_WzqoEt~Pd0T;+_0g*?p=dEQ0#Aemzg_czxPUspzI z^H5oelpi$Z{#zG$emQJ#$q#|K%a0_x5`|;7XGMuQ7lQB9zsnh6b75B9@>ZatHR_6c z0(k}`kfHic{V|@;ghTu>UOZ_jFClp>UT#piDniL(5ZNYXWeW0VRfBerxamg4su5<; z(}Ct2AhR@I-ro0}DdZLRtgI@dm+V`cRZjgV-H+aXm5|Mgz`aZX63i<|oHk-E)cABn z0$NR?(>fla7)Ong28FZSi9Yk0LtYl5lZw5wT!K5=fYT$avgkMKJWx~V#i@7~6_{dM zxDDPIW2l{O2Elv#i^cjYg~lGHRj(W*9gD`(FILKY$R`tL2qo&rtU*c;li!V`O$aV{ z!m|n!FAB2>MR_FVN*Ktv5+2dW4rr3YmfEheyD+48%USM#q6)w%#2}~=5yZE1LLcth zF%VtefH&#AcMx7)JNC$P>~OFuG6sK}F7V$D7m!{ixz&inpAVpFXiu^QruAw@Sc7Y2 z_A^V(2W_+KTGRp2aQSMAgyV#b3@{?5q@hPEP6oF3^}|@8GuD6iKbX;!LI!L=P#Za zL$Zuv#=x3fseRMZ()#SQcXv->xW`C|6quwqL1M&KByBj z2V`}(uL4JB-hUs6304@%QL~S6VF^6ZI=e-Nm9Tc^7gWLd*HM-^S&0d1NuObw-Y3e> zqSXR3>u^~aDQx>tHzn9x?XRk}+__h_LvS~3Fa`#+m*MB9qG(g(GY-^;wO|i#x^?CR zVsOitW{)5m7YV{kb&Z!eXmI}pxP_^kI{}#_ zgjaG)(y7RO*u`io)9E{kXo@kDHrbP;mO`v2Hei32u~HxyuS)acL!R(MUiOKsKCRtv z#H4&dEtrDz|MLy<&(dV!`Pr-J2RVuX1OUME@1%*GzLOchqoc94!9QF$QnrTrRzl`K zYz}h+XD4&p|5Pg33fh+ch;6#w*H5`@6xA;;S5)H>i$}ii2d*l_1qHxY`L3g=t? z!-H0J5>kDt$4DQ{@V3$htxCI;N+$d^K^ad8q~&)NCV6wa5(D${P!Y2w(XF!8d0GpJ zRa=xLRQ;=8`J2+A334};LOIhU`HQ*0v4Upn?w|sciL|{AJSrG_(%-(W9EZb%>EAGG zpDY?z1rQLps`nbCtzqJ#@wxU4}(j!ZQ{`g`g*SXlLah*W9 zyuh)UWoRCknQtd~Lk#BT_qjwj&Kw8U)w=owaJ;A5ae}3)y>{neYNS`|VHJdcSEBF# zBJ6a;T)u;^i#L~LVF-X7!E$SggILXMlsEy~v}K*DM2)f@U~g|Q6I-Pss@)`>fgFWx zsq&7pe!|VA-h;@=fBF{(mR1^{1>ukTYUdyF^#A+(|I_&nm{_xaKn3h4&yMyym2k-wMFg(s@ez=DPmuB%`| z6;e@HQKB(|!PU1sW)W6~x|=8m6rL~4dQ9LTk|RzL-_(_77B4I~ZG=q7K%qHiv!FD8 zmt;Vnhb{ymaydv2V;X-5p zTt2ln?kaB9&(dH_X70^@rrCfz)nwfa9LYTHXO(IPcTEf$QiEhTpl??L+`Eetyqof8 zzl=q)?KdYni!C_9b8Z3xm7r5<5ZG-0uA`u^7Dm7k4mAsQ(rkoWy*^DZJa~#y6+hNG zh?7{D9$a9LS`a@SvZ5?C{JUHovWU9KI}z8YV4pWftx21v*Q;MpU{+b@>Or(}pwO^fu0qA3_k_Bo2}lIxvmMhucG-o>O=+R6YxZ zjs!o%K1AA*q#&bs@~%YA@C;}?!7yIml1`%lT3Cvq4)%A)U0o1)7HM;mm4-ZZK2`Lj zLo?!Kq1G1y1lk>$U~_tOW=%XFoyIui^Cdk511&V}x#n4JeB7>bpQkYIkpGQRHxH$L z%tS=WHC~upIXSem>=TTv?BLsQ37AO88(X+L1bI<;Bt>eY!}wjYoBn#2RGEP49&ZH-Z_}R_JK_ z>o*_y!pOI6?Vf*{x-XT;^(_0}2twfk`*)_lLl0H-g|}BC?dm7CU|^-gNJ~rx z($>97WTKf71$?2|V$Ybpf~Aj@ZZOcb3#uRq51%4^ts-#RMrJhgm|K3QpCsPGW=2dZ zAr5-HYX!D*o#Q&2;jL%X?0{}yH}j*(JC4ck;u%=a_D6CrXyBIM&O#7QWgc?@7MCsY zfH6&xgQmG$U6Miu$iF(*6d8Mq3Z+en_Fi`6VFF=i6L8+;Hr6J zmT=k0A2T{9Ghh9@)|G5R-<3A|qe_a#ipsFs6Yd!}Lcdl8k)I22-)F^4O&GP&1ljl~ z!REpRoer@}YTSWM&mueNci|^H?GbJcfC_Y@?Y+e4Yw?Qoy@VLy_8u2d#0W~C6j(pe zyO6SqpGhB-;)%3lwMGseMkWH0EgErnd9a_pLaxbWJug8$meJoY@o-5kNv&A$MJZ=U z^fXPLqV6m3#x%4V*OYD zUPS&WHikdN<{#Yj|EFQ`UojD4`Zh*CZO4Cv`w^&*FfqBi`iXsWg%%a< zk@*c%j1+xib(4q^nHHO^y5d8iNkvczbqZ5;^ZVu%*PJ!O?X-CoNP*&tOU!5%bwUEw zQN?P*a=KKlu{`7GoA}DE=#nDibRgecw>-*da~7&wgow}|DyCJq!-Lp8a~(zR@tO1 zgu(4s4HptPGn(HmN2ayYs@g+yx1n`nU3KM{tQHhMHBw7f#gwru$=C()`aKZAl^dYc ze7fC)8EZEXOryk6AD&-4L+4cJ&M@3;;{R)mi4=`ti7IZByr^|_HNsjcNFu?mIE)jD za2j)FPwRY!R_YR-P?URm0Pti*e#5jmfK)6EvaKCT{h)kbJl{AGr1Ekt}pG?^e z*botRf-RsB8q10BTroj{ZP**)2zkXTF+{9<4@$aNDreO7%tttKkR3z`3ljd?heAJEe<0%4zYK?};Ur*!a>PbGYFFi(OF-%wyzbKeBdbkjv^i9mn@UocSS z4;J%-Q$l`zb&r*Pb`U;3@qkc=8QaPE9KwmlVwAf01sa*uI2*N`9U^3*1lLsM9dJ(4 zZBkU}os|5YT#Z;PD8xVv!yo$-n{-n4JM5ukjnTciniiT`(cZ6sD6~67e5_?8am%!w zeCLUxq~7x-!Xg#PgKV&caC@7mu<86am{WaXo(lAemt4~I$utSp(URWpYNo$RvU*$N z#%iiA+h`(E;BUg;=I!#EaxO89bUK3*v5Nc3GPmURC5TqzC|))DsFNtJICH6oBW6#q z+B(N{ey+^mk_{!@ z)VhAWXG=_0j|0f9iJ;c404PiIFqK)(AD05Xh`Fk`r$^b`v+>*g+_+h@r)e+ELJ45) z?20~u<}HQyQ5AsBz(teF9!!_GLXnm{5Z0e{Ki*@!=&3x4-RcjBn##DDzHJ|KSZ5(E z9=tFZ)p~-}x%9sCY27)2i>(E-^OiYT?_)a;yXAGR$y+E`myMd;xDA#_Q49t*E}&ql#H~|x z2J2R1_#2lt91NnF!uqW%_=HlbF?A{B{n>}9$g5QF!bh_a7LTU~Jyz}7>W5{_LAov{ zy2_dmGy)d)&7^bJyUjEw%3xj{cuG0Eo zwL*XQB*Oi=r&HIIecC1%lbE;Y-*5|cL955S+2@uR18JDL<0;;Uc2Q9JEyo1R!!sz_ z#BqnkGfbLP#oQJk3y}nwMd(3Tt^PVA#zXnYF7D0W1)#+`i?@cm}fBkKD z+Mpcuim53|v7;8Tv(KraEyOK`HvJq^;rlNzOjIbW&HJDFqW>doN&j7)`RDv#v|PQ+ z03WnB4Y4X@Fe-@%3;He*FjY1MFmkyv0>64Cp~FIDKQTwmFP~_CxZOf{8gPy}I<=JC zo%_bmue&$UU0|GG%%99eI!m#5Y1MD3AsJqG#gt3u{%sj5&tQ&xZpP%fcKdYPtr<3$ zAeqgZ=vdjA;Xi##r%!J+yhK)TDP3%C7Y#J|&N^))dRk&qJSU*b;1W%t1;j#2{l~#{ zo8QYEny2AY>N{z4S6|uBzYp>7nP_tqX#!DfgQfeY6CO7ZRJ10&$5Rc+BEPb{ns!Bi z`y;v{>LQheel`}&OniUiNtQv@;EQP5iR&MitbPCYvoZgL76Tqu#lruAI`#g9F#j!= z^FLRVg0?m$=BCaL`u{ZnNKV>N`O$SuDvY`AoyfIzL9~ zo|bs1ADoXMr{tRGL% zA#cLu%kuMrYQXJq8(&qS|UYUxdCla(;SJLYIdQp)1luCxniVg~duy zUTPo9%ev2~W}Vbm-*=!DKv$%TktO$2rF~7-W-{ODp{sL%yQY_tcupR@HlA0f#^1l8 zbi>MV~o zz)zl1a?sGv)E}kP$4v3CQgTjpSJo?s>_$e>s2i+M^D5EfrwjFAo(8E%(^ROV0vz0o z-cg0jIk24n!wxZainfH)+?MGu@kg$XgaMY-^H}z^vG~XC7z2;p2Kv`b^3S#b5ssMOJ7724v>S36dD zeypxJ<=E~sD4f5wX060RIF-AR0#{Z z=&y$r8A-e6q18lIF{@O9Mi%dYSYT6erw!@zrl=uj>o(3=M*Bg4E$#bLhNUPO+Mn}>+IVN-`>5gM7tT7jre|&*_t;Tpk%PJL z%$qScr*q7OJ6?p&;VjEZ&*A;wHv2GdJ+fE;d(Qj#pmf2WL5#s^ZrXYC8x7)>5vq_7 zMCL}T{jNMA5`}6P5#PaMJDB2~TVt;!yEP)WEDAoi9PUt89S2Cj?+E0V(=_sv4Vn6b z_kS6~X!G;PKK>vZF@gWpg8Zuh%YX^2UYPdCg7?EH#^gkdOWpy(%RnXyyrhmJT~UJw zAR;%Zgb6z(mS+o9MT|Sc6O({!i0pzk;s9?Dq)%tTW3*XdM3zhPn*`z45$Bg!P4xfy zD*{>30*JsSk?bQ-DgG62v>Vw-w`SA}{*Za7%N(d-mr@~xq5&OvPa*F2Q3Mqzzf%Oe z4N$`+<=;f5_$9nBd=PhPRU>9_2N8M`tT<-fcvc&!qkoAo4J{e3&;6(YoF8Wd&A+>; z|MSKXb~83~{=byCWHm57tRs{!AI<5papN(zKssb_p_WT@0kL0T0Z5#KLbz%zfk?f7 zR!vXBs36XaNcq5usS7<>skM_*P$e*^8y1ksiuokbsGFQ_{-8BAMfu!Z6G=88;>Fxt z|F-RU{=9i6obkTa0k~L#g;9ot8GCSxjAsyeN~1;^E=o5`m%u7dO1C*nn1gklHCBUw z;R(LgZ}sHld`c%&=S+Vx%;_I1*36P`WYx%&AboA1W@P;BvuFW+ng*wh?^aH4-b7So zG?9kFs_6ma85@wo!Z`L)B#zQAZz{Mc7S%d<*_4cKYaKRSY`#<{w?}4*Z>f2gvK`P1 zfT~v?LkvzaxnV|3^^P5UZa1I@u*4>TdXADYkent$d1q;jzE~%v?@rFYC~jB;IM5n_U0;r>5Xmdu{;2%zCwa&n>vnRC^&+dUZKy zt=@Lfsb$dsMP}Bn;3sb+u76jBKX(|0P-^P!&CUJ!;M?R?z7)$0DXkMG*ccBLj+xI) zYP=jIl88MY5Jyf@wKN--x@We~_^#kM2#Xg$0yD+2Tu^MZ1w%AIpCToT-qQbctHpc_ z>Z97ECB%ak;R<4hEt6bVqgYm(!~^Yx9?6_FUDqQQVk=HETyWpi!O^`EZ_5AoSv@VbUzsqusIZ;yX!4CsMiznO}S{4e>^0`c<)c~mC#*{90@+T@%EQ~>bovc8n_$bvqkOU7CrYe8uI5~{3O7EijeX`js z-$LNz4pJA7_V5~JA_Wl*uSrQYSh9Wm($%@jowv^fSPW<~kK&M*hAleywHd?7v{`;Y zBhL2+-O+7QK_)7XOJAbdTV-S`!I)t~GE8z+fV7y;wp#!wj75drv;R*UdSh(}u$%{VSd0gLeFp;h6FkiVz%g=EY3G#>RU;alRy;vQmk*| z@x-ba0XKE%IyL4OYw6IXzMiS(q^UDk=t(#XgkuF`{P?=k8k3r)rmhkv`vg@kiWd34 z-~t+1aV3SabTbG=nQYs>3~E<}{5@0g**LAWi*~SfRZhGcgP{e5T!0M7CU}`f@r8xI z0bx%sI!?5);-wG+Mx&S=NRfIi>V-wP(n&$X0Bhd)qI^ch%96s6&u7qpiK8ijA=X_R zk&|9f$GXf-;VgnrxV83Cp-Q!!sHH`5O^o~qZu!xny1t?(Au(EAn)D??v<1Uo;#m7-M@ovk|()C(`o>QMTp}F?> zakm3bHBKUjH-MHXDow7#Z|@wea1X9ePH;%YA)fCZ9-MD)p^(p!2E`aU9nmJlm;CXQ zkx~$WQ`Yq{1h5k>E>Ex{Z=P=)N*0b8_O({IeKg?vqQ)hk=JHe z5iqUKm!~mLP0fnRwkCO(xxTV@&p+o8wdSP$jZofYP}yEkvSc z5yD-^>04{zTP7X44q9Af&-wgt7k|XtncO&L@y-wFFR44RsPu57FRvIBaI^Pqy_*DV z@i13CsaR5@X@xH=NT3}T`_vsy!a02n80eQqya=-p7#YW`Jc0z!QglGg`1zeg6uXwI zsB~hlNMo)kFL(V3Q1<%8yoI6X7ncn-&&Uh3rL@S(6@wKAXt6Wr=a2ObI7}8$D-FoI z>AJA>WsBEMi5ba6JhJ%9EAi&ocd(ZsD|MsXwu@X;2h#|(bSWu@2{+c7soC`%uo{sMYq&Vyufb)?OI59ds)O+kyE8@G z@tlpNr0UO~}qd0HQve6njJ zda2+l$gdX7AvvGhxM6OToCuQ|Zw|9!g1)O+7>~{KNvASjp9#Cqce-or+y5xdzWL3gLWt2oa+T(I+{j(&bF1laUsJB{fOgE-B}qslaS>C z)TjzG8XecbS%a+?yT!0QmTex?E478;D|sL*oS4C-g0Tq(YoH|eyxJ#1j088C|U-w5id`%Sz7X_w#l+U9+)$|2no<}5J zRb_9@0esSr?n}HvVGbD5@$p$8k4?qOe-GNOk3-K^Mw>Xg+drCKi5@$GTeijpI;;IG ziD<&go`ptLC&^<0jw^l0aY?_pUUK+xp#0Bk66iQ29vpR)VBE{JOJ&OL^gKsN<&t<| zCMLTYMSDG5Ie9O>6Dl#T{@cscz%)}?tC#?rj>iwQ0!YUk~R z$rB-k=fa9x&631Z9Mfqj_GRoS1MzqSMEdaZ2!isP19Sr>qG8!yL(WWF)_&{F)r>KnJGSciSp!P0fqHr+G=fGO02Q#9gHK zpwz+yhpC4w*<9JO@#(MdkZcWbdCO5B!H`Z|nV?UtcBo96$BgX+7VYMwp@b-%;BrJu zMd*K!{1txv{kHKPDs9?WZrz_^o1Tq2P=+=|E=Oy4#WE{>9}*9(apqhmE`&AeBzQgQ zELFLCmb~q|6y0FCt|B}*uI*ayZ#6=$BpGtF{Jfye#Q>FZ?BPnk)*Qmd?rNG^tvFUU z_b&antYsZnUR6Q9tQUy81r$&ovT#fy;(Db4F&M*C=KxQgHDrRcVR#d+ z0(D|*9#u`w_%2o3faI{?dNd9$#5nj1PROHNq z7HJ(;7B1ThyM>a@Fo^lJb2ls2lD`}ocREH|5pKN;$>gFyM6k)kZG;lA;@kSJIqUhf zX%dhcN(Jtomz4(rNng&1br3Xx33EvCWz%o8s;SpRiKEUFd+KJ+u|gn|J85dZ)Exc&=V|Ns8Xs#P>qv6PX&VAJXJ(ILZO!WJd0 z`+|f5HrEj~isRN7?dBHotcPI7;6W48*%J(9 zftl1Tr`bKH*WNdFx+h;BZ+`p!qKl~|Zt5izh}#pU9FQKE97#$@*pf38Hr8A+`N+50U3$6h%^!4fBN zjh^cl#8qW5OZbvxCfYzKHuyeKLF4z^@~+oqlz9(Hx8vypIiUlt!(vs}_t#4@nh$s; z>FYERg*KD#Xs+W4q-V-IBQK!)M1)Aa+h+V+is)z!_=gEn&^ci7<DEEmYcoSh?WdXUsP7O4)&lQXA(BVM5jI8s6;mO}94AC0gG(`>|T)yuV1l~i-ejCCt zoejDhX0nrZDP|x9u4zp%S2UeDzV`o#pBGu1tZ-$<9TIbN=ALwhQ0=9S{8#}Uu8n-~ z5~xIvUhLSz@c@0|me$CdZCpZl(vQw@a0Y4^{T0w_>pOkwI^x4KkBf3qGmm)nG|Ps5 z_XTY~^b^mL&_*yjl~RRIi&eS(>y?y}O4-)nWyTEPpQAb#Xz8SnnfIL+nAcNL9nqV9 zRL|eyF)RKI5-kJO6}>Q89XmgY@b1&!JI>g3ryZ@jN2v3vm7O`AL!BTWNouJzV+$+Y zYY}u%i>K6=IYU2O$2TAyVjGt?wgF9xCj;?EK(8fWu!!~48`3u^W$eUlCh*91PLxu1 zRY(F7Q3s7h$Q-p&L$ucN}it*-9KR z_<wHu?!dav0$P+PI3{J8?{+l|n&2YMLV2 z+hRta$A5WpCXl1RNbYBsX8IGX{2v>U|8_I-JD56K|GexW>}F_e_g_1r?08v8Kz{V$ zT=6aGMk>ibvRO@Yrc@ezaD0%ydHkXGHrR{7>q~~tO7ChJflwa4-xL|@#YIJejC5VT zInU4CjQ9V0+lClQY=vh^s4MadwQmk7li{54Y;Ht}gkZOIh9(vfK?3kXLoD72!lHD# zwI-Jg|IhT=Y#s|tso1PWp;|aJ2}M?Y{ETyYG<86woO_b+WVRh<9eJu#i5jxKu(s~3 z4mz+@3=aNl^xt{E2_xewFIsHJfCzEkqQ0<7e|{vT>{;WlICA|DW4c@^A*osWudRAP zJut4A^wh@}XW4*&iFq|rOUqg*x%1F+hu3U6Am;CLXMF&({;q0uEWG2w2lZtg)prt` z=5@!oRH~lpncz1yO4+)?>NkO4NEgP4U~VPmfw~CEWo`!#AeTySp3qOE#{oUW>FwHkZ3rBaFeISHfiVSB7%}M) z=10EZ1Ec&l;4 zG98m5sU!pVqojGEFh8P{2|!ReQ&hfDEH2dmTVkrS;$dN~G2v-qnxn^A2VeHqY@;P} zudZD5vHtVvB*loIDF1M7AEEvS&h0;X`u}!1vj6S-NmdbeL=r{*T2J6^VA7F`S`CDd zY|=AA6|9Tu8>ND6fQhfK4;L3vAdJPBA}d6YOyKP&ZVi%z6{lbkE|VyB*p1_julR^k zqBwjkqmFK=u&e8MfArjW-(Ei8{rWso1vt5NhUdN|zpXqK{ylJ8@}wq-nV~L4bIjtt zt$&(1FTIs+aw}{&0SO4*sa0H2h&7g}VN5uYjfed5h7eGp$2Wu*@m9WIr0kxOc}fX9eOWh zFKfV>+SD$@kESKYm{F*J90XQjr$!<~v(J%&RMuQM+6CkmnYZDGlOUdq}%)VA& zl#acS%XE2KuX~7IamK`og@C`21~*cEEc#PZM6HT*Veb_l&Ej~j0zL7p0Eo`mMu(=X zJ$v;&Lya75I4C^saKROgfi(fdP0C$GM3WyZn%mm3yEI>|S&O(u{{S<}ihUp#`X&_z zmQBma;82#`C;dR5Sx09e07FvtJLhZ{9R~|$FCdU6TDNUwTc9kNct?8e@o2MpQDrkg zN?G+aYtTjiUPA=RX5o{4RYu}6;)ET>TcgL^VpfIpluJ|lQR(_)>6k%L^FZmoK-Wm- zR5qy0P)hm8yvqOL>>Z;k4U}!s?%1~7v7K~m+gh=0c9Ip_9UC3nwr$%^I>yU6`;2kV z-uJ%y-afzA7;BC7jc-=XnpHK+Kf*tcOS>f5ab2&J&5hIOfXzs=&cz|Qmrpu6Z);`R z0%3^dioK5x?o7t~SK7u5m{dyUZ#QUPqBHYn@jETeG>VU=ieZuJ;mm^j>dZM7))cw?a`w8R z%3M0R=kdOt^W^$Kq5Z%aJ(a$(*qFpy^W}Ij$h+Jnmc9eaP(vB@{@8t zz=RQ$x4XYC#enS$fxh@;cSZ|D%7ug;0z{C8I8h{KocN-cyv3UG_nk99UNS4ki^OFkYea`q`rs zG@qdMI;4ogcd5Tr`di1JBg4I*6CFvCID_2SN5&)DZG&wXW{|c+BdQ4)G9_{YGA@A* zaf}o^hQFJCFtzt&*ua~%3NylCjLtqWTfmA-@zw;@*?d&RE3O8G&d;AVC|rZrU}jx# zC-9SF`9;CbQ(?07o8Q9E12vi)EP@tOIYKEKnO@-o!ggkC)^#L-c40iZtb4Y-cS>$I zTn~+>rn*Ts>*y*z^b3-fAlne+M-*%ecrI^rmKAVv23cB`aWD?JDJ5NIafRvRr*~~C z)99Afs`BPK!5BFT)b_^8GyH*{22}yDq;be`GnPl=vW+ITnaqzl(uYOHhXi}S!P+QZ z4SwfEPuu&z4t#?6Zaw}bvN{;|80DfxCTuOdz-}iY%AO}SBj1nx1(*F%3A-zdxU0aj z`zzw9-l?C(2H7rtBA*_)*rea>G?SnBgv#L)17oe57KFyDgzE36&tlDunHKKW$?}ta ztJc>6h<^^#x1@iTYrc}__pe0yf1OnQmoTjWaCG`#Cbdb?g5kXaXd-7;tfx?>Y-gI| zt7_K}yT5WM-2?bD-}ym*?~sZ{FgkQ9tXFSF zls=QGy?fZ=+(@M>P3Y>@O{f44yU^fP>zNzIQ0(&O$JCd_!p?2;} zI6E1j@`DxzgJvqcE@zgapQ?tophO14`=14DUZ*#@%rRi``pi0lkNgidSsHGjXK8gO{drQoNqR&tRjM4>^DtW`)fiRFO4LE=Z+nCBS~|B3gZsh`Y?-$g z@8@Z$D7C!L9l=SWoE;(+*YirPLWvBd$5Ztn3J3EaGM+#pW#@{3%yksGqy(2Bt5PVE zf*fICtPp77%}5j#0G8<=v=)LR>-a3dxja8cy3m$=MZ2#$8mbLvxE%NptMd+L?mG`v zF1cANFv17DqP^P5)AYHDQWHk*s~HFq6OaJ3h#BUqUOMkh)~!(ptZ2WP!_$TBV}!@>Ta#eQS_{ffgpfiRbyw1f)X4S z_iU`lNuTy86;%!sF3yh?$5zjW4F?6E9Ts-TnA zDyx5p1h$Z3IsHv7b*Q{5(bkPc{f`2Wfxg*Z#IvQ;W_q9|GqXGj<@abo)FyPtzI~i25&o zC!cJR%0!}lLf^L2eAfZg7Z69wp{J?D6UhXr%vvAn?%)7Ngct4Hrs@LZqD9qFHYAWy z4l=2LI?ER&$He2n`RiG&nsfLv?8$Cl)&d8a-~-N`I|&EPa@Y=v@>0Gl?jlt>AUY;H z`**5bpS#VGhdp4pKbf3iEF*>-eXg_$bqt5Dc%q0+)R50>zd^l7sN5R5Z)Ut+oz-8_ zJ`Z9HE9(=wRTD)T=%GZTEi9K5naPzlfE$|3GYGLRCLsnqLi8Sc6y&iskqA&Z$#7Ng z7Q@C0)6k;J$TlQ+VKZ5)-Ff_BNoIMm+~!@Cv1yAUI-U!R)LHc@+nSUzo$GlRb+8W< zYPG%NFfr;!(RlnvBbN~~EpT6Xj5*^Z&73tdIQ$LZu`vkfzdTKa5|JJtQ_rm4g$9LO zKtgYVdW=b<2WGM3I_j|Rd8gZ3j;)S#AT(aP^d>9wrtQS_+K>pZDX^?mN!Z>f^jP@1 zlJ;i79_MgOAJa`%S9EdVn>ip{d!k6c5%zizdIoB9Nr!n`*X#%6xP1?vHKc6*6+vKx zmEt|f^02)S_u_wlW_<`7uLQU%{wdH0iojOf_=}2=(krE<*!~kn%==#0Zz`?8v@4gP zPB=-O-W=OO3tD19%eX>PZj3YfrCt0sEjgTd#b$buAgBri#)wW14x7QcHf2Cneuizz z368r7`zpf`YltXY9|2V{stf8VCHgKXVGjv$m!hdDf0gi`(Q!(Pyg~FO28Vr#!BYP| zI)qG2?Ho=1Us9dTml}-ZOR?g5Vk)f+r=dbCN*N1=qNfG>UCLeA8pd3Ub-pRx1b3FA zEn`CIMf`2Mt3>>#3RkE19o}aMzi^C`+Z>8iIPHSdTdmjCdJBtNmd9o0^LrJc9|U9c zD~=FUnSyghk7jScMWT|SHkP(&DK$Z=n&lGm+FDTpGxfoIyKV)H6^nY~INQ#=OtIT! zyB*J=(#oHf=S)MNOncW->!c0r0H#=2QzobO&f@x&Y8sYi-)Ld;83zO$9@nPPhD}yt z{P`*fT@Z(?YAmF{1)C;o?G@dfd2$c+=Av*|;P@Yz1KnclB-Z-fJQ-=+T*g>0B7!g# zQH{dHt_%wj=wlmT&m59)TQ~xK)gB6f^EY$=1zcbGf~Q>p_PzDCHR6lndGmqPY2)&w z$Th^K%1v@KeY-5DpLr4zeJcHqB`HqX0A$e)AIm(Y(hNQk5uqovcuch0v=`DU5YC3y z-5i&?5@i$icVgS3@YrU<+aBw+WUaTr5Ya9$)S>!<@Q?5PsQIz560=q4wGE3Ycs*vK z8@ys>cpbG8Ff74#oVzfy)S@LK27V5-0h|;_~=j1TTZ9_1LrbBUHb?)F4fc)&F7hX1v160!vJc!aRI>vp*bYK=CB(Qbtw7 zDr2O^J%%#zHa7M5hGBh#8(2IBAk}zdhAk$`=QYe^0P6Bb+j5X)Grmi$ z6YH?*kx9hX>KCI04iaM_wzSVD+%EWS)@DR&nWsSBc2VIZ>C(jX((ZiV0=cp}rtTO&|GMvbmE4FpBF5Rd z6ZG=>X&>N3?ZN2^11pXEP4L?XUo`qrwxgQm4X~RCttXmZAhnhu4KDK=VkKq?@@Q_Z za`*xyHrsAEsR zV(7)2+|h)%EHHLD3>Qg{>G|ns_%5g5aSzA#z91R zMDKNuIt@|t?PkPsjCxUy&fu^At*yUYdBV!R_KOyVb?DO&z$GLJh9~b|3ELsysL7U6 zp24`RH+;%C(!bWHtX&*bF!l-jEXsR_|K~XL+9c+$`<11IzZ4>se?JZh1Ds60y#7sW zoh+O!Tuqd}w)1VxzL>W?;A=$xf1Os={m;|NbvBxm+JC@H^Fj$J=?t2XqL|2KWl$3+ zz$K+#_-KW(t)MEg6zBSF8XqU$IUhHj+&VwsZqd7) ztjz$#CZrccfmFdi_1$#&wl~A*RisBaBy~)w|txu1QrvR1?)2mb&m2N$C(5MS%hSX)VJnb@ZGXB5^%(<#1L@ zL^>fBd+dEe`&hxXM<0A9tviIs^BDkByJdc~mtTYr!%F7Q1XnK2$%h$Ob30*hSP$Bt zDd#w{2Z%x^Wpv8!)hm>6u01mY!xmPgwZ#Q0148)SxJc3Udt!-&}eRO^LN ze26pQB!Jhg&Z>#FD>`C`sU44><=v>O>tJdLs!HPpV#AM32^J@Za-9J(CQjKxpzXao zQfRkWP%g9P8XV21MmoHfx{DICLSc*t4qVeQL9t}&Pz0rM}YTba@XsD=XMW@FxFM{QYQJHvM(JsUSa3mcTUl9^qcVA zBveO--fqw%{#QGR1vy;x88+qMcgzmcYc#8U`CPPt6bl?uj%w_`b~9JliftnOa|ziW z|6(q&STs_*0{KNa(Z79@{`X&JY1^+;Xa69b|Dd7D&H!hVf6&hh4NZ5v0pt&DEsMpo zMr0ak4U%PP5+e(ja@sKj)2IONU+B`cVR&53WbXAm5=K>~>@0Qh7kK*=iU^KaC~-ir zYFQA7@!SSrZyYEp95i%GCj*1WgtDId*icG=rKu~O#ZtEB2^+&4+s_Tv1;2OIjh~pG zcfHczxNp>;OeocnVoL-HyKU!i!v0vWF_jJs&O1zm%4%40S7_FVNX1;R4h^c1u9V@f z`YzP6l>w>%a#*jk(Y82xQ@`@L(*zD&H>NY`iH(iyEU5R$qwTKC5jm4>BikQGHp^)u z-RQ`UCa70hJaYQeA=HtU1;fyxkcB2oY&q&->r-G9pis)t$`508$?eDDueFdW=n5hJ z08lH$dKN$y#OEE@k{#|<%GYY=_c~fHfC@pD54KSP9{Ek@T47ez$;m$}iwR}3?)hbkwS$@p2iVH0IM$lB*XYA+#}-re|UNzCE)SOYwy z=Y!fkG4&I%3J(_H#UsV#SjHulRIVcpJ`utDTY{k&6?#fzt~@Om=L(vs6cxAJxkIWI z@H7)f2h%9!jl@C!lm+X4uu;TT6o0pd7 zteFQ(ND@djf#o2kTkjcgT=dHs7ukmP0&l8{f;o3JuHGd2Op*?p7?Ct=jA*tIg{MZk z$2Lsc0e8Tdcwrjx|_Ok?9uB3Il|^2FF%X#ck}WoIvrzQXN%kT$9NI{79Wm~gZ3`8I+O`)`n30feZ( zDO-fl6IG3c^8S;Y_M-)+^CmM0tT^g0?H#>H8!oC8W%oU!~3|DJ?)~LT9*&GAQG13zOGq6gs*={cu|(V7{R$y@{-iV*9q@AD(#Ktb}J&3&k|5Djs$)9WM7!6#EaJ_ilvbfUvyh8c?-{n zfuFrC0u6}UJZ7aj@(cNG_(CKgjQQTA-UK@-MVmick zot}6F%@jhq(*}!rVFp5d6?dg|G}M*moyLriI!PQDI;E1L1eOa6>F9E6&mdLD>^0jJ z09l?1PptuV65gm=)VYiv<5?*<+MH~*G|$~9Z3XEy@B1-M(}o&*Fr9Sv6NYAP#`h{p zbwbUE3xeJ;vD}QMqECN)!yvDHRwb7c1s6IRmW!094`?Fm!l~45w)0X`Hg+6Y0-xf# zSMemBdE)Q=e^58HR{kWrL5-H0X6pDu%o{0=#!KxGp0A;6{N5kI+EoY_eTE%2q|rwm zekNeLY-R?htk!YP2|@dbd8TWG4#G)=bXlE{^ZTb^Q$}Er zz)Fp)ul24tBtQFIegdI37`K$VR3tVdi<(fIsu{#QMx=$&CK9M8oN%3Mk;>ZPd-;Q- zn|sSKSnc-S0yrw#TlA$+p{J~u=u98s>IoL@cNLOxH=+1m?;t1bR$vR=M$US&Z8DO3 z_&zhQuId1$wVNsS=X?&s(ecIi#00o{kuPs6kpYkL$jMyGW8U7mlCVaZeEL=HsIxqm zFRLxWin8B>!Dc#9Z#t0RNQiR-@5J+=;tC7|1D*~rxcwHa5iIVD@99cCFE@BukUC-S z^iJdt?dwU)kH2VY9?|zVShMbZctzFRz5Q4tiXa^>@U%jDYq}$rSyc#p2wXr}mc0qq z^lT>$y)N(Qg0dwmEwTopneoU(y)>Mj+f{iHM0o|>ZtCg-itPj4addYz??aE)Rp&hk z_SI)%XeSf=SjZq18h!Cc>Xy&EynnxdHQ){(x@g|ZA%`3LU^KzX02c5N;F#tEk1)7v z(|V9tO3>?^X|kQ*rRBf4>mWW2$-Lx})|M7z125&VHcxsCqB!<$l1F$zCrJ+nm0f3Z z%Hq^=SKpHyV2@Y*Cu2x>fXC0SscnR*($zEB{KOniJcpn@e`PMH*_Q6*0Z^8RNCEvZ z+UU9!927p9YZ&g=bnUvQUZcdisyn;-4;ACXOe-Xor9K8Qbp{ldE17+G@VQT+9ZJQ*9dZoXfU2ue|mMhrrZk2R7&~YjFW4`BTq45UwVc6JORKU)wBCTanITh0GD}s$`C5pb(9{b9 znwee6j%?-UV)_7opOioCf5@C?@w^@g& z&68+oMmV;5JW@TT63&CSDrfYL2$L)pVseDtAwPwleEM3F^-Ufn3PpfxFmx6o zQ`Wq9x#d$e`VKn5LOXNsrqhGao7~|s(u~drPrZ+;aP!C%z4NskZstCbAibD}O%8Ij zb~C(taxco~WzJLxhL1T}3ctXMbV6}_z=IZN9L0|SxLSe`$X`<)BhM`$1&&)e_}fCh z=idVL<+u6Vn{&ksP*ZLlMo$fC`dtzF_?~L?4Rril2G4%v5^7sUa^&8aMtMX&mtapl zD(dW|cisM3fqMaB`8?QbkyiUl2g>hMB5EoS&IB8TdoC~)b$nT=`%GgU`k-)+8}`)F*~I~DXMaTP%kZftx11~?iALs5J+&Rom#p%Y z>dH}-euH4u=_V3hc6^*2WMtL!9%yRTJ93p}@aV0zdY*?xchFI>m+UivV=;aMFp0P~ zwB8P)wvV6D-GL?6hJ#g7Hy7=2i^&Od#S=j!;Rc_yjO!*4aN7{vqzg2t-R|Dav%_NDk z`H_FVlSi==(~f-#65VmQ{EE92x<03lwo5p)s=ZJ^L7PlS>132Whr zR6v~t(#I+(`usYLCoO;Rt8j&b^5g_xgs*98Gp|N}b>-`HtVm)MscD)71y?(K6DRCZV26RsHPHKk)EKKZA%C99t3$t^B0-k5@?E>A-YMbFe?>ms?J?_guHHNU(;id*>xH zTrtam+Aq?n@-y@uY@A?hy?1qX^eLu_RaH4Ave?A8NapgQF=C%XI7wlcCf4<6BRo_% zBXxxc*A6-3CruF?3i8HOdbc%>N=-iiOF+9HX|ht6SCkz;A^am&qi_I&qk1B(x<=(m z>QG)nswCOLl_1{SZ@_eE#m^qb6#6DoMsB*)`17ui+XvF%(}|J4G$z2G*;E!1ERnAH z@q%=#uV6kBddqy4=g>!VTV)9*1=i{wJ}Ep!I*?)uJdA(LwE?(!?;}_u=^M2NShWC_ z*7l4aBJ=!QVU2-iehgb`$vOI8zkm{W%QO~?xOD;NgI;Iqa3#^$^U5D&McReLe&qs# zR<^@QpR4#W~Laz+QBsPt@3L#KF`Yr8}jgHe;5(cfpQ=;Zjtbt;c%y^#-m=hqOT z;KAYakW+$w0&F}>K10&SiPcD9SrDOuczj@U#W})5jGU-_htU`U6Q%wdy((%?J}y+$ z=$4jw1N nJo)qTxG{D(`3*#8tY|67hJRF;)r6F|#I`Ar6I0aafRa=kr-Z0I^}9xf^u;G5iEQCbpv3b#S#%H|HYHsQaHK$! zU#3Fpz8*^pK%RRmX<_09eIVziB0jOgPgFnI-*QcwEBtBiO#v!>{W1cLNXyw3D9M|A z*oGy(u8BkDA1c;MsXmpK^-~pl=We^RYnhZ4bz*)Q)C2G+E3tgx9PzU0T>c|1ilS!T zyE=bz`=wskDiOi!@!l?Y))#%{FM`}7r~X)i1)1*c6_2Q!_1{)fp%cS|YF+Q-CB%d< z=zYus`Vt@Mx*a7V)=mpLS$-5viaKgNB=+zN657qy0qR94!cTtX-Z%KBCg4OKw7b=t zr=`7q5Ox=lJ%!G5WIyNQC1xpqYU0{!I$hyrk!6%De$gp<_*Gc?ES(OwY8U^)Kjgc{ zSlhpXDb|;{+y9`u{EuMz54rlky2~p6xX2>MV6BZ&k`$q%q7v(xYps2wr9e8^4<;CB zc)eAT~B^rjzO6<4BDDH;il6 zFsM8jL+agQ;zazW(uiQjM%fPf2N~_p{cy29XP11_lQFpt`t#9nlk}>fv((FZt-dBa zuMIc4HmPHW04n0TTG9ug9;&OV9euL$Ib|+M7}}L~z4e%%%b|r~6OQj(S2d7XfYn#xp8;KQ55UYu#gY*De5j6Cc z#R%?rqwpy7I1(kpU7B*Pq=etXeYUn04jg%ZPjYqQNa$==yTG=6KX+=;i2Xg+kjV2T*Gc!(ef z`Q4fR*TA=M5-}z+s%YO+!K{k}S**ic&>o4_Tmv$EQTOp7F6TXPCj-UTXy?OQ=%*y62Qajk{rXbR%jMCOFMiVE3KekQa4xR}B%=iPtd8BXo~q$OX_ zSp910{Ew;m|GATsq_XiJ3w@s(jrj^NDtr(Dp!`Ve!Oq?|EJ9=vY2>IfrV{rT%(jiY zi}W@jA2iqd=?q>s;3%?@oi7~Ndo3Ge-2!zX58j(w&zVlPuXm3rcHb7O0RsM|!Ys(b zh(=*&Aywo3vuJoWZnU!u2_4bNkDTc&&bCYc%T zM~~xYxS#3KXFzQ@OXdc%9QDOxqiTd_> zT;(DX9{5dIuC4pO_xy+3{Ov)1I7j!Z)6&nHUvTRP>VU5dm#849icG)cvl0QOPkCIzG^lOp4#UcNr`VhBp(Ha%8@KPlvT*5u!v_$b#b~%sn3K{mu zaxeD%Q~{;Lw03ZAq(Pc-IVj>n*h3l2{sqioCMGatQY0kx zi`1(WWDQ=;gmLSGptEQ%UFC)th@|71<8eiRtX&Mx@#1q#nMF_BMfQdS>!!Qkx2o}= zuqRi?`UOX5P3fP%M+71Q$ctH4Av}bXED#fQ`KR4!b~60nsAv^*M7c-x`|~B}XIuq% zlqIJOf>WvlhQ@Uw$du|14)tZ?; zPNZ|xZSwp1y+d4sut8E4*l2JWR|~o0A9vD-?zC-w zDc@=wE1YKb*OMSi_Kx}&w;#h3>sHp|8^hnA3w?-WK)X?@Z2dgV7`9Cupf-B2RE4x^ zwlw+~!V9C^tyb`J;m2}ksD`w}G9`yu(^--{SQ+wt^Fu4Li~Fft!3QO`upSkAU?o;# z(1Q%GUVWbbkTK-M=T+ULkk3s6Dc9`G4CO6|=&-S&D+rbJQ$`Y-xL~ol;kc(l)VbU>{&>bV+*?ua;$bnDc29RW+Ig16)Vf6=L|fMR_P2b7>6}0 zdlB#-gj|j*C~M=F^2=K*k~=tl6YM3SXXi&K-`EvEXnWz&4D-^hQRBJI3gKKDj^6|> z*WhHSim1qAffNt60Mve9lfw^+&0bx-AM0%j>QP3%W=S@(l=(nrJ678mRQ(#+sI@d{ zdb#5fo#T;hK7xJ=M58wZf|?DHwD%!OZ3JrTGV5#{cfQwuiMvz%!CQ}CubJ7`z?@rSF<+KHNV2goc)a6hP0oHB@3LLKSH2w{um&J*z1Ka2 zLIR>lvOvh>Oxe%?3A@v<_T|}${zf_&@C~^FCo#jB(W9VLO?DX{)n(BQ0(V0`mI|9Y z#U3WwxixJkU_NTvA>5q(A@r2dnEXJp#6B=pww$XGU}~1~c``UKqQb=^*2P|4Dq*_! zhY^i61Sy%T5$Td0O6^C>h(xVvT!}Y##WeT8+s+Uuz=7)~V$>!zU;%d>H)rm*6^IrsCma%|cifwDLk_ z!^W2voQ)D;I$=v2E>iSaBw!d7aD+|LWl2iD!cBw`Q5p1~fk_xGiPi8e^mY&#viTAk zmaKL8m;JQ4bY(n6uBZt02z#noMMxTfF-RzjKre-c+@B)#J3pN-Zv7F}JtAwNk3j?OkpVCL6W1)Q$FLAj zGI!tX;g`O{%pt=0|q54Jyj##w*4e*|_;Us2Tn?!#^R(>u}|FAw1G_ z#wQsagnj9$TAC`2B_XgB$wNq~Sxgl?#0+QWWcB{G`c6~&SosbtRt}Tukw`TQ!oG1= zYyL(y<;Wh+H24>=E}Gs=Hs2%fg;&Qdvr74{E!R?Bd zIRQ?{{xkLJ_44P@y3^#(Be%(pk%$liKbUUo76wSoVfJmt9iTKL3z{uW6L&?jYg>EY zsx{kRiW@q%<$VZvbS(TKKTO4{Ad6l^IeY(F^3}=mX9|FZmQ`~RErNxlBPl3ast}W$T4V?SW=6kIGn@-^`qJv| zZXwhK4Kl1a4E}nLI`rdOi?^pd6;LZ-|8G&INHgOeC5q{_#s+SXb0r(;5ryHFsoTJD zx$VtNDh=-Tx3t!NTlk=hgAaSM)#U}e>_-Ex(|JoX*hWmBPPdTIa-2(BIOUJ|Iddy| zwY*J%z%W$}*;uSoB!BIJB6N6UhQUIQE_yz_qzI>J^KBi}BY>=s6i!&Tc@qiz!=i?7 zxiX$U`wY+pL|g$eMs`>($`tgd_(wYg79#sL4Fo+aAXig?OQz2#X0Qak(8U8^&8==C z#-0^IygzQfJG4SWwS5vko2aaOJn*kM+f1-)aG{T43VJAgxdP(fJ4&U{XR90*#a)G8+clOwdF?hJ?D) zmxu>0>M|g_QRHe_7G|q6o`C>9x4xd$Gl7lAuR~+FtNid=%DRsnf}YI*yOToWO%xnP zY*1G5yDnTGv{{xg5FhWU65q3-|-(+-rJ2WCeSJn(7Az>ej4Jp9+l-GyZ_| zJ8}>iA4g|}q1AhEEv#uWR&$g&Uyht?fVU(qk(j?^D`))s>oG08pow!f>P1u71P%oL2)UC4GeS87&G?{)NE;D=my1Q9{~;y zJULE=bG6jXE28Y11YmoZoo945`MM*`v%5b=_02*0cwzDve#3(4M}NPt`)?SCa|7*q z-94ks(R6WH-l9fE4m4}10WSu&O`|;ZCIT%vL$_pbABY!}s33@~gIvZ0H4co|=_-T$ zF#lC7r`89_+RL9wYN=E3YwR?2{$^ki(KKd>smX(Wh*^VmQh|Ob5$n_%N{!{9xP~LJO0^=V?BK8AbCEFBhDd$^yih$>U z(o{RReCU{#zHSEavFNdc8Yt<%N9pd1flD{ZVSWQu*ea1t#$J5f6*6;tCx=&;EIN^S}*3s%=M#)`~=nz!&Q0&{EP|9nzWyS<#!QxP;!E8&3D}?QKh^ zqGum|+;xu9QE=F#fe2ws5+y1Igr&l`fLyLKry=1}(W+2W`waeOR`ZXlW1B{|;4sE3 zn^ZVlR11hiV~p<~TaSen8I~ay#7Ql=-_|U@$8yjZsZ=Vi+^`JV2+kn+oiSUi%omO_+7}saXnJ9 z5ETilbag(g#jZPopCgJu+n@(i7g}3EK2@N zd64$77H5a`i%b%a^iRjMaprwzWz(`=7E6QY)o)gek7H)yZ-BLw^6FAoHwTj9nJtWc ztKaytMlWGLg29W{?gr|rx&snb@XyvR_}x3fmC>d=-nQp5ab3*whTw}DfUcKlMDDx` z-%?ek^*|Kqooy#>2lfklZ|jN4X$&n6f)RNNPl(+0S>t(8xSeOGj~X0CGRrWmm(WXT z))DDW_t&y$D#2`9<-+JT0x1==26*gpWPV~IF=rePVF%e-I&y$@5eo~A+>yZ&z6&7> z*INESfBHGNegTWga&d@;n;FSCGyW?}e_Qw#GTLHo*fWxuuG@I~5VA!A1pOdRTiPA~ z^AGe(yo=9bwLJD}@oDf$d+34~=(vIuPtOKiP}obDc|?@hY}J*@V|UynBeAkYa?S{@ z_f$U=K+>deTAi&=a*xv>Ruyw$UsTWY=Yn=xjf;s)6NQu>_niQ_idmzIwuL`Scf)f= zyzK?D5a5)^D@H&qN%F6Zd0JeXX*Knbe~VLe^gi|?JK67&mB4jrapV-$`hCQT;C{%T z*pjxB+Y|~LD9bmMN%Iq}S$F$x1yWU7@GcR91V8h;!O2I5MN_rq*gRx(k8T!1WSDTp zr9eJO4$~H94aG^6k5p8k=kFJ>4lnY0q_Bsa$@vTRW6uY?slH|Qt)Yu6Yun&pfJ zBi!h;6x?FDs&79#PT*HSCEUsKws#s%TFy*=2PAfb`>gEPBn+D-WdfXA?MkB=<8kb_ z1+4D11mdHG0EcAyg4dneLtfJ8)RyHQl@6hWJNe(d_EjyCHf7%Xsd)S4A-4COz{G@% z5xQ!P>AS@H@;4Ws)N91)3A6PleMe2<& z!(zv#%Uc?N`(Xmm)OJPYt)BM`nRjoWA&P0Yxl@c9Y02zlPH1J5l$nhPrMwu=atkz4 z)a-1+OEL;d@ctx=s<<+3Sv1VYy0RYmiji|#hy$66#`5;u~BkH4^$EGZ-Y4xyZ=%3KuaeLYKAUr$xMtIh_5mga> zPz<#G0mQ7IxEw-yO}BueN}RaFlg$RwCDB)vLF$wDu%qZyLYsPKdcbHD23$qn9i#JFqIo#OK?u7db2-$GatzO!On87%}Br};~#}n zziVB;qf_4(K$u>Qyz$ln_kBGS!CD-t4Y}9oxL@7@Sx*?NOAzdeINUD>Hl#*V%pfA; zSA`==YatS*G*crJ3`3ll4)vKss&)UtY#7ZxiVoG%9(4<%`WWcjX2jV(^g7Yhj+h5J z$5=?S=tuCyEt74^6jo@6y|@~N>&cVfFNtaRl=)Gm!vR;Bc$3-;ySCI$%kdmjQ|si` z{$q_YCe6vjy6re9jGN|`43D``)1PODtz0)vhV4XV36nVpOnMx2uM%qZ<3TtcI%>BQ zf0(J`{JqPPJxw>k#&nIvoZ5e9Sno)B2r+E0G} z@&M|zf4E0Q$O*NBR2I;?i7N} z@2^Su#`%qeX}m3cbSojiLk#84kvW1fICNPS`OyT0SpUoA0(s^2m~J<^eKE!dhJx_N zG_T}0&(<*an>oF=@?6?55g&IxSgY3?7|@pmDRE6gJyJNPH6un~%0hZ@?h=hI6O$b^ z)29#<4$E)cE-5IFbRpk9JVrw$$966UDyw;Iym4OY4Fc!&s1ZH4BJ1-$9<)Zt1c)N- zU^&9hsk6z?3%<9kGKHW|6~k;&cghtWz`oz`_YjVuvy;B;T67=L2c6=8`7WyTBv*QH zNv*bo1#KOk{O&)@&pkd*?v+kcJ8tM>AGx$~WMhH{L40_N=bkrVg+^p!H)IqXCQf2_ z0fPig=8CEo>p4vE(nc^DKbZ|9_Xo}$i4zJ`jVh95; z5%aNP3@``=EJ=Vt9U`y+$YtX;%OPzgZ_3+;+mh{p#W&y4-%%Bf`LhOy-*kB0qnB^m z_nBTz_b?-`F$*ymByshU>D)za2g`0j^ioo;A#QeL@x3@|+_!=YXA5f6Xg(Ack&WOg zJ<2i|Fd6OmyH!@YSMVxb;=M)ZDhBt)4`5T*>cUXWPG#%@$&*>K&u3#|`fm2mj*FKVf?du{xZ}WKWETTFhq6_fO$PS5(ItF=3~pFp~*j z!ys1<4EL1)#{`mz@gW|t-FpPkd%pK)n_Rb)F;z7cQ6dym_>YI3&e!=!m006oS3Mjq{q ze%hNzW=G0jpfl2K(x`CDuZCsJV*hm9T~%5n7R_g}VFpk`G((D^MWVMAmRp--T{`P; zwMgD<;e`fm`g3|fPns|6qnd{|FCHY*YAguXH(?%sx%4+Gu|Y)_8mk4EljxmP+MP`* z`SUbI{TCIN2OV+$y#g->Jqv#$wL;}4xJmah#$0`v^ughM_XjTA$B}ux)JZuY5-GW4 zKy440I+w=ZtE-_i+0xImq}vyzD68?8;94-5L~_O6Ty>X3itdA-x?6P(c4jkr+f!H( zUDeqiG>3bn^Sf8(`_YwqPeJ9&-@OCQZm4X{FfRMeBtN4E9Ca@;GVpU*L>lVb;@=PH zTQvTr?^jKyCKh&ZVOI*<y%T*Aw(XCPrFC=39*y$A`FSzxBiQ#W+uW10d8&gYp4{teh;^p@anft+z$5!Hv&@h0X-@xJG>hbTCxjDwMiWK@1b%8wYL6BrV zT41m}tX8g-`P@vj4T!Mlk8F0S!MA`^J=SCy9-jdwDe^hVDa`WwyI^H@ryt=F5y6>b zT8&iI6&j8edAfX^ycgWbnMZQ26Q~`LmdEScKC8|~$Jgyw(>18NAQ$9AwCRmri!96L zp^)b0P2CR-9S%cG$#rU}MXnx21T#031o>2VrDs@sa-FpjfvgLPW>Q&LHUoNOtmkt# zoDZ=5OGp{^vO~=p29^`aXd8K?(+f-bW`N$U;-o;%f?RcR!k02Nod2h^^8ly%Z67#E zC3|IOuj~^YBO=Fklo@3mvd6I{Z*&FZ>iq* zxh|JuJoo2$p8MJ3zO@dQ;%1#~Mrm48 zB0053{1bDi_a@jo<4!@!`w4}B(&Qb`~IeSBh zu+_yIYl2Wgk+?x4pCmAM>x_SqBPUj#c`C`k>_fp@qPlAAwD$!zOxRkL7;=|nu(#ut zyF^;&hm-D_;ji{d6rOloACu5*NkF4IC3@rifMG(|^Skv$H&^YnYL*rpw=UCi;JOuz zN*NX(7wZXS4tF@6PIWAs%*j!$RoL*3sh)}iry%thDvN5AUM888q_(>|Tzt|Yea3AyMYBgm$H_`F^v2%)bux)3s znFIEBDK;-JS5SH|;1?afJb<*=c5puu=w%tv#ihn*R!^Hd$KWAp4$#`joJ*)$kNtZ z2Al6h>Z>(u?3tmzA4^d+jLKx{97!Pb4;CX&u;M||**7zXI7hO6nrdMx*Xa=|-`#1^ zBQ?Ha&7cd7hN=%y4yUp?zl8~Lo;%mQrDe8!ce-W_K94FFMN*g(w8q-_K5S+c0{o29X&PzpV;UJE^!xnFc%b@>kvW4m#xiOj-L*DadC&2N#0Us z;<-(m1WB7$=j6hjcPC6JB)D3T2#IC`ibu#yi!uK7W2!j|Z>~RaJ*&XXy#ytIk2DIp z5?Qd^s90_?ILjU#>ZWk5HXts}grg_!Gmgm!d?eLGR7xEP zvTCrslV~94ym5_i<5oqy(@@?wN}lIdtiY8=?|Ng!XeYnly`@9wCGx2S$3x|0x8T2h zz7A85Vb2>s44rKpI_4Y7_Pnd2^mYj2%^jM|Du>u4`^Psda^JIP%*DK6bo`Vf&f{!% zDTYCwF5Nhi=)QhU2$@eQv&ZzxsX+Hl+gP6kW|e!n9IU2>Vh~cioI{>4WvR}t*4Hpz z%5z?HjLGoka}Q3AbX9AkY|Yjf^M(>@tBAI9JO5pDCQu0R3Nns>)LC#vB2p96C*?K? zvX$un$sBDx$1=+NNj*@Oa@u*b@O*XBr_sg@8sCUq-|LK!MUmC)epklrv}5O_^<{NP zX16|c$9Wtbks3y7geI^tF5oRZJu;v zwkW8j+8Ccxo9stEDOT_Go&j%$KCgVO7pm+^%PKEPBZqbMw%s@732XS{cX+wCSjH1s z5)bc=g**<^NNsroY` z?}fHHlgu^B?2r{^^gQ&j zbF~T((>|Yg&C5WKL8DCnl1}Z3!YHFW2S1|;Xr0`Uz-;=FxEwYc4QpeAtnm7^f~uzX zl;xA!?>MLR?tL80Iudm;mi{!ewL91KhG7Hsa-XepKi<2mc6%zf0GwtbfJ1Zf-<@Xu z#|XWDzv|04t)&9Id!UxAAkN{t5qC%%8-WV3i;3duS19%m2||Y{!3pR1=g|zQYAMqc zff)_2nj-O4wfxy;UNM?|Uieo!^J$A*uDe>@V(NKH;KS;Y_dtE8${p>RdcrW;=2*fj4~d?OG0l-(g?ik}vz} z)5-wDppVts>K-=|@{=!53?=8)Jw#RGpS_FWpbwtn}{v!JEJ$q-sr7F6&OPBuI# zuVNFMPte79XgEu!P&qRq8u4J>r%$l-IQ00Lin90(_KtC)aR_de zxN=pY2<1b29_^AG2WJIGmmX4rv3$!`l15{e(H!1^+x9voZ6;882YAE12q7+lgy+>) zj|s0CyzI9=Mo!R}&LXB`&DYpZ7c?0r(&KNV+~TULd0y^e;G{KVR4nL0KvU9mr8&$^ zxrM-9P8zE`J?aZ(iB~Rz<{vvnk2HaZU#K$aVFfYnbAXVUOLU#As5JvS%+26 zi$sNuPY}dLGUS$0g&;oBqhzv2dY`l3@6Na403M!Sh${B|7(y|_cONa;6BrtUe@ZzV z7SThtHT8k?Rwc)(Z}@BP#H@JJHz&GR&M=E@P9KJ89yQKmRh&I~%vbL1L-K3E>7>CH z)Y!=jXVb1iPrAoAZZ3}3wU*5~nrV!ZjL5zqJ<@NwjHCZC>68Cc<{&E_#S;E*jOdjtg?uKN|l`P8sjz&Qf7a^z9 z;{3-8T+H4y99_zc;JYIvs!sk$G}` z??mt*Mm9Z@glCZb!X?!xXD-21sFDPEpZOK{sbQseQ$%6~b;n+*z0hRoR}0Pe>B|#t z$XrVcXv8M|q*Z8MY&r9J0A=d^1bHpjrUXu)qEj~$%%=gZp`^~%O*lzxUquG^p6;n; z^(3HL+hx4gRP?4N*b2p9!^|2~rcw3!9nQj$vmZusbXYz_x^AVc`3qBFm(jS9ueU5h z^AnNnbswfQ2Jq=W=T+p-V|nQco@bOAH$pLQZ+BKH8E$iM>IDz z3|wc?QP`yI=X5YTlp8h}%p6{Deq?S0QD$Ug>ih1SdPZg237Rl{S~=Ha4~-ckMoIWMn+X@@`V6 z#HHZj>MQbt$Qqp*9T(cjc^lxZ7UO(>PwzF-qEr(wo`vaulxdall|KP`7p4gd`23&Jy=#sAes*0diLB(U$Nx46VQvP)8idSs8^zaV91xw*O-JMH=)FoJshRob|_)O)ojtfP))WHCr(;*2;VMQ75^ zfN@a^f#o<|*9X;3IcGodLUz-3i~FAu+zI4c5h+nW^h_!^)b*B_xw-l4O$TB(ixaqW ziMoa%i=BeS<-F45kMO;Tw|FWa`G2c!SuOA3CbowPhF6csf1|&qqugUrj;UgGHm| z;j^yoH?MZhR;AYOW_XW2Lg2j%%ejL)B@*bUMD`g<#Z${1+fa57r7X82 zcqY-cfPnK%Y^3@szRner zt)bBToYCph6Jv*W+&t?&9FG4(Iu2w46 z4B#AcFy_^J@f*6<{>CN}Sj969*DYV*e7<61U>GoN{tz!Do90+jApFueVY_IW(MQF; zl?4yA_(MvMwN&pWKVyg{3uU_+y6RMdot2vu%mC?st=N0pf-~JZXE?3JFf)j<{1xsU z`2ephz)#HzsWEP!inHm2hI(V(~@W zY7gGU-lO52cHD&SY)>QHgy$=>^X%u0TQZfCizro!*weMyvZC=;MWOawdAx~`3C*W` z%^#^$uRP;gyqEE0<(i8xcQY$oc+6mY#z{-XFxsO1(cN8Y)>p;^q9|5bk`Z*p|c!?(rErw#y;yT(%@c7trQBv6cj)$3>pI z>tz+;IB?D=aQV=s(n)o63*yn8dX1m7#Z4G{%fF@K2o5n3jxR~mU?nzMi#;}8e#(>{ zy{Z4!AI)jZ8TY;nq1aq}tq;~=zzoTv)er06oeX3;9{uP{LWR*2%9cmE%S^`~!BW>X zn3PZFTf3g*dG68~^1*q@#^Ge(_8puPEFLD8OS|0b2a{5e=N4S%;~f3tC>F6UxK#v9 z)N-#Mv8=ePCh1KsUKD1A8jF_%$MPf|_yCN9oy%*@um6D{w*2|4GY zb}gafrSC+f=b*W{)!a!fqwZ9)K>fk=i4qf!4M?0v{CMNTo2A9}mQzV=%3UT&i{3{W z>ulG#M!K7%jPf6Mjff9BMslgQq3zIogY);Cv3v;&b#;^=sh#(Bn%W)H*bHNaLwdpq z85%fUTUJJNjYO_426T2TBj0D{6t zw&S_HZ|C?pI_2q(9Fas&@uJs6nVX;P*5K#6p|#)_(8PM-{L(;2wl`ma{ZAd5gA)?y z>0GSLoK<*FwW+G8@-M3vcffg7I(qm7lzF)n`Q9iCvp*mn7=|CjlpG{x z&r0n}XLWZ!>=lynUr7D`6n`7a_ZgT< zm!i;&?Fb0Q2QmqmCHfZ7ex=_tU~(7b)L?RIvPyEAU=gLIZ-VTAA~WR00yKyTXg^(G zqWLZJs!FnQYMOH3*fN&Tn(IKMLf{Ki?pRo8zZJ6YVyj)y0^)-sR}2-)%mI(Aw2AgT zbbp1T{qB(OSNJd0cVBH^tI>HR(q+#*lmi@LWe*rZz&M2h1L_=50uZ1e*n#E*`6?aw zj`ka&JpceRGe@}Ey1)Q~O}0qHRg4K_u>4e1arvJ7Q9!=t5AuzG`n=a-f0}{+lnCE#zu$`oVn44eS&T?N*wz~t~E&oQDBrB_MSg z_yVrQehWbD0xHX|v-hpselAu;O7s;P*!uAT`dr~}Lie=tknaGoiU?;*8Cwgala-65 zosOB4mATbdXJFujzgA4?UkCKE093A1KM?W&Pw>A?IACqg1z~IZYkdP70EeCfjii(n z3k%ax?4|rY(87N&_vhsyVK1zp@uils|B%`(V4e3%sj5f|i(eIhiSg-fHK1Pb0-mS^ zeh?WA7#{hhNci5e;?n*iVy|)iJiR>|8{TN3!=VBC2dN)~^ISSW_(g<^rHr$)nVrdA z39BMa5wl5q+5F@)4b%5-> zA^-P20l_e^S2PTa&HE2wf3jf)#)2ITVXzndeuMpPo8}kphQKhegB%QO+yBpDpgkcl z1nlPp14#+^bIA7__h16pMFECzKJ3p4`;Rf$gnr%{!5#oG42AH&X8hV8061%4W91ku z`OW_hyI+uBOqYXkVC&BqoKWmv;|{O|4d#Nay<)gkxBr^^N48(VDF7Sj#H1i3>9138 zkhxAU7;M)I18&d!Yw!V9zQA0tp(G4<8U5GX{YoYCQ?p56FxcD-2FwO5fqyx@__=$L zeK6Sg3>XQv)qz1?zW-k$_j`-)tf+yRU_%fXrenc>$^70d1Q-W?T#vy;6#Y-Q-<2)+ z5iTl6MA7j9m&oBhRXTKr*$3gec z3E;zX457RGZwUvD$l&8e42Qb^cbq>zYy@ive8`2N9vk=#6+AQlZZ7qk=?(ap1q0n0 z{B9Fte-{Gi-Tvax1)M+d1}Fyg@9X~sh1m|hsDcZuYOnxriBPN;z)q3<=-yBN2iM6V A?*IS* literal 0 HcmV?d00001 diff --git a/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000..5f0536e --- /dev/null +++ b/utilities/on_subscibe-service/java/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1,2 @@ +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.5/apache-maven-3.9.5-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/utilities/on_subscibe-service/java/README.md b/utilities/on_subscibe-service/java/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/utilities/on_subscibe-service/java/Readme.md b/utilities/on_subscibe-service/java/Readme.md new file mode 100644 index 0000000..b79b032 --- /dev/null +++ b/utilities/on_subscibe-service/java/Readme.md @@ -0,0 +1,69 @@ +### Java Util for Subscribing and Key Generation + +- Clone the repo +- You are required to have Java 17 and Maven. +- Go to the ```main.java.ondc.onboarding.utility.AppConfig``` requestId(java file) should match with message.request_id(subscribe payload) that you will be sending in the subscribe payload. +- Run ```./mvnw spring-boot:run``` +- Hit ```https://subscriber_id/get-keys``` to generate the keys. + ``` + "enc_private_key": "MFECAQEwBQYDK2VuBCIEIPjSJTWFXeb0AH5L5d36q5yknfKGAthnOlsmREO/vBVAgSEAHjjX+uHubKwSOINetLeSedFoWXIaWybDQYON8pXewGQ=", + "sign_private_key": "zeiPflZ2GHCX1bkzm4C4HfOoWclVKdZi9qYXgEnv89g=", + "sign_public_key": "3fdeC79Oqcsb26JLPA8aZSyjWytVR+CdRVtkaneijPk=", + "enc_public_key": "MCowBQYDK2VuAyEAHjjX+uHubKwSOINetLeSedFoWXIaWybDQYON8pXewGQ=" + ``` +- Kindly change the ```message.key_pair.encryption_public_key and signing_public_key``` with the above values. +- Hit ```https://subscriber_id/subscribe``` to subscribe. + ``` + curl --location 'localhost:8080/subscribe' \ + --header 'Content-Type: application/json' \ + --data-raw '{ + "context": { + "operation": { + "ops_no": 2 + } + }, + "message": { + "request_id": "ccfce272-13c3-4ca4-a070-64769f5df2a66", + "timestamp": "2024-02-21T13:02:09.814Z", + "entity": { + "gst": { + "legal_entity_name": "ABC Incorporates", + "business_address": "Trade World, Mansarpur, Coorg, Karnataka 333333", + "city_code": [ + "std:080" + ], + "gst_no": "07AAACN2082N4Z7" + }, + "pan": { + "name_as_per_pan": "ABC Incorporates", + "pan_no": "ASDFP7657Q", + "date_of_incorporation": "23/06/1982" + }, + "name_of_authorised_signatory": "Anand Sharma", + "address_of_authorised_signatory": "405, Pinnacle House, Kandiwali, Mumbai 400001", + "email_id": "anand.sharma@abc.com", + "mobile_no": 9912332199, + "country": "IND", + "subscriber_id": "your.app.com", + "unique_key_id": "ccfce174-17c1-4ca4-a070-7419f5df2a66", + "callback_url": "/", + "key_pair": { + "signing_public_key":"Od5jWsddCTo2bG04iT8jWirXBll5hTgt5v9WJVAyZWM=", + "encryption_public_key": "MCowBQYDK2VuAyEAtixcps5Wt84F4sq90IPFr5ZjuUqPE93nGui7ROr2zzk=", + "valid_from": "2024-02-21T13:02:09.814Z", + "valid_until": "2024-10-20T18:00:15.071Z" + } + }, + "network_participant": [ + { + "subscriber_url": "/", + "domain": "ONDC:RET10", + "type": "sellerApp", + "msn": false, + "city_code": [ + "std:080" + ] + } + ] + } +}'``` diff --git a/utilities/on_subscibe-service/java/mvnw b/utilities/on_subscibe-service/java/mvnw new file mode 100755 index 0000000..66df285 --- /dev/null +++ b/utilities/on_subscibe-service/java/mvnw @@ -0,0 +1,308 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.2.0 +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /usr/local/etc/mavenrc ] ; then + . /usr/local/etc/mavenrc + fi + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "$(uname)" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME + else + JAVA_HOME="/Library/Java/Home"; export JAVA_HOME + fi + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=$(java-config --jre-home) + fi +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --unix "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --unix "$CLASSPATH") +fi + +# For Mingw, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && + JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="$(which javac)" + if [ -n "$javaExecutable" ] && ! [ "$(expr "\"$javaExecutable\"" : '\([^ ]*\)')" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=$(which readlink) + if [ ! "$(expr "$readLink" : '\([^ ]*\)')" = "no" ]; then + if $darwin ; then + javaHome="$(dirname "\"$javaExecutable\"")" + javaExecutable="$(cd "\"$javaHome\"" && pwd -P)/javac" + else + javaExecutable="$(readlink -f "\"$javaExecutable\"")" + fi + javaHome="$(dirname "\"$javaExecutable\"")" + javaHome=$(expr "$javaHome" : '\(.*\)/bin') + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + else + JAVACMD="$(\unset -f command 2>/dev/null; \command -v java)" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=$(cd "$wdir/.." || exit 1; pwd) + fi + # end of workaround + done + printf '%s' "$(cd "$basedir" || exit 1; pwd)" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + # Remove \r in case we run on Windows within Git Bash + # and check out the repository with auto CRLF management + # enabled. Otherwise, we may read lines that are delimited with + # \r\n and produce $'-Xarg\r' rather than -Xarg due to word + # splitting rules. + tr -s '\r\n' ' ' < "$1" + fi +} + +log() { + if [ "$MVNW_VERBOSE" = true ]; then + printf '%s\n' "$1" + fi +} + +BASE_DIR=$(find_maven_basedir "$(dirname "$0")") +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR +log "$MAVEN_PROJECTBASEDIR" + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" +if [ -r "$wrapperJarPath" ]; then + log "Found $wrapperJarPath" +else + log "Couldn't find $wrapperJarPath, downloading it ..." + + if [ -n "$MVNW_REPOURL" ]; then + wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + else + wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + fi + while IFS="=" read -r key value; do + # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) + safeValue=$(echo "$value" | tr -d '\r') + case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; + esac + done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" + log "Downloading from: $wrapperUrl" + + if $cygwin; then + wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") + fi + + if command -v wget > /dev/null; then + log "Found wget ... using wget" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + else + wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + log "Found curl ... using curl" + [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + else + curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" + fi + else + log "Falling back to using Java to download" + javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" + javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaSource=$(cygpath --path --windows "$javaSource") + javaClass=$(cygpath --path --windows "$javaClass") + fi + if [ -e "$javaSource" ]; then + if [ ! -e "$javaClass" ]; then + log " - Compiling MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/javac" "$javaSource") + fi + if [ -e "$javaClass" ]; then + log " - Running MavenWrapperDownloader.java ..." + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +# If specified, validate the SHA-256 sum of the Maven wrapper jar file +wrapperSha256Sum="" +while IFS="=" read -r key value; do + case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; + esac +done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" +if [ -n "$wrapperSha256Sum" ]; then + wrapperSha256Result=false + if command -v sha256sum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + elif command -v shasum > /dev/null; then + if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then + wrapperSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." + echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." + exit 1 + fi + if [ $wrapperSha256Result = false ]; then + echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 + echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 + echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 + exit 1 + fi +fi + +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$JAVA_HOME" ] && + JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") + [ -n "$CLASSPATH" ] && + CLASSPATH=$(cygpath --path --windows "$CLASSPATH") + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") +fi + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $*" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +# shellcheck disable=SC2086 # safe args +exec "$JAVACMD" \ + $MAVEN_OPTS \ + $MAVEN_DEBUG_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/utilities/on_subscibe-service/java/mvnw.cmd b/utilities/on_subscibe-service/java/mvnw.cmd new file mode 100644 index 0000000..95ba6f5 --- /dev/null +++ b/utilities/on_subscibe-service/java/mvnw.cmd @@ -0,0 +1,205 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.2.0 +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* +if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %WRAPPER_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file +SET WRAPPER_SHA_256_SUM="" +FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B +) +IF NOT %WRAPPER_SHA_256_SUM%=="" ( + powershell -Command "&{"^ + "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ + "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ + " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ + " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ + " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ + " exit 1;"^ + "}"^ + "}" + if ERRORLEVEL 1 goto error +) + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% ^ + %JVM_CONFIG_MAVEN_PROPS% ^ + %MAVEN_OPTS% ^ + %MAVEN_DEBUG_OPTS% ^ + -classpath %WRAPPER_JAR% ^ + "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ + %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" +if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%"=="on" pause + +if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% + +cmd /C exit /B %ERROR_CODE% diff --git a/utilities/on_subscibe-service/java/pom.xml b/utilities/on_subscibe-service/java/pom.xml index 0cdd2bf..34edd41 100644 --- a/utilities/on_subscibe-service/java/pom.xml +++ b/utilities/on_subscibe-service/java/pom.xml @@ -1,6 +1,6 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.springframework.boot @@ -33,18 +33,18 @@ bcprov-jdk15on 1.69 - - com.vaadin.external.google - android-json - 0.0.20131108.vaadin1 - compile - - - org.springframework - spring-beans - 6.1.3 - - + + com.vaadin.external.google + android-json + 0.0.20131108.vaadin1 + compile + + + org.springframework + spring-beans + 6.1.3 + + diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java b/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java deleted file mode 100644 index e90a518..0000000 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/OnboardingApplication.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.ondc.onboarding; - -import org.json.JSONException; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -import javax.crypto.BadPaddingException; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.NoSuchPaddingException; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; - -@SpringBootApplication -public class OnboardingApplication { - public static void main(String[] args) throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException { - SpringApplication.run(OnboardingApplication.class, args); - } - -} diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java similarity index 90% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java index 93e2323..3c7c55d 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/AppConfig.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java @@ -1,7 +1,6 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import org.json.JSONException; -import org.json.JSONObject; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -11,11 +10,11 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; -import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import static com.ondc.onboarding.Utils.*; +import static ondc.onboarding.utility.Utils.generateEncDecKey; +import static ondc.onboarding.utility.Utils.generateSigningKeyPair; @Configuration public class AppConfig { diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/CryptoKeyPair.java similarity index 94% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/CryptoKeyPair.java index 95219e9..21e6d37 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/CryptoKeyPair.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/CryptoKeyPair.java @@ -1,7 +1,7 @@ /* * */ -package com.ondc.onboarding; +package ondc.onboarding.utility; diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java similarity index 99% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java index 2be6ff3..9d8c9d5 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Routes.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java @@ -1,4 +1,4 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import java.io.IOException; diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java new file mode 100644 index 0000000..e7d354d --- /dev/null +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/UtilityApplication.java @@ -0,0 +1,13 @@ +package ondc.onboarding.utility; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class UtilityApplication { + + public static void main(String[] args) { + SpringApplication.run(UtilityApplication.class, args); + } + +} diff --git a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java similarity index 99% rename from utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java rename to utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java index b38a821..063a9e7 100644 --- a/utilities/on_subscibe-service/java/src/main/java/com/ondc/onboarding/Utils.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java @@ -1,4 +1,4 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.math.ec.rfc8032.Ed25519; diff --git a/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java b/utilities/on_subscibe-service/java/src/test/java/ondc/onboarding/utility/UtilityApplicationTests.java similarity index 69% rename from utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java rename to utilities/on_subscibe-service/java/src/test/java/ondc/onboarding/utility/UtilityApplicationTests.java index 162295c..89d667e 100644 --- a/utilities/on_subscibe-service/java/src/test/java/com/ondc/onboarding/OnboardingApplicationTests.java +++ b/utilities/on_subscibe-service/java/src/test/java/ondc/onboarding/utility/UtilityApplicationTests.java @@ -1,10 +1,10 @@ -package com.ondc.onboarding; +package ondc.onboarding.utility; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest -class OnboardingApplicationTests { +class UtilityApplicationTests { @Test void contextLoads() { diff --git a/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class b/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoFunctions.class deleted file mode 100644 index f3523071ff15c9a2308f5eaffd0d183529f16bf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4741 zcmb7IX?PRY6+O?gJ+c^sF{{`Dgn&09FmVDlC0N1^jt#ho7#o_p z=t|SHq$KIS?|YN9wINRF-n8kyrcIM3O}e+g+po*lujkE-#*(b0;j=Bxyt(h*d(OS@ z-aCHezYkspa2@^@LInZ}DpgdWTA=QvHmOBYnw5+k8aZj`If3fkre)^#2m~4$2NVPa zRyjghL!YqC+*BkkFO0*Ql}L|=ph$HK1RBzIGBT2$u=FWi%jQx>WL(RQMhrb-pU`)1 z+tC{7O0>4MZQmug)T&sBMFKUJaVi&`${AUKs)pmy#(@w*SgfKRO9U1t4a=~#oY6lq zk}~yPV~RT{)x%%u+A@KS(rVgD=n>tX%H-0KiJX~=#GGr&_iLsd!cwe|a90W_+?}_w zO2uld5va_XNlT#CQ|v02Zmd&r71ooGNy9cz&~{#g=6f2CDcC5`IuG?p-H2rD^rV?E z>`2t%Bj)hY?=1$gNuVMc3t=<1C}>d8h$eyMWk@F50t=ExF27fxrJ-*wWbvGBTFH(^ zcgYV>Ub-WM4G2g(TUA_(2z671FivO(-1M}uB$ z+i<;t8&vGXE`fE$n7n}8{CR zPvnjT=)uhjdR6q{fWV4kb-o-CP+^y)rxQj(B4|7wm7W|@(T^9pPy20il7~cK&3t?A zBVwSzxHNb~U}cFdUnYbB991wVqc=n@q}-|e!J>}Nq-_}EhQ%V$c?F>=tD-}}ae-@! zUCCxxE(Y7S?eYNAW}HhQ9K)^h1TP9<7%x$vNe@TnA)$D;rsvW&PtD#da4_N@fH@6} z_b?JF44e>Hn9q}ZWN#=vIgaO^yYtUuzI+k%sKDkjp!<7c@tviplekrSF{UDg@q%pi z1HSXh-0%ZUa05uI$l#^SDS1R#e@b-`O@}-#1IVh#VS?2&k?tSWvdpx`a>B<-vt4SC z`(LKwluUA;Ms^U}$SJr@;Hsh|b7*v*dSnK1hMlOhD;~lWULljU4PCJ8jRap=FdgOMddYn~CQvUMHD*Jr8Yz=R;xsIGmlu z8&uqZH#(eko0gVhiKNp!y+OQ*buZf2+1u3`-P*RjHH7oHOTk;D%NJNQinHT@kmntDa31%lxL5Z7D%;2!xf;9;Z&&aR74O8m1U5J>SY|q+k7_ob zN8+r|3C&K#+>N73l;KcZdVIR>(Qe3I;OY2%{K(kGG?=4p5Moq%s-1mH1V+W5_zI4PnWw2Q@ zt>sWc4J_8rp~I7-hU&we2lpK!$TcoDKiPOr{5gzrp^SgNIbR%)vKM9Yg@XdOe7pYh(({i-#4rIXxC2{YERz&iU*fw5&mRTof5lja zN2y&O}oC!q1H}gsBlhb2Ovg;>k$Cp#^u)x(t72#kyKB15H zb1EV=1%lu4sHGY3y-FIzwrjlt+)uZDD z8h<#iF?xP_6QnQ7uo{*#_>yfo^D?&^IKVpbkRhuacXC_w@c8j86NHsChO^GtD4>oN z_4L&a_daA&=Qn)vUw>*|Ul!O>60T=y;N0%zA}z9fm+bPV9m?gi*b(%Kiyu_4@zFC% zR&$wMgpf&KQr1|mb0#Q8!9zkJZ-?$RfMvxpF=v_0`5A$x;_~YNn#-j)r;!5o{TGyI zN*gowYgu;pd><`rE-YYdVz$9qGLh|zA`6=#*@LTY^s%Zw| zen-Wp`6(X*Tksivs;&S&i_h_{2KV89uE@=Ipprj8(=3#s8PxRFt$!%kCqE7}HBUor z4zvU=qHY#ThgzCvu>9cG`zT!jX<;250j@`ot*{om_!hVuD{v#%qiEpND=jxsdk`D( z06x#VTCBwv@I~6L$4X4|s)CXgn88KTP{TL8OP*hY)E(fC`ntW+l|XZ#`LgsR+%ji> zp(8O&Dn?KT-Lbdc-Q`%}cG`K+u~$XgvyQzQz9v58S-IJ>qBaqxG;tAYB{CPE%ix&; zy{e-_>Qz0x^2)_ggD;WQ3WwDTL@h(xS%39KT=Os%&SC@EZN7+>qxG$F@w(oo#ezHA zo2Id+Ptr@aqnEH>fENcZ;jkbp%O%)=L-r~L6zriv+=V5$K&tL0t@kj%_c{(Pr@_^H zcf5=*Q*H}$<}3IrVSdfgAeP|kyjVyj-@v!b@EhPKY&MeS8Cj2DNirlGf2dv~))4z;1 z8VUyk;o#-^(=&K^drkdmY4P^=B5Ym)@i(Z8Xx5CN9GuE zljHC7B; diff --git a/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class b/utilities/ondc-crypto-utility-master/target/classes/org/ondc/crypto/util/CryptoKeyPair.class deleted file mode 100644 index 0e3e6a87407f1cee431c9b9d09644ca7cf96d63b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 796 zcmah{%TC)s6g^`cr*REQL!hPf71Tv=s(Jyt0*fHAA!?DRkgBX4W2HmgI5G|rf7MDn zq%Qgad{o7`Vb<#sFdM)cnnWrCCvswIy{VmC_5eHX)w-p5^S4zH$L49b*3&V@Lhef%ojQ(~g zlnE)I3ift-7%Nn}dKiBkfA7cH=dhnJQ}3oxm>h(emh&WO=U?@)!rSiub$p$ z^50#c?6)s4`_nWmajnDVI?uI%3KlR&XPz_jrf9=5UhqT!ag3l6$v}(oOT3zl3AoE$ z$v;Ew2LlTN?wDlL0D48i1W?J(XGS<~v0Ah^e)}A?TWa#I0H12w24S(Nx}oG4A~N{( hR3eRsMAoJf;q#eBr16l*28nF`gGk|xqH7|(c@1Izd0qej diff --git a/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties b/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties deleted file mode 100644 index 5af20f4..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-archiver/pom.properties +++ /dev/null @@ -1,4 +0,0 @@ -#Created by Apache Maven 3.9.6 -groupId=org.ondc -artifactId=ondc-crypto-util -version=0.1-GA diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst deleted file mode 100644 index 4c1ad80..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +++ /dev/null @@ -1,2 +0,0 @@ -org/ondc/crypto/util/CryptoKeyPair.class -org/ondc/crypto/util/CryptoFunctions.class diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst deleted file mode 100644 index f9d72a4..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +++ /dev/null @@ -1,2 +0,0 @@ -/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoFunctions.java -/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/main/java/org/ondc/crypto/util/CryptoKeyPair.java diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst deleted file mode 100644 index 4c3c6df..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/createdFiles.lst +++ /dev/null @@ -1 +0,0 @@ -org/ondc/crypto/util/CryptoTest.class diff --git a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst b/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst deleted file mode 100644 index 8e67e07..0000000 --- a/utilities/ondc-crypto-utility-master/target/maven-status/maven-compiler-plugin/testCompile/default-testCompile/inputFiles.lst +++ /dev/null @@ -1 +0,0 @@ -/Users/pratik/Documents/reference-implementations/utilities/ondc-crypto-utility-master/src/test/java/org/ondc/crypto/util/CryptoTest.java diff --git a/utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class b/utilities/ondc-crypto-utility-master/target/test-classes/org/ondc/crypto/util/CryptoTest.class deleted file mode 100644 index 1868aa2d886f69ccbbdea592a9193352792c061f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6543 zcmdT}d3;<|75;8AlQ%ORD1-(`2{43~q@n2mEd`QNY(fjANgA6FDWTMtnVZRLCNtBS zH)&IZDvAqBtAIc&vM(YElqHQoQP~PDi=v>2f~W}MjvJs-zWbJ0vWdT+{z3ceTkbpe z+;h+Q&Uen8?t1V3hXBkI-T+Eas=*V47i9wbtkDPca9mHs!pnQs$cQOWw!laj=0bte z+F4yb_ylIPCo_g=49ZY%Jh?8E>ZnmB~WrmCSP2QUIj67PPyd`f;hnc4SMnCq!z8cDd z*bmc+tnC=em~wzdCbLviVNW%Z;dah5Ia}%jjXvxzaN3Fgvp)eGh)NC9gE$CP0{dC! z7OyFwrIZEn1dXa4yP;WK0UUxuHH3mV4AlZNCUMb{Y$Bq(ni1GPCKEEPo3g|9{4zPz zt{Z8ABWh>0OrpY(qbp`m3Ex7e*ovq&)X)&>UcPLV4@U@08<3fd9+M$68S0T%fMqm* zTFlZ=7sQd6El~ZR7ZTVjCQSxmkhXF;0Z;9$?xq0dAgtl2AdXgw3Q%VUTENF?O+!S3 z^3U8L=HXb*RXF3f+U}_ek~ zI7h>Y0tbu+S5wxAQ#gPHDD~kZwA^3qI-$CuT8%da(TtOs5_&2{%>wn~g>+1m9nEz5 z5`mKH*-F)^K`g~-+>4oXw>*uZ8*LQlv~Y|5YPECS%%)|?vZW2nHM9ruQLJ#?XXR28 zQ)m7>fdJjNI1x#5LjqN<;sTKw&ez5OI&r#&t{^^!GXxH_EEq>nU~g$D?93UwKjSd2 z$!F3ge>H*cL|xhJ!&%JEa{~bdqO*fotpaa>Bij=ih0wIQys-dY z&WK|4^GJ$qGDgBCqc2g6&YX|*$w+@_U7s}j=w(wMNXaxE=q7}bad@6%*+eEAiI6UO zv+?+l51(X?1$;Q4d_QKM%_eR*DnhX=w>y6TTG0rKqervPmjlCA|`E~ zvh(UXfkXV&&P*8{SLOzSo5W>NaJ~ZA^Kas|{MBhEi`$En_7(z&eDO8fmiMj;164Y{ zuDX@m1-y!Yh~RHp)oD15X0C` zj*?EU6;*aOv&dK9;zrK(;Q@ieKL7}Q*g?S@?A+Yz(=&alw_?hzOQ!qz=)<=Ol>$^K z5f$|B2JtW+DL`LST<@2s@~h&Rg6y|L*=Uu}$M~()DfUXVFynR#ROYLojX$-Rj9Tpa zB$x76_ZsPpxjJgZ*t%K6yBRp;%m`b(!ttl+WVJ%5RXJ1bDTlXb1r8efDVNBs6wT~= zOg&+CDdJ=+(9GIKFSHm5*_IvXk?BsoC(e=bmSjYacj;+Ey*q;*v(F$W9yVEPq#97R z2ZyN+)M<)Fbyus~EGA%5scKC7nbvmKHDfZxjudrkPRv-H^^eO4ziiUIl^UW{v+dTRb_%Sn>Ng$@X`eLY(%+YPENz0*-saX zwIw^Uk-kOoSdz2)1`1^VA~172+4gjDknLx>K=f|{b;Y6?mbwBHI`~>3{|`n&$>(U^ zwxV5+MhU_K!FL>cbAn6B+%Y}g6i-I_JB$soK=z+(DvFdg>Cw>|8K%P67O+W~Vu95> zq?Pq#=FhVptdV2f5k3SulG$`bE@44uqUKL|bJVf|!KDcvVVdKrZ6R zKg9EV6L^7YN|c(CUdnhmwE1pKEw32H0qU+fclADkgImVfjhJSVZwf<%@Y4#wo>LmvL|et@Xp`m{4Y=Eu+>QPprI~ zD(jU+lvp)_kI(lgv!eemb9!^;tQyZ8ci(*!tMCkCP4UJpYb!iku(vXDfJWYmDe5uF zN6!e>R;bGe)~QgILWMHH(={*yKFs9l{|KJBYZ=r!j?6|4n}NAF3XM319sOJ^<2lj5 zvFyR-<6azx2ho6CJZ(LP6Y&!)#M?MYRPk)rj76dcO=1n2MUp4F4Lq5hk5k1aYEW>Q zXG6k)OO?prNBA*eQzQEDA~9Klx#BEpe2F&h!ejU;enuF*%$WzEWDnJOH3T%&YM7(p z6{1wb&-rmGC%(%2FR1F58SY5nS2-XKIY8X1+~ET8Tqlg~`$oQh7yw!Rsn!o0Cb!y{ z{B$0Z7x1xkTuct)V1}`S5$q%;PbVh35W*S6%=A4Ahz%%n8)T;2b(j* zpo7h@=y$N$C{{bze10r8FZf{CJdfCXjo2(zBw0F>*wjdpZzybj&cWmtoV$7#EuwV< z7q#$TtCCSi?PiYT*xDj3Z>5LdYiyFevcao%c`G;Y0OqW$^lry(4P|O* z0^a=w^;MSfQcQ=g0e9pKsF`d#ciCdfhRMY4rdYjN?Ow&d#akJn$@aJLIhfxp_GKqY zB!_u6wORO5VjH-Kh`*SKzl4b2gz4B!sY{9c%lP$j%5UL}E6B%JkwLeTf3N0`T-WeN zs_U2+*E1Jxz((ANoA`G(ZpK@<1@H2h7r)2ss!wOn-6w&!>yiQArP$w^@Q~C{yv#Z2Y_zj;*_+#NV zD?>`LR9uTU$=)8W{W5;bCofmujo*>m%PbzB3(p>IhChwlJYEZ-VUuT%xCvTr%%*oT zJRcOt|DG<|hxb3=Pu$#J@pl%ScgJJ?3z=R2aNg%|?1_&FaQ1{kM)6mr*iJ`Bvz1X6zFleNEm%~syi;+R1p!stT?pjj@1e#`WEE zFt!d)rR57WFW8Rle<~2o4DBTmM?ynV$1UgrgJrj1l$|5Xu-x;CUpA_~T{N=6dbR3U zzFl@af$oBIq-**zZxIIN;d+r%+SG70w17DL${6(ar<-oylPBluQTk zk%mDX5Aaan_P-elq-5Z5w@h%9lp<#imTI1Z{Du4Un8A>SVI3nF73ge0j5)3-n#TeQ znGjpOhl9GUuqfthasHvtIO%U!4~w={FHZ^+Iwn=-f}{lJuP9#}j|H-8o68qlo6Fg` zot53mi3?8_i_%@JR4zRKXl`P5;=+~3V`il?7M_fGzF8pQv9qahRe9qqh9qY2M8n5A zW>u8BBEAtP&I~M_`_fBd4)YoobbJEV^qq#Kv@1OpLCj;d3dE@^l|5KeN~!fs8_MSZ1@FTc+n1rBO2d z6GK{tdu+{4Jf1REj;3a2CZDP+YdXHfx(v575~=uNwYsR+tH zL8~?XE6Ws~t9IWZjgVV#dsj*F6?0Ux46P|cmUS!8nzJ3bSuGt(ch@{Da;GC#w#?$5 z>DubMwi)wJY<7Hachewpz$D&Mo;IZCnFZ2m-dWsS-r8V;hM*eejeZi9pnwBawbIS)gz{zj zOfVzm%T?EstF}@pp*WALN)XW39L~XP(eyk?ep;>Tai2vQ;XDRnU_#N%=N`Wdz6IY+ z!&eZ$a1p@^KGiWeh+p!lhX&Zk*ZfN00N-#&U49LYb-s75q2)#{(X#OxogH^#zaz3A zy+-foCGO`h@#uxx9(%VheH(j7T?h}#uEJ=KM-RAYcO$0PRqP$aTVnre^zSvf1+)aH!^RK-M_-h zdRzLpcuqYwh6(bEk?1ICeEAofF3H;OI&@#a+mYIpMUoPL}~hs z6YCKq?OJH1aIm1!jpG1OLQRJnj+f-9aCEdiQ=y|H(UG?*a(?uE#8hB0$kaVT8^?so ljEcfrfp0FjDg;rQ81W>C5`oSA2u|^e? Date: Tue, 27 Feb 2024 22:58:46 +0530 Subject: [PATCH 179/228] fix: signing key generation using nodejs --- .../signing_and_verification/node/index.js | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/utilities/signing_and_verification/node/index.js b/utilities/signing_and_verification/node/index.js index c306797..808d1d3 100644 --- a/utilities/signing_and_verification/node/index.js +++ b/utilities/signing_and_verification/node/index.js @@ -1,14 +1,19 @@ const nacl = require("tweetnacl"); -const { randomBytes } = require("crypto"); +const crypto = require("crypto"); function generateKeyPairs() { - // Generate signing key pair const signingKeyPair = nacl.sign.keyPair(); - - // Generate X25519 key pair for encryption - const encryptionKeyPair = nacl.box.keyPair.fromSecretKey( - randomBytes(nacl.box.secretKeyLength) - ); + const { privateKey, publicKey } = crypto.generateKeyPairSync('x25519', { + modulusLength: 2048, + publicKeyEncoding: { + type: 'spki', + format: 'pem', + }, + privateKeyEncoding: { + type: 'pkcs8', + format: 'pem', + }, + }); return { Signing_private_key: Buffer.from(signingKeyPair.secretKey).toString( @@ -17,15 +22,16 @@ function generateKeyPairs() { Signing_public_key: Buffer.from(signingKeyPair.publicKey).toString( "base64" ), - Encryption_Privatekey: Buffer.from(encryptionKeyPair.secretKey).toString( - "base64" - ), - Encryption_Publickey: Buffer.from(encryptionKeyPair.publicKey).toString( - "base64" - ), + Encryption_Privatekey: privateKey.toString('utf-8') + .replace(/-----BEGIN PRIVATE KEY-----/, '') + .replace(/-----END PRIVATE KEY-----/, '') + .replace(/\s/g, ''), + Encryption_Publickey: publicKey.toString('utf-8') + .replace(/-----BEGIN PUBLIC KEY-----/, '') + .replace(/-----END PUBLIC KEY-----/, '') + .replace(/\s/g, ''), }; } -// Example usage: const keyPairs = generateKeyPairs(); console.log(keyPairs); From 4a420159eceb28438a4cd10388e538a5bcac8497 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 5 Mar 2024 09:54:12 +0530 Subject: [PATCH 180/228] added srv val --- log_report.md | 15 + .../schema/B2B_json_schema/v2/on_confirm.js | 2 + .../schema/B2B_json_schema/v2/on_update.js | 11 +- .../schema/B2B_json_schema/v2/search.js | 16 +- .../schema/B2B_json_schema/v2/update.js | 2 +- .../SRV_json_schema/keywords/confirm.js | 13 + .../schema/SRV_json_schema/keywords/init.js | 7 + .../schema/SRV_json_schema/keywords/onInit.js | 16 + .../schema/SRV_json_schema/keywords/search.js | 7 + .../schema/SRV_json_schema/schemaValidator.js | 126 +++ .../schema/SRV_json_schema/v2/cancel.js | 95 ++ .../schema/SRV_json_schema/v2/confirm.js | 606 +++++++++++++ .../schema/SRV_json_schema/v2/init.js | 366 ++++++++ .../schema/SRV_json_schema/v2/master.js | 91 ++ .../schema/SRV_json_schema/v2/on_cancel.js | 663 ++++++++++++++ .../schema/SRV_json_schema/v2/on_confirm.js | 687 +++++++++++++++ .../schema/SRV_json_schema/v2/on_init.js | 629 ++++++++++++++ .../schema/SRV_json_schema/v2/on_search.js | 820 ++++++++++++++++++ .../schema/SRV_json_schema/v2/on_select.js | 474 ++++++++++ .../schema/SRV_json_schema/v2/on_status.js | 657 ++++++++++++++ .../schema/SRV_json_schema/v2/on_update.js | 508 +++++++++++ .../schema/SRV_json_schema/v2/search.js | 236 +++++ .../schema/SRV_json_schema/v2/select.js | 226 +++++ .../schema/SRV_json_schema/v2/status.js | 109 +++ .../schema/SRV_json_schema/v2/update.js | 505 +++++++++++ .../v1.2/onConfirmSchema.js | 2 + .../log-verification-utility/schema/main.js | 7 + .../services/service.js | 3 + .../utils/constants.js | 22 +- .../utils/mergeSort.js | 3 + .../utils/services/msgValidator.js | 52 ++ .../utils/services/pinToStd.json | 1 + .../utils/services/srvOnSearch.js | 174 ++++ .../utils/services/srvOnSelect.js | 98 +++ .../utils/services/srvSearch.js | 78 ++ .../utils/services/srvSelect.js | 134 +++ .../log-verification-utility/utils/utils.js | 1 + 37 files changed, 7447 insertions(+), 15 deletions(-) create mode 100644 log_report.md create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js diff --git a/log_report.md b/log_report.md new file mode 100644 index 0000000..077b4fd --- /dev/null +++ b/log_report.md @@ -0,0 +1,15 @@ +**on_search,on_init,/on_confirm** + +- remove static terms (bpp_terms) and cancellation terms as they are not enabled yet + +**/on_cancel** + +- fulfillments/start/instructions have changed for fulfillment type 'Delivery' +- In fulfillments/tags- precancel_state/updated_at is the time when this pre_cancel state was updated in the system (is not recorded correctly in Flow 2 (should reflect the timestamp recorded in fulfillments for this state in /on_status), missing in Flow 3) +- In /items, time/duration for RTO line item does not match the one provided in catalog in /on_search +- use appropriate cancellation reason id for triggering RTO + +**/track,on_track** + +- tracking apis should be implemented +- also add tracking.tags.order, tracking.tags.config; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index cf3c0a3..e6ae899 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -868,6 +868,8 @@ module.exports = { updated_at: { type: "string", format: "date-time", + not:{const: { $data: "/confirm/0/message/order/created_at" }}, + errorMessage:"should not be same as 'created_at'" }, }, additionalProperties: false, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js index 1301497..cc79a88 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -120,11 +120,12 @@ module.exports = { quantity: { type: "object", properties: { - count: { - type: "integer", + selected: { + count: { + type: "integer", + }, }, }, - required: ["count"], }, fulfillment_ids: { type: "array", @@ -133,7 +134,7 @@ module.exports = { }, }, }, - required: ["id", "quantity", "fulfillment_ids"], + required: ["id", "quantity"], }, }, payment: { @@ -418,7 +419,7 @@ module.exports = { type: "string", }, }, - required: ["phone", "email"], + required: ["phone"], }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js index 453ca21..37a34b0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/search.js @@ -92,16 +92,16 @@ module.exports = { }, required: ["name"], }, - category: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], + }, + }, + category: { + type: "object", + properties: { + id: { + type: "string", }, }, + required: ["id"], }, fulfillment: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js index 2067cf4..e28ba1b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/update.js @@ -90,7 +90,7 @@ module.exports = { properties: { update_target: { type: "string", - enum:["fulfillment","item"] + enum:["fulfillment","item","payments"] }, order: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js new file mode 100644 index 0000000..5e7963a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js @@ -0,0 +1,13 @@ +module.exports = { + isFutureDated: (data) => { + const contextTime = data?.context?.timestamp; + const created_at = data?.message?.order?.created_at; + const updated_at = data?.message?.order?.updated_at; + if ( + (created_at && created_at > contextTime) || + (updated_at && updated_at > contextTime) + ) + return false; + return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js new file mode 100644 index 0000000..8f448e9 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js @@ -0,0 +1,7 @@ +module.exports = { + isLengthValid: (data) => { + if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) + return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js new file mode 100644 index 0000000..380b690 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js @@ -0,0 +1,16 @@ +module.exports = { + isQuoteMatching: (data) => { + let quotePrice = parseFloat(data?.price?.value); + const breakupArr = data?.breakup; + let totalBreakup = 0; + breakupArr.forEach((breakup) => { + totalBreakup += parseFloat(breakup?.price?.value); + + }); + totalBreakup= parseFloat(totalBreakup).toFixed(2) + console.log(totalBreakup,quotePrice); + quotePrice=quotePrice.toFixed(2) + if (quotePrice != totalBreakup) return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js new file mode 100644 index 0000000..7a14c5b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js @@ -0,0 +1,7 @@ +module.exports = { + isEndTimeGreater: (data) => { + const startTime = parseInt(data?.start); + const endTime = parseInt(data?.end); + return startTime < endTime; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js new file mode 100644 index 0000000..006e2c8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js @@ -0,0 +1,126 @@ + +const { isLengthValid } = require("./keywords/init"); +const { isQuoteMatching } = require("./keywords/onInit"); +const { isFutureDated } = require("./keywords/confirm"); +const { isEndTimeGreater } = require("./keywords/search"); + +const fs = require("fs"); +//const async = require("async"); +const path = require("path"); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + +const loadSchema = (schemaType, version) => { + try { + return require(`./${version}/${schemaType}.js`); + } catch (error) { + console.log("Error Occurred while importing", error); + } +}; + +const validate_schema = (data, schema,version) => { + const searchSchema = loadSchema("search", version); + const onSearchSchema = loadSchema("on_search", version); + + const selectSchema = loadSchema("select", version); + const onSelectSchema = loadSchema("on_select", version); + + const initSchema = loadSchema("init", version); + const onInitSchema = loadSchema("on_init", version); + + const confirmSchema = loadSchema("confirm", version); + const onConfirmSchema = loadSchema("on_confirm", version); + + const updateSchema = loadSchema("update", version); + const onUpdateSchema = loadSchema("on_update", version); + + const statusSchema = loadSchema("status", version); + const onStatusSchema = loadSchema("on_status", version); + + const cancelSchema = loadSchema("cancel", version); + const onCancelSchema = loadSchema("on_cancel", version); + + const Ajv = require("ajv"); + const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + $data: true, + }); + const addFormats = require("ajv-formats"); + + addFormats(ajv); + require("ajv-errors")(ajv); + let error_list = []; + try { + validate = ajv + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(selectSchema) + .addSchema(onSelectSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema) + .addSchema(cancelSchema) + .addSchema(onCancelSchema) + .addKeyword("isEndTimeGreater", { + validate: (schema, data) => isEndTimeGreater(data), + }) + .addKeyword("isQuoteMatching", { + validate: (schema, data) => isQuoteMatching(data), + }) + .addKeyword("isFutureDated", { + validate: (schema, data) => isFutureDated(data), + }) + .addKeyword("isLengthValid", { + validate: (schema, data) => isLengthValid(data), + }); + + validate = validate.compile(schema); + + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + } catch (error) { + console.log("ERROR!! validating schema"); + console.trace(error); + } + return error_list; +}; + +const validate_schema_srv_master = (data,version) => { + const masterSchema = loadSchema("master", version); + error_list = validate_schema(data, masterSchema,version); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_srv_master, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js new file mode 100644 index 0000000..ffa00b6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js @@ -0,0 +1,95 @@ +module.exports = { + $id: "http://example.com/schema/cancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + }, + version: { + type: "string", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + cancellation_reason_id: { + type: "string", + }, + }, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js new file mode 100644 index 0000000..7d21db8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js @@ -0,0 +1,606 @@ +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + status: { + type: "string", + enum: ["Created"] + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + + }, + required: ["label", "range"], + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["person"], + }, + }, + required: [ + "type", + "location", + "contact", + "time", + "customer", + ], + }, + }, + }, + required: ["id", "type", "tracking", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + }, + required: ["title", "price", "item"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + created_at: { + type: "string", + }, + updated_at: { + type: "string", + }, + xinput: { + type: "object", + properties: { + form: { + type: "object", + properties: { + url: { + type: "string", + }, + mimetype: { + type: "string", + }, + submission_id: { + type: "string", + }, + status: { + type: "string", + }, + }, + required: ["url", "mimetype", "submission_id", "status"], + }, + }, + required: ["form"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at", + "xinput", + ], + }, + }, + required: ["order"], + }, + }, + isFutureDated: true, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js new file mode 100644 index 0000000..88d6b80 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js @@ -0,0 +1,366 @@ +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "init", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + }, + email: { + type: "string", + }, + phone: { + type: "string", + }, + }, + required: [ + "name", + "address", + "state", + "city", + "tax_id", + "email", + "phone", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/id" }, + }, + type: { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/type" }, + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + + }, + required: ["label", "range"], + }, + }, + required: ["type", "location", "contact", "time"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + collected_by: { + type: "string", + const: { + $data: + "/on_select/0/message/order/payments/0/collected_by", + }, + }, + }, + required: ["type","collected_by"], + }, + }, + }, + required: [ + "provider", + "items", + "billing", + "fulfillments", + "payments", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js new file mode 100644 index 0000000..63875c5 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js @@ -0,0 +1,91 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + }, + cancel: { + type: "array", + items: { + $ref: "cancelSchema#", + }, + }, + on_cancel: { + type: "array", + items: { + $ref: "onCancelSchema#", + }, + } + }, + }; + \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js new file mode 100644 index 0000000..8bc73b4 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js @@ -0,0 +1,663 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onCancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_cancel", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + enum: ["Cancelled"], + }, + cancellation: { + type: "object", + properties: { + reason: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + cancelled_by: { + type: "string", + }, + }, + required: ["reason", "cancelled_by"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Cancelled"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + }, + required: ["id", "type", "tracking", "state", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + + updated_at: { + type: "string", + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js new file mode 100644 index 0000000..ffce5d2 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -0,0 +1,687 @@ +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_confirm", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/confirm/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "locations", "rateable"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "id", + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: [ + "id", + "state", + "type", + "stops", + "tracking", + "rateable", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: [ + { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: [ + { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + ], + }, + }, + required: ["descriptor", "list"], + }, + ], + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time" + }, + xinput: { + type: "object", + properties: { + form: { + type: "object", + properties: { + url: { + type: "string", + }, + mimetype: { + type: "string", + }, + submission_id: { + type: "string", + }, + status: { + type: "string", + }, + }, + required: ["url", "mimetype", "submission_id", "status"], + }, + }, + required: ["form"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at", + "xinput", + ], + }, + }, + required: ["order"], + }, + }, + isFutureDated: true, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js new file mode 100644 index 0000000..65fd323 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js @@ -0,0 +1,629 @@ +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_init", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + + }, + required: ["label", "range"], + }, + tags: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + required: ["type", "location", "contact", "time", "tags"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "bank_account_number", + "virtual_payment_address", + ], + }, + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "collected_by", "params", "type", "tags"], + }, + }, + xinput: { + type: "object", + properties: { + form: { + type: "object", + properties: { + url: { + type: "string", + }, + mimetype: { + type: "string", + }, + }, + required: ["url", "mimetype"], + }, + required: { + type: "boolean", + }, + }, + required: ["form", "required"], + }, + }, + required: [ + "provider", + "locations", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "xinput", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js new file mode 100644 index 0000000..d56997b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -0,0 +1,820 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_search", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.SRV_FULFILLMENT_TYPE, + }, + }, + required: ["id", "type"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.SRV_PAYMENT_TYPE, + }, + }, + required: ["id", "type"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "short_desc", "long_desc", "images"], + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + rating: { + type: "string", + }, + ttl: { + type: "string", + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + frequency: { + type: "string", + }, + holidays: { + type: "array", + items: { + type: "string", + }, + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + }, + required: ["label","schedule"], + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + code: { + type: "string", + }, + name: { + type: "string", + }, + }, + required: ["code", "name"], + }, + state: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + }, + required: [ + "id", + "gps", + "address", + "city", + "state", + "country", + "area_code", + ], + }, + }, + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + desc: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["mimetype", "url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + "media", + ], + }, + creator: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + required: ["full"], + }, + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: [ + "name", + "address", + "phone", + "email", + ], + }, + }, + required: ["name", "contact"], + }, + }, + required: ["descriptor"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: [ + "currency", + "value", + "offered_value", + "maximum_value", + ], + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + }, + }, + cancellation_terms: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + cancellation_fee: { + type: "object", + properties: { + amount: { + type: "object", + properties: { + value: { + type: "string", + }, + }, + required: ["value"], + }, + percentage: { + type: "string", + }, + }, + }, + }, + required: ["fulfillment_state", "cancellation_fee"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + frequency: { + type: "string", + }, + holidays: { + type: "array", + items: { + type: "string", + }, + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + }, + required: ["label", "schedule"], + }, + matched: { + type: "boolean", + }, + recommended: { + type: "boolean", + }, + }, + required: [ + "id", + "parent_item_id", + "descriptor", + "creator", + "price", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "tags", + "time", + "matched", + "recommended", + ], + }, + }, + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + item_ids: { + type: "array", + items: { + type: "string", + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + }, + required: [ + "id", + "descriptor", + "location_ids", + "category_ids", + "item_ids", + "time", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["contact"], + }, + }, + }, + required: [ + "id", + "descriptor", + "rating", + "ttl", + "time", + "locations", + "tags", + "items", + "fulfillments", + ], + }, + }, + }, + required: ["fulfillments", "payments", "descriptor", "providers"], + }, + }, + required: ["catalog"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js new file mode 100644 index 0000000..4c3fe3d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js @@ -0,0 +1,474 @@ +module.exports = { + $id: "http://example.com/schema/onSelectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_select", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/select/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + id: { + type: "string", + const: { $data: "/select/0/message/order/items/0/id" }, + }, + parent_item_id: { + type: "string", + const: { $data: "/select/0/message/order/items/0/parent_item_id" }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + frequency: { + type: "string", + }, + holidays: { + type: "array", + items: { + type: "string", + }, + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + required: ["label", "schedule"], + }, + }, + required: [ + "fulfillment_ids", + "id", + "parent_item_id", + "location_ids", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["Serviceable","Non-serviceable"] + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + enum: ["confirmed","rejected"] + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + tags: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + required: ["type", "location", "time", "tags"], + }, + }, + }, + required: ["id", "state", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching:true, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + collected_by: { + type: "string", + enum:["BAP","BPP"] + }, + }, + required: ["type","collected_by"], + }, + }, + }, + required: ["provider", "items", "fulfillments", "quote","payments"], + }, + }, + required: ["order"], + }, + error: { + type: "object", + properties: { + code: { + type: "string", + }, + message: { + type: "string", + }, + }, + required: ["code", "message"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js new file mode 100644 index 0000000..239e2c1 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js @@ -0,0 +1,657 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_status", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + enum: constants.SRV_ORDER_STATE, + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city","phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.SRV_FULFILLMENT_STATE, + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + }, + required: ["id", "type", "tracking", "state", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "string", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", + }, + }, + required: ["url", "label"], + }, + }, + + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + + updated_at: { + type: "string", + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "documents", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js new file mode 100644 index 0000000..b217a7a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js @@ -0,0 +1,508 @@ +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_update", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/update/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "location_ids", + ], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "state", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "payments", + "fulfillments", + "quote", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js new file mode 100644 index 0000000..25333cc --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js @@ -0,0 +1,236 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "search", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + category: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.SRV_FULFILLMENT_TYPE + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + const: "end" + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: constants.GPS_PATTERN, + errorMessage: "Incorrect gps value (minimum of six decimal places are required)" + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time" + }, + end: { + type: "string", + format: "date-time" + }, + }, + required: ["start", "end"], + }, + days: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["range"], + }, + }, + required: ["type", "location"], + }, + }, + }, + required: ["type", "stops"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.SRV_PAYMENT_TYPE + }, + collected_by: { + type: "string", + enum: constants.PAYMENT_COLLECTEDBY + }, + }, + required: ["type", "collected_by"], + }, + tags: { + type: "array", + minItems: 1, + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BAP_Terms"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + minItems: 2, + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["finder_fee_type","finder_fee_amount"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ "fulfillment", "payment", "tags"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js new file mode 100644 index 0000000..e526c4c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js @@ -0,0 +1,226 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/selectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "select", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["id", "parent_item_id", "location_ids"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + const: "selected" + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + days: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["label", "range"], + }, + }, + required: ["type", "location"], + }, + }, + }, + required: ["stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.SRV_PAYMENT_TYPE + }, + }, + required: ["type"], + }, + }, + }, + required: ["provider", "items", "fulfillments", "payments"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js new file mode 100644 index 0000000..a298aff --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js @@ -0,0 +1,109 @@ +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "status", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js new file mode 100644 index 0000000..54e0bf6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js @@ -0,0 +1,505 @@ +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "update", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum: ["payments","fulfillments"] + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "location_ids", + ], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "state", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "payments", + "fulfillments", + "quote", + ], + }, + }, + required: ["update_target", "order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 8823f76..2def77a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -890,6 +890,8 @@ module.exports = { }, updated_at: { type: "string", + not:{const: { $data: "/confirm/0/message/order/created_at" }}, + errorMessage:"should not be same as 'created_at'" }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/main.js b/utilities/logistics-b2b/log-verification-utility/schema/main.js index cc7470e..ec3a032 100755 --- a/utilities/logistics-b2b/log-verification-utility/schema/main.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/main.js @@ -6,6 +6,10 @@ const { validate_schema_b2b_master, } = require("./B2B_json_schema/schemaValidator"); +const { + validate_schema_srv_master, +} = require("./SRV_json_schema/schemaValidator"); + const fs = require("fs"); const validate_schema_for_domain_json = (vertical, data, version) => { @@ -19,6 +23,9 @@ const validate_schema_for_domain_json = (vertical, data, version) => { res = validate_schema_b2b_master(data,version); return res; + case "services": + res = validate_schema_srv_master(data,version); + return res; default: console.log("Invalid Domain!!"); } diff --git a/utilities/logistics-b2b/log-verification-utility/services/service.js b/utilities/logistics-b2b/log-verification-utility/services/service.js index 42886b6..c12d185 100755 --- a/utilities/logistics-b2b/log-verification-utility/services/service.js +++ b/utilities/logistics-b2b/log-verification-utility/services/service.js @@ -1,6 +1,7 @@ const { logisticsVal } = require("../utils/logistics/msgValidator"); const { b2bVal } = require("../utils/b2b/msgValidator"); const _ = require("lodash"); +const { srvVal } = require("../utils/services/msgValidator"); const checkMessage = async (domain, element, action, msgIdSet) => { const busnsErr = {}; @@ -9,6 +10,8 @@ const checkMessage = async (domain, element, action, msgIdSet) => { return logisticsVal(element, action, msgIdSet); case "b2b": return b2bVal(element, action, msgIdSet); + case "services": + return srvVal(element, action, msgIdSet); } return busnsErr; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 7b3912a..23d3986 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -54,6 +54,16 @@ module.exports = Object.freeze({ "confirm", "on_confirm", ], + SRV_SORTED_INDEX: [ + "search", + "on_search", + "select", + "on_select", + "init", + "on_init", + "confirm", + "on_confirm", + ], RET_SEARCH: "search", RET_ONSEARCH: "on_search", RET_SELECT: "select", @@ -176,5 +186,15 @@ module.exports = Object.freeze({ TERMS:["buyer_id","bap_terms","bpp_terms"], B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"], - G2TAGS:["time_to_ship","cancellable","tax_rate"] + G2TAGS:["time_to_ship","cancellable","tax_rate"], + + //services + SRV_FULFILLMENT_TYPE:["Home-Service","Store-Service"], + SRV_PAYMENT_TYPE:["PRE-FULFILLMENT","ON-FULFILLMENT","POST-FULFILLMENT"], + SRV_FULFILLMENT_STATE:["Pending","At-Location","In-Transit","Completed","Cancelled"], + SRV_ORDER_STATE:["Created","Accepted","In-progress","Completed","Cancelled","Pending"], + GPS_PATTERN: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", + SERVICEABILITY:["location","category","type","val","unit"], + RESCHEDULE_TERMS:["fulfillment_state","reschedule_eligible","reschedule_fee","reschedule_within"] + }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js index 61aa6db..d0c9cab 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js @@ -17,6 +17,9 @@ const sortMerge = (domain, directory, destination) => { case "b2b": map = constants.B2B_SORTED_INDEX; break; + case "services": + map = constants.SRV_SORTED_INDEX; + break; } mergedlogs = files.reduce((acc, item) => { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js new file mode 100644 index 0000000..7a4a7a5 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js @@ -0,0 +1,52 @@ +// const checkConfirm = require("./b2bConfirm"); +// const checkInit = require("./b2bInit"); +const checkSelect = require("./srvSelect"); +// const checkOnInit = require("./b2bOnInit"); +// const checkOnConfirm = require("./b2bOnConfirm"); +// const checkOnSelect = require("./b2bOnSelect"); +const checkOnSearch = require("./srvOnSearch"); +// const checkOnUpdate = require("./b2bOnUpdate"); +// const checkUpdate = require("./b2bUpdate"); +// const checkOnStatus = require("./b2bOnStatus"); +const checkSearch = require("./srvSearch"); +const _ = require("lodash"); + +const srvVal = (element, action, msgIdSet) => { + const busnsErr = {}; + switch (action) { + case "search": + return checkSearch(element, msgIdSet); + + case "on_search": + return checkOnSearch(element, msgIdSet); + + case "select": + return checkSelect(element, msgIdSet); + + // case "on_select": + // return checkOnSelect(element, msgIdSet); + + // case "init": + // return checkInit(element, msgIdSet); + + // case "on_init": + // return checkOnInit(element, msgIdSet); + + // case "confirm": + // return checkConfirm(element, msgIdSet); + + // case "on_confirm": + // return checkOnConfirm(element, msgIdSet); + + // case "update": + // return checkUpdate(element,msgIdSet); + + // case "on_update": + // return checkOnUpdate(element,msgIdSet) + + // case "on_status": + // return checkOnStatus(element,msgIdSet) + } + return busnsErr; +}; +module.exports = { srvVal }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json b/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json new file mode 100644 index 0000000..4875211 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json @@ -0,0 +1 @@ +{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"08414","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js new file mode 100644 index 0000000..35eef0c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js @@ -0,0 +1,174 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); + +const checkOnSearch = async (data, msgIdSet) => { + const onSrchObj = {}; + let onSearch = data; + let domain = onSearch.context.domain; + onSearch = onSearch.message.catalog; + + //saving fulfillments + try { + console.log("checking attr"); + console.log(constants.ATTR_DOMAINS.includes(domain)); + } catch (error) { + console.log(error); + } + const fulfillments = onSearch?.fulfillments; + + dao.setValue("fulfillmentsArr", fulfillments); + + try { + console.log(`Saving provider items array in /on_search api`); + if (onSearch["providers"]) { + let providers = onSearch["providers"]; + dao.setValue("providersArr", providers); + providers.forEach((provider, i) => { + let itemsArr = provider.items; + const providerId = provider.id; + + dao.setValue(`${providerId}itemsArr`, itemsArr); + }); + } + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + if (onSearch.hasOwnProperty("providers")) { + const providers = onSearch["providers"]; + for (let i = 0; i < providers.length; i++) { + const provider = providers[i]; + if (provider.hasOwnProperty("locations")) { + const locations = provider.locations; + for (let j = 0; j < locations.length; j++) { + const { id, gps, area_code } = locations[j]; + try { + const [lat, long] = gps.split(","); + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) { + onSrchObj[ + "bpp/provider:location:" + id + ":RGC" + ] = `Reverse Geocoding for location ID ${id} failed for provider with id '${provider?.id}'. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } + } catch (error) { + console.log("bpp/providers error: ", error); + } + } + } + + try { + console.log("Checking provider serviceability"); + + let providerTags = provider?.tags; + if (providerTags) { + providerTags.forEach((tag) => { + if (tag?.descriptor?.code === "serviceability" && tag?.list) { + mandatoryTags = constants.SERVICEABILITY; + let missingTags = utils.findMissingTags( + tag?.list, + "serviceability", + mandatoryTags + ); + if (missingTags.length > 0) { + onSrchObj.mssngTagErr = `'${missingTags}' code/s required in providers/tags for serviceability`; + } + } + }); + } else { + onSrchObj.servcbltyErr = + "serviceability tag is required for a provider in providers/tags"; + } + } catch (error) { + console.log(error); + } + + try { + console.log("Checking item tags"); + let items = provider?.items; + items.forEach((item) => { + let itemTags = item?.tags; + if (itemTags) { + itemTags.forEach((tag) => { + if (tag?.descriptor?.code === "reschedule_terms" && tag?.list) { + mandatoryTags = constants.RESCHEDULE_TERMS; + let missingTags = utils.findMissingTags( + tag?.list, + "reschedule_terms", + mandatoryTags + ); + if (missingTags.length > 0) { + onSrchObj.mssngRescdlTagErr = `'${missingTags}' code/s required in providers/tags for ${tag?.descriptor?.code}`; + } + } + }); + } else { + onSrchObj.reschdlTrmErr = `reschedule_terms tag is required for an item in items/tags`; + } + }); + } catch (error) { + console.log(error); + } + //checking mandatory attributes for fashion and electronics + + // provider.items.forEach((item) => { + // let itemTags = item?.tags; + // let mandatoryAttr = []; + // let attrPresent = false; + // let missingAttr = []; + + // itemTags.forEach((tag) => { + // let { descriptor, list } = tag; + // if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { + + // if (domain === "ONDC:RET12") { + // mandatoryAttr = constants.FASHION_ATTRIBUTES; + // } + // if (domain === "ONDC:RET14") { + // mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + // } + // if (domain === "ONDC:RET12") { + // mandatoryAttr = constants.FASHION_ATTRIBUTES; + // } + // if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { + // mandatoryAttr = constants.MANDATORY_ATTRIBUTES; + // } + // attrPresent = true; + // missingAttr = utils.findMissingTags( + // list, + // descriptor.code, + // mandatoryAttr + // ); + + // if (missingAttr.length > 0) { + // onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + // } + // } + // if (descriptor?.code === "g2") { + // mandatoryAttr = constants.G2TAGS; + // missingAttr = utils.findMissingTags( + // list, + // descriptor.code, + // mandatoryAttr + // ); + + // if (missingAttr.length > 0) { + // onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; + // } + // } + // }); + // if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { + // onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; + // } + // }); + } + } + + return onSrchObj; +}; +module.exports = checkOnSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js new file mode 100644 index 0000000..8ada7a1 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js @@ -0,0 +1,98 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnSelect = async (data, msgIdSet) => { + const onSelectObj = {}; + let onSelect = data; + onSelect = onSelect.message.order; + let quote = onSelect?.quote; + const items = onSelect.items; + let fulfillments = onSelect?.fulfillments; + let ffState, ffId; + let deliveryQuoteItem = false; + let deliveryCharge = 0 + dao.setValue("onSlctdItemsArray", items) + const selectedItems = dao.getValue("slctdItemsArray"); + try { + console.log("Checking fulfillment object in /on_select"); + if (fulfillments) { + fulfillments.forEach((fulfillment) => { + ffId = fulfillment?.id; + ffState = fulfillment?.state?.descriptor?.code; + }); + } + } catch (error) { + console.log(error); + } + +// try { +// console.log("Comparing items object with /select"); +// const itemDiff = utils.findDifferencesInArrays(items, selectedItems); +// console.log(itemDiff); +// itemDiff.forEach((item, i) => { +// if(item?.attributes?.length>0){ +// let itemkey = `item-${i}-DiffErr`; +// onSelectObj[ +// itemkey +// ] = `In /items, '${item.attributes}' mismatch from /select`; +// } +// }); +// } catch (error) { +// console.log(error); +// } + + +// try { +// console.log(`Checking quote object in /on_select api`); +// quote?.breakup.forEach((breakup, i) => { +// let itemPrice = parseFloat(breakup?.item?.price?.value); +// let available = Number(breakup?.item?.quantity?.available?.count); +// let quantity = breakup["@ondc/org/item_quantity"]; + +// if ( +// breakup["@ondc/org/title_type"] === "delivery" && +// breakup["@ondc/org/item_id"] === ffId +// ) { +// deliveryQuoteItem = true; +// deliveryCharge= breakup?.price?.value +// console.log("deliverycharge",deliveryCharge); +// } +// if ( +// breakup["@ondc/org/title_type"] === "item" && +// quantity && +// parseFloat(breakup.price.value).toFixed(2) != +// parseFloat(itemPrice * quantity?.count).toFixed(2) +// ) { +// let item = `quoteErr${i}`; +// onSelectObj[ +// item +// ] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; +// } + +// if ( +// breakup["@ondc/org/title_type"] === "item" && +// quantity && +// quantity?.count > available +// ) { +// let item = `quoteErr${i}`; +// onSelectObj[ +// item +// ] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; +// } +// }); + +// if (ffState === "Non-serviceable" && !data.error) { +// onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; +// } +// } catch (error) { +// console.log( +// `!!Error while checking providers array in /on_select api`, +// error +// ); +// } + + return onSelectObj; +}; +module.exports = checkOnSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js new file mode 100644 index 0000000..ebe216e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js @@ -0,0 +1,78 @@ +const _ = require("lodash"); +const fs = require("fs"); +const path = require("path"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); + +const checkSearch = async (data, msgIdSet) => { + let srchObj = {}; + let search = data; + let contextTime = search.context.timestamp; + search = search.message.intent; + + try { + console.log("Checking buyer app finder fee in /search"); + + search.tags.forEach((tag) => { + if (tag?.descriptor?.code === "BAP_Terms" && tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "finder_fee_type") { + dao.setValue("buyerFinderFeeType", val?.value); + } + if (val?.descriptor?.code === "finder_fee_amount") { + dao.setValue("buyerFinderFeeAmount", val?.value); + } + }); + } + }); + } catch (error) { + console.log(error); + } + + const stops = data?.message?.intent?.fulfillment?.stops; + let endLocation; + stops.forEach((stop) => { + if (stop.type === "end") { + endLocation = stop?.location; + } + }); + + if (endLocation) { + console.log( + "Checking Reverse Geocoding for `end` location in `fullfilment`" + ); + try { + const [lat, long] = endLocation?.gps.split(","); + const area_code = endLocation?.area_code; + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) + srchObj[ + "RGC-end-Err" + ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } catch (error) { + console.log("Error in end location", error); + } + + // check for context cityCode and fulfillment end location + try { + const pinToStd = JSON.parse( + fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + ); + const stdCode = data.context?.location?.city?.code.split(":")[1]; + const area_code = endLocation?.area_code; + if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { + srchObj[ + "CityCode-Err" + ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + } + } catch (err) { + console.error("Error in city code check: ", err.message); + } + } + dao.setValue("searchObj", search); + return srchObj; +}; + +module.exports = checkSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js new file mode 100644 index 0000000..eb4c7f2 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js @@ -0,0 +1,134 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkSelect = async (data, msgIdSet) => { + const selectObj = {}; + let select = data; + select = select.message.order; + let fulfillments = select?.fulfillments; + let providersArr = dao.getValue("providersArr"); + let fulfillmentsArr = dao.getValue("fulfillmentsArr"); + let itemsArr = select.items; + dao.setValue("slctdItemsArray",itemsArr) + + // provider check + try { + console.log(`Comparing provider object in /select and /on_search`); + if (select.provider) { + onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); + let providerObj = providersArr?.filter( + (prov) => prov.id === select.provider.id + ); + if (!providerObj || providerObj?.length < 1) { + selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; + } else { + if ( + (!select?.provider?.locations || + select?.provider?.locations?.length < 1) && + providerObj[0]?.locations?.length > 1 + ) { + selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + } else if (select?.provider?.locations) { + let providerLocArr = select.provider.locations; + let providerLocExists = false; + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + selectObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; + }); + } + } + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.LOG_select}`, + error + ); + } + + //item check + try { + console.log(`Comparing item object in /select and /on_search`); + + itemsArr?.forEach((item, i) => { + let itemExists = false; + onSearchitemsArr?.forEach((element) => { + if (item.id === element.id) itemExists = true; + }); + if (!itemExists) { + let itemkey = `itemErr${i}`; + selectObj[ + itemkey + ] = `Item Id '${item.id}' does not exist in /on_search`; + } else { + let itemObj = onSearchitemsArr.filter( + (element) => element.id === item.id + ); + + itemObj = itemObj[0]; + // dao.setValue("selectedItem", itemObj.id); + console.log(itemObj.id); + if ( + !_.every(item.fulfillment_ids, (element) => + _.includes(itemObj.fulfillment_ids, element) + ) + ) { + let itemkey = `flflmntIdErr${i}`; + selectObj[ + itemkey + ] = `Fulfillment ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + if ( + !_.every(item.location_ids, (element) => + _.includes(itemObj.location_ids, element) + ) + ) { + let itemkey = `lctnIdErr${i}`; + selectObj[ + itemkey + ] = `Location ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + + if ( + item.parent_item_id!==itemObj.parent_item_id + ) { + let itemkey = `parentItmIdErr${i}`; + selectObj[ + itemkey + ] = `Parent item id ${item.parent_item_id} for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + + //checking fulfillments + fulfillments.forEach((fulfillment, i) => { + let bppfulfillment = fulfillmentsArr?.find( + (element) => element.type === fulfillment.type + ); + if (!bppfulfillment) { + let itemkey = `flfillmentIDerr${i}`; + selectObj[ + itemkey + ] = `Fulfillment of type '${fulfillment.type}' does not match with the catalog provided in /on_search`; + } + }); + } + }); + } catch (error) { + console.log(error); + } + + return selectObj; +}; +module.exports = checkSelect; + \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index e6e9502..fcdb41d 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -206,6 +206,7 @@ const getVersion = (data,vertical) => { if (data?.search && data?.search[0]?.context?.version === "2.0.1") return "v1"; else return "v2"; } + if(vertical==="services") return "v2" }; function compareDates(dateString1, dateString2) { From 836e8ecd2dbc9474eac8f97614c11b98bfc22f3e Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 5 Mar 2024 09:56:45 +0530 Subject: [PATCH 181/228] deleted log report.md --- log_report.md | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 log_report.md diff --git a/log_report.md b/log_report.md deleted file mode 100644 index 077b4fd..0000000 --- a/log_report.md +++ /dev/null @@ -1,15 +0,0 @@ -**on_search,on_init,/on_confirm** - -- remove static terms (bpp_terms) and cancellation terms as they are not enabled yet - -**/on_cancel** - -- fulfillments/start/instructions have changed for fulfillment type 'Delivery' -- In fulfillments/tags- precancel_state/updated_at is the time when this pre_cancel state was updated in the system (is not recorded correctly in Flow 2 (should reflect the timestamp recorded in fulfillments for this state in /on_status), missing in Flow 3) -- In /items, time/duration for RTO line item does not match the one provided in catalog in /on_search -- use appropriate cancellation reason id for triggering RTO - -**/track,on_track** - -- tracking apis should be implemented -- also add tracking.tags.order, tracking.tags.config; \ No newline at end of file From a55719e26e6b724b0b24e540bc4f5c43940068c0 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 5 Mar 2024 12:29:12 +0530 Subject: [PATCH 182/228] updated validation --- .../schema/B2B_json_schema/v2/on_search.js | 4 +- .../utils/b2b/b2bConfirm.js | 2 +- .../utils/b2b/b2bInit.js | 2 +- .../utils/b2b/b2bOnInit.js | 7 +- .../utils/b2b/b2bOnSelect.js | 32 ++++--- .../utils/services/srvOnSelect.js | 94 +++++-------------- .../log-verification-utility/utils/utils.js | 2 +- 7 files changed, 58 insertions(+), 85 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index a5d8c44..99088f4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -614,7 +614,7 @@ module.exports = { type: "string", }, }, - "add_ons": { + add_ons: { type: "array", items: { type: "object", @@ -706,6 +706,7 @@ module.exports = { }, cancellation_fee: { type: "object", + maxProperties: 1, properties: { percentage: { type: "string", @@ -726,6 +727,7 @@ module.exports = { required: [], }, }, + additionalProperties: false, required: [ "fulfillment_state", "reason_required", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index 17a33b3..8e21de4 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -22,7 +22,7 @@ const checkConfirm = async (data, msgIdSet) => { let itemkey = `item-${i}-DiffErr`; cnfrmObj[ itemkey - ] = `In /items, '${item.attributes}' mismatch from /select`; + ] = `In /items, '${item.attributes}' mismatch from /on_select`; } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index 2d6bbbf..68e7a46 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -20,7 +20,7 @@ const checkInit = (data, msgIdSet) => { let itemkey = `item-${i}-DiffErr`; initObj[ itemkey - ] = `In /items, '${item.attributes}' mismatch from /select`; + ] = `In /items, '${item.attributes}' mismatch from /on_select`; } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index 635c8f9..c98e5e6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -7,8 +7,10 @@ const checkOnInit = async (data, msgIdSet) => { const onInitObj = {}; let onInit = data; onInit = onInit.message.order; + let quote = onInit?.quote; let payments = onInit?.payments; + try { console.log(`Checking payment object in /on_init api`); payments.forEach((payment) => { @@ -18,7 +20,10 @@ const checkOnInit = async (data, msgIdSet) => { if (feeType != dao.getValue("buyerFinderFeeType")) { onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } - if (parseFloat(feeAmount) != parseFloat(dao.getValue("buyerFinderFeeAmount"))) { + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; } }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index d948165..56642d3 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -12,8 +12,8 @@ const checkOnSelect = async (data, msgIdSet) => { let fulfillments = onSelect?.fulfillments; let ffState, ffId; let deliveryQuoteItem = false; - let deliveryCharge = 0 - dao.setValue("onSlctdItemsArray", items) + let deliveryCharge = 0; + dao.setValue("onSlctdItemsArray", items); const selectedItems = dao.getValue("slctdItemsArray"); try { console.log("Checking fulfillment object in /on_select"); @@ -31,19 +31,23 @@ const checkOnSelect = async (data, msgIdSet) => { console.log("Comparing items object with /select"); const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); + itemDiff.forEach((item, i) => { - if(item?.attributes?.length>0){ - let itemkey = `item-${i}-DiffErr`; - onSelectObj[ - itemkey - ] = `In /items, '${item.attributes}' mismatch from /select`; - } + let index = item.attributes.indexOf("fulfillment_ids"); + if (index !== -1) { + item.attributes.splice(index, 1); + } + if (item.attributes?.length > 0) { + let itemkey = `item-${i}-DiffErr`; + onSelectObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select for item with id ${item.index}`; + } }); } catch (error) { console.log(error); } - try { console.log(`Checking quote object in /on_select api`); quote?.breakup.forEach((breakup, i) => { @@ -56,8 +60,8 @@ const checkOnSelect = async (data, msgIdSet) => { breakup["@ondc/org/item_id"] === ffId ) { deliveryQuoteItem = true; - deliveryCharge= breakup?.price?.value - console.log("deliverycharge",deliveryCharge); + deliveryCharge = breakup?.price?.value; + console.log("deliverycharge", deliveryCharge); } if ( breakup["@ondc/org/title_type"] === "item" && @@ -86,7 +90,11 @@ const checkOnSelect = async (data, msgIdSet) => { if (!deliveryQuoteItem && ffState === "Serviceable") { onSelectObj.deliveryQuoteErr = `Delivery charges should be provided in quote/breakup when fulfillment is 'Serviceable'`; } - if (deliveryQuoteItem && deliveryCharge!=0 && ffState === "Non-serviceable") { + if ( + deliveryQuoteItem && + deliveryCharge != 0 && + ffState === "Non-serviceable" + ) { onSelectObj.deliveryQuoteErr = `Delivery charges are not required or should be zero in quote/breakup when fulfillment is 'Non-serviceable'`; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js index 8ada7a1..02ae26f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js @@ -11,9 +11,7 @@ const checkOnSelect = async (data, msgIdSet) => { const items = onSelect.items; let fulfillments = onSelect?.fulfillments; let ffState, ffId; - let deliveryQuoteItem = false; - let deliveryCharge = 0 - dao.setValue("onSlctdItemsArray", items) + dao.setValue("onSlctdItemsArray", items); const selectedItems = dao.getValue("slctdItemsArray"); try { console.log("Checking fulfillment object in /on_select"); @@ -23,75 +21,35 @@ const checkOnSelect = async (data, msgIdSet) => { ffState = fulfillment?.state?.descriptor?.code; }); } + + if (ffState === "Non-serviceable" && !data.error) { + onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; + } } catch (error) { console.log(error); } -// try { -// console.log("Comparing items object with /select"); -// const itemDiff = utils.findDifferencesInArrays(items, selectedItems); -// console.log(itemDiff); -// itemDiff.forEach((item, i) => { -// if(item?.attributes?.length>0){ -// let itemkey = `item-${i}-DiffErr`; -// onSelectObj[ -// itemkey -// ] = `In /items, '${item.attributes}' mismatch from /select`; -// } -// }); -// } catch (error) { -// console.log(error); -// } - - -// try { -// console.log(`Checking quote object in /on_select api`); -// quote?.breakup.forEach((breakup, i) => { -// let itemPrice = parseFloat(breakup?.item?.price?.value); -// let available = Number(breakup?.item?.quantity?.available?.count); -// let quantity = breakup["@ondc/org/item_quantity"]; - -// if ( -// breakup["@ondc/org/title_type"] === "delivery" && -// breakup["@ondc/org/item_id"] === ffId -// ) { -// deliveryQuoteItem = true; -// deliveryCharge= breakup?.price?.value -// console.log("deliverycharge",deliveryCharge); -// } -// if ( -// breakup["@ondc/org/title_type"] === "item" && -// quantity && -// parseFloat(breakup.price.value).toFixed(2) != -// parseFloat(itemPrice * quantity?.count).toFixed(2) -// ) { -// let item = `quoteErr${i}`; -// onSelectObj[ -// item -// ] = `Total price of the item with item id ${breakup["@ondc/org/item_id"]} is not in sync with the unit price and quantity`; -// } - -// if ( -// breakup["@ondc/org/title_type"] === "item" && -// quantity && -// quantity?.count > available -// ) { -// let item = `quoteErr${i}`; -// onSelectObj[ -// item -// ] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; -// } -// }); - -// if (ffState === "Non-serviceable" && !data.error) { -// onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; -// } -// } catch (error) { -// console.log( -// `!!Error while checking providers array in /on_select api`, -// error -// ); -// } + try { + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + + + itemDiff.forEach((item, i) => { + let index = item.attributes.indexOf("fulfillment_ids"); + if (index !== -1) { + item.attributes.splice(index, 1); + } + if(item.attributes?.length>0){ + let itemkey = `item-${i}-DiffErr`; + onSelectObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select for item with id ${item.index}`; + } + }); + } catch (error) { + console.log(error); + } return onSelectObj; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index fcdb41d..e3c787f 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -399,7 +399,7 @@ function findDifferencesInArrays(array1, array2) { // Check if the properties are equal using lodash's _.isEqual if (!_.isEqual(item1, item2)) { const differingAttributes = findDifferentAttributes(item1, item2); - differences.push({ index: i, attributes: differingAttributes }); + differences.push({ index: item2?.id, attributes: differingAttributes }); } } From 3240ab2ac60d7bec6ff3e6ad12af410edcb242e8 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 13 Mar 2024 14:11:19 +0530 Subject: [PATCH 183/228] added services validations --- .../schema/B2B_json_schema/v2/init.js | 40 +++-- .../schema/B2B_json_schema/v2/on_search.js | 28 ++++ .../schema/SRV_json_schema/v2/init.js | 1 + .../schema/SRV_json_schema/v2/on_cancel.js | 3 + .../schema/SRV_json_schema/v2/on_confirm.js | 4 +- .../schema/SRV_json_schema/v2/on_search.js | 157 +++++++++++++++--- .../schema/SRV_json_schema/v2/select.js | 2 +- .../utils/b2b/b2bConfirm.js | 4 +- .../utils/b2b/b2bInit.js | 4 +- .../utils/logistics/logConfirm.js | 9 + .../utils/logistics/logOnConfirm.js | 10 ++ .../utils/services/msgValidator.js | 18 +- .../utils/services/srvConfirm.js | 87 ++++++++++ .../utils/services/srvOnInit.js | 68 ++++++++ .../utils/services/srvOnSelect.js | 42 ++++- .../log-verification-utility/utils/utils.js | 62 +++---- 16 files changed, 447 insertions(+), 92 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index dae8f08..67ebf76 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -80,7 +80,7 @@ module.exports = { }, ttl: { type: "string", - const: "PT30S" + const: "PT30S", }, }, required: [ @@ -126,10 +126,10 @@ module.exports = { }, required: ["id"], }, - } + }, }, required: ["id", "locations"], - additionalProperties:false + additionalProperties: false, }, items: { type: "array", @@ -210,14 +210,16 @@ module.exports = { $data: "/select/0/message/order/items/0/tags/0/list/0/value", }, - errorMessage:"Buyer terms should be same as provided in /select" + errorMessage: + "Buyer terms should be same as provided in /select", }, { const: { $data: "/select/0/message/order/items/0/tags/0/list/1/value", }, - errorMessage:"Buyer terms should be same as provided in /select" + errorMessage: + "Buyer terms should be same as provided in /select", }, ], }, @@ -230,7 +232,7 @@ module.exports = { }, }, }, - required: ["id", "fulfillment_ids","quantity"], + required: ["id", "fulfillment_ids", "quantity"], }, }, billing: { @@ -271,6 +273,8 @@ module.exports = { }, phone: { type: "string", + pattern: "^(\\+[0-9]+)?[0-9]{10}$", + errorMessage: `should match the format of a phone number` }, created_at: { type: "string", @@ -308,7 +312,8 @@ module.exports = { type: "string", pattern: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", - errorMessage: "Incorrect gps value (minimum of six decimal places are required)", + errorMessage: + "Incorrect gps value (minimum of six decimal places are required)", }, address: { type: "string", @@ -358,6 +363,8 @@ module.exports = { properties: { phone: { type: "string", + pattern: "^(\\+[0-9]+)?[0-9]{10}$", + errorMessage: `should match the format of a phone number` }, }, required: ["phone"], @@ -493,13 +500,16 @@ module.exports = { ], const: { $data: "/select/0/message/order/payments/0/type" }, }, - collected_by:{ - type:"string", - enum:["BAP","BPP"], - const: { $data: "/on_select/0/message/order/payments/0/collected_by" }, - } + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + const: { + $data: + "/on_select/0/message/order/payments/0/collected_by", + }, + }, }, - required: ["type","collected_by"], + required: ["type", "collected_by"], }, }, tags: { @@ -512,7 +522,7 @@ module.exports = { properties: { code: { type: "string", - enum: constants.TERMS + enum: constants.TERMS, }, }, }, @@ -525,7 +535,7 @@ module.exports = { properties: { code: { type: "string", - enum: constants.B2B_BPP_TERMS + enum: constants.B2B_BPP_TERMS, }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 99088f4..edec1b2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -138,6 +138,10 @@ module.exports = { "POST-FULFILLMENT", ], }, + collected_by:{ + type: "string", + enum: ["BAP","BPP"] + } }, required: ["id", "type"], }, @@ -996,6 +1000,30 @@ module.exports = { required: ["contact"], }, }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: [ + "PRE-FULFILLMENT", + "ON-FULFILLMENT", + "POST-FULFILLMENT", + ], + }, + collected_by:{ + type: "string", + enum: ["BAP","BPP"] + } + }, + required: ["id", "type"], + }, + }, }, required: [ "id", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js index 88d6b80..91e3182 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js @@ -304,6 +304,7 @@ module.exports = { properties: { label: { type: "string", + enum:["confirmed"] }, range: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js index 8bc73b4..343f8b7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js @@ -641,6 +641,9 @@ module.exports = { updated_at: { type: "string", + format: "date-time", + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js index ffce5d2..0c3302a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -637,7 +637,9 @@ module.exports = { }, updated_at: { type: "string", - format: "date-time" + format: "date-time", + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", }, xinput: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js index d56997b..cdc8dc8 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -258,7 +258,7 @@ module.exports = { required: ["holidays"], }, }, - required: ["label","schedule"], + required: ["label", "schedule"], }, locations: { type: "array", @@ -340,6 +340,68 @@ module.exports = { required: ["id", "type", "desc", "url"], }, }, + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + }, + required: ["name", "code"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + }, + }, tags: { type: "array", items: { @@ -439,7 +501,6 @@ module.exports = { "short_desc", "long_desc", "images", - "media", ], }, creator: { @@ -502,12 +563,7 @@ module.exports = { type: "string", }, }, - required: [ - "currency", - "value", - "offered_value", - "maximum_value", - ], + required: ["currency", "value"], }, category_ids: { type: "array", @@ -662,22 +718,36 @@ module.exports = { type: "boolean", }, }, - required: [ - "id", - "parent_item_id", - "descriptor", - "creator", - "price", - "category_ids", - "fulfillment_ids", - "location_ids", - "payment_ids", - "cancellation_terms", - "tags", - "time", - "matched", - "recommended", - ], + if: { properties: { parent_item_id: { const: "" } } }, + then: { + required: [ + "id", + "parent_item_id", + "descriptor", + "creator", + "price", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "tags", + "time", + "matched", + "recommended", + ], + }, + else: { + required: [ + "id", + "parent_item_id", + "descriptor", + "price", + "quantity", + "category_ids", + "tags", + ], + }, }, }, offers: { @@ -763,6 +833,45 @@ module.exports = { }, required: ["label", "range"], }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, }, required: [ "id", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js index e526c4c..61b45eb 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js @@ -195,7 +195,7 @@ module.exports = { required: ["label", "range"], }, }, - required: ["type", "location"], + required: ["type", "location","time"], }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index 8e21de4..e374b99 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -14,7 +14,7 @@ const checkConfirm = async (data, msgIdSet) => { const selectedItems = dao.getValue("onSlctdItemsArray"); try { - console.log("Comparing items object with /select"); + console.log("Comparing items object with /on_select"); const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { @@ -22,7 +22,7 @@ const checkConfirm = async (data, msgIdSet) => { let itemkey = `item-${i}-DiffErr`; cnfrmObj[ itemkey - ] = `In /items, '${item.attributes}' mismatch from /on_select`; + ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index 68e7a46..dfe3580 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -12,7 +12,7 @@ const checkInit = (data, msgIdSet) => { const selectedItems = dao.getValue("onSlctdItemsArray"); try { - console.log("Comparing items object with /select"); + console.log("Comparing items object with /on_select"); const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { @@ -20,7 +20,7 @@ const checkInit = (data, msgIdSet) => { let itemkey = `item-${i}-DiffErr`; initObj[ itemkey - ] = `In /items, '${item.attributes}' mismatch from /on_select`; + ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 30107da..918ee29 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -87,11 +87,20 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); console.log("checking linked order in /confirm"); const orderWeight =linkedOrder?.order?.weight?.value; + const unit = linkedOrder?.order?.weight?.unit; + + if(unit === 'kilogram'){ + orderWeight = orderWeight*1000; + } let totalUnitWeight=0; linkedOrder?.items.forEach(item=>{ const quantity = item?.quantity?.measure?.value + const quantityUnit = item?.quantity?.measure?.unit + if(quantityUnit === 'kilogram'){ + quantity = quantity*1000; + } const count = item?.quantity?.count const unitWeight = (quantity*count) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 822a3ed..8ad4859 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -56,11 +56,21 @@ const checkOnConfirm = (data, msgIdSet) => { console.log("checking linked order in /confirm"); const orderWeight =linkedOrder?.order?.weight?.value; + const unit = linkedOrder?.order?.weight?.unit; + + if(unit === 'kilogram'){ + orderWeight = orderWeight*1000; + } + let totalUnitWeight=0; linkedOrder?.items.forEach(item=>{ const quantity = item?.quantity?.measure?.value + const quantityUnit = item?.quantity?.measure?.unit + if(quantityUnit === 'kilogram'){ + quantity = quantity*1000; + } const count = item?.quantity?.count const unitWeight = (quantity*count) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js index 7a4a7a5..2eedd36 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js @@ -1,9 +1,9 @@ -// const checkConfirm = require("./b2bConfirm"); +const checkConfirm = require("./srvConfirm"); // const checkInit = require("./b2bInit"); const checkSelect = require("./srvSelect"); -// const checkOnInit = require("./b2bOnInit"); +const checkOnInit = require("./srvOnInit"); // const checkOnConfirm = require("./b2bOnConfirm"); -// const checkOnSelect = require("./b2bOnSelect"); +const checkOnSelect = require("./srvOnSelect"); const checkOnSearch = require("./srvOnSearch"); // const checkOnUpdate = require("./b2bOnUpdate"); // const checkUpdate = require("./b2bUpdate"); @@ -23,17 +23,17 @@ const srvVal = (element, action, msgIdSet) => { case "select": return checkSelect(element, msgIdSet); - // case "on_select": - // return checkOnSelect(element, msgIdSet); + case "on_select": + return checkOnSelect(element, msgIdSet); // case "init": // return checkInit(element, msgIdSet); - // case "on_init": - // return checkOnInit(element, msgIdSet); + case "on_init": + return checkOnInit(element, msgIdSet); - // case "confirm": - // return checkConfirm(element, msgIdSet); + case "confirm": + return checkConfirm(element, msgIdSet); // case "on_confirm": // return checkOnConfirm(element, msgIdSet); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js new file mode 100644 index 0000000..c55304d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js @@ -0,0 +1,87 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkConfirm = async (data, msgIdSet) => { + const cnfrmObj = {}; + let confirm = data; + confirm = confirm.message.order; + let orderState = confirm.state; + let payments = confirm?.payments; + + let items = confirm.items; + const selectedItems = dao.getValue("onSlctdItemsArray"); + + try { + console.log("Comparing items object with /on_select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ + let itemkey = `item-${i}-DiffErr`; + cnfrmObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; + } + }); + } catch (error) { + console.log(error); + } + + try { + console.log(`Checking payment object in /confirm api`); + payments.forEach((payment) => { + + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let payment_collected = payment?.collected_by; + let params = payment?.params; + + let tags = payment.tags; + tags.forEach((tag) => { + if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "Buyer_Finder_Fee_Type") { + feeType = val?.value; + } + if (val?.descriptor?.code === "Buyer_Finder_Fee_Amount") { + feeAmount = val?.value; + } + }); + } + if (feeType != dao.getValue("buyerFinderFeeType")) { + cnfrmObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + cnfrmObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); + if (paymentStatus === "PAID" && !params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + cnfrmObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; + } + + }); + } catch (error) { + console.log( + `!!Error while checking payment object in /confirm api`, + error + ); + } + + return cnfrmObj; +}; +module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js new file mode 100644 index 0000000..c1130b0 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js @@ -0,0 +1,68 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnInit = async (data, msgIdSet) => { + const onInitObj = {}; + let onInit = data; + onInit = onInit.message.order; + let quote = onInit?.quote; + let payments = onInit?.payments; + let feeType, feeAmount, settlementDetailsPresent, buyerFinderFeePresent; + + try { + console.log(`Checking payment object in /on_init api`); + payments.forEach((payment) => { + let tags = payment.tags; + let payment_collected = payment?.collected_by; + tags.forEach((tag) => { + if (tag?.descriptor?.code === "Settlement_Details") { + settlementDetailsPresent = true; + if (tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "Counterparty") { + let counterparty = val?.value; + if (payment_collected === "BAP" && counterparty === "BAP") { + onInit.cntrprty = `Counterparty will be BPP when BAP is collecting the payment`; + } + } + }); + } + } + if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { + buyerFinderFeePresent = true; + tag.list.forEach((val) => { + if (val?.descriptor?.code === "Buyer_Finder_Fee_Type") { + feeType = val?.value; + } + if (val?.descriptor?.code === "Buyer_Finder_Fee_Amount") { + feeAmount = val?.value; + } + }); + } + if (feeType != dao.getValue("buyerFinderFeeType")) { + onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); + + if (payment_collected === "BAP" && !settlementDetailsPresent) { + onInitObj.sttlmntDtls = `Settlement details should be sent by BPP in payments/tags when BAP is collecting the payment`; + } + if (!buyerFinderFeePresent) { + onInitObj.sttlmntDtls = `Buyer Finder Fee should be sent by BPP in payments/tags`; + } + }); + } catch (error) { + console.log(`!!Error while checking payment object in /on_init api`, error); + } + + return onInitObj; +}; +module.exports = checkOnInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js index 02ae26f..9b76377 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js @@ -32,20 +32,46 @@ const checkOnSelect = async (data, msgIdSet) => { try { console.log("Comparing items object with /select"); const itemDiff = utils.findDifferencesInArrays(items, selectedItems); - console.log(itemDiff); - itemDiff.forEach((item, i) => { let index = item.attributes.indexOf("fulfillment_ids"); if (index !== -1) { item.attributes.splice(index, 1); } - if(item.attributes?.length>0){ - let itemkey = `item-${i}-DiffErr`; - onSelectObj[ - itemkey - ] = `In /items, '${item.attributes}' mismatch from /select for item with id ${item.index}`; - } + if (item.attributes?.length > 0) { + let itemkey = `item-${i}-DiffErr`; + onSelectObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select for item with id ${item.index}`; + } + }); + } catch (error) { + console.log(error); + } + + try { + console.log( + "Comparing fulfillment_ids in /items and /fulfillments in /on_select" + ); + items.forEach((item) => { + let fulfillment_ids = item.fulfillment_ids; + let fulfillmentSet = new Set(); + + for (let fulfillment of fulfillments) { + fulfillmentSet.add(fulfillment.id); + } + + let missingIds = []; + + for (let id of fulfillment_ids) { + if (!fulfillmentSet.has(id)) { + missingIds.push(id); + } + } + + if (missingIds.length > 0) { + onSelectObj.missingFlmntIds = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; + } }); } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index e3c787f..5859a05 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -197,17 +197,18 @@ const timestampCheck = (date) => { } }; -const getVersion = (data,vertical) => { - if(vertical==='logistics'){ - if (data?.search && data?.search[0]?.context?.core_version === "1.1.0") return "v1.1"; - else return "v1.2"; +const getVersion = (data, vertical) => { + if (vertical === "logistics") { + if (data?.search && data?.search[0]?.context?.core_version === "1.1.0") + return "v1.1"; + else return "v1.2"; } - if(vertical==='b2b'){ - if (data?.search && data?.search[0]?.context?.version === "2.0.1") return "v1"; + if (vertical === "b2b") { + if (data?.search && data?.search[0]?.context?.version === "2.0.1") + return "v1"; else return "v2"; } - if(vertical==="services") return "v2" - + if (vertical === "services") return "v2"; }; function compareDates(dateString1, dateString2) { const date1 = new Date(dateString1); @@ -236,17 +237,16 @@ function compareDates(dateString1, dateString2) { } } - function iso8601DurationToSeconds(duration) { const unitMap = { - 'D': 24 * 60 * 60 * 1000, // Days to seconds - 'H': 60 * 60 * 1000, // Hours to seconds - 'M': 60 * 1000, // Minutes to seconds - 'S': 1000 // Seconds + D: 24 * 60 * 60 * 1000, // Days to seconds + H: 60 * 60 * 1000, // Hours to seconds + M: 60 * 1000, // Minutes to seconds + S: 1000, // Seconds }; if (duration.startsWith("P")) { - duration = duration.slice(1); // Remove the 'P' at the beginning + duration = duration.slice(1); // Remove the 'P' at the beginning } let totalSeconds = 0; @@ -264,9 +264,9 @@ function iso8601DurationToSeconds(duration) { } // Example usages: -console.log(iso8601DurationToSeconds("P6D")); // 518400 seconds (6 days) -console.log(iso8601DurationToSeconds("PT30S")); // 30 seconds -console.log(iso8601DurationToSeconds("PT2H30M")); // 9000 seconds (2 hours 30 minutes) +console.log(iso8601DurationToSeconds("P6D")); // 518400 seconds (6 days) +console.log(iso8601DurationToSeconds("PT30S")); // 30 seconds +console.log(iso8601DurationToSeconds("PT2H30M")); // 9000 seconds (2 hours 30 minutes) const hasTwoOrLessDecimalPlaces = (inputString) => { const parts = inputString.split("."); @@ -391,33 +391,35 @@ function findDifferencesInArrays(array1, array2) { return differences; } - // Iterate over each item in the arrays + // Iterate over each item in the array1 and check for difference in array 2 for (let i = 0; i < array1?.length; i++) { + for(let j= 0; j< array2.length; j++){ const item1 = array1[i]; - const item2 = array2[i]; - - // Check if the properties are equal using lodash's _.isEqual - if (!_.isEqual(item1, item2)) { - const differingAttributes = findDifferentAttributes(item1, item2); - differences.push({ index: item2?.id, attributes: differingAttributes }); + const item2 = array2[j]; + if (item1.id === item2.id) { + if (!_.isEqual(item1, item2)) { + const differingAttributes = findDifferentAttributes(item1, item2); + differences.push({ index: item1?.id, attributes: differingAttributes }); + } } } + // Check if the properties are equal using lodash's _.isEqual + } return differences; } -const findMissingTags =(list,code,mandatoryAttr) =>{ +const findMissingTags = (list, code, mandatoryAttr) => { const encounteredAttr = []; list.map(({ descriptor, value }) => { encounteredAttr.push(descriptor?.code); }); - // Check if all mandatory attributes are encountered - const missingAttr = mandatoryAttr.filter( + // Check if all mandatory attributes are encountered + const missingAttr = mandatoryAttr.filter( (code) => !encounteredAttr.includes(code) ); return missingAttr; - -} +}; module.exports = { uuidCheck, timestampCheck, @@ -446,5 +448,5 @@ module.exports = { findDifferencesInArrays, grocery_categories_id, fnb_categories_id, - findMissingTags + findMissingTags, }; From e1a52242334c31ec8cd781e9c22abc245f5b578a Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 14 Mar 2024 10:49:32 +0530 Subject: [PATCH 184/228] added vals --- .../logistics_api_json_schema/v1.2/confirmSchema.js | 2 +- .../logistics_api_json_schema/v1.2/initSchema.js | 2 +- .../logistics_api_json_schema/v1.2/searchSchema.js | 11 +++++++---- .../log-verification-utility/utils/constants.js | 2 +- .../utils/logistics/logConfirm.js | 9 +++++---- .../utils/logistics/logOnConfirm.js | 6 +++--- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 1b3b5d0..29f1eff 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -188,7 +188,7 @@ module.exports = { required: ["label", "duration", "timestamp"], }, }, - required: ["id", "category_id", "descriptor", "fulfillment_id"], + required: ["id", "category_id", "descriptor","time", "fulfillment_id"], // anyOf: [ // { // allOf: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index 90f07c2..ab464d0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -300,7 +300,7 @@ module.exports = { format: "email", }, }, - required: ["phone", "email"], + required: ["phone"], }, }, required: ["location", "contact"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js index a750922..7871f43 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/searchSchema.js @@ -109,6 +109,9 @@ module.exports = { }, required: ["holidays"], }, + duration: { + type: "string", + }, range: { type: "object", properties: { @@ -255,7 +258,7 @@ module.exports = { }, value: { type: "number", - minimum: 0 + minimum: 0, }, }, required: ["unit", "value"], @@ -272,7 +275,7 @@ module.exports = { }, value: { type: "number", - minimum: 0 + minimum: 0, }, }, required: ["unit", "value"], @@ -286,7 +289,7 @@ module.exports = { }, value: { type: "number", - minimum: 0 + minimum: 0, }, }, required: ["unit", "value"], @@ -300,7 +303,7 @@ module.exports = { }, value: { type: "number", - minimum: 0 + minimum: 0, }, }, required: ["unit", "value"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 23d3986..fd51519 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -111,7 +111,7 @@ module.exports = Object.freeze({ ], PAYMENT_TYPE: ["ON-ORDER", "ON-FULFILLMENT", "POST-FULFILLMENT"], PAYMENT_COLLECTEDBY: ["BAP", "BPP"], - UNITS_WEIGHT: ["kilogram", "gram"], + UNITS_WEIGHT: ["unit","dozen","gram","kilogram","tonne","litre","millilitre"], UNITS_DIMENSIONS: ["centimeter", "meter"], CATEGORIES: [ "Grocery", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 918ee29..d9010b1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -86,7 +86,7 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); try { console.log("checking linked order in /confirm"); - const orderWeight =linkedOrder?.order?.weight?.value; + let orderWeight =linkedOrder?.order?.weight?.value; const unit = linkedOrder?.order?.weight?.unit; if(unit === 'kilogram'){ @@ -106,9 +106,10 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); const unitWeight = (quantity*count) totalUnitWeight+=unitWeight; }) - - if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2)){ - cnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` + console.log("hello"); + console.log(totalUnitWeight,orderWeight); + if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2) && quantityUnit!== 'unit'){ + cnfrmObj.weightErr=`Total order weight '${orderWeight}' does not match the total unit weight of items '${totalUnitWeight}'` } } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 8ad4859..4adc5cc 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -55,7 +55,7 @@ const checkOnConfirm = (data, msgIdSet) => { try { console.log("checking linked order in /confirm"); - const orderWeight =linkedOrder?.order?.weight?.value; + let orderWeight =linkedOrder?.order?.weight?.value; const unit = linkedOrder?.order?.weight?.unit; if(unit === 'kilogram'){ @@ -77,8 +77,8 @@ const checkOnConfirm = (data, msgIdSet) => { totalUnitWeight+=unitWeight; }) - if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2)){ - onCnfrmObj.weightErr=`Total order weight '${orderWeight} does not match the total unit weight of items '${totalUnitWeight}'` + if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2) && quantityUnit!== 'unit'){ + onCnfrmObj.weightErr=`Total order weight '${orderWeight}' does not match the total unit weight of items '${totalUnitWeight}'` } } catch (error) { console.log(error); From 60a7b0048079f843968d46f0517d96a4525be435 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Mar 2024 12:24:14 +0530 Subject: [PATCH 185/228] updated checks --- .../schema/B2B_json_schema/v2/init.js | 8 +- .../schema/SRV_json_schema/v2/on_confirm.js | 3 +- .../schema/SRV_json_schema/v2/on_init.js | 3 +- .../schema/SRV_json_schema/v2/on_status.js | 4 + .../v1.2/confirmSchema.js | 7 +- .../utils/logistics/logConfirm.js | 7 +- .../utils/logistics/logOnConfirm.js | 6 +- .../utils/services/msgValidator.js | 14 +- .../utils/services/srvOnStatus.js | 177 ++++++++++++++++++ 9 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 67ebf76..ce1c1f2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -273,8 +273,8 @@ module.exports = { }, phone: { type: "string", - pattern: "^(\\+[0-9]+)?[0-9]{10}$", - errorMessage: `should match the format of a phone number` + pattern: "^[0-9]{10}$", + errorMessage: `should match the format of a 10 digit phone number` }, created_at: { type: "string", @@ -363,8 +363,8 @@ module.exports = { properties: { phone: { type: "string", - pattern: "^(\\+[0-9]+)?[0-9]{10}$", - errorMessage: `should match the format of a phone number` + pattern: "^[0-9]{10}$", + errorMessage: `should match the format of a 10 digit phone number` }, }, required: ["phone"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js index 0c3302a..5570352 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -676,8 +676,7 @@ module.exports = { "quote", "payments", "created_at", - "updated_at", - "xinput", + "updated_at" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js index 65fd323..9776bee 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js @@ -617,8 +617,7 @@ module.exports = { "billing", "fulfillments", "quote", - "payments", - "xinput", + "payments" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js index 239e2c1..24a7e8b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js @@ -633,6 +633,9 @@ module.exports = { updated_at: { type: "string", + format: "date-time", + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", }, }, required: [ @@ -653,5 +656,6 @@ module.exports = { required: ["order"], }, }, + isFutureDated: true, required: ["context", "message"], }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 29f1eff..96402ac 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -434,7 +434,7 @@ module.exports = { maxLength: 6, pattern: "^[a-zA-Z0-9]{1,6}$", errorMessage: - "should not be an empty string or have more than 6 digits", + "should not be an empty string or have more than 6 alphanumeric", }, }, }, @@ -529,6 +529,9 @@ module.exports = { properties: { short_desc: { type: "string", + not: { const: { $data: "3/start/instructions/short_desc" } }, + errorMessage: + "PCC should not be same as DCC ${3/start/instructions/short_desc}", }, long_desc: { type: "string", @@ -561,7 +564,7 @@ module.exports = { maxLength: 6, pattern: "^[a-zA-Z0-9]{1,6}$", errorMessage: - "should not be an empty string or have more than 6 digits", + "should not be an empty string or have more than 6 alphanumeric", }, }, required: ["short_desc"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index d9010b1..9872852 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -94,10 +94,11 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); } let totalUnitWeight=0; + let quantityUnit; linkedOrder?.items.forEach(item=>{ - const quantity = item?.quantity?.measure?.value - const quantityUnit = item?.quantity?.measure?.unit + let quantity = item?.quantity?.measure?.value + quantityUnit = item?.quantity?.measure?.unit if(quantityUnit === 'kilogram'){ quantity = quantity*1000; } @@ -106,7 +107,7 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); const unitWeight = (quantity*count) totalUnitWeight+=unitWeight; }) - console.log("hello"); + console.log(totalUnitWeight,orderWeight); if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2) && quantityUnit!== 'unit'){ cnfrmObj.weightErr=`Total order weight '${orderWeight}' does not match the total unit weight of items '${totalUnitWeight}'` diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 4adc5cc..073e544 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -64,10 +64,10 @@ const checkOnConfirm = (data, msgIdSet) => { let totalUnitWeight=0; - + let quantityUnit; linkedOrder?.items.forEach(item=>{ - const quantity = item?.quantity?.measure?.value - const quantityUnit = item?.quantity?.measure?.unit + let quantity = item?.quantity?.measure?.value + quantityUnit = item?.quantity?.measure?.unit if(quantityUnit === 'kilogram'){ quantity = quantity*1000; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js index 2eedd36..8f89161 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js @@ -1,13 +1,13 @@ const checkConfirm = require("./srvConfirm"); -// const checkInit = require("./b2bInit"); +// const checkInit = require("./srvInit"); const checkSelect = require("./srvSelect"); const checkOnInit = require("./srvOnInit"); -// const checkOnConfirm = require("./b2bOnConfirm"); +// const checkOnConfirm = require("./srvOnConfirm"); const checkOnSelect = require("./srvOnSelect"); const checkOnSearch = require("./srvOnSearch"); -// const checkOnUpdate = require("./b2bOnUpdate"); -// const checkUpdate = require("./b2bUpdate"); -// const checkOnStatus = require("./b2bOnStatus"); +// const checkOnUpdate = require("./srvOnUpdate"); +// const checkUpdate = require("./srvUpdate"); +const checkOnStatus = require("./srvOnStatus"); const checkSearch = require("./srvSearch"); const _ = require("lodash"); @@ -44,8 +44,8 @@ const srvVal = (element, action, msgIdSet) => { // case "on_update": // return checkOnUpdate(element,msgIdSet) - // case "on_status": - // return checkOnStatus(element,msgIdSet) + case "on_status": + return checkOnStatus(element,msgIdSet) } return busnsErr; }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js new file mode 100644 index 0000000..55ad3dd --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js @@ -0,0 +1,177 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnStatus = (data, msgIdSet) => { + let onStatusObj = {}; + let on_status = data; + let contextTime = on_status.context.timestamp; + let messageId = on_status.context.message_id; + + on_status = on_status.message.order; + let ffState; + let orderState = on_status.state; + let items = on_status.items; + let fulfillments = on_status.fulfillments; + let pickupTime, deliveryTime; + let payments = on_status?.payments; + let invoice = on_status?.documents; + + try { + console.log(`Checking payment object in /on_status`); + payments.forEach((payment) => { + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let params = payment?.params; + + if (paymentStatus === "PAID" && !params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + onStatusObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; + } + }); + } catch (error) { + console.log(error); + } + + try { + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + console.log( + `Comparing pickup and delivery timestamps for on_status_${ffState}` + ); + //Pending,Packed,Agent-assigned + if (fulfillment.type === "Home-Service") { + if ( + ffState === "Pending" + ) { + + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + if (stop?.time?.timestamp) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + // if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up for Non RFQ Flow.` + } + //In transit + + if (ffState === "In-Transit") { + + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; + } + + if (_.gt(pickupTime, contextTime)) { + onStatusObj.tmstmpErr = `fulfillments/start/time/timestamp cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required` + } + + //At-Location + if (ffState === "At-Location") { + + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + + if (!pickupTime) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; + } else if ( + dao.getValue("pickupTime") && + pickupTime !== dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot change for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required` + } + + //Completed + if (ffState === "Completed") { + + if (orderState !== "Completed") { + onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + if (!pickupTime) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; + } else if ( + dao.getValue("pickupTime") && + pickupTime !== dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot change for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + deliveryTime = stop?.time?.timestamp; + dao.setValue("deliveryTime", deliveryTime); + + if (!deliveryTime) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp is required for fulfillment state - ${ffState}`; + } + if (_.gt(deliveryTime, contextTime)) { + onStatusObj.tmstmpErr = `fulfillments/end/time/timestamp cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + if (_.gte(pickupTime, deliveryTime)) { + onStatusObj.tmstmpErr = `fulfillments/start/time/timestamp cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; + } + } + }); + if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required` + } + } + + }); + } catch (error) { + console.log(`Error checking fulfillments/start in /on_status`); + } + console.log(onStatusObj); + return onStatusObj; +}; + +module.exports = checkOnStatus; From 1df0475d72bbd8ad66b8ce5811e85ec50422becd Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 20 Mar 2024 12:38:46 +0530 Subject: [PATCH 186/228] removed services from main --- .../SRV_json_schema/keywords/confirm.js | 13 - .../schema/SRV_json_schema/keywords/init.js | 7 - .../schema/SRV_json_schema/keywords/onInit.js | 16 - .../schema/SRV_json_schema/keywords/search.js | 7 - .../schema/SRV_json_schema/schemaValidator.js | 126 --- .../schema/SRV_json_schema/v2/cancel.js | 95 -- .../schema/SRV_json_schema/v2/confirm.js | 606 ------------ .../schema/SRV_json_schema/v2/init.js | 367 ------- .../schema/SRV_json_schema/v2/master.js | 91 -- .../schema/SRV_json_schema/v2/on_cancel.js | 666 ------------- .../schema/SRV_json_schema/v2/on_confirm.js | 688 ------------- .../schema/SRV_json_schema/v2/on_init.js | 628 ------------ .../schema/SRV_json_schema/v2/on_search.js | 929 ------------------ .../schema/SRV_json_schema/v2/on_select.js | 474 --------- .../schema/SRV_json_schema/v2/on_status.js | 661 ------------- .../schema/SRV_json_schema/v2/on_update.js | 508 ---------- .../schema/SRV_json_schema/v2/search.js | 236 ----- .../schema/SRV_json_schema/v2/select.js | 226 ----- .../schema/SRV_json_schema/v2/status.js | 109 -- .../schema/SRV_json_schema/v2/update.js | 505 ---------- .../utils/services/msgValidator.js | 52 - .../utils/services/pinToStd.json | 1 - .../utils/services/srvConfirm.js | 87 -- .../utils/services/srvOnInit.js | 68 -- .../utils/services/srvOnSearch.js | 174 ---- .../utils/services/srvOnSelect.js | 82 -- .../utils/services/srvOnStatus.js | 177 ---- .../utils/services/srvSearch.js | 78 -- .../utils/services/srvSelect.js | 134 --- 29 files changed, 7811 deletions(-) delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js delete mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js deleted file mode 100644 index 5e7963a..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - isFutureDated: (data) => { - const contextTime = data?.context?.timestamp; - const created_at = data?.message?.order?.created_at; - const updated_at = data?.message?.order?.updated_at; - if ( - (created_at && created_at > contextTime) || - (updated_at && updated_at > contextTime) - ) - return false; - return true; - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js deleted file mode 100644 index 8f448e9..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - isLengthValid: (data) => { - if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) - return false; - else return true; - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js deleted file mode 100644 index 380b690..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js +++ /dev/null @@ -1,16 +0,0 @@ -module.exports = { - isQuoteMatching: (data) => { - let quotePrice = parseFloat(data?.price?.value); - const breakupArr = data?.breakup; - let totalBreakup = 0; - breakupArr.forEach((breakup) => { - totalBreakup += parseFloat(breakup?.price?.value); - - }); - totalBreakup= parseFloat(totalBreakup).toFixed(2) - console.log(totalBreakup,quotePrice); - quotePrice=quotePrice.toFixed(2) - if (quotePrice != totalBreakup) return false; - else return true; - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js deleted file mode 100644 index 7a14c5b..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - isEndTimeGreater: (data) => { - const startTime = parseInt(data?.start); - const endTime = parseInt(data?.end); - return startTime < endTime; - }, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js deleted file mode 100644 index 006e2c8..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js +++ /dev/null @@ -1,126 +0,0 @@ - -const { isLengthValid } = require("./keywords/init"); -const { isQuoteMatching } = require("./keywords/onInit"); -const { isFutureDated } = require("./keywords/confirm"); -const { isEndTimeGreater } = require("./keywords/search"); - -const fs = require("fs"); -//const async = require("async"); -const path = require("path"); - -const formatted_error = (errors) => { - error_list = []; - let status = ""; - errors.forEach((error) => { - error_dict = { - message: `${error.message}${ - error.params.allowedValues ? ` (${error.params.allowedValues})` : "" - }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ - error.params.additionalProperty - ? ` (${error.params.additionalProperty})` - : "" - }`, - details: error.instancePath, - }; - error_list.push(error_dict); - }); - if (error_list.length === 0) status = "pass"; - else status = "fail"; - error_json = { errors: error_list, status: status }; - return error_json; -}; - -const loadSchema = (schemaType, version) => { - try { - return require(`./${version}/${schemaType}.js`); - } catch (error) { - console.log("Error Occurred while importing", error); - } -}; - -const validate_schema = (data, schema,version) => { - const searchSchema = loadSchema("search", version); - const onSearchSchema = loadSchema("on_search", version); - - const selectSchema = loadSchema("select", version); - const onSelectSchema = loadSchema("on_select", version); - - const initSchema = loadSchema("init", version); - const onInitSchema = loadSchema("on_init", version); - - const confirmSchema = loadSchema("confirm", version); - const onConfirmSchema = loadSchema("on_confirm", version); - - const updateSchema = loadSchema("update", version); - const onUpdateSchema = loadSchema("on_update", version); - - const statusSchema = loadSchema("status", version); - const onStatusSchema = loadSchema("on_status", version); - - const cancelSchema = loadSchema("cancel", version); - const onCancelSchema = loadSchema("on_cancel", version); - - const Ajv = require("ajv"); - const ajv = new Ajv({ - allErrors: true, - strict: false, - strictRequired: false, - strictTypes: false, - $data: true, - }); - const addFormats = require("ajv-formats"); - - addFormats(ajv); - require("ajv-errors")(ajv); - let error_list = []; - try { - validate = ajv - .addSchema(searchSchema) - .addSchema(onSearchSchema) - .addSchema(selectSchema) - .addSchema(onSelectSchema) - .addSchema(initSchema) - .addSchema(onInitSchema) - .addSchema(confirmSchema) - .addSchema(onConfirmSchema) - .addSchema(updateSchema) - .addSchema(onUpdateSchema) - .addSchema(statusSchema) - .addSchema(onStatusSchema) - .addSchema(cancelSchema) - .addSchema(onCancelSchema) - .addKeyword("isEndTimeGreater", { - validate: (schema, data) => isEndTimeGreater(data), - }) - .addKeyword("isQuoteMatching", { - validate: (schema, data) => isQuoteMatching(data), - }) - .addKeyword("isFutureDated", { - validate: (schema, data) => isFutureDated(data), - }) - .addKeyword("isLengthValid", { - validate: (schema, data) => isLengthValid(data), - }); - - validate = validate.compile(schema); - - const valid = validate(data); - if (!valid) { - error_list = validate.errors; - } - } catch (error) { - console.log("ERROR!! validating schema"); - console.trace(error); - } - return error_list; -}; - -const validate_schema_srv_master = (data,version) => { - const masterSchema = loadSchema("master", version); - error_list = validate_schema(data, masterSchema,version); - return formatted_error(error_list); -}; - -module.exports = { - validate_schema_srv_master, -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js deleted file mode 100644 index ffa00b6..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js +++ /dev/null @@ -1,95 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/cancelSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - }, - version: { - type: "string", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order_id: { - type: "string", - }, - cancellation_reason_id: { - type: "string", - }, - }, - required: ["order_id", "cancellation_reason_id"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js deleted file mode 100644 index 7d21db8..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js +++ /dev/null @@ -1,606 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/confirmSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - id: { - type: "string", - }, - status: { - type: "string", - enum: ["Created"] - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - required: ["selected", "measure"], - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - const: { $data: "/init/0/message/order/billing/name" }, - }, - address: { - type: "string", - const: { $data: "/init/0/message/order/billing/address" }, - }, - state: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/state/name", - }, - }, - }, - required: ["name"], - }, - city: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/city/name", - }, - }, - }, - required: ["name"], - }, - tax_id: { - type: "string", - const: { $data: "/init/0/message/order/billing/tax_id" }, - }, - email: { - type: "string", - const: { $data: "/init/0/message/order/billing/email" }, - }, - phone: { - type: "string", - const: { $data: "/init/0/message/order/billing/phone" }, - }, - }, - - required: ["name", "address", "state", "city", "phone"], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "gps", - "address", - "city", - "country", - "area_code", - "state", - ], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone", "email"], - }, - time: { - type: "object", - properties: { - label: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - - }, - required: ["label", "range"], - }, - customer: { - type: "object", - properties: { - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: ["person"], - }, - }, - required: [ - "type", - "location", - "contact", - "time", - "customer", - ], - }, - }, - }, - required: ["id", "type", "tracking", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "quantity", "price"], - }, - }, - required: ["title", "price", "item"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - enum: ["BAP", "BPP"], - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - transaction_id: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - "transaction_id", - "bank_account_number", - "virtual_payment_address", - ], - }, - status: { - type: "string", - }, - type: { - type: "string", - const: { $data: "/select/0/message/order/payments/0/type" }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "collected_by", - "params", - "status", - "type", - "tags", - ], - }, - }, - created_at: { - type: "string", - }, - updated_at: { - type: "string", - }, - xinput: { - type: "object", - properties: { - form: { - type: "object", - properties: { - url: { - type: "string", - }, - mimetype: { - type: "string", - }, - submission_id: { - type: "string", - }, - status: { - type: "string", - }, - }, - required: ["url", "mimetype", "submission_id", "status"], - }, - }, - required: ["form"], - }, - }, - required: [ - "id", - "status", - "provider", - "items", - "billing", - "fulfillments", - "quote", - "payments", - "created_at", - "updated_at", - "xinput", - ], - }, - }, - required: ["order"], - }, - }, - isFutureDated: true, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js deleted file mode 100644 index 91e3182..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js +++ /dev/null @@ -1,367 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/initSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "init", - }, - version: { - type: "string", - const: "2.0.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - required: ["selected", "measure"], - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - }, - address: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - tax_id: { - type: "string", - }, - email: { - type: "string", - }, - phone: { - type: "string", - }, - }, - required: [ - "name", - "address", - "state", - "city", - "tax_id", - "email", - "phone", - ], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/on_select/0/message/order/fulfillments/0/id" }, - }, - type: { - type: "string", - const: { $data: "/on_select/0/message/order/fulfillments/0/type" }, - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "gps", - "address", - "city", - "country", - "area_code", - "state", - ], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - }, - required: ["phone"], - }, - time: { - type: "object", - properties: { - label: { - type: "string", - enum:["confirmed"] - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - - }, - required: ["label", "range"], - }, - }, - required: ["type", "location", "contact", "time"], - }, - }, - }, - required: ["id", "type", "stops"], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - const: { $data: "/select/0/message/order/payments/0/type" }, - }, - collected_by: { - type: "string", - const: { - $data: - "/on_select/0/message/order/payments/0/collected_by", - }, - }, - }, - required: ["type","collected_by"], - }, - }, - }, - required: [ - "provider", - "items", - "billing", - "fulfillments", - "payments", - ], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js deleted file mode 100644 index 63875c5..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js +++ /dev/null @@ -1,91 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/masterSchema", - type: "object", - properties: { - search: { - type: "array", - items: { - $ref: "searchSchema#", - }, - }, - on_search: { - type: "array", - items: { - $ref: "onSearchSchema#", - }, - }, - select: { - type: "array", - items: { - $ref: "selectSchema#", - }, - }, - on_select: { - type: "array", - items: { - $ref: "onSelectSchema#", - }, - }, - init: { - type: "array", - items: { - $ref: "initSchema#", - }, - }, - on_init: { - type: "array", - items: { - $ref: "onInitSchema#", - }, - }, - confirm: { - type: "array", - items: { - $ref: "confirmSchema#", - }, - }, - on_confirm: { - type: "array", - items: { - $ref: "onConfirmSchema#", - }, - }, - update: { - type: "array", - items: { - $ref: "updateSchema#", - }, - }, - on_update: { - type: "array", - items: { - $ref: "onUpdateSchema#", - }, - }, - status: { - type: "array", - items: { - $ref: "statusSchema#", - }, - }, - on_status: { - type: "array", - items: { - $ref: "onStatusSchema#", - }, - }, - cancel: { - type: "array", - items: { - $ref: "cancelSchema#", - }, - }, - on_cancel: { - type: "array", - items: { - $ref: "onCancelSchema#", - }, - } - }, - }; - \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js deleted file mode 100644 index 343f8b7..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js +++ /dev/null @@ -1,666 +0,0 @@ -const constants = require("../../../utils/constants"); - -module.exports = { - $id: "http://example.com/schema/onCancelSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_cancel", - }, - version: { - type: "string", - const: "2.0.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/confirm/0/message/order/id" }, - }, - status: { - type: "string", - enum: ["Cancelled"], - }, - cancellation: { - type: "object", - properties: { - reason: { - type: "object", - properties: { - descriptor: { - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - cancelled_by: { - type: "string", - }, - }, - required: ["reason", "cancelled_by"], - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - required: ["selected", "measure"], - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - const: { $data: "/init/0/message/order/billing/name" }, - }, - address: { - type: "string", - const: { $data: "/init/0/message/order/billing/address" }, - }, - state: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/state/name", - }, - }, - }, - required: ["name"], - }, - city: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/city/name", - }, - }, - }, - required: ["name"], - }, - tax_id: { - type: "string", - const: { $data: "/init/0/message/order/billing/tax_id" }, - }, - email: { - type: "string", - const: { $data: "/init/0/message/order/billing/email" }, - }, - phone: { - type: "string", - const: { $data: "/init/0/message/order/billing/phone" }, - }, - }, - - required: ["name", "address", "state", "city", "phone"], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: ["Cancelled"], - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: ["gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - timestamp: { - type: "string", - }, - }, - required: ["range"], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone", "email"], - }, - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], - }, - }, - }, - required: ["id", "type", "tracking", "state", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "quantity", "price"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - transaction_id: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - "transaction_id", - "bank_account_number", - "virtual_payment_address", - ], - }, - status: { - type: "string", - }, - type: { - type: "string", - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "collected_by", - "params", - "status", - "type", - "tags", - ], - }, - }, - - created_at: { - type: "string", - format: "date-time", - const: { $data: "/confirm/0/message/order/created_at" }, - errorMessage: - "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", - }, - - updated_at: { - type: "string", - format: "date-time", - not: { const: { $data: "/confirm/0/message/order/created_at" } }, - errorMessage: "should not be same as 'created_at'", - }, - }, - required: [ - "id", - "status", - "provider", - "items", - "billing", - "fulfillments", - "quote", - "payments", - "updated_at", - ], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js deleted file mode 100644 index 5570352..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js +++ /dev/null @@ -1,688 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/onConfirmSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_confirm", - }, - version: { - type: "string", - const: "2.0.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - const: { $data: "/confirm/0/context/message_id" }, - errorMessage: - "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", - }, - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/confirm/0/message/order/id" }, - }, - status: { - type: "string", - enum: ["Created", "Accepted", "Cancelled"], - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - rateable: { - type: "boolean", - }, - }, - required: ["id", "locations", "rateable"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - required: ["selected", "measure"], - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - const: { $data: "/init/0/message/order/billing/name" }, - }, - address: { - type: "string", - const: { $data: "/init/0/message/order/billing/address" }, - }, - state: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/state/name", - }, - }, - }, - required: ["name"], - }, - city: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/city/name", - }, - }, - }, - required: ["name"], - }, - tax_id: { - type: "string", - const: { $data: "/init/0/message/order/billing/tax_id" }, - }, - email: { - type: "string", - const: { $data: "/init/0/message/order/billing/email" }, - }, - phone: { - type: "string", - const: { $data: "/init/0/message/order/billing/phone" }, - }, - }, - - required: ["name", "address", "state", "city", "phone"], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - location: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: ["gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - }, - required: ["range"], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone", "email"], - }, - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "id", - "type", - "location", - "time", - "contact", - "person", - ], - }, - }, - rateable: { - type: "boolean", - }, - }, - required: [ - "id", - "state", - "type", - "stops", - "tracking", - "rateable", - ], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "quantity", "price"], - }, - tags: { - type: "array", - items: [ - { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: [ - { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - ], - }, - }, - required: ["descriptor", "list"], - }, - ], - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - enum: ["BAP", "BPP"], - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - transaction_id: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - "transaction_id", - "bank_account_number", - "virtual_payment_address", - ], - }, - status: { - type: "string", - }, - type: { - type: "string", - const: { $data: "/select/0/message/order/payments/0/type" }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "collected_by", - "params", - "status", - "type", - "tags", - ], - }, - }, - created_at: { - type: "string", - format: "date-time", - const: { $data: "/confirm/0/message/order/created_at" }, - errorMessage: - "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", - }, - updated_at: { - type: "string", - format: "date-time", - not: { const: { $data: "/confirm/0/message/order/created_at" } }, - errorMessage: "should not be same as 'created_at'", - }, - xinput: { - type: "object", - properties: { - form: { - type: "object", - properties: { - url: { - type: "string", - }, - mimetype: { - type: "string", - }, - submission_id: { - type: "string", - }, - status: { - type: "string", - }, - }, - required: ["url", "mimetype", "submission_id", "status"], - }, - }, - required: ["form"], - }, - }, - required: [ - "id", - "status", - "provider", - "items", - "billing", - "fulfillments", - "quote", - "payments", - "created_at", - "updated_at" - ], - }, - }, - required: ["order"], - }, - }, - isFutureDated: true, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js deleted file mode 100644 index 9776bee..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js +++ /dev/null @@ -1,628 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/onInitSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_init", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - const: { $data: "/init/0/context/message_id" }, - errorMessage: - "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", - }, - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - required: ["selected", "measure"], - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - const: { $data: "/init/0/message/order/billing/name" }, - }, - address: { - type: "string", - const: { $data: "/init/0/message/order/billing/address" }, - }, - state: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/state/name", - }, - }, - }, - required: ["name"], - }, - city: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/city/name", - }, - }, - }, - required: ["name"], - }, - tax_id: { - type: "string", - const: { $data: "/init/0/message/order/billing/tax_id" }, - }, - email: { - type: "string", - const: { $data: "/init/0/message/order/billing/email" }, - }, - phone: { - type: "string", - const: { $data: "/init/0/message/order/billing/phone" }, - }, - }, - - required: ["name", "address", "state", "city", "phone"], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "gps", - "address", - "city", - "country", - "area_code", - "state", - ], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - }, - required: ["phone"], - }, - time: { - type: "object", - properties: { - label: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - - }, - required: ["label", "range"], - }, - tags: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - required: ["type", "location", "contact", "time", "tags"], - }, - }, - }, - required: ["id", "type", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "quantity", "price"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - enum: ["BAP", "BPP"], - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - "bank_account_number", - "virtual_payment_address", - ], - }, - type: { - type: "string", - const: { $data: "/select/0/message/order/payments/0/type" }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["id", "collected_by", "params", "type", "tags"], - }, - }, - xinput: { - type: "object", - properties: { - form: { - type: "object", - properties: { - url: { - type: "string", - }, - mimetype: { - type: "string", - }, - }, - required: ["url", "mimetype"], - }, - required: { - type: "boolean", - }, - }, - required: ["form", "required"], - }, - }, - required: [ - "provider", - "locations", - "items", - "billing", - "fulfillments", - "quote", - "payments" - ], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js deleted file mode 100644 index cdc8dc8..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ /dev/null @@ -1,929 +0,0 @@ -const constants = require("../../../utils/constants"); - -module.exports = { - $id: "http://example.com/schema/onSearchSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - const: { $data: "/search/0/context/location/city/code" }, - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - const: { $data: "/search/0/context/location/country/code" }, - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_search", - }, - version: { - type: "string", - const: "2.0.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/search/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - const: { $data: "/search/0/context/message_id" }, - errorMessage: - "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", - }, - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - const: "PT30S", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - catalog: { - type: "object", - properties: { - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - enum: constants.SRV_FULFILLMENT_TYPE, - }, - }, - required: ["id", "type"], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - enum: constants.SRV_PAYMENT_TYPE, - }, - }, - required: ["id", "type"], - }, - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - }, - }, - required: ["url"], - }, - }, - }, - required: ["name", "short_desc", "long_desc", "images"], - }, - providers: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - code: { - type: "string", - }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - }, - }, - required: ["url"], - }, - }, - }, - required: [ - "name", - "code", - "short_desc", - "long_desc", - "images", - ], - }, - rating: { - type: "string", - }, - ttl: { - type: "string", - }, - time: { - type: "object", - properties: { - label: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - frequency: { - type: "string", - }, - holidays: { - type: "array", - items: { - type: "string", - }, - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays"], - }, - }, - required: ["label", "schedule"], - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - code: { - type: "string", - }, - name: { - type: "string", - }, - }, - required: ["code", "name"], - }, - state: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - }, - required: [ - "id", - "gps", - "address", - "city", - "state", - "country", - "area_code", - ], - }, - }, - creds: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - desc: { - type: "string", - }, - url: { - type: "string", - }, - }, - required: ["id", "type", "desc", "url"], - }, - }, - categories: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - code: { - type: "string", - }, - }, - required: ["name", "code"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - code: { - type: "string", - }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - }, - }, - required: ["url"], - }, - }, - media: { - type: "array", - items: { - type: "object", - properties: { - mimetype: { - type: "string", - }, - url: { - type: "string", - }, - }, - required: ["mimetype", "url"], - }, - }, - }, - required: [ - "name", - "code", - "short_desc", - "long_desc", - "images", - ], - }, - creator: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - contact: { - type: "object", - properties: { - name: { - type: "string", - }, - address: { - type: "object", - properties: { - full: { - type: "string", - }, - }, - required: ["full"], - }, - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: [ - "name", - "address", - "phone", - "email", - ], - }, - }, - required: ["name", "contact"], - }, - }, - required: ["descriptor"], - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - offered_value: { - type: "string", - }, - maximum_value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - category_ids: { - type: "array", - items: { - type: "string", - }, - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - }, - }, - payment_ids: { - type: "array", - items: { - type: "string", - }, - }, - cancellation_terms: { - type: "array", - items: { - type: "object", - properties: { - fulfillment_state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - cancellation_fee: { - type: "object", - properties: { - amount: { - type: "object", - properties: { - value: { - type: "string", - }, - }, - required: ["value"], - }, - percentage: { - type: "string", - }, - }, - }, - }, - required: ["fulfillment_state", "cancellation_fee"], - }, - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - time: { - type: "object", - properties: { - label: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - frequency: { - type: "string", - }, - holidays: { - type: "array", - items: { - type: "string", - }, - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["holidays"], - }, - }, - required: ["label", "schedule"], - }, - matched: { - type: "boolean", - }, - recommended: { - type: "boolean", - }, - }, - if: { properties: { parent_item_id: { const: "" } } }, - then: { - required: [ - "id", - "parent_item_id", - "descriptor", - "creator", - "price", - "category_ids", - "fulfillment_ids", - "location_ids", - "payment_ids", - "cancellation_terms", - "tags", - "time", - "matched", - "recommended", - ], - }, - else: { - required: [ - "id", - "parent_item_id", - "descriptor", - "price", - "quantity", - "category_ids", - "tags", - ], - }, - }, - }, - offers: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - code: { - type: "string", - }, - short_desc: { - type: "string", - }, - long_desc: { - type: "string", - }, - images: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - }, - }, - required: ["url"], - }, - }, - }, - required: [ - "name", - "code", - "short_desc", - "long_desc", - "images", - ], - }, - location_ids: { - type: "array", - items: { - type: "string", - }, - }, - category_ids: { - type: "array", - items: { - type: "string", - }, - }, - item_ids: { - type: "array", - items: { - type: "string", - }, - }, - time: { - type: "object", - properties: { - label: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - }, - required: ["label", "range"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "descriptor", - "location_ids", - "category_ids", - "item_ids", - "time", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone", "email"], - }, - }, - required: ["contact"], - }, - }, - }, - required: [ - "id", - "descriptor", - "rating", - "ttl", - "time", - "locations", - "tags", - "items", - "fulfillments", - ], - }, - }, - }, - required: ["fulfillments", "payments", "descriptor", "providers"], - }, - }, - required: ["catalog"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js deleted file mode 100644 index 4c3fe3d..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js +++ /dev/null @@ -1,474 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/onSelectSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_select", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - const: { $data: "/select/0/context/message_id" }, - errorMessage: - "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", - }, - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/select/0/message/order/provider/id" }, - }, - }, - required: ["id"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - id: { - type: "string", - const: { $data: "/select/0/message/order/items/0/id" }, - }, - parent_item_id: { - type: "string", - const: { $data: "/select/0/message/order/items/0/parent_item_id" }, - }, - location_ids: { - type: "array", - items: { - type: "string", - }, - }, - time: { - type: "object", - properties: { - label: { - type: "string", - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - schedule: { - type: "object", - properties: { - frequency: { - type: "string", - }, - holidays: { - type: "array", - items: { - type: "string", - }, - }, - times: { - type: "array", - items: { - type: "string", - }, - }, - }, - }, - }, - required: ["label", "schedule"], - }, - }, - required: [ - "fulfillment_ids", - "id", - "parent_item_id", - "location_ids", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - tracking: { - type: "boolean", - }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum:["Serviceable","Non-serviceable"] - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - required: ["gps", "area_code"], - }, - time: { - type: "object", - properties: { - label: { - type: "string", - enum: ["confirmed","rejected"] - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - }, - required: ["label", "range"], - }, - tags: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - required: ["type", "location", "time", "tags"], - }, - }, - }, - required: ["id", "state", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "quantity", "price"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - isQuoteMatching:true, - required: ["price", "breakup", "ttl"], - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - const: { $data: "/select/0/message/order/payments/0/type" }, - }, - collected_by: { - type: "string", - enum:["BAP","BPP"] - }, - }, - required: ["type","collected_by"], - }, - }, - }, - required: ["provider", "items", "fulfillments", "quote","payments"], - }, - }, - required: ["order"], - }, - error: { - type: "object", - properties: { - code: { - type: "string", - }, - message: { - type: "string", - }, - }, - required: ["code", "message"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js deleted file mode 100644 index 24a7e8b..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js +++ /dev/null @@ -1,661 +0,0 @@ -const constants = require("../../../utils/constants"); - -module.exports = { - $id: "http://example.com/schema/onStatusSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_status", - }, - version: { - type: "string", - const: "2.0.0", - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/confirm/0/message/order/id" }, - }, - status: { - type: "string", - enum: constants.SRV_ORDER_STATE, - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "integer", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - required: ["selected", "measure"], - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], - }, - }, - billing: { - type: "object", - properties: { - name: { - type: "string", - const: { $data: "/init/0/message/order/billing/name" }, - }, - address: { - type: "string", - const: { $data: "/init/0/message/order/billing/address" }, - }, - state: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/state/name", - }, - }, - }, - required: ["name"], - }, - city: { - type: "object", - properties: { - name: { - type: "string", - const: { - $data: "/init/0/message/order/billing/city/name", - }, - }, - }, - required: ["name"], - }, - tax_id: { - type: "string", - const: { $data: "/init/0/message/order/billing/tax_id" }, - }, - email: { - type: "string", - const: { $data: "/init/0/message/order/billing/email" }, - }, - phone: { - type: "string", - const: { $data: "/init/0/message/order/billing/phone" }, - }, - }, - - required: ["name", "address", "state", "city","phone"], - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: constants.SRV_FULFILLMENT_STATE, - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - gps: { - type: "string", - }, - address: { - type: "string", - }, - city: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - area_code: { - type: "string", - }, - state: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: ["gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - timestamp: { - type: "string", - }, - }, - required: ["range"], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone", "email"], - }, - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], - }, - }, - }, - required: ["id", "type", "tracking", "state", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - quantity: { - type: "object", - properties: { - selected: { - type: "object", - properties: { - count: { - type: "string", - }, - }, - required: ["count"], - }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, - }, - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "quantity", "price"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - transaction_id: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - "transaction_id", - "bank_account_number", - "virtual_payment_address", - ], - }, - status: { - type: "string", - }, - type: { - type: "string", - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "collected_by", - "params", - "status", - "type", - "tags", - ], - }, - }, - documents: { - type: "array", - items: { - type: "object", - properties: { - url: { - type: "string", - }, - label: { - type: "string", - }, - }, - required: ["url", "label"], - }, - }, - - created_at: { - type: "string", - format: "date-time", - const: { $data: "/confirm/0/message/order/created_at" }, - errorMessage: - "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", - }, - - updated_at: { - type: "string", - format: "date-time", - not: { const: { $data: "/confirm/0/message/order/created_at" } }, - errorMessage: "should not be same as 'created_at'", - }, - }, - required: [ - "id", - "status", - "provider", - "items", - "billing", - "fulfillments", - "quote", - "payments", - "documents", - "created_at", - "updated_at", - ], - }, - }, - required: ["order"], - }, - }, - isFutureDated: true, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js deleted file mode 100644 index b217a7a..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js +++ /dev/null @@ -1,508 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/onUpdateSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "on_update", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - const: { $data: "/update/0/context/message_id" }, - errorMessage: - "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", - }, - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/confirm/0/message/order/id" }, - }, - status: { - type: "string", - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "location_ids", - ], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - transaction_id: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - "transaction_id", - "bank_account_number", - "virtual_payment_address", - ], - }, - status: { - type: "string", - }, - type: { - type: "string", - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "collected_by", - "params", - "status", - "type", - "tags", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - gps: { - type: "string", - }, - }, - required: ["id", "descriptor", "gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - }, - required: ["range"], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone", "email"], - }, - instructions: { - type: "object", - properties: { - name: { - type: "string", - }, - short_desc: { - type: "string", - }, - }, - required: ["name", "short_desc"], - }, - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], - }, - }, - rateable: { - type: "boolean", - }, - }, - required: ["id", "state", "type", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "price"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - }, - required: [ - "id", - "status", - "provider", - "items", - "payments", - "fulfillments", - "quote", - ], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js deleted file mode 100644 index 25333cc..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js +++ /dev/null @@ -1,236 +0,0 @@ -const constants = require("../../../utils/constants"); - -module.exports = { - $id: "http://example.com/schema/searchSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "search", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - transaction_id: { - type: "string", - }, - message_id: { - type: "string", - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - const: "PT30S" - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - intent: { - type: "object", - properties: { - item: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - }, - category: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - fulfillment: { - type: "object", - properties: { - type: { - type: "string", - enum: constants.SRV_FULFILLMENT_TYPE - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - const: "end" - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - pattern: constants.GPS_PATTERN, - errorMessage: "Incorrect gps value (minimum of six decimal places are required)" - }, - area_code: { - type: "string", - }, - }, - required: ["gps", "area_code"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - format: "date-time" - }, - end: { - type: "string", - format: "date-time" - }, - }, - required: ["start", "end"], - }, - days: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["range"], - }, - }, - required: ["type", "location"], - }, - }, - }, - required: ["type", "stops"], - }, - payment: { - type: "object", - properties: { - type: { - type: "string", - enum: constants.SRV_PAYMENT_TYPE - }, - collected_by: { - type: "string", - enum: constants.PAYMENT_COLLECTEDBY - }, - }, - required: ["type", "collected_by"], - }, - tags: { - type: "array", - minItems: 1, - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum: ["BAP_Terms"] - }, - }, - required: ["code"], - }, - list: { - type: "array", - minItems: 2, - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - enum:["finder_fee_type","finder_fee_amount"] - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ "fulfillment", "payment", "tags"], - }, - }, - required: ["intent"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js deleted file mode 100644 index 61b45eb..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js +++ /dev/null @@ -1,226 +0,0 @@ -const constants = require("../../../utils/constants"); - -module.exports = { - $id: "http://example.com/schema/selectSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "select", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - const: "PT30S" - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order: { - type: "object", - properties: { - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - location_ids: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["id", "parent_item_id", "location_ids"], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - gps: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - required: ["gps", "area_code"], - }, - time: { - type: "object", - properties: { - label: { - type: "string", - const: "selected" - }, - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - days: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: ["label", "range"], - }, - }, - required: ["type", "location","time"], - }, - }, - }, - required: ["stops"], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - enum: constants.SRV_PAYMENT_TYPE - }, - }, - required: ["type"], - }, - }, - }, - required: ["provider", "items", "fulfillments", "payments"], - }, - }, - required: ["order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js deleted file mode 100644 index a298aff..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js +++ /dev/null @@ -1,109 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/statusSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "status", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - const: "PT30S" - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - order_id: { - type: "string", - const: { $data: "/confirm/0/message/order/id" }, - }, - }, - required: ["order_id"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js deleted file mode 100644 index 54e0bf6..0000000 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js +++ /dev/null @@ -1,505 +0,0 @@ -module.exports = { - $id: "http://example.com/schema/updateSchema", - type: "object", - properties: { - context: { - type: "object", - properties: { - domain: { - type: "string", - }, - location: { - type: "object", - properties: { - city: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - country: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["city", "country"], - }, - action: { - type: "string", - const: "update", - }, - version: { - type: "string", - const: "2.0.0" - }, - bap_id: { - type: "string", - }, - bap_uri: { - type: "string", - }, - bpp_id: { - type: "string", - }, - bpp_uri: { - type: "string", - }, - transaction_id: { - type: "string", - const: { $data: "/select/0/context/transaction_id" }, - errorMessage: - "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", - }, - message_id: { - type: "string", - allOf: [ - { - not: { - const: { $data: "1/transaction_id" }, - }, - errorMessage: - "Message ID should not be equal to transaction_id: ${1/transaction_id}", - }, - ], - }, - timestamp: { - type: "string", - format: "date-time", - }, - ttl: { - type: "string", - const: "PT30S" - }, - }, - required: [ - "domain", - "location", - "action", - "version", - "bap_id", - "bap_uri", - "bpp_id", - "bpp_uri", - "transaction_id", - "message_id", - "timestamp", - "ttl", - ], - }, - message: { - type: "object", - properties: { - update_target: { - type: "string", - enum: ["payments","fulfillments"] - }, - order: { - type: "object", - properties: { - id: { - type: "string", - const: { $data: "/confirm/0/message/order/id" }, - }, - state: { - type: "string", - }, - provider: { - type: "object", - properties: { - id: { - type: "string", - }, - locations: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - }, - required: ["id"], - }, - }, - }, - required: ["id", "locations"], - }, - items: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - parent_item_id: { - type: "string", - }, - fulfillment_ids: { - type: "array", - items: { - type: "string", - }, - }, - location_ids: { - type: "array", - items: { - type: "string", - }, - }, - }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "location_ids", - ], - }, - }, - payments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - collected_by: { - type: "string", - }, - params: { - type: "object", - properties: { - amount: { - type: "string", - }, - currency: { - type: "string", - }, - transaction_id: { - type: "string", - }, - bank_account_number: { - type: "string", - }, - virtual_payment_address: { - type: "string", - }, - }, - required: [ - "amount", - "currency", - ], - }, - status: { - type: "string", - }, - type: { - type: "string", - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: [ - "id", - "collected_by", - "params", - "status", - "type", - "tags", - ], - }, - }, - fulfillments: { - type: "array", - items: { - type: "object", - properties: { - id: { - type: "string", - }, - state: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - }, - required: ["descriptor"], - }, - type: { - type: "string", - }, - tracking: { - type: "boolean", - }, - stops: { - type: "array", - items: { - type: "object", - properties: { - type: { - type: "string", - }, - location: { - type: "object", - properties: { - id: { - type: "string", - }, - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - gps: { - type: "string", - }, - }, - required: ["gps"], - }, - time: { - type: "object", - properties: { - range: { - type: "object", - properties: { - start: { - type: "string", - }, - end: { - type: "string", - }, - }, - required: ["start", "end"], - }, - }, - required: ["range"], - }, - contact: { - type: "object", - properties: { - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: ["phone"], - }, - instructions: { - type: "object", - properties: { - name: { - type: "string", - }, - short_desc: { - type: "string", - }, - }, - required: ["name", "short_desc"], - }, - person: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], - }, - }, - rateable: { - type: "boolean", - }, - }, - required: ["id", "state", "type", "stops"], - }, - }, - quote: { - type: "object", - properties: { - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - breakup: { - type: "array", - items: { - type: "object", - properties: { - title: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - item: { - type: "object", - properties: { - id: { - type: "string", - }, - price: { - type: "object", - properties: { - currency: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["currency", "value"], - }, - }, - required: ["id", "price"], - }, - tags: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - list: { - type: "array", - items: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - code: { - type: "string", - }, - }, - required: ["code"], - }, - value: { - type: "string", - }, - }, - required: ["descriptor", "value"], - }, - }, - }, - required: ["descriptor", "list"], - }, - }, - }, - required: ["title", "price", "item", "tags"], - }, - }, - ttl: { - type: "string", - }, - }, - required: ["price", "breakup", "ttl"], - }, - }, - required: [ - "id", - "status", - "provider", - "items", - "payments", - "fulfillments", - "quote", - ], - }, - }, - required: ["update_target", "order"], - }, - }, - required: ["context", "message"], -}; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js deleted file mode 100644 index 8f89161..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js +++ /dev/null @@ -1,52 +0,0 @@ -const checkConfirm = require("./srvConfirm"); -// const checkInit = require("./srvInit"); -const checkSelect = require("./srvSelect"); -const checkOnInit = require("./srvOnInit"); -// const checkOnConfirm = require("./srvOnConfirm"); -const checkOnSelect = require("./srvOnSelect"); -const checkOnSearch = require("./srvOnSearch"); -// const checkOnUpdate = require("./srvOnUpdate"); -// const checkUpdate = require("./srvUpdate"); -const checkOnStatus = require("./srvOnStatus"); -const checkSearch = require("./srvSearch"); -const _ = require("lodash"); - -const srvVal = (element, action, msgIdSet) => { - const busnsErr = {}; - switch (action) { - case "search": - return checkSearch(element, msgIdSet); - - case "on_search": - return checkOnSearch(element, msgIdSet); - - case "select": - return checkSelect(element, msgIdSet); - - case "on_select": - return checkOnSelect(element, msgIdSet); - - // case "init": - // return checkInit(element, msgIdSet); - - case "on_init": - return checkOnInit(element, msgIdSet); - - case "confirm": - return checkConfirm(element, msgIdSet); - - // case "on_confirm": - // return checkOnConfirm(element, msgIdSet); - - // case "update": - // return checkUpdate(element,msgIdSet); - - // case "on_update": - // return checkOnUpdate(element,msgIdSet) - - case "on_status": - return checkOnStatus(element,msgIdSet) - } - return busnsErr; -}; -module.exports = { srvVal }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json b/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json deleted file mode 100644 index 4875211..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json +++ /dev/null @@ -1 +0,0 @@ -{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"08414","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js deleted file mode 100644 index c55304d..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js +++ /dev/null @@ -1,87 +0,0 @@ -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils"); - -const checkConfirm = async (data, msgIdSet) => { - const cnfrmObj = {}; - let confirm = data; - confirm = confirm.message.order; - let orderState = confirm.state; - let payments = confirm?.payments; - - let items = confirm.items; - const selectedItems = dao.getValue("onSlctdItemsArray"); - - try { - console.log("Comparing items object with /on_select"); - const itemDiff = utils.findDifferencesInArrays(items, selectedItems); - console.log(itemDiff); - itemDiff.forEach((item, i) => { - if(item?.attributes?.length>0){ - let itemkey = `item-${i}-DiffErr`; - cnfrmObj[ - itemkey - ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; - } - }); - } catch (error) { - console.log(error); - } - - try { - console.log(`Checking payment object in /confirm api`); - payments.forEach((payment) => { - - let paymentStatus = payment?.status; - let paymentType = payment?.type; - let payment_collected = payment?.collected_by; - let params = payment?.params; - - let tags = payment.tags; - tags.forEach((tag) => { - if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { - tag.list.forEach((val) => { - if (val?.descriptor?.code === "Buyer_Finder_Fee_Type") { - feeType = val?.value; - } - if (val?.descriptor?.code === "Buyer_Finder_Fee_Amount") { - feeAmount = val?.value; - } - }); - } - if (feeType != dao.getValue("buyerFinderFeeType")) { - cnfrmObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; - } - if ( - parseFloat(feeAmount) != - parseFloat(dao.getValue("buyerFinderFeeAmount")) - ) { - cnfrmObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; - } - }); - if (paymentStatus === "PAID" && !params?.transaction_id) { - cnfrmObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; - } - if (paymentStatus === "NOT-PAID" && params?.transaction_id) { - cnfrmObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; - } - if ( - paymentType === "ON-FULFILLMENT" && - orderState != "Completed" && - paymentStatus === "PAID" - ) { - cnfrmObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; - } - - }); - } catch (error) { - console.log( - `!!Error while checking payment object in /confirm api`, - error - ); - } - - return cnfrmObj; -}; -module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js deleted file mode 100644 index c1130b0..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js +++ /dev/null @@ -1,68 +0,0 @@ -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils"); - -const checkOnInit = async (data, msgIdSet) => { - const onInitObj = {}; - let onInit = data; - onInit = onInit.message.order; - let quote = onInit?.quote; - let payments = onInit?.payments; - let feeType, feeAmount, settlementDetailsPresent, buyerFinderFeePresent; - - try { - console.log(`Checking payment object in /on_init api`); - payments.forEach((payment) => { - let tags = payment.tags; - let payment_collected = payment?.collected_by; - tags.forEach((tag) => { - if (tag?.descriptor?.code === "Settlement_Details") { - settlementDetailsPresent = true; - if (tag?.list) { - tag.list.forEach((val) => { - if (val?.descriptor?.code === "Counterparty") { - let counterparty = val?.value; - if (payment_collected === "BAP" && counterparty === "BAP") { - onInit.cntrprty = `Counterparty will be BPP when BAP is collecting the payment`; - } - } - }); - } - } - if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { - buyerFinderFeePresent = true; - tag.list.forEach((val) => { - if (val?.descriptor?.code === "Buyer_Finder_Fee_Type") { - feeType = val?.value; - } - if (val?.descriptor?.code === "Buyer_Finder_Fee_Amount") { - feeAmount = val?.value; - } - }); - } - if (feeType != dao.getValue("buyerFinderFeeType")) { - onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; - } - if ( - parseFloat(feeAmount) != - parseFloat(dao.getValue("buyerFinderFeeAmount")) - ) { - onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; - } - }); - - if (payment_collected === "BAP" && !settlementDetailsPresent) { - onInitObj.sttlmntDtls = `Settlement details should be sent by BPP in payments/tags when BAP is collecting the payment`; - } - if (!buyerFinderFeePresent) { - onInitObj.sttlmntDtls = `Buyer Finder Fee should be sent by BPP in payments/tags`; - } - }); - } catch (error) { - console.log(`!!Error while checking payment object in /on_init api`, error); - } - - return onInitObj; -}; -module.exports = checkOnInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js deleted file mode 100644 index 35eef0c..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js +++ /dev/null @@ -1,174 +0,0 @@ -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils"); -const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); - -const checkOnSearch = async (data, msgIdSet) => { - const onSrchObj = {}; - let onSearch = data; - let domain = onSearch.context.domain; - onSearch = onSearch.message.catalog; - - //saving fulfillments - try { - console.log("checking attr"); - console.log(constants.ATTR_DOMAINS.includes(domain)); - } catch (error) { - console.log(error); - } - const fulfillments = onSearch?.fulfillments; - - dao.setValue("fulfillmentsArr", fulfillments); - - try { - console.log(`Saving provider items array in /on_search api`); - if (onSearch["providers"]) { - let providers = onSearch["providers"]; - dao.setValue("providersArr", providers); - providers.forEach((provider, i) => { - let itemsArr = provider.items; - const providerId = provider.id; - - dao.setValue(`${providerId}itemsArr`, itemsArr); - }); - } - } catch (error) { - console.log( - `!!Error while checking providers array in /on_search api`, - error - ); - } - - if (onSearch.hasOwnProperty("providers")) { - const providers = onSearch["providers"]; - for (let i = 0; i < providers.length; i++) { - const provider = providers[i]; - if (provider.hasOwnProperty("locations")) { - const locations = provider.locations; - for (let j = 0; j < locations.length; j++) { - const { id, gps, area_code } = locations[j]; - try { - const [lat, long] = gps.split(","); - const match = await reverseGeoCodingCheck(lat, long, area_code); - if (!match) { - onSrchObj[ - "bpp/provider:location:" + id + ":RGC" - ] = `Reverse Geocoding for location ID ${id} failed for provider with id '${provider?.id}'. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; - } - } catch (error) { - console.log("bpp/providers error: ", error); - } - } - } - - try { - console.log("Checking provider serviceability"); - - let providerTags = provider?.tags; - if (providerTags) { - providerTags.forEach((tag) => { - if (tag?.descriptor?.code === "serviceability" && tag?.list) { - mandatoryTags = constants.SERVICEABILITY; - let missingTags = utils.findMissingTags( - tag?.list, - "serviceability", - mandatoryTags - ); - if (missingTags.length > 0) { - onSrchObj.mssngTagErr = `'${missingTags}' code/s required in providers/tags for serviceability`; - } - } - }); - } else { - onSrchObj.servcbltyErr = - "serviceability tag is required for a provider in providers/tags"; - } - } catch (error) { - console.log(error); - } - - try { - console.log("Checking item tags"); - let items = provider?.items; - items.forEach((item) => { - let itemTags = item?.tags; - if (itemTags) { - itemTags.forEach((tag) => { - if (tag?.descriptor?.code === "reschedule_terms" && tag?.list) { - mandatoryTags = constants.RESCHEDULE_TERMS; - let missingTags = utils.findMissingTags( - tag?.list, - "reschedule_terms", - mandatoryTags - ); - if (missingTags.length > 0) { - onSrchObj.mssngRescdlTagErr = `'${missingTags}' code/s required in providers/tags for ${tag?.descriptor?.code}`; - } - } - }); - } else { - onSrchObj.reschdlTrmErr = `reschedule_terms tag is required for an item in items/tags`; - } - }); - } catch (error) { - console.log(error); - } - //checking mandatory attributes for fashion and electronics - - // provider.items.forEach((item) => { - // let itemTags = item?.tags; - // let mandatoryAttr = []; - // let attrPresent = false; - // let missingAttr = []; - - // itemTags.forEach((tag) => { - // let { descriptor, list } = tag; - // if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { - - // if (domain === "ONDC:RET12") { - // mandatoryAttr = constants.FASHION_ATTRIBUTES; - // } - // if (domain === "ONDC:RET14") { - // mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; - // } - // if (domain === "ONDC:RET12") { - // mandatoryAttr = constants.FASHION_ATTRIBUTES; - // } - // if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { - // mandatoryAttr = constants.MANDATORY_ATTRIBUTES; - // } - // attrPresent = true; - // missingAttr = utils.findMissingTags( - // list, - // descriptor.code, - // mandatoryAttr - // ); - - // if (missingAttr.length > 0) { - // onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; - // } - // } - // if (descriptor?.code === "g2") { - // mandatoryAttr = constants.G2TAGS; - // missingAttr = utils.findMissingTags( - // list, - // descriptor.code, - // mandatoryAttr - // ); - - // if (missingAttr.length > 0) { - // onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; - // } - // } - // }); - // if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { - // onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; - // } - // }); - } - } - - return onSrchObj; -}; -module.exports = checkOnSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js deleted file mode 100644 index 9b76377..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js +++ /dev/null @@ -1,82 +0,0 @@ -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils"); - -const checkOnSelect = async (data, msgIdSet) => { - const onSelectObj = {}; - let onSelect = data; - onSelect = onSelect.message.order; - let quote = onSelect?.quote; - const items = onSelect.items; - let fulfillments = onSelect?.fulfillments; - let ffState, ffId; - dao.setValue("onSlctdItemsArray", items); - const selectedItems = dao.getValue("slctdItemsArray"); - try { - console.log("Checking fulfillment object in /on_select"); - if (fulfillments) { - fulfillments.forEach((fulfillment) => { - ffId = fulfillment?.id; - ffState = fulfillment?.state?.descriptor?.code; - }); - } - - if (ffState === "Non-serviceable" && !data.error) { - onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; - } - } catch (error) { - console.log(error); - } - - try { - console.log("Comparing items object with /select"); - const itemDiff = utils.findDifferencesInArrays(items, selectedItems); - - itemDiff.forEach((item, i) => { - let index = item.attributes.indexOf("fulfillment_ids"); - if (index !== -1) { - item.attributes.splice(index, 1); - } - if (item.attributes?.length > 0) { - let itemkey = `item-${i}-DiffErr`; - onSelectObj[ - itemkey - ] = `In /items, '${item.attributes}' mismatch from /select for item with id ${item.index}`; - } - }); - } catch (error) { - console.log(error); - } - - try { - console.log( - "Comparing fulfillment_ids in /items and /fulfillments in /on_select" - ); - items.forEach((item) => { - let fulfillment_ids = item.fulfillment_ids; - let fulfillmentSet = new Set(); - - for (let fulfillment of fulfillments) { - fulfillmentSet.add(fulfillment.id); - } - - let missingIds = []; - - for (let id of fulfillment_ids) { - if (!fulfillmentSet.has(id)) { - missingIds.push(id); - } - } - - if (missingIds.length > 0) { - onSelectObj.missingFlmntIds = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; - } - }); - } catch (error) { - console.log(error); - } - - return onSelectObj; -}; -module.exports = checkOnSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js deleted file mode 100644 index 55ad3dd..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js +++ /dev/null @@ -1,177 +0,0 @@ -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils.js"); - -const checkOnStatus = (data, msgIdSet) => { - let onStatusObj = {}; - let on_status = data; - let contextTime = on_status.context.timestamp; - let messageId = on_status.context.message_id; - - on_status = on_status.message.order; - let ffState; - let orderState = on_status.state; - let items = on_status.items; - let fulfillments = on_status.fulfillments; - let pickupTime, deliveryTime; - let payments = on_status?.payments; - let invoice = on_status?.documents; - - try { - console.log(`Checking payment object in /on_status`); - payments.forEach((payment) => { - let paymentStatus = payment?.status; - let paymentType = payment?.type; - let params = payment?.params; - - if (paymentStatus === "PAID" && !params?.transaction_id) { - onStatusObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; - } - if (paymentStatus === "NOT-PAID" && params?.transaction_id) { - onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; - } - if ( - paymentType === "ON-FULFILLMENT" && - orderState != "Completed" && - paymentStatus === "PAID" - ) { - onStatusObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; - } - }); - } catch (error) { - console.log(error); - } - - try { - fulfillments.forEach((fulfillment) => { - ffState = fulfillment?.state?.descriptor?.code; - console.log( - `Comparing pickup and delivery timestamps for on_status_${ffState}` - ); - //Pending,Packed,Agent-assigned - if (fulfillment.type === "Home-Service") { - if ( - ffState === "Pending" - ) { - - fulfillment.stops.forEach((stop) => { - if (stop.type === "start") { - if (stop?.time?.timestamp) { - onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot be provided for fulfillment state - ${ffState}`; - } - } - - if (stop.type === "end") { - if (stop?.time?.timestamp) { - onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; - } - } - }); - // if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up for Non RFQ Flow.` - } - //In transit - - if (ffState === "In-Transit") { - - if (orderState !== "In-progress") { - onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; - } - fulfillment.stops.forEach((stop) => { - if (stop.type === "start") { - pickupTime = stop?.time?.timestamp; - dao.setValue("pickupTime", pickupTime); - if (!pickupTime) { - onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; - } - - if (_.gt(pickupTime, contextTime)) { - onStatusObj.tmstmpErr = `fulfillments/start/time/timestamp cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; - } - } - - if (stop.type === "end") { - if (stop?.time?.timestamp) { - onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; - } - } - }); - if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required` - } - - //At-Location - if (ffState === "At-Location") { - - if (orderState !== "In-progress") { - onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; - } - fulfillment.stops.forEach((stop) => { - if (stop.type === "start") { - pickupTime = stop?.time?.timestamp; - - if (!pickupTime) { - onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; - } else if ( - dao.getValue("pickupTime") && - pickupTime !== dao.getValue("pickupTime") - ) { - onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot change for fulfillment state - ${ffState}`; - } - } - - if (stop.type === "end") { - if (stop?.time?.timestamp) { - onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; - } - } - }); - if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required` - } - - //Completed - if (ffState === "Completed") { - - if (orderState !== "Completed") { - onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; - } - fulfillment.stops.forEach((stop) => { - if (stop.type === "start") { - pickupTime = stop?.time?.timestamp; - if (!pickupTime) { - onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; - } else if ( - dao.getValue("pickupTime") && - pickupTime !== dao.getValue("pickupTime") - ) { - onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot change for fulfillment state - ${ffState}`; - } - } - - if (stop.type === "end") { - deliveryTime = stop?.time?.timestamp; - dao.setValue("deliveryTime", deliveryTime); - - if (!deliveryTime) { - onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp is required for fulfillment state - ${ffState}`; - } - if (_.gt(deliveryTime, contextTime)) { - onStatusObj.tmstmpErr = `fulfillments/end/time/timestamp cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; - } - if (_.gte(pickupTime, deliveryTime)) { - onStatusObj.tmstmpErr = `fulfillments/start/time/timestamp cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; - } - } - }); - if(!invoice) onStatusObj.invoiceErr=`/documents (Invoice) is required` - } - } - - }); - } catch (error) { - console.log(`Error checking fulfillments/start in /on_status`); - } - console.log(onStatusObj); - return onStatusObj; -}; - -module.exports = checkOnStatus; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js deleted file mode 100644 index ebe216e..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js +++ /dev/null @@ -1,78 +0,0 @@ -const _ = require("lodash"); -const fs = require("fs"); -const path = require("path"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils.js"); -const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); - -const checkSearch = async (data, msgIdSet) => { - let srchObj = {}; - let search = data; - let contextTime = search.context.timestamp; - search = search.message.intent; - - try { - console.log("Checking buyer app finder fee in /search"); - - search.tags.forEach((tag) => { - if (tag?.descriptor?.code === "BAP_Terms" && tag?.list) { - tag.list.forEach((val) => { - if (val?.descriptor?.code === "finder_fee_type") { - dao.setValue("buyerFinderFeeType", val?.value); - } - if (val?.descriptor?.code === "finder_fee_amount") { - dao.setValue("buyerFinderFeeAmount", val?.value); - } - }); - } - }); - } catch (error) { - console.log(error); - } - - const stops = data?.message?.intent?.fulfillment?.stops; - let endLocation; - stops.forEach((stop) => { - if (stop.type === "end") { - endLocation = stop?.location; - } - }); - - if (endLocation) { - console.log( - "Checking Reverse Geocoding for `end` location in `fullfilment`" - ); - try { - const [lat, long] = endLocation?.gps.split(","); - const area_code = endLocation?.area_code; - const match = await reverseGeoCodingCheck(lat, long, area_code); - if (!match) - srchObj[ - "RGC-end-Err" - ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; - } catch (error) { - console.log("Error in end location", error); - } - - // check for context cityCode and fulfillment end location - try { - const pinToStd = JSON.parse( - fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") - ); - const stdCode = data.context?.location?.city?.code.split(":")[1]; - const area_code = endLocation?.area_code; - if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { - srchObj[ - "CityCode-Err" - ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; - } - } catch (err) { - console.error("Error in city code check: ", err.message); - } - } - dao.setValue("searchObj", search); - return srchObj; -}; - -module.exports = checkSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js deleted file mode 100644 index eb4c7f2..0000000 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js +++ /dev/null @@ -1,134 +0,0 @@ -const _ = require("lodash"); -const dao = require("../../dao/dao"); -const constants = require("../constants"); -const utils = require("../utils"); - -const checkSelect = async (data, msgIdSet) => { - const selectObj = {}; - let select = data; - select = select.message.order; - let fulfillments = select?.fulfillments; - let providersArr = dao.getValue("providersArr"); - let fulfillmentsArr = dao.getValue("fulfillmentsArr"); - let itemsArr = select.items; - dao.setValue("slctdItemsArray",itemsArr) - - // provider check - try { - console.log(`Comparing provider object in /select and /on_search`); - if (select.provider) { - onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); - let providerObj = providersArr?.filter( - (prov) => prov.id === select.provider.id - ); - if (!providerObj || providerObj?.length < 1) { - selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; - } else { - if ( - (!select?.provider?.locations || - select?.provider?.locations?.length < 1) && - providerObj[0]?.locations?.length > 1 - ) { - selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; - } else if (select?.provider?.locations) { - let providerLocArr = select.provider.locations; - let providerLocExists = false; - providerLocArr.forEach((location, i) => { - providerObj[0]?.locations?.forEach((element) => { - console.log(location.id, element.id); - - if (location.id === element.id) providerLocExists = true; - }); - - if (!providerLocExists) { - let itemkey = `providerLocErr${i}`; - selectObj[ - itemkey - ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; - } - providerLocExists = false; - }); - } - } - } - } catch (error) { - console.log( - `!!Error while checking provider object in /${constants.LOG_select}`, - error - ); - } - - //item check - try { - console.log(`Comparing item object in /select and /on_search`); - - itemsArr?.forEach((item, i) => { - let itemExists = false; - onSearchitemsArr?.forEach((element) => { - if (item.id === element.id) itemExists = true; - }); - if (!itemExists) { - let itemkey = `itemErr${i}`; - selectObj[ - itemkey - ] = `Item Id '${item.id}' does not exist in /on_search`; - } else { - let itemObj = onSearchitemsArr.filter( - (element) => element.id === item.id - ); - - itemObj = itemObj[0]; - // dao.setValue("selectedItem", itemObj.id); - console.log(itemObj.id); - if ( - !_.every(item.fulfillment_ids, (element) => - _.includes(itemObj.fulfillment_ids, element) - ) - ) { - let itemkey = `flflmntIdErr${i}`; - selectObj[ - itemkey - ] = `Fulfillment ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; - } - if ( - !_.every(item.location_ids, (element) => - _.includes(itemObj.location_ids, element) - ) - ) { - let itemkey = `lctnIdErr${i}`; - selectObj[ - itemkey - ] = `Location ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; - } - - if ( - item.parent_item_id!==itemObj.parent_item_id - ) { - let itemkey = `parentItmIdErr${i}`; - selectObj[ - itemkey - ] = `Parent item id ${item.parent_item_id} for item with id '${item.id}' does not match with the catalog provided in /on_search`; - } - - //checking fulfillments - fulfillments.forEach((fulfillment, i) => { - let bppfulfillment = fulfillmentsArr?.find( - (element) => element.type === fulfillment.type - ); - if (!bppfulfillment) { - let itemkey = `flfillmentIDerr${i}`; - selectObj[ - itemkey - ] = `Fulfillment of type '${fulfillment.type}' does not match with the catalog provided in /on_search`; - } - }); - } - }); - } catch (error) { - console.log(error); - } - - return selectObj; -}; -module.exports = checkSelect; - \ No newline at end of file From eff0f6cb6903350e2bd875dcf52f5bc0cf901531 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 22 Mar 2024 16:53:32 +0530 Subject: [PATCH 187/228] updated services schemas --- .../schema/SRV_json_schema/v2/confirm.js | 2 +- .../schema/SRV_json_schema/v2/on_cancel.js | 2 +- .../schema/SRV_json_schema/v2/on_confirm.js | 2 +- .../schema/SRV_json_schema/v2/on_init.js | 2 +- .../schema/SRV_json_schema/v2/on_select.js | 2 +- .../schema/SRV_json_schema/v2/on_status.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js index 7d21db8..5e242ca 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js @@ -412,7 +412,7 @@ module.exports = { type: "object", properties: { count: { - type: "string", + type: "integer", }, }, required: ["count"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js index 343f8b7..8d193ed 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js @@ -453,7 +453,7 @@ module.exports = { type: "object", properties: { count: { - type: "string", + type: "integer", }, }, required: ["count"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js index 5570352..eabb063 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -445,7 +445,7 @@ module.exports = { type: "object", properties: { count: { - type: "string", + type: "integer", }, }, required: ["count"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js index 9776bee..94284e9 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js @@ -423,7 +423,7 @@ module.exports = { type: "object", properties: { count: { - type: "string", + type: "integer", }, }, required: ["count"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js index 4c3fe3d..36a4138 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js @@ -350,7 +350,7 @@ module.exports = { type: "object", properties: { count: { - type: "string", + type: "integer", }, }, required: ["count"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js index 24a7e8b..5de177f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js @@ -430,7 +430,7 @@ module.exports = { type: "object", properties: { count: { - type: "string", + type: "integer", }, }, required: ["count"], From bbe246d07a45b54e4f3f09f723060a0c288fce28 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 27 Mar 2024 14:33:56 +0530 Subject: [PATCH 188/228] added vals --- .../SRV_json_schema/keywords/confirm.js | 13 + .../schema/SRV_json_schema/keywords/init.js | 7 + .../schema/SRV_json_schema/keywords/onInit.js | 16 + .../schema/SRV_json_schema/keywords/search.js | 7 + .../schema/SRV_json_schema/schemaValidator.js | 126 +++ .../schema/SRV_json_schema/v2/cancel.js | 95 ++ .../schema/SRV_json_schema/v2/confirm.js | 594 +++++++++++ .../schema/SRV_json_schema/v2/init.js | 367 +++++++ .../schema/SRV_json_schema/v2/master.js | 91 ++ .../schema/SRV_json_schema/v2/on_cancel.js | 654 ++++++++++++ .../schema/SRV_json_schema/v2/on_confirm.js | 676 +++++++++++++ .../schema/SRV_json_schema/v2/on_init.js | 616 ++++++++++++ .../schema/SRV_json_schema/v2/on_search.js | 929 ++++++++++++++++++ .../schema/SRV_json_schema/v2/on_select.js | 462 +++++++++ .../schema/SRV_json_schema/v2/on_status.js | 649 ++++++++++++ .../schema/SRV_json_schema/v2/on_update.js | 508 ++++++++++ .../schema/SRV_json_schema/v2/search.js | 236 +++++ .../schema/SRV_json_schema/v2/select.js | 226 +++++ .../schema/SRV_json_schema/v2/status.js | 109 ++ .../schema/SRV_json_schema/v2/update.js | 505 ++++++++++ .../v1.2/onConfirmSchema.js | 208 +++- .../v1.2/onUpdateSchema.js | 189 +++- .../v1.2/updateSchema.js | 181 +++- .../utils/logistics/logOnCancel.js | 35 +- .../utils/logistics/logOnConfirm.js | 5 + .../utils/services/msgValidator.js | 52 + .../utils/services/pinToStd.json | 1 + .../utils/services/srvConfirm.js | 87 ++ .../utils/services/srvOnInit.js | 68 ++ .../utils/services/srvOnSearch.js | 174 ++++ .../utils/services/srvOnSelect.js | 82 ++ .../utils/services/srvOnStatus.js | 177 ++++ .../utils/services/srvSearch.js | 78 ++ .../utils/services/srvSelect.js | 134 +++ 34 files changed, 8321 insertions(+), 36 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js create mode 100644 utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js new file mode 100644 index 0000000..5e7963a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/confirm.js @@ -0,0 +1,13 @@ +module.exports = { + isFutureDated: (data) => { + const contextTime = data?.context?.timestamp; + const created_at = data?.message?.order?.created_at; + const updated_at = data?.message?.order?.updated_at; + if ( + (created_at && created_at > contextTime) || + (updated_at && updated_at > contextTime) + ) + return false; + return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js new file mode 100644 index 0000000..8f448e9 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/init.js @@ -0,0 +1,7 @@ +module.exports = { + isLengthValid: (data) => { + if (data?.name?.length + data?.building?.length + data?.locality?.length > 190) + return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js new file mode 100644 index 0000000..380b690 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/onInit.js @@ -0,0 +1,16 @@ +module.exports = { + isQuoteMatching: (data) => { + let quotePrice = parseFloat(data?.price?.value); + const breakupArr = data?.breakup; + let totalBreakup = 0; + breakupArr.forEach((breakup) => { + totalBreakup += parseFloat(breakup?.price?.value); + + }); + totalBreakup= parseFloat(totalBreakup).toFixed(2) + console.log(totalBreakup,quotePrice); + quotePrice=quotePrice.toFixed(2) + if (quotePrice != totalBreakup) return false; + else return true; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js new file mode 100644 index 0000000..7a14c5b --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/keywords/search.js @@ -0,0 +1,7 @@ +module.exports = { + isEndTimeGreater: (data) => { + const startTime = parseInt(data?.start); + const endTime = parseInt(data?.end); + return startTime < endTime; + }, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js new file mode 100644 index 0000000..006e2c8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/schemaValidator.js @@ -0,0 +1,126 @@ + +const { isLengthValid } = require("./keywords/init"); +const { isQuoteMatching } = require("./keywords/onInit"); +const { isFutureDated } = require("./keywords/confirm"); +const { isEndTimeGreater } = require("./keywords/search"); + +const fs = require("fs"); +//const async = require("async"); +const path = require("path"); + +const formatted_error = (errors) => { + error_list = []; + let status = ""; + errors.forEach((error) => { + error_dict = { + message: `${error.message}${ + error.params.allowedValues ? ` (${error.params.allowedValues})` : "" + }${error.params.allowedValue ? ` (${error.params.allowedValue})` : ""}${ + error.params.additionalProperty + ? ` (${error.params.additionalProperty})` + : "" + }`, + details: error.instancePath, + }; + error_list.push(error_dict); + }); + if (error_list.length === 0) status = "pass"; + else status = "fail"; + error_json = { errors: error_list, status: status }; + return error_json; +}; + +const loadSchema = (schemaType, version) => { + try { + return require(`./${version}/${schemaType}.js`); + } catch (error) { + console.log("Error Occurred while importing", error); + } +}; + +const validate_schema = (data, schema,version) => { + const searchSchema = loadSchema("search", version); + const onSearchSchema = loadSchema("on_search", version); + + const selectSchema = loadSchema("select", version); + const onSelectSchema = loadSchema("on_select", version); + + const initSchema = loadSchema("init", version); + const onInitSchema = loadSchema("on_init", version); + + const confirmSchema = loadSchema("confirm", version); + const onConfirmSchema = loadSchema("on_confirm", version); + + const updateSchema = loadSchema("update", version); + const onUpdateSchema = loadSchema("on_update", version); + + const statusSchema = loadSchema("status", version); + const onStatusSchema = loadSchema("on_status", version); + + const cancelSchema = loadSchema("cancel", version); + const onCancelSchema = loadSchema("on_cancel", version); + + const Ajv = require("ajv"); + const ajv = new Ajv({ + allErrors: true, + strict: false, + strictRequired: false, + strictTypes: false, + $data: true, + }); + const addFormats = require("ajv-formats"); + + addFormats(ajv); + require("ajv-errors")(ajv); + let error_list = []; + try { + validate = ajv + .addSchema(searchSchema) + .addSchema(onSearchSchema) + .addSchema(selectSchema) + .addSchema(onSelectSchema) + .addSchema(initSchema) + .addSchema(onInitSchema) + .addSchema(confirmSchema) + .addSchema(onConfirmSchema) + .addSchema(updateSchema) + .addSchema(onUpdateSchema) + .addSchema(statusSchema) + .addSchema(onStatusSchema) + .addSchema(cancelSchema) + .addSchema(onCancelSchema) + .addKeyword("isEndTimeGreater", { + validate: (schema, data) => isEndTimeGreater(data), + }) + .addKeyword("isQuoteMatching", { + validate: (schema, data) => isQuoteMatching(data), + }) + .addKeyword("isFutureDated", { + validate: (schema, data) => isFutureDated(data), + }) + .addKeyword("isLengthValid", { + validate: (schema, data) => isLengthValid(data), + }); + + validate = validate.compile(schema); + + const valid = validate(data); + if (!valid) { + error_list = validate.errors; + } + } catch (error) { + console.log("ERROR!! validating schema"); + console.trace(error); + } + return error_list; +}; + +const validate_schema_srv_master = (data,version) => { + const masterSchema = loadSchema("master", version); + error_list = validate_schema(data, masterSchema,version); + return formatted_error(error_list); +}; + +module.exports = { + validate_schema_srv_master, +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js new file mode 100644 index 0000000..ffa00b6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/cancel.js @@ -0,0 +1,95 @@ +module.exports = { + $id: "http://example.com/schema/cancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + }, + version: { + type: "string", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + }, + cancellation_reason_id: { + type: "string", + }, + }, + required: ["order_id", "cancellation_reason_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js new file mode 100644 index 0000000..960a8ef --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js @@ -0,0 +1,594 @@ +module.exports = { + $id: "http://example.com/schema/confirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + }, + status: { + type: "string", + enum: ["Created"] + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + + }, + required: ["label", "range"], + }, + customer: { + type: "object", + properties: { + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["person"], + }, + }, + required: [ + "type", + "location", + "contact", + "time", + "customer", + ], + }, + }, + }, + required: ["id", "type", "tracking", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + }, + required: ["title", "price", "item"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + created_at: { + type: "string", + }, + updated_at: { + type: "string", + }, + xinput: { + type: "object", + properties: { + form: { + type: "object", + properties: { + url: { + type: "string", + }, + mimetype: { + type: "string", + }, + submission_id: { + type: "string", + }, + status: { + type: "string", + }, + }, + required: ["url", "mimetype", "submission_id", "status"], + }, + }, + required: ["form"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at", + "xinput", + ], + }, + }, + required: ["order"], + }, + }, + isFutureDated: true, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js new file mode 100644 index 0000000..91e3182 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js @@ -0,0 +1,367 @@ +module.exports = { + $id: "http://example.com/schema/initSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "init", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + }, + email: { + type: "string", + }, + phone: { + type: "string", + }, + }, + required: [ + "name", + "address", + "state", + "city", + "tax_id", + "email", + "phone", + ], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/id" }, + }, + type: { + type: "string", + const: { $data: "/on_select/0/message/order/fulfillments/0/type" }, + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + enum:["confirmed"] + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + + }, + required: ["label", "range"], + }, + }, + required: ["type", "location", "contact", "time"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + collected_by: { + type: "string", + const: { + $data: + "/on_select/0/message/order/payments/0/collected_by", + }, + }, + }, + required: ["type","collected_by"], + }, + }, + }, + required: [ + "provider", + "items", + "billing", + "fulfillments", + "payments", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js new file mode 100644 index 0000000..63875c5 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/master.js @@ -0,0 +1,91 @@ +module.exports = { + $id: "http://example.com/schema/masterSchema", + type: "object", + properties: { + search: { + type: "array", + items: { + $ref: "searchSchema#", + }, + }, + on_search: { + type: "array", + items: { + $ref: "onSearchSchema#", + }, + }, + select: { + type: "array", + items: { + $ref: "selectSchema#", + }, + }, + on_select: { + type: "array", + items: { + $ref: "onSelectSchema#", + }, + }, + init: { + type: "array", + items: { + $ref: "initSchema#", + }, + }, + on_init: { + type: "array", + items: { + $ref: "onInitSchema#", + }, + }, + confirm: { + type: "array", + items: { + $ref: "confirmSchema#", + }, + }, + on_confirm: { + type: "array", + items: { + $ref: "onConfirmSchema#", + }, + }, + update: { + type: "array", + items: { + $ref: "updateSchema#", + }, + }, + on_update: { + type: "array", + items: { + $ref: "onUpdateSchema#", + }, + }, + status: { + type: "array", + items: { + $ref: "statusSchema#", + }, + }, + on_status: { + type: "array", + items: { + $ref: "onStatusSchema#", + }, + }, + cancel: { + type: "array", + items: { + $ref: "cancelSchema#", + }, + }, + on_cancel: { + type: "array", + items: { + $ref: "onCancelSchema#", + }, + } + }, + }; + \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js new file mode 100644 index 0000000..4b31e31 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js @@ -0,0 +1,654 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onCancelSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_cancel", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + enum: ["Cancelled"], + }, + cancellation: { + type: "object", + properties: { + reason: { + type: "object", + properties: { + descriptor: { + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + cancelled_by: { + type: "string", + }, + }, + required: ["reason", "cancelled_by"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["Cancelled"], + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + }, + required: ["id", "type", "tracking", "state", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + + updated_at: { + type: "string", + format: "date-time", + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js new file mode 100644 index 0000000..3baf482 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -0,0 +1,676 @@ +module.exports = { + $id: "http://example.com/schema/onConfirmSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_confirm", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/confirm/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + enum: ["Created", "Accepted", "Cancelled"], + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "locations", "rateable"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "id", + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: [ + "id", + "state", + "type", + "stops", + "tracking", + "rateable", + ], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: [ + { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: [ + { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + ], + }, + }, + required: ["descriptor", "list"], + }, + ], + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + updated_at: { + type: "string", + format: "date-time", + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", + }, + xinput: { + type: "object", + properties: { + form: { + type: "object", + properties: { + url: { + type: "string", + }, + mimetype: { + type: "string", + }, + submission_id: { + type: "string", + }, + status: { + type: "string", + }, + }, + required: ["url", "mimetype", "submission_id", "status"], + }, + }, + required: ["form"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "created_at", + "updated_at" + ], + }, + }, + required: ["order"], + }, + }, + isFutureDated: true, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js new file mode 100644 index 0000000..9d34634 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js @@ -0,0 +1,616 @@ +module.exports = { + $id: "http://example.com/schema/onInitSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_init", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/init/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city", "phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "gps", + "address", + "city", + "country", + "area_code", + "state", + ], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + }, + required: ["phone"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + + }, + required: ["label", "range"], + }, + tags: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + required: ["type", "location", "contact", "time", "tags"], + }, + }, + }, + required: ["id", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + enum: ["BAP", "BPP"], + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "bank_account_number", + "virtual_payment_address", + ], + }, + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["id", "collected_by", "params", "type", "tags"], + }, + }, + xinput: { + type: "object", + properties: { + form: { + type: "object", + properties: { + url: { + type: "string", + }, + mimetype: { + type: "string", + }, + }, + required: ["url", "mimetype"], + }, + required: { + type: "boolean", + }, + }, + required: ["form", "required"], + }, + }, + required: [ + "provider", + "locations", + "items", + "billing", + "fulfillments", + "quote", + "payments" + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js new file mode 100644 index 0000000..cdc8dc8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -0,0 +1,929 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onSearchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/city/code" }, + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + const: { $data: "/search/0/context/location/country/code" }, + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_search", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/search/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/search/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/search/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/search/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + catalog: { + type: "object", + properties: { + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.SRV_FULFILLMENT_TYPE, + }, + }, + required: ["id", "type"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + enum: constants.SRV_PAYMENT_TYPE, + }, + }, + required: ["id", "type"], + }, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: ["name", "short_desc", "long_desc", "images"], + }, + providers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + rating: { + type: "string", + }, + ttl: { + type: "string", + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + frequency: { + type: "string", + }, + holidays: { + type: "array", + items: { + type: "string", + }, + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + }, + required: ["label", "schedule"], + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + code: { + type: "string", + }, + name: { + type: "string", + }, + }, + required: ["code", "name"], + }, + state: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + }, + required: [ + "id", + "gps", + "address", + "city", + "state", + "country", + "area_code", + ], + }, + }, + creds: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + desc: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["id", "type", "desc", "url"], + }, + }, + categories: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + }, + required: ["name", "code"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + media: { + type: "array", + items: { + type: "object", + properties: { + mimetype: { + type: "string", + }, + url: { + type: "string", + }, + }, + required: ["mimetype", "url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + creator: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + contact: { + type: "object", + properties: { + name: { + type: "string", + }, + address: { + type: "object", + properties: { + full: { + type: "string", + }, + }, + required: ["full"], + }, + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: [ + "name", + "address", + "phone", + "email", + ], + }, + }, + required: ["name", "contact"], + }, + }, + required: ["descriptor"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + offered_value: { + type: "string", + }, + maximum_value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + payment_ids: { + type: "array", + items: { + type: "string", + }, + }, + cancellation_terms: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + cancellation_fee: { + type: "object", + properties: { + amount: { + type: "object", + properties: { + value: { + type: "string", + }, + }, + required: ["value"], + }, + percentage: { + type: "string", + }, + }, + }, + }, + required: ["fulfillment_state", "cancellation_fee"], + }, + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + frequency: { + type: "string", + }, + holidays: { + type: "array", + items: { + type: "string", + }, + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["holidays"], + }, + }, + required: ["label", "schedule"], + }, + matched: { + type: "boolean", + }, + recommended: { + type: "boolean", + }, + }, + if: { properties: { parent_item_id: { const: "" } } }, + then: { + required: [ + "id", + "parent_item_id", + "descriptor", + "creator", + "price", + "category_ids", + "fulfillment_ids", + "location_ids", + "payment_ids", + "cancellation_terms", + "tags", + "time", + "matched", + "recommended", + ], + }, + else: { + required: [ + "id", + "parent_item_id", + "descriptor", + "price", + "quantity", + "category_ids", + "tags", + ], + }, + }, + }, + offers: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + code: { + type: "string", + }, + short_desc: { + type: "string", + }, + long_desc: { + type: "string", + }, + images: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + }, + required: ["url"], + }, + }, + }, + required: [ + "name", + "code", + "short_desc", + "long_desc", + "images", + ], + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + category_ids: { + type: "array", + items: { + type: "string", + }, + }, + item_ids: { + type: "array", + items: { + type: "string", + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "descriptor", + "location_ids", + "category_ids", + "item_ids", + "time", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + }, + required: ["contact"], + }, + }, + }, + required: [ + "id", + "descriptor", + "rating", + "ttl", + "time", + "locations", + "tags", + "items", + "fulfillments", + ], + }, + }, + }, + required: ["fulfillments", "payments", "descriptor", "providers"], + }, + }, + required: ["catalog"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js new file mode 100644 index 0000000..56b03f8 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js @@ -0,0 +1,462 @@ +module.exports = { + $id: "http://example.com/schema/onSelectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_select", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/select/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/select/0/message/order/provider/id" }, + }, + }, + required: ["id"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + id: { + type: "string", + const: { $data: "/select/0/message/order/items/0/id" }, + }, + parent_item_id: { + type: "string", + const: { $data: "/select/0/message/order/items/0/parent_item_id" }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + time: { + type: "object", + properties: { + label: { + type: "string", + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + schedule: { + type: "object", + properties: { + frequency: { + type: "string", + }, + holidays: { + type: "array", + items: { + type: "string", + }, + }, + times: { + type: "array", + items: { + type: "string", + }, + }, + }, + }, + }, + required: ["label", "schedule"], + }, + }, + required: [ + "fulfillment_ids", + "id", + "parent_item_id", + "location_ids", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["Serviceable","Non-serviceable"] + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + enum: ["confirmed","rejected"] + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["label", "range"], + }, + tags: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + required: ["type", "location", "time", "tags"], + }, + }, + }, + required: ["id", "state", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + isQuoteMatching:true, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + const: { $data: "/select/0/message/order/payments/0/type" }, + }, + collected_by: { + type: "string", + enum:["BAP","BPP"] + }, + }, + required: ["type","collected_by"], + }, + }, + }, + required: ["provider", "items", "fulfillments", "quote","payments"], + }, + }, + required: ["order"], + }, + error: { + type: "object", + properties: { + code: { + type: "string", + }, + message: { + type: "string", + }, + }, + required: ["code", "message"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js new file mode 100644 index 0000000..f3f3c2a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js @@ -0,0 +1,649 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/onStatusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_status", + }, + version: { + type: "string", + const: "2.0.0", + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + enum: constants.SRV_ORDER_STATE, + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["selected", "measure"], + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "quantity", + ], + }, + }, + billing: { + type: "object", + properties: { + name: { + type: "string", + const: { $data: "/init/0/message/order/billing/name" }, + }, + address: { + type: "string", + const: { $data: "/init/0/message/order/billing/address" }, + }, + state: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/state/name", + }, + }, + }, + required: ["name"], + }, + city: { + type: "object", + properties: { + name: { + type: "string", + const: { + $data: "/init/0/message/order/billing/city/name", + }, + }, + }, + required: ["name"], + }, + tax_id: { + type: "string", + const: { $data: "/init/0/message/order/billing/tax_id" }, + }, + email: { + type: "string", + const: { $data: "/init/0/message/order/billing/email" }, + }, + phone: { + type: "string", + const: { $data: "/init/0/message/order/billing/phone" }, + }, + }, + + required: ["name", "address", "state", "city","phone"], + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: constants.SRV_FULFILLMENT_STATE, + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + address: { + type: "string", + }, + city: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + area_code: { + type: "string", + }, + state: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + timestamp: { + type: "string", + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + }, + required: ["id", "type", "tracking", "state", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "quantity", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + documents: { + type: "array", + items: { + type: "object", + properties: { + url: { + type: "string", + }, + label: { + type: "string", + }, + }, + required: ["url", "label"], + }, + }, + + created_at: { + type: "string", + format: "date-time", + const: { $data: "/confirm/0/message/order/created_at" }, + errorMessage: + "should remain same as in /confirm - ${/confirm/0/message/order/created_at}", + }, + + updated_at: { + type: "string", + format: "date-time", + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "billing", + "fulfillments", + "quote", + "payments", + "documents", + "created_at", + "updated_at", + ], + }, + }, + required: ["order"], + }, + }, + isFutureDated: true, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js new file mode 100644 index 0000000..b217a7a --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js @@ -0,0 +1,508 @@ +module.exports = { + $id: "http://example.com/schema/onUpdateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "on_update", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + const: { $data: "/update/0/context/message_id" }, + errorMessage: + "Message ID for on_action API should be same as action API: ${/select/0/context/message_id}", + }, + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + status: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "location_ids", + ], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + "transaction_id", + "bank_account_number", + "virtual_payment_address", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + }, + required: ["id", "descriptor", "gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone", "email"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "state", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "payments", + "fulfillments", + "quote", + ], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js new file mode 100644 index 0000000..25333cc --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js @@ -0,0 +1,236 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/searchSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "search", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + intent: { + type: "object", + properties: { + item: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + }, + category: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + fulfillment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.SRV_FULFILLMENT_TYPE + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + const: "end" + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + pattern: constants.GPS_PATTERN, + errorMessage: "Incorrect gps value (minimum of six decimal places are required)" + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + format: "date-time" + }, + end: { + type: "string", + format: "date-time" + }, + }, + required: ["start", "end"], + }, + days: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["range"], + }, + }, + required: ["type", "location"], + }, + }, + }, + required: ["type", "stops"], + }, + payment: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.SRV_PAYMENT_TYPE + }, + collected_by: { + type: "string", + enum: constants.PAYMENT_COLLECTEDBY + }, + }, + required: ["type", "collected_by"], + }, + tags: { + type: "array", + minItems: 1, + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum: ["BAP_Terms"] + }, + }, + required: ["code"], + }, + list: { + type: "array", + minItems: 2, + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + enum:["finder_fee_type","finder_fee_amount"] + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ "fulfillment", "payment", "tags"], + }, + }, + required: ["intent"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js new file mode 100644 index 0000000..61b45eb --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js @@ -0,0 +1,226 @@ +const constants = require("../../../utils/constants"); + +module.exports = { + $id: "http://example.com/schema/selectSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "select", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order: { + type: "object", + properties: { + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["id", "parent_item_id", "location_ids"], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + gps: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + required: ["gps", "area_code"], + }, + time: { + type: "object", + properties: { + label: { + type: "string", + const: "selected" + }, + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + days: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: ["label", "range"], + }, + }, + required: ["type", "location","time"], + }, + }, + }, + required: ["stops"], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + enum: constants.SRV_PAYMENT_TYPE + }, + }, + required: ["type"], + }, + }, + }, + required: ["provider", "items", "fulfillments", "payments"], + }, + }, + required: ["order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js new file mode 100644 index 0000000..a298aff --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/status.js @@ -0,0 +1,109 @@ +module.exports = { + $id: "http://example.com/schema/statusSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "status", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + order_id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + }, + required: ["order_id"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js new file mode 100644 index 0000000..54e0bf6 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/update.js @@ -0,0 +1,505 @@ +module.exports = { + $id: "http://example.com/schema/updateSchema", + type: "object", + properties: { + context: { + type: "object", + properties: { + domain: { + type: "string", + }, + location: { + type: "object", + properties: { + city: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + country: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["city", "country"], + }, + action: { + type: "string", + const: "update", + }, + version: { + type: "string", + const: "2.0.0" + }, + bap_id: { + type: "string", + }, + bap_uri: { + type: "string", + }, + bpp_id: { + type: "string", + }, + bpp_uri: { + type: "string", + }, + transaction_id: { + type: "string", + const: { $data: "/select/0/context/transaction_id" }, + errorMessage: + "Transaction ID should be same across the transaction: ${/select/0/context/transaction_id}", + }, + message_id: { + type: "string", + allOf: [ + { + not: { + const: { $data: "1/transaction_id" }, + }, + errorMessage: + "Message ID should not be equal to transaction_id: ${1/transaction_id}", + }, + ], + }, + timestamp: { + type: "string", + format: "date-time", + }, + ttl: { + type: "string", + const: "PT30S" + }, + }, + required: [ + "domain", + "location", + "action", + "version", + "bap_id", + "bap_uri", + "bpp_id", + "bpp_uri", + "transaction_id", + "message_id", + "timestamp", + "ttl", + ], + }, + message: { + type: "object", + properties: { + update_target: { + type: "string", + enum: ["payments","fulfillments"] + }, + order: { + type: "object", + properties: { + id: { + type: "string", + const: { $data: "/confirm/0/message/order/id" }, + }, + state: { + type: "string", + }, + provider: { + type: "object", + properties: { + id: { + type: "string", + }, + locations: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + }, + required: ["id"], + }, + }, + }, + required: ["id", "locations"], + }, + items: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + parent_item_id: { + type: "string", + }, + fulfillment_ids: { + type: "array", + items: { + type: "string", + }, + }, + location_ids: { + type: "array", + items: { + type: "string", + }, + }, + }, + required: [ + "id", + "parent_item_id", + "fulfillment_ids", + "location_ids", + ], + }, + }, + payments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + collected_by: { + type: "string", + }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + transaction_id: { + type: "string", + }, + bank_account_number: { + type: "string", + }, + virtual_payment_address: { + type: "string", + }, + }, + required: [ + "amount", + "currency", + ], + }, + status: { + type: "string", + }, + type: { + type: "string", + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: [ + "id", + "collected_by", + "params", + "status", + "type", + "tags", + ], + }, + }, + fulfillments: { + type: "array", + items: { + type: "object", + properties: { + id: { + type: "string", + }, + state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + type: { + type: "string", + }, + tracking: { + type: "boolean", + }, + stops: { + type: "array", + items: { + type: "object", + properties: { + type: { + type: "string", + }, + location: { + type: "object", + properties: { + id: { + type: "string", + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + gps: { + type: "string", + }, + }, + required: ["gps"], + }, + time: { + type: "object", + properties: { + range: { + type: "object", + properties: { + start: { + type: "string", + }, + end: { + type: "string", + }, + }, + required: ["start", "end"], + }, + }, + required: ["range"], + }, + contact: { + type: "object", + properties: { + phone: { + type: "string", + }, + email: { + type: "string", + }, + }, + required: ["phone"], + }, + instructions: { + type: "object", + properties: { + name: { + type: "string", + }, + short_desc: { + type: "string", + }, + }, + required: ["name", "short_desc"], + }, + person: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + }, + required: [ + "type", + "location", + "time", + "contact", + "person", + ], + }, + }, + rateable: { + type: "boolean", + }, + }, + required: ["id", "state", "type", "stops"], + }, + }, + quote: { + type: "object", + properties: { + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + breakup: { + type: "array", + items: { + type: "object", + properties: { + title: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + item: { + type: "object", + properties: { + id: { + type: "string", + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: ["id", "price"], + }, + tags: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + list: { + type: "array", + items: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + value: { + type: "string", + }, + }, + required: ["descriptor", "value"], + }, + }, + }, + required: ["descriptor", "list"], + }, + }, + }, + required: ["title", "price", "item", "tags"], + }, + }, + ttl: { + type: "string", + }, + }, + required: ["price", "breakup", "ttl"], + }, + }, + required: [ + "id", + "status", + "provider", + "items", + "payments", + "fulfillments", + "quote", + ], + }, + }, + required: ["update_target", "order"], + }, + }, + required: ["context", "message"], +}; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index 2def77a..f7e7d48 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -214,7 +214,7 @@ module.exports = { required: ["label", "duration", "timestamp"], }, }, - required: ["id", "category_id", "descriptor","fulfillment_id"], + required: ["id", "category_id", "descriptor", "fulfillment_id"], }, }, quote: { @@ -465,6 +465,9 @@ module.exports = { time: { type: "object", properties: { + duration: { + type: "string", + }, range: { type: "object", properties: { @@ -594,8 +597,13 @@ module.exports = { properties: { short_desc: { type: "string", - not: { const: { $data: "3/start/instructions/short_desc" } }, - errorMessage: "cannot be same as PCC - ${3/start/instructions/short_desc}" + not: { + const: { + $data: "3/start/instructions/short_desc", + }, + }, + errorMessage: + "cannot be same as PCC - ${3/start/instructions/short_desc}", }, long_desc: { type: "string", @@ -872,14 +880,191 @@ module.exports = { ], }, "@ondc/org/linked_order": { - allOf: [ - { - $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + type: "object", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + category_id: { + type: "string", + enum: constants.CATEGORIES, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["count", "measure"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "category_id", + "descriptor", + "quantity", + "price", + ], + }, }, - { - $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + provider: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + + required: [ + "name", + "locality", + "city", + "state", + "area_code", + ], + }, + }, + required: ["descriptor", "address"], }, - ], + order: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/confirm/0/message/order/@ondc~1org~1linked_order/order/id", + }, + }, + weight: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + const: { + $data: + "/confirm/0/message/order/@ondc~1org~1linked_order/order/weight/value", + }, + errorMessage: + "Payload weight mismatches from /search", + }, + }, + required: ["unit", "value"], + }, + dimensions: { + type: "object", + properties: { + length: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + breadth: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + height: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["length", "breadth", "height"], + }, + }, + required: ["id", "weight"], + }, + }, + required: ["items", "provider", "order"], }, created_at: { type: "string", @@ -890,10 +1075,9 @@ module.exports = { }, updated_at: { type: "string", - not:{const: { $data: "/confirm/0/message/order/created_at" }}, - errorMessage:"should not be same as 'created_at'" + not: { const: { $data: "/confirm/0/message/order/created_at" } }, + errorMessage: "should not be same as 'created_at'", }, - }, required: [ "id", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index 55d31d2..3fbd07b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -464,14 +464,191 @@ module.exports = { ], }, "@ondc/org/linked_order": { - allOf: [ - { - $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + type: "object", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + category_id: { + type: "string", + enum: constants.CATEGORIES, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["count", "measure"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "category_id", + "descriptor", + "quantity", + "price", + ], + }, }, - { - $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + provider: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + address: { + type: "object", + properties: { + name: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + + required: [ + "name", + "locality", + "city", + "state", + "area_code", + ], + }, + }, + required: ["descriptor", "address"], }, - ], + order: { + type: "object", + properties: { + id: { + type: "string", + const: { + $data: + "/update/0/message/order/@ondc~1org~1linked_order/order/id", + }, + }, + weight: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + const: { + $data: + "/update/0/message/order/@ondc~1org~1linked_order/order/weight/value", + }, + errorMessage: + "Payload weight mismatches from /update", + }, + }, + required: ["unit", "value"], + }, + dimensions: { + type: "object", + properties: { + length: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + breadth: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + height: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["length", "breadth", "height"], + }, + }, + required: ["id", "weight"], + }, + }, + required: ["items", "provider", "order"], }, created_at: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 13962f6..4701275 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -4,6 +4,7 @@ const { FULFILLMENT_TAGS_LIST_CODE, FULFILLMENT_TAGS_LIST_VALUE, } = require("../../../utils/constants"); +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/updateSchema", type: "object", @@ -310,21 +311,181 @@ module.exports = { }, }, "@ondc/org/linked_order": { - allOf: [ - { - $merge: { - source: { - $ref: "confirmSchema#/properties/message/properties/order/properties/@ondc~1org~1linked_order", + type: "object", + properties: { + items: { + type: "array", + items: { + type: "object", + properties: { + category_id: { + type: "string", + enum: constants.CATEGORIES, + }, + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], + }, + quantity: { + type: "object", + properties: { + count: { + type: "integer", + }, + measure: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["count", "measure"], + }, + price: { + type: "object", + properties: { + currency: { + type: "string", + }, + value: { + type: "string", + }, + }, + required: ["currency", "value"], + }, + }, + required: [ + "category_id", + "descriptor", + "quantity", + "price", + ], + }, + }, + provider: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + name: { + type: "string", + }, + }, + required: ["name"], }, - with: { - required: ["items", "order"], + address: { + type: "object", + properties: { + name: { + type: "string", + }, + locality: { + type: "string", + }, + city: { + type: "string", + }, + state: { + type: "string", + }, + area_code: { + type: "string", + }, + }, + + required: [ + "name", + "locality", + "city", + "state", + "area_code", + ], }, }, + required: ["descriptor", "address"], }, - { - $data: "/confirm/0/message/order/@ondc~1org~1linked_order", + order: { + type: "object", + properties: { + id: { + type: "string", + }, + weight: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_WEIGHT, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + dimensions: { + type: "object", + properties: { + length: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + breadth: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + height: { + type: "object", + properties: { + unit: { + type: "string", + enum: constants.UNITS_DIMENSIONS, + }, + value: { + type: "number", + }, + }, + required: ["unit", "value"], + }, + }, + required: ["length", "breadth", "height"], + }, + }, + required: ["id", "weight"], }, - ], + }, + required: ["items", "provider", "order"], }, updated_at: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index 1d1624b..a0ac04c 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -46,7 +46,7 @@ const checkOnCancel = (data, msgIdSet) => { } if (onSearchItemsArr) { - selectedItem = onSearchItemsArr.filter( + selectedItem = onSearchItemsArr.filter( (element) => element?.parent_item_id === dao.getValue("selectedItem") ); selectedItem = selectedItem[0]; @@ -100,9 +100,9 @@ const checkOnCancel = (data, msgIdSet) => { } let fulTags = fulfillment?.tags; if (!fulTags) { - onCancelObj.msngflfllmntTags = `fulfillments/tags are required in case of RTO (rto_event, pre_cancel_state)`; + onCancelObj.msngflfllmntTags = `fulfillments/tags are required in case of RTO (rto_event, precancel_state)`; } else { - let rtoID; + let rtoID, reasonId,preCnclState; fulTags.forEach((tag) => { if (tag.code === "rto_event") { @@ -111,8 +111,27 @@ const checkOnCancel = (data, msgIdSet) => { if (list.code === "rto_id") { rtoID = list.value; - if (rtoID !== selectedItem.fulfillment_id) { - onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; + if (rtoID !== selectedItem?.fulfillment_id) { + onCancelObj.rtoIdTagsErr = `rto_id '${rtoID}' in fulfillments/tags does not match with the one provided in on_search '${selectedItem?.fulfillment_id}' in /fulfillments`; + } + } + if (list.code === "cancellation_reason_id") { + reasonId = list.value; + if (reasonId !== on_cancel?.cancellation?.reason?.id) { + onCancelObj.rsnIdTagsErr = `Cancellation reason id in /fulfillments/tags does not match with order/cancellation/reason/id`; + } + } + }); + } + if(tag.code === "precancel_state"){ + + const lists = tag.list; + lists.forEach((list) => { + if (list.code === "fulfillment_state") { + preCnclState = list.value; + + if (!constants.FULFILLMENT_STATE.includes(preCnclState)) { + onCancelObj.preCnclStateErr = `${preCnclState} is not a valid precancel state in fulfillments/tags`; } } }); @@ -126,8 +145,8 @@ const checkOnCancel = (data, msgIdSet) => { onCancelObj.ordrStatErr = `Order state should be 'Cancelled' for fulfillment state - ${ffState}`; } console.log(fulfillment.id, selectedItem?.fulfillment_id); - if (fulfillment.id !== selectedItem.fulfillment_id) { - onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${selectedItem.fulfillment_id}' in /fulfillments`; + if (fulfillment.id !== selectedItem?.fulfillment_id) { + onCancelObj.rtoIdErr = `RTO id - '${fulfillment.id}' of fulfillment type 'RTO' does not match with the one provided in on_search '${selectedItem?.fulfillment_id}' in /fulfillments`; } if (ffState === "RTO-Initiated") { RtoPickupTime = fulfillment?.start?.time?.timestamp; @@ -144,7 +163,7 @@ const checkOnCancel = (data, msgIdSet) => { } }); } catch (error) { - console.trace(`Error checking fulfillments/start in /on_cancel`); + console.trace(`Error checking fulfillments/start in /on_cancel`,error); } return onCancelObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 073e544..2a8d35f 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -33,6 +33,11 @@ const checkOnConfirm = (data, msgIdSet) => { try { console.log(`checking start and end time range in fulfillments`); fulfillments.forEach((fulfillment) => { + let avgPickupTime= fulfillment?.start?.time?.duration; +console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); + if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ + onCnfrmObj.avgPckupErr=`Average Pickup Time ${avgPickupTime} (fulfillments/start/time/duration) mismatches from the one provided in /on_search (${dao.getValue(`${fulfillment?.id}-avgPickupTime`)})` + } if(categoryId==='Immediate Delivery' && fulfillment.tracking !== true){ onCnfrmObj.trckErr= `tracking should be enabled (true) for hyperlocal (Immediate Delivery)` } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js new file mode 100644 index 0000000..8f89161 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/msgValidator.js @@ -0,0 +1,52 @@ +const checkConfirm = require("./srvConfirm"); +// const checkInit = require("./srvInit"); +const checkSelect = require("./srvSelect"); +const checkOnInit = require("./srvOnInit"); +// const checkOnConfirm = require("./srvOnConfirm"); +const checkOnSelect = require("./srvOnSelect"); +const checkOnSearch = require("./srvOnSearch"); +// const checkOnUpdate = require("./srvOnUpdate"); +// const checkUpdate = require("./srvUpdate"); +const checkOnStatus = require("./srvOnStatus"); +const checkSearch = require("./srvSearch"); +const _ = require("lodash"); + +const srvVal = (element, action, msgIdSet) => { + const busnsErr = {}; + switch (action) { + case "search": + return checkSearch(element, msgIdSet); + + case "on_search": + return checkOnSearch(element, msgIdSet); + + case "select": + return checkSelect(element, msgIdSet); + + case "on_select": + return checkOnSelect(element, msgIdSet); + + // case "init": + // return checkInit(element, msgIdSet); + + case "on_init": + return checkOnInit(element, msgIdSet); + + case "confirm": + return checkConfirm(element, msgIdSet); + + // case "on_confirm": + // return checkOnConfirm(element, msgIdSet); + + // case "update": + // return checkUpdate(element,msgIdSet); + + // case "on_update": + // return checkOnUpdate(element,msgIdSet) + + case "on_status": + return checkOnStatus(element,msgIdSet) + } + return busnsErr; +}; +module.exports = { srvVal }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json b/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json new file mode 100644 index 0000000..4875211 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/pinToStd.json @@ -0,0 +1 @@ +{"110001":"011","110002":"011","110003":"011","110004":"011","110005":"011","110006":"011","110007":"011","110008":"011","110009":"011","110010":"011","110011":"011","110012":"011","110013":"011","110014":"011","110015":"011","110016":"011","110017":"011","110018":"011","110019":"011","110020":"011","110021":"011","110022":"011","110023":"011","110024":"011","110025":"011","110026":"011","110027":"011","110028":"011","110029":"011","110030":"011","110031":"011","110032":"011","110033":"011","110034":"011","110035":"011","110036":"011","110037":"011","110038":"011","110039":"011","110040":"011","110041":"011","110042":"011","110043":"011","110044":"011","110045":"011","110046":"011","110047":"011","110048":"011","110049":"011","110051":"011","110052":"011","110053":"011","110054":"011","110055":"011","110056":"011","110057":"011","110058":"011","110059":"011","110060":"011","110061":"011","110062":"011","110063":"011","110064":"011","110065":"011","110066":"011","110067":"011","110068":"011","110069":"011","110070":"011","110071":"011","110072":"011","110073":"011","110074":"011","110075":"011","110076":"011","110077":"011","110078":"011","110080":"011","110081":"011","110082":"011","110083":"011","110084":"011","110085":"011","110086":"011","110087":"011","110088":"011","110089":"011","110090":"011","110091":"011","110092":"011","110093":"011","110094":"011","110095":"011","110096":"011","110097":"011","110099":"011","110110":"011","121001":"0129","121002":"0129","121003":"0129","121004":"01275","121005":"0129","121006":"0129","121007":"0129","121008":"0129","121009":"0129","121010":"0129","121012":"0129","121013":"0129","121014":"0129","121015":"0129","121101":"0129","121102":"01275","121103":"01275","121105":"01275","121106":"01275","121107":"01275","122001":"0124","122002":"0124","122003":"0124","122004":"0124","122005":"0124","122006":"0124","122007":"0124","122008":"0124","122009":"0124","122010":"0124","122011":"0124","122012":"0124","122015":"0124","122016":"0124","122017":"0124","122018":"0124","122051":"0124","122052":"0124","122098":"0124","122101":"0124","122102":"0124","122103":"01267","122104":"01267","122105":"01267","122107":"01267","122108":"01267","122413":"0124","122414":"0124","122502":"01274","122503":"0124","122504":"0124","122505":"0124","122506":"0124","122508":"01267","123001":"01285","123021":"01285","123023":"01285","123024":"01285","123027":"01285","123028":"01285","123029":"01285","123031":"01285","123034":"01285","123035":"01274","123101":"01274","123102":"01274","123103":"01274","123106":"01274","123110":"01274","123301":"01274","123302":"01274","123303":"01274","123401":"01274","123411":"01274","123412":"01274","123501":"01274","124001":"01262","124010":"01262","124021":"01262","124022":"01262","124102":"01251","124103":"01251","124104":"01251","124105":"01251","124106":"01251","124107":"01251","124108":"01251","124109":"01251","124111":"01262","124112":"01262","124113":"01262","124141":"01251","124142":"01251","124146":"01251","124201":"01262","124202":"01262","124303":"01262","124401":"01262","124404":"01262","124406":"01262","124411":"01262","124412":"01262","124501":"01262","124504":"01251","124505":"01251","124506":"01251","124507":"01251","124508":"01251","124513":"01262","124514":"01262","125001":"01662","125004":"01662","125005":"01662","125006":"01662","125007":"01662","125011":"01662","125033":"01662","125037":"01662","125038":"01662","125039":"01662","125042":"01662","125044":"01662","125047":"01662","125048":"01667","125049":"01662","125050":"01662","125051":"01667","125052":"01662","125053":"01667","125054":"05334","125055":"05334","125056":"05334","125058":"05334","125060":"05334","125075":"05334","125076":"05334","125077":"05334","125078":"05334","125101":"05334","125102":"05334","125103":"05334","125104":"05334","125106":"01667","125110":"05334","125111":"01667","125112":"01662","125113":"01662","125120":"01667","125121":"01662","125133":"01667","125201":"05334","126101":"01681","126102":"01681","126110":"01681","126111":"01681","126112":"01681","126113":"01681","126114":"01681","126115":"01681","126116":"01681","126125":"01681","126152":"01681","127021":"01664","127022":"01250","127025":"01250","127026":"01250","127027":"01664","127028":"01664","127029":"01664","127030":"01664","127031":"01664","127032":"01664","127035":"01664","127040":"01664","127041":"01664","127042":"01250","127043":"01664","127045":"01664","127046":"01664","127111":"01664","127114":"01664","127201":"01664","127306":"01250","127307":"01250","127308":"01250","127309":"01664","127310":"01250","127311":"01664","127312":"01250","131001":"0130","131021":"0130","131022":"0130","131023":"0130","131024":"0130","131027":"0130","131028":"0130","131029":"0130","131030":"0130","131039":"0130","131101":"0130","131102":"0130","131103":"0130","131301":"0130","131302":"0130","131304":"0130","131305":"0130","131306":"0130","131402":"0130","131403":"0130","131408":"0130","131409":"0130","132001":"0184","132022":"0184","132023":"0184","132024":"0184","132036":"0184","132037":"0184","132039":"0184","132040":"0184","132041":"0184","132046":"0184","132054":"0184","132101":"0180","132102":"0180","132103":"0180","132104":"0180","132105":"0180","132106":"0180","132107":"0180","132108":"0180","132113":"0180","132114":"0184","132115":"0180","132116":"0184","132117":"0184","132122":"0180","132140":"0180","132145":"0180","132157":"0184","133001":"0171","133004":"0171","133005":"0171","133006":"0171","133008":"0171","133010":"0171","133101":"0171","133102":"0171","133103":"01732","133104":"0171","133201":"0171","133202":"01732","133203":"0171","133204":"01732","133205":"0171","133206":"01732","133207":"0171","133301":"0172","133302":"0172","134003":"0171","134005":"0171","134007":"0171","134008":"0171","134101":"0172","134102":"0172","134103":"0172","134104":"0172","134105":"0172","134107":"0172","134108":"0172","134109":"0172","134112":"0172","134113":"0172","134114":"0172","134116":"0172","134117":"0172","134118":"0172","134201":"0172","134202":"0171","134203":"0171","134204":"0172","134205":"0172","135001":"01732","135002":"01732","135003":"01732","135004":"01732","135021":"01732","135101":"01732","135102":"01732","135103":"01732","135106":"01732","135133":"01732","136020":"01746","136021":"01746","136026":"01746","136027":"01746","136030":"01744","136033":"01746","136034":"01746","136035":"01746","136038":"01744","136042":"01746","136043":"01746","136044":"01746","136117":"01746","136118":"01744","136119":"01744","136128":"01744","136129":"01744","136130":"01744","136131":"01744","136132":"01744","136134":"01744","136135":"01744","136136":"01744","136156":"01744","140001":"01881","140101":"01881","140102":"01881","140103":"0172","140108":"01881","140109":"0172","140110":"0172","140111":"01881","140112":"01881","140113":"01881","140114":"01881","140115":"01881","140116":"01881","140117":"01881","140118":"01881","140119":"01881","140123":"01881","140124":"01881","140125":"01881","140126":"01881","140127":"01881","140128":"01881","140133":"01881","140201":"0172","140301":"0172","140306":"0172","140307":"0172","140308":"0172","140401":"0175","140402":"0175","140405":"01763","140406":"01763","140407":"01763","140408":"01763","140412":"01763","140413":"0172","140417":"0175","140501":"0172","140506":"0172","140507":"0172","140601":"0172","140602":"0175","140603":"0172","140604":"0172","140701":"0175","140702":"0175","140802":"01763","140901":"0172","141001":"0161","141002":"0161","141003":"0161","141004":"0161","141006":"0161","141007":"0161","141008":"0161","141010":"0161","141011":"0161","141012":"0161","141013":"0161","141014":"0161","141015":"0161","141016":"0161","141017":"0161","141101":"0161","141102":"0161","141103":"0161","141104":"0161","141105":"0161","141106":"0161","141107":"0161","141108":"0161","141109":"0161","141110":"0161","141112":"0161","141113":"0161","141114":"0161","141115":"0161","141116":"0161","141117":"0161","141118":"0161","141119":"0161","141120":"0161","141121":"0161","141122":"0161","141123":"0161","141125":"0161","141126":"0161","141127":"0161","141201":"0161","141202":"0161","141203":"0161","141204":"0161","141205":"0161","141206":"0161","141401":"0161","141411":"01763","141412":"0161","141413":"0161","141414":"0161","141415":"0161","141416":"0161","141417":"0161","141418":"0161","141419":"0161","141421":"0161","141422":"0161","141801":"01763","142001":"01636","142002":"01636","142003":"01636","142011":"01636","142021":"0161","142022":"0161","142023":"0161","142024":"0161","142025":"0161","142026":"0161","142027":"0161","142028":"0161","142029":"0161","142030":"0161","142031":"0161","142032":"0161","142033":"0161","142034":"0161","142035":"0161","142036":"0161","142037":"01636","142038":"01636","142039":"01636","142040":"01636","142041":"01636","142042":"01636","142043":"01636","142044":"01632","142045":"01636","142046":"01636","142047":"01632","142048":"01636","142049":"01636","142050":"01632","142052":"01632","142053":"01636","142054":"01636","142055":"01636","142056":"01636","142057":"01636","142058":"01636","142060":"01632","143001":"0183","143002":"0183","143003":"0183","143004":"0183","143005":"0183","143006":"0183","143008":"0183","143009":"0183","143022":"0183","143101":"0183","143102":"0183","143103":"0183","143105":"0183","143107":"01852","143108":"0183","143109":"0183","143111":"0183","143112":"0183","143113":"0183","143114":"0183","143115":"0183","143116":"0183","143117":"01852","143118":"01852","143119":"0183","143149":"0183","143201":"0183","143202":"0183","143203":"0183","143204":"0183","143205":"0183","143301":"01852","143302":"01852","143303":"01852","143304":"01852","143305":"01852","143401":"01852","143402":"01852","143406":"01852","143407":"01852","143408":"01852","143409":"01852","143410":"01852","143411":"01852","143412":"01852","143413":"0183","143414":"01852","143415":"01852","143416":"01852","143419":"01852","143422":"01852","143501":"0183","143502":"0183","143504":"0183","143505":"01874","143506":"01874","143507":"01874","143511":"01874","143512":"01874","143513":"01874","143514":"01874","143515":"01874","143516":"01874","143517":"01874","143518":"01874","143519":"01874","143520":"01874","143521":"01874","143525":"0186","143526":"01874","143527":"01874","143528":"01874","143529":"01874","143530":"01874","143531":"0186","143532":"01874","143533":"0186","143534":"0186","143601":"0183","143602":"01874","143603":"0183","143604":"01874","143605":"01874","143606":"0183","144001":"0181","144002":"0181","144003":"0181","144004":"0181","144005":"0181","144006":"0181","144007":"0181","144008":"0181","144009":"0181","144010":"0181","144011":"0181","144012":"0181","144020":"0181","144021":"0181","144022":"0181","144023":"0181","144024":"0181","144025":"0181","144026":"0181","144027":"0181","144028":"0181","144029":"01823","144030":"0181","144031":"0181","144032":"0181","144033":"0181","144034":"0181","144035":"0181","144036":"0181","144037":"0181","144039":"0181","144040":"0181","144041":"0181","144042":"0181","144043":"0181","144044":"0181","144101":"0181","144102":"0181","144103":"0181","144104":"0181","144105":"01882","144106":"0181","144201":"0181","144202":"01882","144204":"01882","144205":"01882","144206":"01882","144207":"01882","144208":"01882","144209":"01882","144210":"01882","144211":"01882","144212":"01882","144213":"01882","144214":"01882","144216":"01882","144221":"01882","144222":"01882","144223":"01882","144224":"01882","144301":"0181","144302":"0181","144303":"0181","144305":"01882","144306":"01882","144311":"0181","144401":"01822","144402":"01822","144403":"01822","144404":"01882","144405":"01822","144406":"01882","144407":"01822","144408":"01822","144409":"0181","144410":"0181","144411":"01822","144415":"01823","144416":"0181","144417":"01823","144418":"0181","144419":"0181","144421":"01823","144422":"01823","144501":"01823","144502":"01823","144503":"01823","144504":"01823","144505":"01823","144506":"01823","144507":"01823","144508":"01823","144509":"01823","144510":"01823","144511":"01823","144512":"01823","144513":"01823","144514":"01823","144515":"01823","144516":"01823","144517":"01823","144518":"01823","144519":"01882","144520":"01882","144521":"01823","144522":"01823","144523":"01882","144524":"01823","144525":"01823","144526":"01823","144527":"01882","144528":"01882","144529":"01882","144530":"01882","144531":"01882","144532":"01882","144533":"01823","144601":"01822","144602":"01822","144603":"01822","144606":"01822","144620":"01822","144621":"01822","144622":"01822","144623":"01822","144624":"01822","144625":"01822","144626":"01822","144628":"01822","144629":"0181","144630":"0181","144631":"01822","144632":"01823","144633":"0181","144701":"0181","144702":"0181","144703":"0181","144801":"0181","144802":"01822","144803":"0181","144804":"01822","144805":"0181","144806":"0181","144819":"01822","145001":"0186","145022":"0186","145023":"0186","145024":"0186","145025":"0186","145026":"0186","145027":"0186","145029":"0186","145101":"0186","146001":"01882","146021":"01882","146022":"01882","146023":"01882","146024":"01882","146101":"01882","146102":"01882","146103":"01882","146104":"01882","146105":"01882","146106":"01882","146107":"01882","146108":"01882","146109":"01882","146110":"01882","146111":"01882","146112":"01882","146113":"01882","146114":"01882","146115":"01882","146116":"01882","147001":"0175","147002":"0175","147003":"0175","147004":"0175","147005":"0175","147006":"0175","147007":"0175","147008":"0175","147021":"0175","147101":"0175","147102":"0175","147103":"0175","147104":"0175","147105":"0175","147111":"0175","147201":"0175","147202":"0175","147203":"01763","147301":"01763","148001":"01672","148002":"01672","148017":"01672","148018":"01672","148019":"01675","148020":"01672","148021":"01675","148022":"01672","148023":"01672","148024":"01672","148025":"01672","148026":"01672","148027":"01672","148028":"01672","148029":"01672","148030":"01672","148031":"01672","148033":"01672","148034":"01672","148035":"01672","148100":"01679","148101":"01679","148102":"01679","148103":"01679","148104":"01679","148105":"01679","148106":"01672","148107":"01679","148108":"01679","148109":"01679","151001":"0164","151002":"0164","151003":"0164","151004":"0164","151005":"0164","151006":"0164","151101":"0164","151102":"0164","151103":"0164","151104":"0164","151105":"0164","151106":"0164","151108":"0164","151111":"0164","151201":"0164","151202":"01633","151203":"01639","151204":"01639","151205":"01639","151206":"0164","151207":"01636","151208":"01636","151209":"01639","151210":"01633","151211":"01633","151212":"01639","151213":"01639","151214":"01639","151301":"0164","151302":"01652","151401":"0164","151501":"01652","151502":"01652","151503":"01652","151504":"01652","151505":"01652","151506":"01652","151507":"01652","151508":"01652","151509":"01652","151510":"01652","152001":"01632","152002":"01632","152003":"01632","152004":"01632","152005":"01632","152020":"01638","152021":"01632","152022":"01632","152023":"01632","152024":"01638","152025":"01633","152026":"01633","152028":"01636","152031":"01633","152032":"01633","152033":"01638","152101":"01633","152107":"01633","152112":"01633","152113":"01633","152114":"01633","152115":"01633","152116":"01638","152117":"01638","152118":"01638","152121":"01638","152122":"01638","152123":"01638","152124":"01638","152128":"01638","152132":"01638","160001":"0172","160002":"0172","160003":"0172","160004":"0172","160005":"0172","160006":"0172","160009":"0172","160011":"0172","160012":"0172","160014":"0172","160015":"0172","160016":"0172","160017":"0172","160018":"0172","160019":"0172","160020":"0172","160022":"0172","160023":"0172","160025":"0172","160030":"0172","160036":"0172","160043":"0172","160047":"0172","160055":"0172","160059":"0172","160062":"0172","160071":"0172","160101":"0172","160102":"0172","160103":"0172","160104":"0172","171001":"0177","171002":"0177","171003":"0177","171004":"0177","171005":"0177","171006":"0177","171007":"0177","171008":"0177","171009":"0177","171010":"0177","171011":"0177","171012":"0177","171013":"0177","171014":"0177","171015":"0177","171018":"0177","171019":"0177","171102":"01792","171103":"0177","171201":"0177","171202":"0177","171203":"0177","171204":"0177","171205":"0177","171206":"0177","171207":"0177","171208":"0177","171209":"0177","171210":"0177","171211":"0177","171212":"0177","171213":"0177","171214":"0177","171215":"0177","171216":"0177","171217":"0177","171218":"0177","171219":"0177","171220":"0177","171221":"0177","171222":"0177","171223":"0177","171224":"0177","171225":"0177","171226":"01702","171301":"0177","172001":"0177","172002":"01902","172021":"0177","172022":"0177","172023":"01902","172024":"0177","172025":"01902","172026":"01902","172027":"0177","172028":"0177","172029":"0177","172030":"0177","172031":"0177","172032":"01902","172033":"01902","172034":"0177","172101":"0177","172102":"0177","172103":"01786","172104":"01786","172105":"01786","172106":"01786","172107":"01786","172108":"01786","172109":"01786","172110":"01786","172111":"01900","172112":"01786","172113":"01900","172114":"01900","172115":"01786","172116":"01786","172117":"01900","172118":"01786","172201":"0177","173001":"01702","173021":"01702","173022":"01702","173023":"01702","173024":"01702","173025":"01702","173026":"01702","173027":"01702","173029":"01702","173030":"01702","173031":"01702","173032":"01702","173101":"01702","173104":"01702","173201":"01792","173202":"01792","173204":"01792","173205":"01792","173206":"01792","173207":"01792","173208":"01792","173209":"01792","173210":"01792","173211":"01792","173212":"01792","173213":"01792","173214":"01792","173215":"01792","173217":"01792","173218":"01792","173220":"01792","173221":"01792","173222":"01792","173223":"01792","173225":"01792","173229":"01792","173230":"01792","173233":"01792","173234":"01792","173235":"01792","173236":"01792","174001":"07752","174002":"07752","174003":"07752","174004":"07752","174005":"07752","174011":"07752","174012":"07752","174013":"07752","174015":"07752","174017":"07752","174021":"07752","174023":"07752","174024":"07752","174026":"07752","174027":"07752","174028":"07752","174029":"07752","174030":"07752","174031":"07752","174032":"07752","174033":"07752","174034":"07752","174035":"07752","174036":"07752","174101":"01792","174102":"01792","174103":"01792","174201":"07752","174301":"02875","174302":"02875","174303":"02875","174304":"05282","174305":"05282","174306":"02875","174307":"02875","174308":"02875","174309":"05282","174310":"07752","174311":"05282","174312":"05282","174314":"02875","174315":"02875","174316":"02875","174317":"02875","174319":"02875","174320":"02875","174321":"02875","174405":"05282","174503":"02875","174505":"05282","174507":"02875","175001":"01905","175002":"01905","175003":"01905","175004":"01905","175005":"01905","175006":"01905","175007":"01905","175008":"01905","175009":"01905","175010":"01905","175011":"01905","175012":"01905","175013":"01905","175014":"01905","175015":"01905","175016":"01905","175017":"01905","175018":"01905","175019":"01905","175020":"01905","175021":"01905","175023":"01905","175024":"01905","175025":"01905","175026":"01905","175027":"01905","175028":"01905","175029":"01905","175030":"01905","175031":"01905","175032":"01905","175033":"01905","175034":"01905","175035":"01905","175036":"01905","175037":"01905","175038":"01905","175039":"01905","175040":"01905","175042":"01905","175045":"01905","175046":"01905","175047":"01905","175048":"01905","175049":"01905","175050":"01905","175051":"01905","175052":"01905","175075":"01905","175101":"01902","175102":"01902","175103":"01902","175104":"01902","175105":"01902","175106":"01905","175121":"01905","175123":"01905","175124":"01905","175125":"01905","175126":"01902","175128":"01902","175129":"01902","175130":"01902","175131":"01902","175132":"01900","175133":"01900","175134":"01902","175136":"01902","175138":"01902","175139":"01900","175140":"01900","175141":"01905","175142":"01900","175143":"01902","176001":"01892","176002":"01892","176021":"01892","176022":"01892","176023":"01892","176025":"01892","176026":"01892","176027":"01892","176028":"01892","176029":"01892","176030":"01892","176031":"01892","176032":"01892","176033":"01892","176036":"01892","176037":"01892","176038":"01892","176039":"05282","176040":"05282","176041":"05282","176042":"05282","176043":"05282","176044":"05282","176045":"05282","176047":"01892","176048":"05282","176049":"05282","176051":"01892","176052":"01892","176053":"01892","176054":"01892","176055":"01892","176056":"01892","176057":"01892","176058":"01892","176059":"01892","176060":"01892","176061":"01892","176062":"01892","176063":"01892","176064":"01892","176065":"01892","176066":"01892","176067":"01892","176071":"01892","176073":"01892","176075":"01892","176076":"01892","176077":"01892","176081":"01892","176082":"01892","176083":"01892","176084":"01892","176085":"01892","176086":"01892","176087":"01892","176088":"01892","176089":"01892","176090":"01905","176091":"01892","176092":"01892","176093":"01892","176094":"01892","176095":"01892","176096":"01892","176097":"01892","176098":"01892","176101":"01892","176102":"01892","176103":"01892","176107":"01892","176108":"05282","176109":"05282","176110":"05282","176111":"05282","176115":"01892","176125":"01892","176128":"01892","176200":"01892","176201":"01892","176202":"01892","176203":"01892","176204":"01892","176205":"01892","176206":"01892","176207":"01376","176208":"01892","176209":"01892","176210":"01892","176211":"01892","176213":"01892","176214":"01892","176215":"01892","176216":"01892","176217":"01892","176218":"01892","176219":"01892","176225":"01892","176301":"01376","176302":"01376","176303":"01376","176304":"01376","176305":"01376","176306":"01376","176308":"01376","176309":"01376","176310":"01376","176311":"01376","176312":"01376","176313":"01376","176314":"01376","176315":"01376","176316":"01376","176317":"01376","176318":"01376","176319":"01376","176320":"01376","176321":"01376","176323":"01376","176324":"01376","176325":"01376","176326":"01376","176401":"01892","176402":"01892","176403":"01892","176501":"01892","176502":"01892","176601":"02875","177001":"05282","177005":"05282","177006":"05282","177007":"05282","177020":"05282","177021":"05282","177022":"05282","177023":"05282","177024":"05282","177025":"05282","177026":"05282","177027":"05282","177028":"05282","177029":"05282","177031":"02875","177033":"01892","177034":"01892","177038":"02875","177039":"02875","177040":"05282","177041":"05282","177042":"05282","177043":"01892","177044":"05282","177045":"05282","177048":"05282","177101":"01892","177103":"01892","177104":"01892","177105":"01892","177106":"01892","177107":"01892","177108":"01892","177109":"02875","177110":"02875","177111":"01892","177112":"01892","177113":"01892","177114":"01892","177117":"01892","177118":"05282","177119":"05282","177201":"02875","177202":"02875","177203":"02875","177204":"02875","177205":"02875","177206":"02875","177207":"02875","177208":"02875","177209":"02875","177210":"02875","177211":"02875","177212":"02875","177213":"02875","177219":"02875","177220":"02875","177301":"05282","177401":"05282","177501":"05282","177601":"05282","180001":"0191","180002":"0191","180003":"0191","180004":"0191","180005":"0191","180006":"0191","180007":"0191","180009":"0191","180010":"0191","180011":"0191","180012":"01992","180013":"0191","180015":"0191","180016":"0191","180017":"0191","180018":"0191","180019":"0191","180020":"0191","181101":"0191","181102":"0191","181111":"0191","181121":"0191","181122":"0191","181123":"0191","181124":"0191","181131":"0191","181132":"0191","181133":"01923","181141":"01923","181143":"01923","181145":"01923","181152":"0191","181201":"0191","181202":"0191","181203":"0191","181204":"0191","181205":"0191","181206":"0191","181207":"0191","181221":"0191","181224":"0191","182101":"01992","182104":"01992","182121":"01992","182122":"01992","182124":"01992","182125":"01992","182126":"01992","182127":"01992","182128":"01992","182141":"01992","182142":"01992","182143":"01998","182144":"01998","182145":"01998","182146":"01998","182147":"01996","182148":"01998","182161":"01992","182201":"01996","182202":"01996","182203":"01995","182204":"01995","182205":"01995","182206":"01995","182207":"01996","182221":"01996","182222":"01996","182301":"01991","182311":"01991","182312":"01991","182313":"01991","182315":"01991","182320":"01991","184101":"01922","184102":"01922","184104":"01922","184120":"01923","184121":"01992","184141":"01923","184142":"01922","184143":"01922","184144":"01922","184145":"01922","184148":"01922","184151":"01922","184152":"01922","184201":"01922","184202":"01922","184203":"01922","184204":"01922","184205":"01992","184206":"01922","185101":"01965","185102":"01965","185121":"01965","185131":"01962","185132":"01962","185133":"01962","185135":"01962","185151":"01962","185152":"01962","185153":"01962","185154":"01991","185155":"01962","185156":"01962","185201":"01962","185202":"01962","185203":"01991","185211":"01965","185212":"01962","185233":"01962","185234":"01962","190001":"0194","190002":"0194","190003":"0194","190004":"0194","190005":"0194","190006":"0194","190007":"01951","190008":"0194","190009":"0194","190010":"0194","190011":"0194","190012":"0194","190014":"01951","190015":"0194","190017":"0194","190018":"0194","190019":"0194","190020":"0194","190021":"01951","190023":"0194","190024":"0194","190025":"0194","191101":"0194","191102":"01933","191103":"01933","191111":"01951","191112":"01921","191113":"01951","191121":"0194","191131":"0194","191132":"01951","191201":"0194","191202":"0194","192101":"01932","192121":"01933","192122":"01933","192123":"01933","192124":"01921","192125":"01932","192126":"01932","192129":"01932","192201":"01932","192202":"01932","192210":"01932","192211":"01932","192212":"01932","192221":"01932","192231":"01931","192232":"01921","192233":"01931","192301":"01933","192302":"01933","192303":"01921","192304":"01933","192305":"01921","192306":"01921","192401":"01932","193101":"01952","193103":"01952","193108":"01952","193109":"01952","193121":"01952","193122":"01952","193123":"01952","193201":"01952","193221":"01955","193222":"01955","193223":"01955","193224":"01955","193225":"01955","193301":"01952","193302":"01955","193303":"01955","193401":"01951","193402":"01952","193403":"01952","193404":"01951","193411":"01951","193501":"0194","193502":"01957","193503":"01957","193504":"0194","193505":"01957","194101":"01982","194102":"01985","194103":"01985","194104":"01982","194105":"01985","194106":"01982","194107":"01982","194109":"01985","194201":"01982","194202":"01982","194301":"01985","194302":"01985","194303":"01985","194401":"01982","194402":"01982","194404":"01982","201001":"0120","201002":"0120","201003":"0120","201004":"0120","201005":"0120","201006":"0120","201007":"0120","201008":"0120","201009":"0120","201010":"0120","201011":"0120","201012":"0120","201013":"0120","201014":"0120","201015":"0122","201016":"0120","201017":"0120","201018":"0120","201019":"0120","201020":"0120","201021":"0120","201102":"0120","201103":"0120","201201":"0120","201204":"0120","201206":"0120","201301":"0120","201302":"0120","201303":"0120","201304":"0120","201305":"0120","201306":"0120","201307":"0120","201309":"0120","201310":"0120","201311":"0120","201312":"0120","201313":"0120","201314":"0120","201315":"0120","201316":"0120","201317":"0120","201318":"0120","202001":"0571","202002":"0571","202121":"0571","202122":"0571","202123":"0571","202124":"0571","202125":"0571","202126":"0571","202127":"0571","202128":"0571","202129":"0571","202130":"0571","202131":"0571","202132":"0571","202133":"0571","202134":"0571","202135":"0571","202136":"0571","202137":"0571","202138":"0571","202139":"05722","202140":"0571","202141":"0571","202142":"0571","202143":"0571","202145":"0571","202146":"0571","202150":"05722","202155":"0571","202165":"0571","202170":"0571","202280":"0571","202281":"0571","202282":"0571","203001":"05722","203002":"05732","203129":"05732","203131":"05732","203132":"05732","203135":"0120","203141":"0120","203150":"05732","203155":"0120","203201":"0120","203202":"0120","203203":"0120","203205":"05732","203206":"05732","203207":"0120","203209":"0120","203389":"05732","203390":"05732","203391":"05732","203392":"05732","203393":"05732","203394":"05732","203395":"05732","203396":"05732","203397":"05732","203398":"05732","203399":"05732","203401":"05732","203402":"05732","203403":"05732","203405":"05732","203407":"05732","203408":"05732","203409":"05732","203411":"05732","203412":"05732","204101":"05722","204102":"05722","204211":"05722","204212":"05722","204213":"05722","204214":"05722","204215":"05722","204216":"05722","205001":"05672","205119":"05672","205121":"05672","205247":"05672","205261":"05672","205262":"05672","205263":"05672","205264":"05672","205265":"05672","205267":"05672","205268":"05672","205301":"05672","205303":"05672","205304":"05672","206001":"05688","206002":"05688","206003":"05688","206120":"05688","206121":"05688","206122":"05683","206123":"05688","206124":"05688","206125":"05688","206126":"05688","206127":"05688","206128":"05688","206129":"05683","206130":"05688","206131":"05688","206241":"05683","206242":"05688","206243":"05683","206244":"05683","206245":"05688","206246":"05683","206247":"05683","206248":"05683","206249":"05683","206250":"05683","206251":"05683","206252":"05683","206253":"05688","206255":"05683","207001":"05742","207002":"05742","207003":"05742","207120":"05742","207121":"05742","207122":"05742","207123":"05744","207124":"05744","207125":"05742","207241":"05744","207242":"05744","207243":"05744","207244":"05744","207245":"05744","207246":"05744","207247":"05742","207248":"05744","207249":"05742","207250":"05742","207301":"05742","207302":"05742","207401":"05742","207402":"05744","207403":"05744","208001":"0512","208002":"0512","208003":"0512","208004":"0512","208005":"0512","208006":"0512","208007":"0512","208008":"0512","208009":"0512","208010":"0512","208011":"0512","208012":"0512","208013":"0512","208014":"0512","208015":"0512","208016":"0512","208017":"0512","208019":"0512","208020":"0512","208021":"0512","208022":"0512","208023":"0512","208024":"0512","208025":"0512","208026":"0512","208027":"0512","209101":"05113","209111":"05113","209112":"05113","209115":"05113","209121":"0512","209125":"05113","209202":"0512","209203":"0512","209204":"05113","209205":"0512","209206":"0512","209208":"05113","209209":"0512","209210":"0512","209214":"0512","209217":"0512","209301":"05113","209302":"05113","209303":"05113","209304":"0512","209305":"0512","209306":"05113","209307":"0512","209308":"0512","209310":"05113","209311":"0512","209312":"05113","209401":"0512","209402":"0565","209501":"05692","209502":"05692","209503":"05692","209504":"05692","209505":"05692","209601":"05692","209602":"05692","209621":"05692","209622":"05692","209625":"05692","209651":"05692","209652":"05692","209720":"05672","209721":"05694","209722":"05694","209723":"05694","209724":"05694","209725":"05694","209726":"05694","209727":"05694","209728":"05694","209729":"05694","209731":"05694","209732":"05694","209733":"05694","209734":"05694","209735":"05694","209736":"05694","209738":"05694","209739":"05692","209743":"05692","209745":"05692","209747":"05694","209749":"05692","209801":"0515","209821":"0515","209825":"0515","209827":"0515","209831":"0515","209841":"0515","209859":"0515","209860":"0515","209861":"0515","209862":"0515","209863":"0515","209864":"0515","209865":"0515","209866":"0515","209867":"0515","209868":"0515","209869":"0515","209870":"0515","209871":"0515","209881":"0515","210001":"07583","210120":"07583","210121":"07583","210122":"07583","210123":"07583","210125":"07583","210126":"07583","210128":"07583","210129":"07583","210201":"07583","210202":"05191","210203":"07583","210204":"05191","210205":"05191","210206":"05191","210207":"05191","210208":"05191","210209":"05191","210301":"05282","210341":"05282","210421":"05281","210422":"05282","210423":"05281","210424":"05281","210425":"05281","210426":"05281","210427":"05281","210428":"05282","210429":"05281","210430":"05282","210431":"05282","210432":"05282","210433":"05281","210501":"05282","210502":"05282","210504":"05281","210505":"05282","210506":"05282","210507":"05282","211001":"0532","211002":"0532","211003":"0532","211004":"0532","211005":"0532","211006":"0532","211007":"0532","211008":"0532","211010":"0532","211011":"0532","211012":"0532","211013":"0532","211014":"0532","211015":"0532","211016":"0532","211017":"0532","211018":"0532","211019":"0532","211020":"0532","211021":"0532","211022":"0532","211023":"0532","212104":"0532","212105":"0532","212106":"0532","212107":"0532","212108":"0532","212109":"0532","212111":"0532","212201":"05331","212202":"0532","212203":"05331","212204":"05331","212205":"05331","212206":"05331","212207":"05331","212208":"0532","212212":"0532","212213":"05331","212214":"05331","212216":"05331","212217":"05331","212218":"05331","212301":"0532","212302":"0532","212303":"0532","212305":"0532","212306":"0532","212307":"0532","212308":"0532","212401":"0532","212402":"0532","212404":"0532","212405":"0532","212502":"0532","212503":"0532","212507":"0532","212601":"05240","212620":"05240","212621":"05240","212622":"05240","212631":"05240","212635":"05240","212641":"05240","212645":"05240","212650":"05240","212651":"05240","212652":"0120","212653":"05240","212654":"05240","212655":"05240","212656":"05240","212657":"05240","212658":"05240","212659":"05240","212661":"05240","212663":"05240","212664":"05240","212665":"05240","221001":"0542","221002":"0542","221003":"0542","221004":"0542","221005":"0542","221006":"0542","221007":"0542","221008":"0542","221009":"05412","221010":"0542","221011":"0542","221012":"0542","221101":"0542","221103":"0542","221104":"0542","221105":"0542","221106":"0542","221107":"0542","221108":"0542","221109":"0542","221110":"05412","221112":"0542","221115":"05412","221116":"0542","221201":"0542","221202":"0542","221204":"0542","221206":"0542","221207":"0542","221208":"0542","221301":"05414","221302":"0542","221303":"05414","221304":"05414","221305":"0542","221306":"05414","221307":"0542","221308":"05414","221309":"05414","221310":"05414","221311":"0542","221313":"0542","221314":"05414","221401":"05414","221402":"05414","221403":"0542","221404":"05414","221405":"0542","221406":"05414","221407":"0542","221409":"05414","221502":"0532","221503":"0532","221505":"0532","221507":"0532","221508":"0532","221601":"0547","221602":"0547","221603":"0547","221701":"05498","221705":"0547","221706":"0547","221709":"05498","221711":"05498","221712":"05498","221713":"05498","221715":"05498","221716":"05498","221717":"05498","221718":"05498","222001":"05452","222002":"05452","222003":"05452","222105":"05452","222109":"05452","222125":"05452","222126":"05452","222127":"05452","222128":"05452","222129":"05452","222131":"05452","222132":"05452","222133":"05452","222135":"05452","222136":"05452","222137":"05452","222138":"05452","222139":"05452","222141":"05452","222142":"05452","222143":"05452","222144":"05452","222145":"05452","222146":"05452","222148":"05452","222149":"05452","222161":"05452","222162":"05452","222165":"05452","222170":"05452","222175":"05452","222180":"05452","222181":"05452","222201":"05452","222202":"05452","222203":"05452","222204":"05452","222301":"01828","222302":"01828","222303":"01828","223101":"05452","223102":"05452","223103":"05452","223104":"05452","223105":"05452","223221":"05462","223222":"05462","223223":"05462","223224":"05462","223225":"05462","223226":"05462","223227":"05462","224001":"05278","224116":"05278","224117":"05278","224118":"05278","224119":"05278","224120":"05278","224121":"05278","224122":"05271","224123":"05278","224125":"05271","224126":"05278","224127":"05278","224129":"05271","224132":"05271","224133":"05278","224135":"05278","224137":"05271","224139":"05271","224141":"05278","224143":"05271","224145":"05271","224146":"05271","224147":"05271","224149":"05271","224151":"05271","224152":"05271","224153":"05278","224155":"05271","224157":"05271","224158":"05278","224159":"05271","224161":"05278","224164":"05278","224168":"05271","224171":"05278","224172":"05612","224176":"05271","224181":"05271","224182":"05278","224183":"05271","224186":"05271","224188":"05278","224189":"05278","224190":"05271","224195":"05278","224201":"05278","224202":"05278","224203":"05278","224204":"05278","224205":"05278","224206":"05278","224207":"05278","224208":"05278","224209":"05278","224210":"05271","224225":"05278","224227":"05271","224228":"05278","224229":"05278","224230":"05271","224231":"05271","224232":"05271","224234":"05278","224235":"05271","224238":"05271","224284":"05278","225001":"05248","225002":"05248","225003":"05248","225119":"05248","225120":"05248","225121":"05248","225122":"05248","225123":"05248","225124":"05248","225125":"05248","225126":"05248","225201":"05248","225202":"05248","225203":"05248","225204":"05248","225205":"05248","225206":"05248","225207":"05248","225208":"05248","225301":"05248","225302":"05248","225303":"05248","225304":"05248","225305":"05248","225306":"05248","225401":"05248","225403":"05248","225404":"05248","225405":"05248","225409":"05248","225412":"05248","225413":"05248","225414":"05248","225415":"05248","225416":"05248","226001":"0522","226002":"0522","226003":"0522","226004":"0522","226005":"0522","226006":"0522","226007":"0522","226008":"0522","226009":"0522","226010":"0522","226011":"0522","226012":"0522","226013":"0522","226014":"0522","226015":"0522","226016":"0522","226017":"0522","226018":"0522","226019":"0522","226020":"0522","226021":"0522","226022":"0522","226023":"0522","226024":"0522","226025":"0522","226026":"0522","226027":"0522","226028":"0522","226029":"0522","226030":"0522","226031":"0522","226101":"0522","226102":"0522","226103":"0522","226104":"0522","226201":"0522","226202":"0522","226203":"0522","226301":"0522","226302":"0522","226303":"0522","226401":"0522","226501":"0522","227304":"01828","227405":"05368","227406":"05368","227407":"05368","227408":"01828","227409":"05368","227411":"05368","227412":"05368","227413":"05368","227801":"05368","227805":"01828","227806":"01828","227807":"05368","227808":"01828","227809":"05368","227811":"05368","227812":"01828","227813":"01828","227814":"01828","227815":"01828","227816":"01828","227817":"05368","228001":"01828","228118":"01828","228119":"01828","228120":"01828","228121":"01828","228125":"01828","228131":"01828","228132":"01828","228133":"01828","228141":"01828","228142":"01828","228145":"01828","228151":"01828","228155":"01828","228159":"01828","228161":"01828","228171":"01828","228172":"01828","229001":"0535","229010":"0535","229103":"0535","229120":"0535","229121":"0535","229122":"0535","229123":"0535","229124":"0535","229125":"0535","229126":"0535","229127":"0535","229128":"0535","229129":"0535","229130":"0535","229135":"05368","229201":"0535","229202":"0535","229203":"0535","229204":"0535","229205":"0535","229206":"0535","229207":"0535","229208":"0535","229209":"0535","229210":"0535","229211":"0535","229212":"0535","229215":"0535","229216":"0535","229301":"0535","229302":"0535","229303":"0535","229304":"0535","229305":"0535","229306":"0535","229307":"0535","229308":"0535","229309":"05368","229310":"0535","229311":"0535","229316":"0535","229401":"0535","229402":"0535","229404":"0535","229405":"0535","229406":"0535","229408":"05342","229410":"05342","229411":"0532","229412":"0532","229413":"0532","229801":"0535","229802":"0535","230001":"05342","230002":"05342","230121":"05342","230124":"05342","230125":"05342","230126":"05342","230127":"05342","230128":"05342","230129":"05342","230130":"05342","230131":"05342","230132":"05342","230133":"05342","230134":"05342","230135":"05342","230136":"05342","230137":"05342","230138":"05342","230139":"05342","230141":"05342","230142":"05342","230143":"05342","230144":"05342","230201":"05342","230202":"05342","230204":"05342","230301":"05342","230302":"05342","230304":"05342","230306":"05342","230401":"05342","230402":"05342","230403":"05342","230404":"05342","230405":"05342","230501":"05342","230502":"05342","230503":"05342","231001":"05442","231205":"05444","231206":"05444","231207":"05444","231208":"05444","231209":"05444","231210":"05444","231211":"05442","231212":"05444","231213":"05444","231215":"05444","231216":"05444","231217":"05444","231218":"05444","231219":"05444","231220":"05444","231221":"05444","231222":"05444","231223":"05444","231224":"05444","231225":"05444","231226":"05444","231301":"05442","231302":"05442","231303":"05442","231304":"05442","231305":"05442","231306":"05442","231307":"05442","231309":"05442","231311":"05442","231312":"05442","231313":"05442","231314":"05442","231501":"05442","232101":"05412","232102":"05412","232103":"05412","232104":"05412","232105":"05412","232106":"05412","232107":"05412","232108":"05412","232109":"05412","232110":"05412","232111":"05412","232118":"05412","232120":"05412","232325":"0548","232326":"0548","232327":"0548","232328":"0548","232329":"0548","232330":"0548","232331":"0548","232332":"0548","232333":"0548","232336":"0548","232339":"0548","232340":"0548","232341":"0548","233001":"0548","233002":"0548","233221":"0548","233222":"0548","233223":"0548","233224":"0548","233225":"0548","233226":"0548","233227":"0548","233228":"0548","233229":"0548","233230":"0548","233231":"0548","233232":"0548","233233":"0548","233234":"0548","233300":"0548","233301":"0548","233302":"0548","233303":"0548","233304":"0548","233305":"0548","233306":"0548","233307":"0548","233310":"0548","233311":"0548","241001":"0565","241121":"05852","241122":"05852","241123":"05852","241124":"05852","241125":"05852","241126":"05852","241127":"05852","241201":"05852","241202":"05852","241203":"05852","241204":"05852","241301":"05852","241302":"05852","241303":"05852","241304":"05852","241305":"05852","241401":"05852","241402":"05852","241403":"05852","241404":"05852","241405":"05852","241406":"05852","241407":"05852","242001":"05842","242021":"05923","242042":"05842","242127":"05842","242220":"05842","242221":"05842","242223":"05842","242226":"05842","242301":"05842","242303":"05842","242305":"05842","242306":"05842","242307":"05842","242401":"05842","242405":"05842","242406":"05842","242407":"05842","243001":"0581","243002":"0581","243003":"0581","243004":"0581","243005":"0581","243006":"0581","243122":"0581","243123":"0581","243126":"0581","243201":"0581","243202":"0581","243203":"0581","243301":"0581","243302":"0581","243303":"0581","243401":"0581","243402":"0581","243403":"0581","243407":"0581","243501":"0581","243502":"0581","243503":"0581","243504":"0581","243505":"0581","243506":"0581","243601":"05832","243630":"05832","243631":"05832","243632":"05832","243633":"05832","243634":"05832","243635":"05832","243636":"05832","243637":"05832","243638":"05923","243639":"05832","243641":"05832","243720":"05832","243722":"05923","243723":"05923","243724":"05832","243725":"05832","243726":"05832","243727":"05923","243751":"05923","244001":"0591","244102":"05923","244103":"0591","244104":"0591","244105":"0591","244221":"05922","244222":"05922","244223":"05922","244225":"05922","244231":"05922","244235":"05922","244236":"05922","244241":"05922","244242":"05922","244245":"05922","244251":"05922","244255":"05922","244301":"05923","244302":"05923","244303":"05923","244304":"05923","244401":"0591","244402":"0591","244410":"05923","244411":"05923","244412":"05923","244413":"0591","244414":"05923","244415":"0591","244501":"0591","244504":"0591","244601":"0591","244602":"0591","244701":"0595","244712":"05944","244713":"05944","244715":"05942","244716":"05944","244717":"05944","244720":"05944","244901":"0595","244921":"0595","244922":"0595","244923":"05944","244924":"05944","244925":"0595","244926":"0595","244927":"0595","244928":"0595","245101":"0122","245201":"0122","245205":"0122","245206":"0121","245207":"0122","245208":"0122","245301":"0122","245304":"0122","246001":"01368","246113":"01368","246121":"01368","246123":"01368","246124":"01368","246125":"01368","246127":"01368","246128":"01368","246129":"01368","246130":"01368","246131":"01368","246141":"01364","246142":"01368","246144":"01368","246146":"01368","246147":"01368","246148":"01368","246149":"01368","246150":"01368","246155":"01368","246159":"01368","246161":"01368","246162":"01368","246163":"01368","246164":"01368","246165":"01368","246166":"01368","246167":"01368","246169":"01368","246171":"01364","246172":"01368","246173":"01368","246174":"01368","246175":"01368","246176":"01368","246177":"01368","246178":"01368","246179":"01368","246193":"01368","246194":"01368","246275":"01368","246276":"01368","246277":"01368","246278":"01368","246279":"01368","246285":"01368","246401":"01372","246419":"01364","246421":"01364","246422":"01372","246424":"01372","246425":"01364","246426":"01372","246427":"01372","246428":"01372","246429":"01364","246431":"01372","246435":"01372","246439":"01364","246440":"01372","246441":"01372","246442":"01364","246443":"01372","246444":"01372","246445":"01364","246446":"01372","246448":"01364","246449":"01372","246453":"01372","246455":"01372","246469":"01364","246471":"01364","246472":"01372","246473":"01372","246474":"01372","246475":"01364","246481":"01372","246482":"01372","246483":"01372","246486":"01372","246487":"01372","246488":"01372","246495":"01364","246701":"01342","246721":"01342","246722":"01342","246723":"01342","246724":"01342","246725":"01342","246726":"01342","246727":"01342","246728":"01342","246729":"01342","246731":"01342","246732":"01342","246733":"01342","246734":"01342","246735":"01342","246736":"01342","246737":"01342","246745":"01342","246746":"01342","246747":"01342","246749":"01342","246761":"01342","246762":"01342","246763":"01342","246764":"01342","247001":"0132","247002":"0132","247120":"0132","247121":"0132","247122":"0132","247129":"0132","247231":"0132","247232":"0132","247340":"0132","247341":"0132","247342":"0132","247343":"0132","247451":"0132","247452":"0132","247453":"0132","247551":"0132","247554":"0132","247656":"01334","247661":"01334","247662":"0132","247663":"01334","247664":"01334","247665":"01334","247666":"01334","247667":"01334","247668":"01334","247669":"0132","247670":"01334","247671":"01334","247771":"01398","247772":"01398","247773":"01398","247774":"01398","247775":"01398","247776":"01398","247777":"01398","247778":"01398","248001":"0135","248002":"0135","248003":"0135","248005":"0135","248006":"0135","248007":"0135","248008":"01376","248009":"0135","248011":"0135","248012":"0135","248013":"0135","248014":"0135","248015":"0135","248016":"0135","248018":"0135","248019":"0135","248121":"0135","248122":"0135","248123":"0135","248124":"0135","248125":"0135","248140":"0135","248142":"0135","248143":"0135","248145":"0135","248146":"0135","248158":"01376","248159":"0135","248165":"0135","248171":"0135","248179":"01376","248195":"0135","248196":"0135","248197":"0135","248198":"0135","248199":"0135","249001":"01376","249121":"01376","249122":"01376","249123":"01376","249124":"01376","249125":"01376","249126":"01376","249127":"01376","249128":"01374","249130":"01376","249131":"01376","249132":"01376","249135":"01374","249136":"01374","249137":"01376","249141":"01374","249145":"01376","249146":"01376","249151":"01374","249152":"01374","249155":"01376","249161":"01376","249165":"01374","249171":"01374","249175":"01376","249180":"01376","249181":"01376","249185":"01374","249186":"01376","249192":"01376","249193":"01374","249194":"01374","249195":"01374","249196":"01374","249199":"01376","249201":"0135","249202":"0135","249203":"0135","249204":"0135","249205":"0135","249301":"01376","249302":"01368","249304":"01368","249306":"01368","249401":"01334","249402":"01334","249403":"01334","249404":"01334","249405":"01334","249407":"01334","249408":"01334","249410":"01334","249411":"01334","250001":"0121","250002":"0121","250003":"0121","250004":"0121","250005":"0121","250101":"01234","250103":"0121","250104":"0121","250106":"0121","250110":"0121","250205":"0121","250221":"0121","250222":"0121","250223":"0121","250341":"0121","250342":"0121","250344":"0121","250345":"01234","250401":"0121","250402":"0121","250404":"0121","250406":"0121","250501":"0121","250502":"0121","250601":"01234","250606":"01234","250609":"01234","250611":"01234","250615":"01234","250617":"01234","250619":"01234","250620":"01234","250621":"01234","250622":"01234","250623":"01234","250625":"01234","250626":"0121","251001":"0131","251002":"0131","251003":"0131","251201":"0131","251202":"0131","251203":"0131","251301":"01398","251305":"01398","251306":"0131","251307":"0131","251308":"0131","251309":"0131","251310":"0131","251311":"0131","251314":"0131","251315":"0131","251316":"0131","251318":"0131","251319":"01398","251320":"0131","251327":"0131","261001":"07834","261121":"07834","261125":"07834","261131":"07834","261135":"07834","261136":"07834","261141":"07834","261145":"07834","261151":"07834","261201":"07834","261202":"07834","261203":"07834","261204":"07834","261205":"07834","261206":"07834","261207":"07834","261208":"07834","261301":"07834","261302":"07834","261303":"07834","261401":"07834","261402":"07834","261403":"07834","261404":"07834","261405":"07834","261501":"05872","261502":"05872","261505":"07834","261506":"05872","262001":"05882","262121":"05882","262122":"05882","262123":"05882","262124":"05882","262201":"05882","262202":"05882","262203":"05882","262302":"05882","262305":"05882","262308":"05944","262309":"05962","262310":"05962","262311":"05944","262401":"05944","262402":"05942","262405":"05944","262406":"0581","262501":"05964","262502":"05964","262520":"05964","262521":"05964","262522":"05964","262523":"05962","262524":"05962","262525":"05962","262526":"05964","262527":"05962","262528":"05962","262529":"05964","262530":"05964","262531":"05964","262532":"05964","262533":"05964","262534":"05964","262540":"05964","262541":"05964","262542":"05964","262543":"05964","262544":"05964","262545":"05964","262546":"05964","262547":"05964","262550":"05964","262551":"05964","262552":"05964","262553":"05964","262554":"05964","262555":"05964","262561":"05962","262572":"05964","262576":"05964","262580":"05962","262701":"05872","262702":"05872","262721":"07834","262722":"07834","262723":"05872","262724":"05872","262725":"05872","262726":"05872","262727":"05872","262728":"07834","262801":"05872","262802":"05872","262803":"05872","262804":"05872","262805":"05872","262901":"05872","262902":"05872","262903":"05872","262904":"05882","262905":"05872","262906":"05872","262907":"05872","262908":"05872","263001":"05942","263126":"05942","263127":"05942","263128":"05942","263132":"05942","263134":"05942","263135":"05942","263136":"05942","263137":"05942","263138":"05942","263139":"05942","263140":"05942","263142":"05942","263145":"05944","263148":"05944","263149":"05944","263150":"05944","263151":"05944","263152":"05944","263153":"05944","263156":"05942","263157":"05942","263158":"05942","263159":"05942","263160":"05944","263601":"05962","263619":"05963","263620":"05963","263621":"05962","263622":"05962","263623":"05962","263624":"05962","263625":"05962","263626":"05962","263628":"05963","263629":"05962","263630":"05963","263631":"05963","263632":"05963","263633":"05963","263634":"05963","263635":"05963","263636":"05962","263637":"05962","263638":"05962","263639":"05963","263640":"05963","263641":"05963","263642":"05963","263643":"05962","263645":"05962","263646":"05962","263651":"05962","263652":"05962","263653":"05962","263655":"05962","263656":"05962","263658":"05962","263659":"05962","263660":"05962","263661":"05962","263663":"05962","263664":"05962","263665":"05962","263667":"05962","263676":"05962","263678":"05962","263679":"05963","263680":"05962","271001":"05262","271002":"05262","271003":"05262","271122":"05262","271123":"05262","271124":"05262","271125":"05262","271126":"05262","271129":"05262","271201":"05252","271202":"05262","271203":"07831","271204":"05262","271205":"07831","271206":"07831","271207":"07831","271208":"07831","271209":"05262","271210":"07831","271215":"07831","271301":"05262","271302":"05262","271303":"05262","271304":"05262","271305":"05262","271306":"07831","271307":"05262","271308":"05262","271309":"05262","271310":"05262","271311":"05262","271312":"05262","271313":"05262","271319":"05262","271401":"05262","271402":"05262","271403":"05262","271502":"05262","271503":"05262","271504":"05262","271601":"05262","271602":"05262","271603":"05262","271604":"07831","271607":"07831","271609":"07831","271801":"05252","271802":"05252","271803":"05252","271804":"05252","271805":"05252","271806":"05252","271821":"05252","271824":"05252","271825":"05252","271830":"05252","271831":"05252","271835":"05252","271840":"05252","271841":"05252","271845":"05252","271851":"05252","271855":"05252","271861":"07831","271865":"05252","271870":"05252","271871":"05252","271872":"05252","271875":"05252","271881":"05252","271882":"05252","271901":"05252","271902":"05252","271903":"05252","271904":"05252","272001":"05542","272002":"05542","272123":"05542","272124":"05542","272125":"05547","272126":"05547","272127":"05542","272128":"05542","272129":"05542","272130":"05542","272131":"05542","272148":"05544","272150":"05542","272151":"05544","272152":"05544","272153":"05544","272154":"05547","272155":"05542","272161":"05542","272162":"05547","272163":"05542","272164":"05547","272165":"05547","272171":"05542","272172":"05547","272173":"05547","272175":"05547","272176":"05547","272177":"05542","272178":"05544","272181":"05542","272182":"05542","272189":"05544","272190":"05542","272191":"05544","272192":"05544","272193":"05544","272194":"05542","272195":"05544","272199":"05547","272201":"05544","272202":"05544","272203":"05544","272204":"05544","272205":"05544","272206":"05544","272207":"05544","272208":"05544","272270":"05547","272271":"05547","272301":"05542","272302":"05542","273001":"0551","273002":"0551","273003":"0551","273004":"0551","273005":"0551","273006":"0551","273007":"0551","273008":"0551","273009":"0551","273010":"0551","273012":"0551","273013":"0551","273014":"0551","273015":"0551","273016":"0551","273017":"0551","273151":"05523","273152":"0551","273155":"05523","273157":"05523","273158":"0551","273161":"05523","273162":"05523","273163":"05523","273164":"05523","273165":"05523","273201":"0551","273202":"0551","273203":"0551","273207":"05523","273209":"0551","273211":"0551","273212":"0551","273213":"0551","273301":"05523","273302":"05523","273303":"05523","273304":"05523","273305":"05523","273306":"05523","273308":"05523","273309":"05523","273310":"05523","273311":"05523","273401":"0551","273402":"0551","273403":"0551","273404":"0551","273405":"0551","273406":"0551","273407":"0551","273408":"0551","273409":"0551","273411":"0551","273412":"0551","273413":"0551","274001":"05568","274149":"05564","274182":"05568","274201":"05568","274202":"05568","274203":"05564","274204":"05568","274205":"05568","274206":"05564","274207":"05564","274208":"05568","274301":"05564","274302":"05564","274303":"05564","274304":"05564","274305":"05564","274306":"05564","274307":"05564","274308":"0532","274309":"05564","274401":"05564","274402":"05564","274403":"05564","274404":"05568","274405":"05568","274406":"05564","274407":"05564","274408":"05568","274409":"05564","274501":"05568","274502":"05568","274505":"05568","274506":"05568","274508":"05568","274509":"05568","274601":"05568","274602":"05568","274603":"05568","274604":"05568","274701":"05568","274702":"05568","274703":"05568","274704":"05568","274705":"05568","274801":"05564","274802":"05564","274806":"05568","274807":"05568","274808":"05568","275101":"0547","275102":"0547","275103":"0547","275105":"0547","275201":"0548","275202":"0548","275203":"0548","275204":"0548","275205":"0548","275301":"0547","275302":"0547","275303":"0547","275304":"0547","275305":"0547","275306":"0547","275307":"0547","276001":"05462","276121":"05462","276122":"05462","276123":"05462","276124":"05462","276125":"05462","276126":"05462","276127":"05462","276128":"05462","276129":"0547","276131":"05462","276135":"05462","276136":"05462","276137":"05462","276138":"05462","276139":"05462","276140":"05462","276141":"05462","276142":"05462","276143":"05462","276201":"05462","276202":"05462","276203":"05462","276204":"05462","276205":"05462","276206":"05462","276207":"05462","276208":"05462","276288":"05462","276301":"05462","276302":"05462","276303":"05462","276304":"05462","276305":"05462","276306":"0547","276402":"0547","276403":"0547","276404":"05462","276405":"0547","276406":"0547","277001":"05498","277121":"05498","277123":"05498","277124":"05498","277201":"05498","277202":"05498","277203":"05498","277204":"05498","277205":"05498","277207":"05498","277208":"05498","277209":"05498","277210":"05498","277211":"05498","277213":"05498","277214":"05498","277216":"05498","277219":"05498","277301":"05498","277302":"05498","277303":"05498","277304":"05498","277401":"05498","277402":"05498","277403":"05498","277501":"05498","277502":"05498","277503":"05498","277504":"05498","277506":"05498","281001":"0565","281003":"0565","281004":"0565","281005":"0565","281006":"0565","281104":"05722","281121":"0565","281122":"0565","281123":"0565","281201":"0565","281202":"0565","281203":"0565","281204":"0565","281205":"0565","281206":"0565","281301":"0565","281302":"05722","281303":"0565","281305":"0565","281306":"05722","281307":"05722","281308":"0565","281401":"0565","281403":"0565","281404":"0565","281405":"0565","281406":"0565","281501":"0565","281502":"0565","281504":"0565","282001":"0562","282002":"0562","282003":"0562","282004":"0562","282005":"0562","282006":"0562","282007":"0562","282008":"0562","282009":"0562","282010":"0562","283101":"0562","283102":"0562","283103":"05612","283104":"0562","283105":"0562","283110":"0562","283111":"0562","283112":"0562","283113":"0562","283114":"0562","283115":"0562","283119":"0562","283121":"0562","283122":"0562","283123":"0562","283124":"0562","283125":"0562","283126":"0562","283130":"05612","283135":"05612","283136":"05612","283141":"05612","283142":"05612","283145":"05612","283151":"05612","283152":"05612","283201":"0562","283202":"0562","283203":"05612","283204":"05612","283205":"05612","283206":"05612","283207":"05612","284001":"0510","284002":"0510","284003":"0510","284120":"0510","284121":"0510","284122":"05176","284123":"05176","284124":"05176","284125":"05176","284126":"05176","284127":"0510","284128":"0510","284135":"0510","284136":"05176","284201":"0510","284202":"0510","284203":"0510","284204":"0510","284205":"0510","284206":"0510","284301":"0510","284302":"0510","284303":"0510","284304":"0510","284305":"0510","284306":"0510","284401":"0510","284402":"05176","284403":"05176","284404":"05176","284405":"05176","284406":"05176","284419":"0510","284501":"05176","285001":"05168","285121":"05168","285122":"05168","285123":"05168","285124":"05168","285125":"05168","285126":"05168","285127":"05168","285128":"05168","285129":"05168","285130":"05168","285201":"05168","285202":"05168","285203":"05168","285204":"05168","285205":"0510","285206":"05168","285223":"05168","301001":"0144","301002":"0144","301018":"0144","301019":"0144","301020":"0144","301021":"0144","301022":"0144","301023":"0144","301024":"0144","301025":"0144","301026":"0144","301027":"0144","301028":"0144","301030":"0144","301035":"0144","301401":"0144","301402":"0144","301403":"0144","301404":"0144","301405":"0144","301406":"0144","301407":"0144","301408":"0144","301409":"0144","301410":"0144","301411":"0144","301412":"0144","301413":"0144","301414":"0144","301415":"0144","301416":"0144","301427":"0144","301604":"0144","301701":"0144","301702":"0144","301703":"0144","301704":"0144","301705":"0144","301706":"0144","301707":"0144","301708":"0144","301709":"0144","301713":"0144","301714":"0144","302001":"0141","302002":"0141","302003":"0141","302004":"0141","302005":"0141","302006":"0141","302012":"0141","302013":"0141","302015":"0141","302016":"0141","302017":"0141","302018":"0141","302019":"0141","302020":"0141","302021":"0141","302022":"0141","302026":"0141","302027":"0141","302028":"0141","302029":"0141","302031":"0141","302033":"0141","302034":"0141","302036":"0141","302037":"0141","302038":"0141","302039":"0141","302040":"0141","302041":"0141","302042":"0141","302043":"0141","302044":"0141","302045":"0141","302046":"0141","303001":"0141","303002":"0141","303003":"0141","303004":"01427","303005":"0141","303006":"0141","303007":"0141","303008":"0141","303009":"0141","303012":"0141","303102":"0141","303103":"0141","303104":"0141","303105":"0141","303106":"0141","303107":"0141","303108":"0141","303109":"0141","303110":"0141","303119":"0141","303120":"0141","303121":"0141","303122":"0141","303123":"0141","303124":"0141","303301":"0141","303302":"01427","303303":"01427","303304":"01427","303305":"0141","303313":"01427","303315":"01427","303323":"01427","303325":"01427","303326":"01427","303327":"01427","303328":"0141","303329":"0141","303338":"0141","303348":"0141","303501":"01427","303502":"01427","303503":"01427","303504":"01427","303505":"01427","303506":"01427","303507":"01427","303508":"01427","303509":"01427","303510":"01427","303511":"01427","303601":"0141","303602":"0141","303603":"0141","303604":"0141","303701":"0141","303702":"0141","303704":"0141","303706":"0141","303712":"0141","303801":"0141","303803":"0141","303804":"0141","303805":"0141","303806":"0141","303807":"0141","303901":"0141","303903":"0141","303904":"0141","303905":"0141","303908":"0141","304001":"01432","304021":"01432","304022":"01432","304023":"01432","304024":"01432","304025":"01432","304026":"01432","304501":"01432","304502":"01432","304503":"01432","304504":"01432","304505":"01432","304507":"01432","304801":"01432","304802":"01432","304803":"01432","304804":"01432","305001":"0145","305002":"0145","305003":"0145","305004":"0145","305005":"0145","305007":"0145","305009":"0145","305012":"0145","305021":"0145","305022":"0145","305023":"0145","305024":"0145","305025":"0145","305026":"01582","305201":"0145","305202":"0145","305203":"0145","305204":"0145","305205":"0145","305206":"0145","305207":"0145","305401":"0145","305402":"0145","305403":"0145","305404":"0145","305405":"0145","305406":"0145","305407":"0145","305408":"0145","305412":"0145","305415":"0145","305601":"0145","305621":"0145","305622":"0145","305623":"0145","305624":"0145","305625":"01482","305627":"0145","305628":"0145","305629":"0145","305630":"0145","305631":"0145","305801":"0145","305802":"0145","305811":"0145","305812":"0145","305813":"0145","305814":"0145","305815":"0145","305816":"0145","305817":"0145","305819":"0145","305901":"02952","305921":"02952","305922":"02952","305923":"0145","305924":"0145","305925":"02952","305926":"0145","305927":"0145","306001":"07816","306021":"07816","306022":"07816","306023":"07816","306101":"07816","306102":"07816","306103":"07816","306104":"07816","306105":"07816","306114":"07816","306115":"07816","306116":"07816","306119":"07816","306126":"07816","306301":"07816","306302":"07816","306303":"07816","306304":"07816","306305":"07816","306306":"07816","306307":"07816","306308":"07816","306401":"07816","306421":"07816","306422":"07816","306501":"07816","306502":"07816","306503":"07816","306504":"07816","306601":"07816","306602":"07816","306603":"07816","306701":"07816","306702":"07816","306703":"07816","306704":"07816","306705":"07816","306706":"07816","306707":"07816","306708":"07816","306709":"07816","306901":"07816","306902":"07816","306912":"07816","307001":"02972","307019":"02972","307022":"02972","307023":"02972","307024":"02972","307025":"0294","307026":"02972","307027":"02972","307028":"02972","307029":"02973","307030":"02973","307031":"02972","307032":"02972","307043":"02972","307501":"02972","307510":"02972","307511":"02972","307512":"02972","307513":"02972","307514":"02972","307515":"02973","307801":"02972","307802":"02972","307803":"02973","311001":"01482","311011":"01482","311021":"01482","311022":"01482","311023":"01482","311024":"01482","311025":"01482","311026":"01482","311030":"01482","311201":"01482","311202":"01482","311203":"01482","311204":"01482","311301":"01482","311302":"02952","311401":"01482","311402":"01482","311403":"01482","311404":"01482","311407":"01482","311408":"01482","311601":"01482","311602":"01482","311603":"01482","311604":"01482","311605":"01482","311606":"01482","311801":"01482","311802":"01482","311803":"01482","311804":"01482","311805":"01482","311806":"01482","312001":"01472","312021":"01472","312022":"01472","312023":"01472","312024":"01472","312025":"01472","312027":"01472","312201":"01472","312202":"01472","312203":"01472","312204":"01472","312205":"01472","312206":"01472","312207":"01472","312401":"01472","312402":"01472","312403":"01472","312404":"01472","312601":"01472","312602":"01472","312603":"01472","312604":"05342","312605":"05342","312606":"01472","312612":"01472","312613":"01472","312614":"01472","312615":"05342","312616":"05342","312617":"01472","312619":"05342","312620":"01472","312622":"01472","312623":"05342","312624":"05342","312625":"05342","312626":"05342","312627":"01472","312901":"01472","313001":"0294","313002":"0294","313003":"0294","313004":"0294","313011":"0294","313022":"0294","313024":"0294","313026":"0294","313027":"0294","313031":"0294","313038":"0294","313201":"0294","313202":"0294","313203":"0294","313204":"0294","313205":"0294","313206":"0294","313207":"02952","313211":"02952","313301":"02952","313321":"02952","313322":"0294","313323":"02952","313324":"02952","313325":"02952","313327":"02952","313328":"02952","313329":"02952","313330":"02952","313331":"02952","313332":"02952","313333":"02952","313334":"02952","313341":"02952","313342":"02952","313601":"0294","313602":"0294","313603":"0294","313604":"0294","313701":"0294","313702":"0294","313703":"0294","313704":"0294","313705":"0294","313706":"0294","313708":"0294","313801":"0294","313802":"0294","313803":"0294","313804":"0294","313805":"0294","313901":"0294","313902":"0294","313903":"0294","313904":"0294","313905":"0294","313906":"0294","314001":"01582","314011":"02964","314021":"02964","314022":"02964","314023":"02964","314024":"02964","314025":"02964","314026":"02964","314027":"02964","314028":"02964","314029":"02964","314030":"02964","314031":"02964","314032":"02964","314034":"02964","314035":"02964","314036":"02964","314037":"02964","314038":"02964","314401":"02964","314402":"02964","314403":"02964","314404":"02964","314406":"02964","314801":"02964","314804":"02964","321001":"07835","321021":"07835","321022":"07835","321023":"07835","321024":"07835","321025":"07835","321026":"07835","321028":"07835","321201":"07835","321202":"07835","321203":"07835","321204":"07835","321205":"07835","321206":"07835","321301":"07835","321302":"07835","321303":"07835","321401":"07835","321402":"07835","321403":"07835","321404":"07835","321405":"07835","321406":"07835","321407":"07835","321408":"07835","321409":"07835","321410":"07835","321411":"07835","321601":"07835","321602":"07835","321605":"0144","321606":"0144","321607":"0144","321608":"01427","321609":"01427","321610":"07464","321611":"07464","321612":"01427","321613":"01427","321614":"07835","321615":"07835","321633":"0144","321642":"07835","322001":"07462","322021":"07462","322023":"07462","322024":"07462","322025":"07462","322026":"07462","322027":"07462","322028":"07462","322029":"07462","322030":"07462","322033":"07462","322034":"07462","322201":"07462","322202":"07462","322203":"07462","322204":"07462","322205":"07462","322211":"07462","322212":"07462","322213":"07464","322214":"07462","322215":"07462","322216":"07464","322218":"07464","322219":"07462","322220":"07464","322230":"07464","322234":"07464","322236":"07464","322238":"07464","322240":"01427","322241":"07464","322242":"07464","322243":"07464","322249":"07464","322251":"07464","322252":"07464","322254":"07464","322255":"07464","322701":"07462","322702":"07462","322703":"07462","322704":"07462","323001":"0747","323021":"0747","323022":"0747","323023":"0747","323024":"0747","323025":"0747","323026":"0747","323301":"0747","323303":"01472","323304":"01472","323305":"01472","323306":"01472","323307":"01472","323601":"0747","323602":"0747","323603":"0747","323613":"0747","323614":"0747","323615":"0747","323616":"0747","323801":"0747","323802":"0747","323803":"0747","324001":"07753","324002":"07753","324003":"07753","324004":"07753","324005":"07753","324006":"07753","324007":"07753","324008":"07753","324009":"07753","324010":"07753","325001":"07753","325003":"07753","325004":"07753","325009":"07753","325201":"07753","325202":"07453","325203":"07753","325204":"07753","325205":"07453","325206":"07453","325207":"07753","325208":"07753","325209":"07453","325214":"07753","325215":"07453","325216":"07453","325217":"07453","325218":"07453","325219":"07453","325220":"07453","325221":"07453","325222":"07453","325223":"07453","325224":"07453","325601":"07753","325602":"07753","326001":"07432","326021":"07432","326022":"07432","326023":"07432","326033":"07432","326034":"07432","326035":"07432","326036":"07432","326037":"07432","326038":"07432","326039":"07432","326501":"07432","326502":"07432","326512":"07432","326513":"07432","326514":"07432","326515":"07432","326516":"07432","326517":"07753","326518":"07753","326519":"07753","326520":"07753","326529":"07753","326530":"07753","327001":"02962","327021":"02962","327022":"02962","327023":"02962","327024":"02962","327025":"02962","327026":"02962","327027":"02962","327031":"02962","327032":"02962","327034":"02962","327601":"02962","327602":"02962","327603":"02962","327604":"02962","327605":"02962","327606":"02962","327801":"02962","328001":"05642","328021":"05642","328022":"05642","328023":"05642","328024":"05642","328025":"05642","328026":"05642","328027":"05642","328028":"05642","328029":"05642","328030":"05642","328031":"05642","328041":"05642","331001":"01562","331021":"01562","331022":"01562","331023":"01562","331024":"01572","331025":"01592","331026":"01592","331027":"01592","331028":"01592","331029":"01562","331030":"01592","331031":"01562","331301":"01562","331302":"01562","331303":"01562","331304":"01562","331305":"01562","331402":"01562","331403":"01562","331411":"01562","331501":"01562","331502":"01562","331503":"01562","331504":"01562","331505":"01562","331506":"01562","331507":"01562","331517":"01562","331518":"01562","331701":"01562","331801":"0151","331802":"01562","331803":"0151","331811":"0151","332001":"01572","332002":"01572","332021":"01572","332023":"01572","332024":"01572","332025":"01572","332026":"01572","332027":"01572","332028":"01572","332029":"01572","332030":"01572","332031":"01572","332041":"01572","332042":"01572","332301":"01572","332302":"01572","332303":"01572","332304":"01572","332305":"01572","332307":"01572","332311":"01572","332312":"01572","332315":"01572","332316":"01572","332317":"01572","332318":"01572","332401":"01572","332402":"01572","332403":"01572","332404":"01572","332405":"01572","332406":"01572","332411":"01572","332601":"01572","332602":"01572","332603":"01572","332701":"01572","332702":"01572","332703":"01572","332705":"01572","332706":"01572","332707":"01572","332708":"01572","332709":"01572","332710":"01572","332711":"01572","332712":"01572","332713":"01572","332714":"01572","332715":"01572","332716":"01592","332718":"01572","332719":"01572","332721":"01572","332722":"01572","332742":"01572","332746":"01592","333001":"01592","333010":"01592","333011":"01592","333012":"01592","333020":"01592","333021":"01592","333022":"01592","333023":"01592","333024":"01592","333025":"01592","333026":"01592","333027":"01592","333028":"01592","333029":"01592","333030":"01592","333031":"01592","333032":"01592","333033":"01592","333034":"01592","333035":"01592","333036":"01592","333041":"01592","333042":"01592","333053":"01592","333055":"01592","333302":"01592","333303":"01592","333304":"01592","333305":"01592","333307":"01592","333308":"01592","333501":"01592","333502":"01592","333503":"01592","333504":"01592","333514":"01592","333515":"01592","333516":"01592","333517":"01592","333701":"01592","333702":"01592","333704":"01592","333705":"01592","333707":"01592","333801":"01592","334001":"0151","334003":"0151","334004":"0151","334006":"0151","334021":"0151","334022":"0151","334023":"0151","334201":"0151","334202":"0151","334302":"0151","334303":"0151","334305":"0151","334401":"0151","334402":"0151","334403":"0151","334601":"0151","334602":"0151","334603":"0151","334604":"0151","334801":"0151","334802":"0151","334803":"0151","334804":"0151","334808":"0151","335001":"0154","335002":"0154","335021":"0154","335022":"0154","335023":"0154","335024":"0154","335025":"0154","335027":"0154","335037":"0154","335038":"0154","335039":"0154","335040":"0154","335041":"0154","335051":"0154","335061":"0154","335062":"01552","335063":"01552","335064":"01552","335065":"01552","335073":"0154","335501":"01552","335502":"01552","335503":"01552","335504":"01552","335511":"01552","335512":"01552","335513":"01552","335522":"01552","335523":"01552","335524":"01552","335525":"01552","335526":"01552","335701":"0154","335702":"0154","335703":"0154","335704":"0154","335705":"0154","335707":"0154","335708":"0154","335711":"0154","335801":"01552","335802":"01552","335803":"01552","335804":"0154","335805":"0154","335901":"0154","341001":"01582","341020":"01582","341021":"01582","341022":"01582","341023":"01582","341024":"01582","341025":"01582","341026":"01582","341027":"01582","341028":"01582","341029":"01582","341030":"01582","341031":"01582","341301":"01582","341302":"01582","341303":"01582","341304":"01582","341305":"01582","341306":"01582","341316":"01582","341317":"01582","341318":"01582","341319":"01582","341501":"01582","341502":"01582","341503":"01582","341504":"01582","341505":"01582","341506":"01582","341507":"01582","341508":"01582","341509":"01582","341510":"01582","341511":"01582","341512":"01582","341513":"01582","341514":"01582","341515":"01582","341516":"01582","341517":"01582","341518":"01582","341519":"01582","341520":"01582","341533":"01582","341542":"01582","341551":"01582","342001":"0291","342002":"0291","342003":"0291","342005":"0291","342006":"0291","342007":"0291","342008":"0291","342011":"0291","342012":"0291","342013":"0291","342014":"0291","342015":"0291","342021":"0291","342022":"0291","342023":"0291","342024":"0291","342025":"0291","342026":"0291","342027":"0291","342028":"0291","342029":"0291","342030":"0291","342037":"0291","342301":"0291","342302":"0291","342303":"0291","342304":"0291","342305":"0291","342306":"0291","342307":"0291","342308":"0291","342309":"0291","342310":"02992","342311":"0291","342312":"0291","342314":"0291","342601":"0291","342602":"0291","342603":"0291","342604":"0291","342605":"0291","342606":"0291","342801":"0291","342802":"0291","342901":"0291","342902":"01582","343001":"02973","343002":"02973","343021":"02973","343022":"02973","343023":"02973","343024":"02973","343025":"02973","343027":"02973","343028":"02973","343029":"02973","343030":"02973","343032":"02973","343039":"02973","343040":"02973","343041":"02973","343042":"02973","343048":"02973","343049":"02973","344001":"02982","344011":"02982","344012":"02982","344021":"02982","344022":"02982","344024":"02982","344025":"02982","344026":"02982","344027":"02982","344031":"02982","344032":"02982","344033":"02982","344034":"02982","344035":"02982","344037":"02982","344043":"02982","344044":"02982","344501":"02982","344502":"02982","344701":"02982","344702":"02982","344703":"02982","344704":"02982","344705":"02982","344706":"02982","344708":"02982","344801":"02982","345001":"02992","345021":"0291","345022":"02992","345023":"02992","345024":"02992","345025":"02992","345026":"02992","345027":"02992","345028":"02992","345031":"02992","345033":"07432","345034":"02992","360001":"0281","360002":"0281","360003":"0281","360004":"0281","360005":"0281","360006":"0281","360007":"0281","360020":"0281","360021":"0281","360022":"0281","360023":"0281","360024":"0281","360025":"0281","360026":"0281","360028":"0281","360030":"0281","360035":"0281","360040":"0281","360045":"0281","360050":"0281","360055":"0281","360060":"0281","360070":"0281","360110":"0281","360311":"0281","360320":"0281","360325":"0281","360330":"0281","360360":"0281","360370":"0281","360375":"0281","360380":"0281","360405":"0281","360410":"0281","360421":"0281","360430":"0281","360440":"0281","360450":"0281","360452":"0281","360460":"0281","360465":"0281","360470":"0281","360480":"0281","360485":"0281","360490":"0281","360510":"02833","360515":"02833","360520":"0288","360530":"0288","360531":"0288","360540":"0288","360545":"0286","360550":"0286","360570":"0286","360575":"0286","360576":"0286","360577":"0286","360578":"0286","360579":"0286","360590":"0286","361001":"0288","361002":"0288","361003":"0288","361004":"0288","361005":"0288","361006":"0288","361007":"0288","361008":"0288","361009":"0288","361010":"0288","361011":"0288","361012":"0288","361013":"0288","361110":"0288","361120":"0288","361130":"0288","361140":"0288","361142":"0288","361150":"0288","361160":"0288","361162":"0288","361170":"0288","361210":"0288","361220":"0288","361230":"0288","361240":"0288","361250":"0288","361280":"0288","361305":"02833","361306":"02833","361310":"02833","361315":"02833","361320":"02833","361325":"02833","361330":"02833","361335":"02833","361345":"02833","361347":"02833","361350":"02833","362001":"0285","362002":"0285","362011":"0285","362015":"0285","362020":"0285","362030":"0285","362037":"0285","362110":"0285","362120":"0285","362130":"0285","362135":"0285","362140":"02876","362150":"0285","362205":"0285","362215":"0285","362220":"0285","362222":"0285","362225":"0285","362226":"0285","362227":"0285","362230":"0286","362240":"0285","362245":"0285","362250":"0285","362255":"0285","362260":"0285","362263":"0285","362265":"02876","362268":"02876","362275":"02876","362310":"0285","362315":"0285","362510":"02876","362520":"02875","362530":"02876","362540":"02875","362550":"02876","362560":"02876","362565":"02876","362570":"02875","362610":"0285","362620":"0286","362625":"0285","362630":"0285","362640":"0285","362650":"0286","362710":"02876","362715":"02876","362720":"02876","363001":"02752","363002":"02752","363020":"02752","363030":"02752","363035":"02752","363040":"02752","363110":"02752","363115":"02752","363310":"02752","363320":"02752","363330":"02752","363351":"02822","363410":"02752","363421":"02752","363423":"02752","363427":"02752","363430":"02752","363435":"02752","363440":"02752","363510":"02752","363520":"02752","363530":"02752","363621":"02822","363623":"02822","363630":"02822","363641":"02822","363642":"02822","363643":"02822","363650":"0281","363655":"02822","363660":"02822","363670":"02822","363745":"02752","363750":"02752","363755":"02752","363760":"02752","363765":"02752","363775":"02752","363780":"02752","364001":"0278","364002":"0278","364003":"0278","364004":"0278","364005":"0278","364006":"0278","364050":"0278","364060":"0278","364070":"0278","364081":"0278","364110":"0278","364120":"02849","364130":"0278","364135":"0278","364140":"0278","364145":"0278","364150":"0278","364210":"0278","364230":"0278","364240":"0278","364250":"0278","364260":"0278","364265":"0278","364270":"0278","364275":"0278","364280":"0278","364290":"0278","364295":"0278","364310":"0278","364313":"0278","364320":"02849","364330":"0278","364505":"0278","364510":"0278","364515":"02792","364521":"02792","364522":"02792","364525":"0278","364530":"0278","364710":"02849","364720":"02849","364730":"02849","364740":"02849","364750":"02849","364760":"02849","364765":"02849","365220":"02792","365410":"02792","365421":"02792","365430":"02792","365435":"02792","365440":"0285","365450":"02792","365455":"02792","365456":"02792","365460":"02792","365480":"0281","365535":"02792","365540":"02792","365541":"02792","365550":"02792","365555":"02792","365560":"02792","365601":"02792","365610":"02792","365620":"02792","365630":"02792","365635":"02792","365640":"02792","365645":"02792","365650":"02792","365730":"02792","370001":"02832","370015":"02832","370020":"02832","370030":"02832","370040":"02832","370105":"02832","370110":"02832","370115":"02832","370130":"02832","370135":"02832","370140":"02832","370145":"02832","370150":"02832","370155":"02832","370160":"02832","370165":"02832","370201":"02832","370203":"02832","370205":"02832","370210":"02832","370230":"02832","370240":"02832","370405":"02832","370410":"02832","370415":"02832","370421":"02832","370425":"02832","370427":"02832","370430":"02832","370435":"02832","370445":"02832","370450":"02832","370455":"02832","370460":"02832","370465":"02832","370475":"02832","370485":"02832","370490":"02832","370510":"02832","370601":"02832","370605":"02832","370610":"02832","370615":"02832","370620":"02832","370625":"02832","370627":"02832","370630":"02832","370641":"02832","370645":"02832","370650":"02832","370655":"02832","370660":"02832","370665":"02832","370670":"02832","370675":"02832","380001":"079","380002":"079","380003":"079","380004":"079","380005":"079","380006":"079","380007":"079","380008":"079","380009":"079","380013":"079","380014":"079","380015":"079","380016":"079","380018":"079","380019":"079","380021":"079","380022":"079","380023":"079","380024":"079","380026":"079","380027":"079","380028":"079","380049":"079","380050":"079","380051":"079","380052":"079","380054":"079","380055":"079","380058":"079","380059":"079","380060":"079","380061":"079","380063":"079","382006":"079","382007":"079","382010":"079","382016":"079","382021":"079","382024":"079","382028":"079","382030":"079","382041":"079","382042":"079","382045":"079","382110":"079","382115":"02762","382120":"02762","382122":"079","382130":"02752","382140":"079","382145":"079","382150":"079","382170":"02762","382210":"079","382213":"079","382220":"079","382225":"079","382230":"079","382240":"079","382245":"02849","382250":"02849","382255":"02849","382260":"079","382265":"079","382305":"079","382308":"079","382315":"079","382320":"079","382321":"079","382330":"079","382340":"079","382345":"079","382350":"079","382355":"079","382405":"079","382415":"079","382418":"079","382421":"079","382422":"079","382423":"079","382424":"079","382425":"079","382426":"079","382427":"079","382428":"079","382430":"079","382433":"079","382435":"079","382443":"079","382445":"079","382449":"079","382450":"02849","382455":"079","382460":"079","382463":"079","382465":"079","382470":"079","382475":"079","382480":"079","382481":"079","382610":"079","382620":"079","382630":"079","382640":"079","382650":"079","382721":"079","382722":"079","382725":"079","382729":"079","382735":"079","382740":"079","382810":"079","382835":"079","382845":"079","382855":"079","383001":"02772","383002":"02778","383006":"02772","383010":"02772","383030":"02778","383110":"02772","383120":"02772","383205":"02772","383210":"02772","383215":"02772","383220":"02772","383225":"02772","383230":"02772","383235":"02772","383240":"02772","383245":"02774","383246":"02772","383250":"02774","383251":"02774","383255":"02772","383260":"02774","383270":"02772","383275":"02772","383276":"02772","383305":"02772","383307":"02772","383310":"02774","383315":"02774","383316":"02774","383317":"02774","383320":"02774","383325":"02774","383330":"02774","383335":"02774","383340":"02774","383345":"02774","383350":"02774","383355":"02774","383410":"02772","383421":"02772","383422":"02778","383430":"02772","383434":"02772","383440":"02772","383450":"02772","383460":"02772","383462":"02772","384001":"02762","384002":"02762","384003":"02762","384005":"02762","384012":"02762","384110":"07621","384120":"02762","384130":"02762","384135":"02762","384140":"02762","384151":"07621","384160":"02762","384170":"02762","384220":"07621","384221":"07621","384225":"07621","384229":"07621","384230":"07621","384240":"07621","384241":"07621","384245":"07621","384246":"07621","384255":"07621","384260":"07621","384265":"07621","384272":"07621","384275":"07621","384285":"07621","384290":"07621","384305":"02762","384310":"02762","384315":"02762","384320":"02762","384325":"02762","384330":"02762","384335":"02762","384340":"02762","384345":"02762","384355":"02762","384360":"02762","384410":"02762","384412":"02762","384415":"02762","384421":"02762","384430":"02762","384435":"02762","384440":"02762","384441":"02762","384445":"02762","384450":"02762","384455":"02762","384460":"02762","384465":"02762","384470":"02762","384515":"02762","384520":"02762","384530":"02762","384540":"02762","384550":"02762","384560":"02762","384565":"02762","384570":"02762","385001":"02742","385010":"02742","385110":"02742","385120":"02742","385130":"02742","385135":"02742","385210":"02742","385310":"02742","385320":"02742","385330":"02742","385340":"07621","385350":"07621","385360":"07621","385410":"02742","385421":"02742","385505":"02742","385506":"02742","385510":"02742","385515":"02742","385520":"02742","385530":"02742","385535":"02742","385540":"02742","385545":"02742","385550":"02742","385555":"02742","385560":"02742","385565":"02742","385566":"02742","385570":"02742","385575":"02742","387001":"02694","387002":"02694","387003":"02694","387110":"02694","387115":"02694","387120":"02694","387130":"02694","387210":"02694","387220":"02692","387230":"02694","387240":"02692","387305":"02772","387310":"02692","387315":"02694","387320":"02694","387325":"02694","387330":"02694","387335":"02694","387340":"02694","387345":"02694","387350":"02694","387355":"02694","387360":"02694","387365":"02694","387370":"02694","387375":"02694","387380":"02694","387411":"02694","387430":"02694","387510":"02694","387520":"02694","387530":"02694","387540":"02694","387550":"02694","387560":"02694","387570":"02694","387610":"02694","387620":"02694","387630":"02694","387635":"02694","387640":"02694","387650":"02694","387710":"02694","388001":"02692","388110":"02692","388120":"02692","388121":"02692","388130":"02692","388140":"02692","388150":"02692","388160":"02692","388170":"02692","388180":"02694","388205":"02692","388210":"02692","388215":"02694","388220":"02694","388225":"02694","388230":"02694","388235":"02672","388239":"02694","388245":"02694","388250":"02694","388255":"02672","388260":"02672","388265":"02672","388270":"02672","388305":"02692","388306":"02692","388307":"02692","388310":"02692","388315":"02692","388320":"02692","388325":"02692","388330":"02692","388335":"02692","388340":"02692","388345":"02692","388350":"02692","388355":"02692","388360":"02692","388365":"02692","388370":"02692","388410":"02692","388421":"02692","388430":"02692","388440":"02694","388450":"02692","388460":"02692","388465":"02692","388470":"02692","388480":"02692","388510":"02692","388520":"02692","388530":"02692","388540":"02692","388543":"02692","388545":"02692","388550":"02692","388560":"02692","388570":"02692","388580":"02692","388590":"02692","388610":"02692","388620":"02692","388625":"02692","388630":"02692","388640":"02692","388710":"02672","388713":"02672","389001":"02672","389002":"02672","389110":"02672","389115":"02672","389120":"02672","389130":"02673","389140":"02673","389146":"02673","389151":"02673","389152":"02673","389154":"02673","389155":"02673","389160":"02673","389170":"02673","389172":"02672","389175":"02673","389180":"02673","389190":"02672","389210":"02672","389220":"02672","389230":"02672","389232":"02672","389235":"02672","389250":"02672","389260":"02672","389265":"02672","389310":"02672","389320":"02672","389330":"02672","389340":"02672","389341":"02672","389350":"02672","389360":"02672","389365":"02672","389370":"02672","389380":"02672","389382":"02673","389390":"02672","390001":"0265","390002":"0265","390003":"0265","390004":"0265","390006":"0265","390007":"0265","390009":"0265","390010":"0265","390011":"0265","390012":"0265","390013":"0265","390014":"0265","390016":"0265","390017":"0265","390018":"0265","390019":"0265","390020":"0265","390021":"0265","390022":"0265","390023":"0265","390024":"0265","390025":"0265","391101":"0265","391105":"0265","391107":"0265","391110":"0265","391115":"0265","391120":"02649","391125":"02669","391130":"02669","391135":"02669","391140":"02669","391145":"02669","391150":"02669","391152":"02669","391156":"02669","391160":"02669","391165":"02669","391168":"02669","391170":"02669","391210":"0265","391220":"0265","391240":"0265","391243":"0265","391244":"0265","391250":"0265","391310":"0265","391320":"0265","391330":"0265","391340":"0265","391345":"0265","391350":"0265","391410":"0265","391421":"0265","391430":"0265","391440":"0265","391445":"0265","391450":"0265","391510":"0265","391520":"0265","391530":"0265","391740":"0265","391745":"0265","391750":"0265","391760":"0265","391761":"0265","391770":"0265","391774":"0265","391775":"0265","391776":"0265","391780":"0265","391810":"02642","392001":"02642","392011":"02642","392012":"02642","392015":"02642","392020":"02642","392025":"02642","392030":"02642","392035":"02642","392040":"02642","392110":"02642","392130":"02642","392135":"02642","392140":"02642","392150":"02642","392155":"02642","392160":"02642","392165":"02642","392170":"02642","392180":"02642","392210":"02642","392215":"02642","392220":"0265","392230":"02642","392240":"02642","392310":"0265","393001":"02642","393002":"02642","393010":"02642","393017":"02642","393020":"02642","393025":"02649","393030":"02642","393040":"02649","393041":"02649","393050":"02649","393105":"0265","393110":"02642","393115":"02642","393120":"02649","393125":"02642","393130":"02649","393135":"02642","393140":"02649","393145":"02649","393150":"02649","393151":"02649","394101":"0261","394105":"0261","394107":"0261","394110":"0261","394111":"0261","394112":"0261","394115":"02642","394120":"0261","394125":"0261","394130":"0261","394140":"0261","394150":"0261","394155":"0261","394160":"0261","394163":"0261","394170":"0261","394180":"0261","394185":"0261","394190":"0261","394210":"0261","394221":"0261","394230":"0261","394235":"0261","394240":"0261","394245":"0261","394246":"02628","394248":"0261","394250":"02628","394270":"0261","394305":"0261","394310":"0261","394315":"0261","394317":"0261","394320":"0261","394325":"0261","394326":"0261","394327":"0261","394330":"0261","394335":"0261","394340":"02628","394345":"0261","394350":"0261","394352":"0261","394355":"0261","394360":"02628","394365":"02628","394370":"02628","394375":"02628","394380":"02628","394405":"0261","394410":"0261","394421":"0261","394430":"0261","394440":"0261","394445":"0261","394510":"0261","394515":"0261","394516":"0261","394517":"0261","394518":"0261","394520":"0261","394530":"0261","394540":"0261","394541":"0261","394550":"0261","394601":"0261","394620":"02628","394630":"02628","394633":"02628","394635":"02628","394640":"02628","394641":"02628","394650":"02628","394651":"02628","394652":"02628","394655":"02628","394660":"02628","394670":"02628","394680":"02628","394690":"02628","394710":"02631","394715":"02631","394716":"02628","394720":"02631","394730":"02631","394810":"02642","395001":"0261","395002":"0261","395003":"0261","395004":"0261","395005":"0261","395006":"0261","395007":"0261","395008":"0261","395009":"0261","395010":"0261","395011":"0261","395012":"0261","395013":"0261","395017":"0261","395023":"0261","396001":"02632","396002":"02632","396007":"02632","396020":"02632","396030":"02632","396035":"02632","396040":"02637","396045":"02632","396050":"02632","396051":"02632","396055":"02632","396060":"02637","396065":"02632","396067":"02632","396105":"02632","396110":"02637","396115":"02632","396120":"02632","396125":"02632","396126":"02632","396130":"02632","396135":"02632","396140":"02632","396145":"02632","396150":"02632","396155":"02632","396165":"02632","396170":"02632","396171":"02632","396180":"02632","396185":"02632","396191":"02632","396193":"02632","396195":"02632","396210":"0260","396215":"02632","396220":"0260","396230":"02632","396235":"02632","396240":"02632","396310":"02637","396321":"02637","396325":"02637","396350":"02637","396360":"02637","396370":"02637","396375":"02632","396380":"02637","396385":"02632","396403":"02637","396406":"02637","396409":"02637","396412":"02637","396415":"02637","396418":"02637","396421":"02637","396424":"02637","396427":"02637","396430":"02637","396433":"02637","396436":"02637","396439":"02637","396440":"02637","396445":"02637","396450":"02637","396460":"02637","396463":"02637","396466":"02637","396469":"02637","396472":"02637","396475":"02637","396510":"0261","396521":"02637","396530":"02637","396540":"02637","396560":"02637","396570":"02637","396580":"02637","396590":"02637","400001":"022","400002":"022","400003":"022","400004":"022","400005":"022","400006":"022","400007":"022","400008":"022","400009":"022","400010":"022","400011":"022","400012":"022","400013":"022","400014":"022","400015":"022","400016":"022","400017":"022","400018":"022","400019":"022","400020":"022","400021":"022","400022":"022","400024":"022","400025":"022","400026":"022","400027":"022","400028":"022","400029":"022","400030":"022","400031":"022","400032":"022","400033":"022","400034":"022","400035":"022","400037":"022","400042":"022","400043":"022","400049":"022","400050":"022","400051":"022","400052":"022","400053":"022","400054":"022","400055":"022","400056":"022","400057":"022","400058":"022","400059":"022","400060":"022","400061":"022","400063":"022","400064":"022","400065":"022","400066":"022","400067":"022","400068":"022","400069":"022","400070":"022","400071":"022","400072":"022","400074":"022","400075":"022","400076":"022","400077":"022","400078":"022","400079":"022","400080":"022","400081":"022","400082":"022","400083":"022","400084":"022","400085":"022","400086":"022","400087":"022","400088":"022","400089":"022","400091":"022","400092":"022","400093":"022","400094":"022","400095":"022","400096":"022","400097":"022","400098":"022","400099":"022","400101":"022","400102":"022","400103":"022","400104":"022","400601":"022","400602":"022","400603":"022","400604":"022","400605":"022","400606":"022","400607":"022","400608":"022","400610":"022","400612":"022","400614":"022","400615":"022","400701":"022","400702":"02194","400703":"022","400704":"02194","400705":"022","400706":"022","400707":"02194","400708":"022","400709":"022","400710":"022","401101":"022","401102":"02525","401103":"02525","401105":"02525","401106":"022","401107":"022","401201":"02525","401202":"02525","401203":"02525","401204":"022","401206":"022","401207":"02525","401208":"02525","401209":"02525","401301":"02525","401302":"02525","401303":"02525","401304":"02525","401305":"02525","401401":"02525","401402":"02525","401403":"02525","401404":"02525","401405":"02525","401501":"02525","401502":"02525","401503":"02525","401504":"02525","401506":"02525","401601":"02525","401602":"02525","401603":"02525","401604":"02525","401605":"02525","401606":"02525","401607":"02525","401608":"02525","401701":"02525","401702":"02525","401703":"02525","402101":"02194","402102":"02194","402103":"02194","402104":"02194","402105":"02194","402106":"02194","402107":"02194","402108":"02194","402109":"02194","402110":"02194","402111":"02194","402112":"02194","402113":"02194","402114":"02194","402115":"02194","402116":"02194","402117":"02194","402120":"02194","402122":"02194","402125":"02194","402126":"02194","402201":"02194","402202":"02194","402203":"02194","402204":"02194","402207":"02194","402208":"02194","402209":"02194","402301":"02194","402302":"02194","402303":"02194","402304":"02194","402305":"02194","402306":"02194","402307":"02194","402308":"02194","402309":"02194","402401":"02194","402402":"02194","402403":"02194","402404":"02194","403001":"0832","403002":"0832","403004":"0832","403005":"0832","403006":"0832","403101":"0832","403102":"0832","403103":"0832","403104":"0832","403105":"0832","403106":"0832","403107":"0832","403108":"0832","403109":"0832","403110":"0832","403114":"0832","403115":"0832","403201":"0832","403202":"0832","403203":"0832","403204":"0832","403206":"0832","403401":"0832","403402":"0832","403403":"0832","403404":"0832","403406":"0832","403409":"0832","403410":"0832","403501":"0832","403502":"0832","403503":"0832","403504":"0832","403505":"0832","403506":"0832","403507":"0832","403508":"0832","403509":"0832","403510":"0832","403511":"0832","403512":"0832","403513":"0832","403515":"0832","403516":"0832","403517":"0832","403521":"0832","403523":"0832","403524":"0832","403526":"0832","403527":"0832","403529":"0832","403530":"0832","403601":"0832","403602":"0832","403701":"0832","403702":"0832","403703":"0832","403704":"0832","403705":"0832","403706":"0832","403707":"0832","403708":"0832","403709":"0832","403710":"0832","403711":"0832","403712":"0832","403713":"0832","403714":"0832","403715":"0832","403716":"0832","403717":"0832","403718":"0832","403719":"0832","403720":"0832","403721":"0832","403722":"0832","403723":"0832","403724":"0832","403725":"0832","403726":"0832","403728":"0832","403729":"0832","403731":"0832","403801":"0832","403802":"0832","403803":"0832","403804":"0832","403806":"0832","410101":"02194","410102":"02194","410201":"02194","410202":"02194","410203":"02194","410204":"02194","410205":"02194","410206":"02194","410207":"02194","410208":"02194","410209":"02194","410210":"02194","410216":"02194","410218":"02194","410220":"02194","410221":"02194","410222":"02194","410301":"020","410302":"020","410401":"020","410402":"020","410403":"020","410405":"020","410406":"020","410501":"020","410502":"020","410503":"020","410504":"020","410505":"020","410506":"020","410507":"020","410508":"020","410509":"020","410510":"020","410511":"020","410512":"020","410513":"020","410515":"020","410516":"020","411001":"020","411002":"020","411003":"020","411004":"020","411005":"020","411006":"020","411007":"020","411008":"020","411009":"020","411011":"020","411012":"020","411013":"020","411014":"020","411015":"020","411016":"020","411017":"020","411018":"020","411019":"020","411020":"020","411021":"020","411022":"020","411023":"020","411024":"020","411025":"020","411026":"020","411027":"020","411028":"020","411030":"020","411031":"020","411032":"020","411033":"020","411034":"020","411035":"020","411036":"020","411037":"020","411038":"020","411039":"020","411040":"020","411041":"020","411042":"020","411043":"020","411044":"020","411045":"020","411046":"020","411047":"020","411048":"020","411051":"020","411052":"020","411057":"020","411058":"020","411060":"020","411061":"020","411062":"020","411067":"020","411068":"020","411069":"020","412101":"020","412102":"020","412103":"020","412104":"020","412105":"020","412106":"020","412107":"020","412108":"020","412109":"020","412110":"020","412112":"020","412115":"020","412201":"020","412202":"020","412203":"020","412204":"020","412205":"020","412206":"02162","412207":"020","412208":"020","412209":"020","412210":"020","412211":"020","412212":"020","412213":"020","412214":"020","412215":"020","412216":"020","412218":"020","412219":"020","412220":"020","412301":"020","412303":"020","412304":"020","412305":"020","412306":"020","412307":"020","412308":"020","412311":"020","412312":"020","412401":"020","412402":"020","412403":"020","412404":"020","412405":"020","412406":"020","412408":"020","412409":"020","412410":"020","412411":"020","412412":"020","412801":"02162","412802":"02162","412803":"02162","412804":"02162","412805":"02162","412806":"02162","413001":"0217","413002":"0217","413003":"0217","413004":"0217","413005":"0217","413006":"0217","413007":"0217","413008":"0217","413101":"0217","413102":"020","413103":"020","413104":"020","413105":"020","413106":"020","413107":"0217","413108":"0217","413109":"0217","413110":"020","413111":"0217","413112":"0217","413113":"0217","413114":"020","413115":"020","413116":"020","413118":"0217","413120":"020","413130":"020","413132":"020","413133":"020","413201":"0241","413202":"0217","413203":"0217","413204":"0241","413205":"0241","413206":"0217","413207":"02442","413208":"0217","413209":"0217","413210":"0217","413211":"0217","413212":"0217","413213":"0217","413214":"0217","413215":"0217","413216":"0217","413217":"0217","413218":"0217","413219":"0217","413220":"0217","413221":"0217","413222":"0217","413223":"0217","413224":"0217","413226":"0217","413227":"0217","413228":"0217","413229":"02442","413248":"0217","413249":"02442","413250":"0217","413251":"0217","413252":"0217","413253":"0217","413255":"0217","413301":"0217","413302":"0217","413303":"0217","413304":"0217","413305":"0217","413306":"0217","413307":"0217","413308":"0217","413309":"0217","413310":"0217","413314":"0217","413315":"0217","413317":"0217","413319":"0217","413322":"0217","413324":"0217","413401":"0217","413402":"0217","413403":"0217","413404":"0217","413405":"02472","413406":"0217","413409":"0217","413410":"0217","413411":"0217","413412":"0217","413501":"02472","413502":"02472","413503":"02472","413504":"02472","413505":"02472","413506":"02472","413507":"02472","413508":"02472","413509":"02472","413510":"02472","413511":"02382","413512":"02382","413513":"02382","413514":"02382","413515":"02382","413516":"02382","413517":"02382","413518":"02382","413519":"02382","413520":"02382","413521":"02382","413522":"02382","413523":"02382","413524":"02382","413525":"02472","413526":"02472","413527":"02382","413528":"02472","413529":"02382","413530":"02382","413531":"02382","413532":"02382","413534":"02472","413544":"02382","413581":"02382","413582":"02472","413601":"02472","413602":"02472","413603":"02472","413604":"02472","413605":"02472","413606":"02472","413607":"02382","413608":"02472","413623":"02472","413624":"02472","413701":"0241","413702":"0241","413703":"0241","413704":"0241","413705":"0241","413706":"0241","413707":"0241","413708":"0241","413709":"0241","413710":"0241","413711":"0241","413712":"0241","413713":"0241","413714":"0241","413715":"0241","413716":"0241","413717":"0241","413718":"0241","413719":"0241","413720":"0241","413721":"0241","413722":"0241","413723":"0241","413725":"0241","413726":"0241","413728":"0241","413736":"0241","413737":"0241","413738":"0241","413739":"0241","413801":"020","413802":"020","414001":"0241","414002":"0241","414003":"0241","414005":"0241","414006":"0241","414101":"0241","414102":"0241","414103":"0241","414105":"0241","414106":"0241","414110":"0241","414111":"0241","414113":"0241","414201":"0241","414202":"02442","414203":"02442","414204":"02442","414205":"02442","414208":"02442","414301":"0241","414302":"0241","414303":"0241","414304":"0241","414305":"0241","414306":"0241","414401":"0241","414402":"0241","414403":"0241","414501":"0241","414502":"0241","414503":"0241","414504":"0241","414505":"0241","414601":"0241","414602":"0241","414603":"0241","414604":"0241","414605":"0241","414606":"0241","414607":"0241","414609":"0241","414701":"0241","415001":"02162","415002":"02162","415003":"02162","415004":"02162","415010":"02162","415011":"02162","415012":"02162","415013":"02162","415014":"02162","415015":"02162","415019":"02162","415020":"02162","415021":"02162","415022":"02162","415023":"02162","415101":"0231","415102":"02162","415103":"02162","415104":"02162","415105":"02162","415106":"02162","415107":"02162","415108":"02162","415109":"02162","415110":"02162","415111":"02162","415112":"02162","415114":"02162","415115":"02162","415116":"02162","415122":"02162","415124":"02162","415202":"02352","415203":"02352","415205":"02162","415206":"02162","415207":"02162","415208":"02352","415209":"02162","415211":"02162","415212":"02162","415213":"02194","415214":"02352","415301":"0233","415302":"0233","415303":"0233","415304":"0233","415305":"0233","415306":"0233","415307":"0233","415308":"0233","415309":"0233","415310":"0233","415311":"0233","415312":"02162","415313":"0233","415315":"0233","415401":"0233","415402":"0233","415403":"0233","415404":"0233","415405":"0233","415406":"0233","415407":"0233","415408":"0233","415409":"0233","415410":"0233","415411":"0233","415412":"0233","415413":"0233","415414":"0233","415415":"0233","415501":"02162","415502":"02162","415503":"02162","415504":"02162","415505":"02162","415506":"02162","415507":"02162","415508":"02162","415509":"02162","415510":"02162","415511":"02162","415512":"02162","415513":"02162","415514":"02162","415515":"02162","415516":"02162","415517":"02162","415518":"02162","415519":"02162","415520":"02162","415521":"02162","415522":"02162","415523":"02162","415524":"02162","415525":"02162","415526":"02162","415527":"02162","415528":"02162","415530":"02162","415536":"02162","415537":"02162","415538":"02162","415539":"02162","415540":"02162","415601":"02352","415602":"02352","415603":"02352","415604":"02352","415605":"02352","415606":"02352","415607":"02352","415608":"02352","415609":"02352","415610":"02352","415611":"02352","415612":"02352","415613":"02352","415614":"02352","415615":"02352","415616":"02352","415617":"02352","415619":"02352","415620":"02352","415621":"02352","415626":"02352","415628":"02352","415629":"02352","415634":"02352","415637":"02352","415639":"02352","415640":"02352","415641":"02352","415643":"02352","415701":"02352","415702":"02352","415703":"02352","415705":"02352","415706":"02352","415708":"02352","415709":"02352","415710":"02352","415711":"02352","415712":"02352","415713":"02352","415714":"02352","415715":"02352","415716":"02352","415717":"02352","415718":"02352","415719":"02352","415720":"02352","415722":"02352","415724":"02352","415726":"02352","415727":"02352","415728":"02352","415729":"02352","415730":"02352","415801":"02352","415802":"02352","415803":"02352","415804":"02352","415805":"02352","415806":"02352","415807":"02352","416001":"0231","416002":"0231","416003":"0231","416004":"0231","416005":"0231","416006":"0231","416007":"0231","416008":"0231","416010":"0231","416011":"0231","416012":"0231","416013":"0231","416101":"0231","416102":"0231","416103":"0231","416104":"0231","416105":"0231","416106":"0231","416107":"0231","416108":"0231","416109":"0231","416110":"0231","416111":"0231","416112":"0231","416113":"0231","416114":"0231","416115":"0231","416116":"0231","416118":"0231","416119":"0231","416120":"0231","416121":"0231","416122":"0231","416138":"0231","416143":"0231","416144":"0231","416146":"0231","416201":"0231","416202":"0231","416203":"0231","416204":"0231","416205":"0231","416206":"0231","416207":"0231","416208":"0231","416209":"0231","416210":"0231","416211":"0231","416212":"0231","416213":"0231","416214":"0231","416215":"0231","416216":"0231","416218":"0231","416219":"0231","416220":"0231","416221":"0231","416223":"0231","416229":"0231","416230":"0231","416231":"0231","416232":"0231","416234":"0231","416235":"0231","416236":"0231","416301":"0233","416302":"0233","416303":"0233","416304":"0233","416305":"0233","416306":"0233","416307":"0233","416308":"0233","416309":"0233","416310":"0233","416311":"0233","416312":"0233","416313":"0233","416314":"0233","416315":"0233","416316":"0233","416401":"0233","416402":"0233","416403":"0233","416404":"0233","416405":"0233","416406":"0233","416407":"0233","416408":"0233","416409":"0233","416410":"0233","416411":"0233","416412":"0233","416413":"0233","416414":"0233","416415":"0233","416416":"0233","416417":"0233","416418":"0233","416419":"0233","416420":"0233","416436":"0233","416437":"0233","416501":"0231","416502":"0231","416503":"0231","416504":"0231","416505":"0231","416506":"0231","416507":"0231","416508":"0231","416509":"0231","416510":"02362","416511":"02362","416512":"02362","416513":"02362","416514":"02362","416515":"02362","416516":"02362","416517":"02362","416518":"02362","416519":"02362","416520":"02362","416521":"02362","416522":"02362","416523":"02362","416524":"02362","416525":"02362","416526":"0231","416527":"0231","416528":"02362","416529":"02362","416531":"02362","416534":"02362","416549":"02362","416550":"02362","416551":"0231","416552":"0231","416601":"02362","416602":"02362","416603":"02362","416604":"02362","416605":"02362","416606":"02362","416608":"02362","416609":"02362","416610":"02362","416611":"02362","416612":"02362","416613":"02362","416614":"02362","416615":"02362","416616":"02362","416620":"02362","416623":"02362","416626":"02362","416628":"02362","416630":"02362","416632":"02362","416701":"02352","416702":"02352","416703":"02362","416704":"02352","416705":"02352","416707":"02352","416709":"02352","416712":"02352","416713":"02352","416801":"02362","416803":"02362","416804":"02362","416805":"02362","416806":"02362","416807":"02362","416810":"02362","416811":"02362","416812":"02362","416813":"02362","421002":"022","421004":"022","421005":"022","421101":"022","421102":"022","421103":"022","421201":"022","421202":"022","421203":"022","421204":"022","421301":"022","421302":"022","421303":"02525","421305":"022","421306":"022","421308":"022","421311":"022","421312":"02525","421401":"022","421402":"022","421403":"022","421501":"022","421502":"022","421503":"022","421505":"022","421506":"022","421601":"022","421602":"022","421603":"022","421605":"022","422001":"0253","422002":"0253","422003":"0253","422004":"0253","422005":"0253","422006":"0253","422007":"0253","422008":"0253","422009":"0253","422010":"0253","422011":"0253","422012":"0253","422013":"0253","422101":"0253","422102":"0253","422103":"0253","422104":"0253","422105":"0253","422112":"0253","422113":"0253","422201":"0253","422202":"0253","422203":"0253","422204":"0253","422205":"0253","422206":"0253","422207":"0253","422208":"0253","422209":"0253","422210":"0253","422211":"0253","422212":"0253","422213":"0253","422214":"0253","422215":"0253","422221":"0253","422222":"0253","422301":"0253","422302":"0253","422303":"0253","422304":"0253","422305":"0253","422306":"0253","422308":"0253","422401":"0253","422402":"0253","422403":"0253","422501":"0253","422502":"0253","422601":"0241","422602":"0241","422603":"0241","422604":"0241","422605":"0241","422606":"0253","422608":"0241","422610":"0241","422611":"0241","422620":"0241","422622":"0241","423101":"0253","423102":"0253","423104":"0253","423105":"0253","423106":"0253","423107":"0241","423108":"0253","423109":"0241","423110":"0253","423111":"0253","423117":"0253","423201":"0253","423202":"0253","423203":"0253","423204":"0253","423205":"0253","423206":"0253","423208":"0253","423212":"0253","423213":"0253","423301":"0253","423302":"0253","423303":"0253","423401":"0253","423402":"0253","423403":"0253","423501":"0253","423502":"0253","423601":"0241","423602":"0241","423603":"0241","423604":"0241","423605":"0241","423607":"0241","423701":"0240","423702":"0240","423703":"0240","424001":"02562","424002":"02562","424004":"02562","424005":"02562","424006":"02562","424101":"0257","424102":"0257","424103":"0257","424104":"0257","424105":"0257","424106":"0257","424107":"0257","424108":"0257","424109":"0253","424119":"0257","424201":"0257","424202":"0257","424203":"0257","424204":"0257","424205":"0257","424206":"0257","424207":"0257","424208":"0257","424301":"02562","424302":"02562","424303":"02562","424304":"02562","424305":"02562","424306":"02562","424307":"02562","424308":"02562","424309":"02562","424310":"02562","424311":"02562","424318":"02562","425001":"0257","425002":"0257","425003":"0257","425004":"0257","425101":"0257","425102":"0257","425103":"0257","425104":"0257","425105":"0257","425107":"0257","425108":"0257","425109":"0257","425110":"0257","425111":"0257","425112":"0257","425113":"0257","425114":"0257","425115":"0257","425116":"0257","425201":"0257","425203":"0257","425301":"0257","425302":"0257","425303":"0257","425304":"0257","425305":"0257","425306":"0257","425307":"0257","425308":"0257","425309":"0257","425310":"0257","425311":"0257","425327":"0257","425401":"0257","425402":"0257","425403":"02562","425404":"02562","425405":"02562","425406":"02562","425407":"02562","425408":"02564","425409":"02564","425410":"02564","425411":"02564","425412":"02564","425413":"02564","425414":"02564","425415":"02564","425416":"02564","425417":"02564","425418":"02564","425419":"02564","425420":"0257","425421":"02562","425422":"02564","425423":"02564","425424":"02564","425426":"02564","425427":"02562","425428":"02562","425432":"02564","425442":"02564","425444":"02564","425452":"02564","425501":"0257","425502":"0257","425503":"0257","425504":"0257","425505":"0257","425506":"0257","425507":"0257","425508":"0257","425524":"0257","431001":"0240","431002":"0240","431003":"0240","431004":"0240","431005":"0240","431006":"0240","431007":"0240","431008":"0240","431009":"0240","431010":"0240","431011":"0240","431101":"0240","431102":"0240","431103":"0240","431104":"0240","431105":"0240","431107":"0240","431109":"0240","431110":"0240","431111":"0240","431112":"02482","431113":"0240","431114":"02482","431115":"0240","431116":"0240","431117":"0240","431118":"0240","431120":"0240","431121":"02482","431122":"02442","431123":"02442","431124":"02442","431125":"02442","431126":"02442","431127":"02442","431128":"02442","431129":"02442","431130":"02442","431131":"02442","431132":"02482","431133":"0240","431134":"02482","431135":"02482","431136":"0240","431137":"02482","431142":"02442","431143":"02442","431144":"02442","431147":"0240","431148":"0240","431150":"0240","431151":"0240","431152":"0240","431153":"02442","431154":"02482","431202":"02482","431203":"02482","431204":"02482","431205":"02482","431206":"02482","431207":"02482","431208":"02482","431209":"02482","431211":"02482","431212":"02482","431213":"02482","431214":"02482","431215":"02482","431401":"02452","431402":"02452","431501":"02482","431502":"02482","431503":"02452","431504":"02482","431505":"02452","431506":"02452","431507":"02482","431508":"02452","431509":"02452","431510":"02452","431511":"02452","431512":"02456","431513":"02456","431514":"02452","431515":"02442","431516":"02452","431517":"02442","431518":"02442","431519":"02442","431520":"02442","431521":"02452","431522":"02382","431523":"02442","431530":"02442","431536":"02452","431537":"02452","431540":"02452","431541":"02452","431542":"02456","431601":"02462","431602":"02462","431603":"02462","431604":"02462","431605":"02462","431606":"02462","431701":"02456","431702":"02456","431703":"02456","431704":"02462","431705":"02456","431707":"02462","431708":"02462","431709":"02462","431710":"02462","431711":"02462","431712":"02462","431713":"02462","431714":"02462","431715":"02462","431716":"02462","431717":"02462","431718":"02462","431719":"02462","431720":"02452","431721":"02462","431722":"02462","431723":"02462","431731":"02462","431736":"02462","431741":"02462","431742":"02462","431743":"02462","431745":"02462","431746":"02462","431750":"02462","431801":"02462","431802":"02462","431803":"02462","431804":"02462","431805":"02462","431806":"02462","431807":"02462","431808":"02462","431809":"02462","431810":"02462","431811":"02462","440001":"0712","440002":"0712","440003":"0712","440005":"0712","440006":"0712","440007":"0712","440008":"0712","440010":"0712","440012":"0712","440013":"0712","440014":"0712","440015":"0712","440016":"0712","440017":"0712","440018":"0712","440019":"0712","440020":"0712","440021":"0712","440022":"0712","440023":"0712","440024":"0712","440025":"0712","440026":"0712","440027":"0712","440030":"0712","440032":"0712","440033":"0712","440034":"0712","440035":"0712","440036":"0712","440037":"0712","441001":"0712","441101":"0712","441102":"0712","441103":"0712","441104":"0712","441105":"0712","441106":"0712","441107":"0712","441108":"0712","441109":"0712","441110":"0712","441111":"0712","441112":"0712","441113":"0712","441122":"0712","441123":"0712","441201":"0712","441202":"0712","441203":"0712","441204":"0712","441205":"07172","441206":"07172","441207":"07132","441208":"07132","441209":"07132","441210":"0712","441212":"07172","441214":"0712","441215":"07172","441217":"07132","441221":"07172","441222":"07172","441223":"07172","441224":"07172","441225":"07172","441226":"07172","441301":"0712","441302":"0712","441303":"0712","441304":"0712","441305":"0712","441306":"0712","441401":"0712","441404":"0712","441501":"0712","441502":"0712","441601":"07182","441614":"07182","441701":"07182","441702":"07182","441801":"07182","441802":"07184","441803":"07184","441804":"07184","441805":"07184","441806":"07182","441807":"07182","441809":"07184","441901":"07182","441902":"07182","441903":"07184","441904":"07184","441905":"07184","441906":"07184","441907":"07184","441908":"07184","441909":"07184","441910":"07184","441911":"07182","441912":"07184","441913":"07184","441914":"07184","441915":"07184","441916":"07182","441924":"07184","442001":"07152","442003":"07152","442101":"07152","442102":"07152","442104":"07152","442105":"07152","442106":"07152","442107":"07152","442111":"07152","442201":"07152","442202":"07152","442203":"07152","442301":"07152","442302":"07152","442303":"07152","442304":"07152","442305":"07152","442306":"07152","442307":"07152","442401":"07172","442402":"07172","442403":"07172","442404":"07172","442406":"07172","442501":"07172","442502":"07172","442503":"07172","442504":"07132","442505":"07172","442507":"07172","442603":"07132","442604":"07132","442605":"07132","442606":"07132","442701":"07172","442702":"07172","442703":"07132","442704":"07132","442705":"07132","442707":"07132","442709":"07132","442710":"07132","442901":"07172","442902":"07172","442903":"07172","442904":"07172","442905":"07172","442906":"07172","442907":"07172","442908":"07172","442914":"07172","442916":"07172","442917":"07172","442918":"07132","442919":"07132","443001":"07262","443002":"07262","443101":"07262","443102":"07262","443103":"07262","443104":"07262","443106":"07262","443112":"07262","443201":"07262","443202":"07262","443203":"07262","443204":"07262","443206":"07262","443301":"07262","443302":"07262","443303":"07262","443304":"07262","443308":"07262","443401":"07262","443402":"07262","443403":"07262","443404":"07262","444001":"0724","444002":"0724","444003":"0724","444004":"0724","444005":"0724","444006":"0724","444007":"0724","444101":"0724","444102":"0724","444103":"0724","444104":"0724","444105":"07252","444106":"0724","444107":"0724","444108":"0724","444109":"0724","444110":"07252","444111":"0724","444117":"0724","444126":"0724","444201":"07262","444202":"07262","444203":"07262","444204":"07262","444301":"07262","444302":"0724","444303":"07262","444304":"07262","444306":"07262","444311":"0724","444312":"07262","444401":"0724","444402":"07252","444403":"07252","444404":"07252","444405":"0724","444407":"0724","444409":"07252","444501":"0724","444502":"0724","444503":"07252","444504":"07252","444505":"07252","444506":"07252","444507":"07252","444510":"07252","444511":"0724","444601":"0721","444602":"0721","444603":"0721","444604":"0721","444605":"0721","444606":"0721","444607":"0721","444701":"0721","444702":"0721","444704":"0721","444705":"0721","444706":"0721","444707":"0721","444708":"0721","444709":"0721","444710":"0721","444711":"0721","444717":"0721","444719":"0721","444720":"0721","444723":"0721","444801":"0721","444802":"0721","444803":"0721","444804":"0721","444805":"0721","444806":"0721","444807":"0721","444808":"0721","444809":"0721","444810":"0721","444813":"0721","444901":"0721","444902":"0721","444903":"0721","444904":"0721","444905":"0721","444906":"0721","444907":"0721","444908":"0721","444915":"0721","445001":"07232","445002":"07232","445101":"07232","445102":"07232","445103":"07232","445105":"07232","445106":"07232","445109":"07232","445110":"07232","445201":"07232","445202":"07232","445203":"07232","445204":"07232","445205":"07232","445206":"07232","445207":"07232","445209":"07232","445210":"07232","445211":"07232","445215":"07232","445216":"07232","445230":"07232","445301":"07232","445302":"07232","445303":"07232","445304":"07232","445305":"07232","445306":"07232","445307":"07232","445308":"07232","445323":"07232","445324":"07232","445401":"07232","445402":"07232","450221":"07325","450331":"07325","450332":"07325","450445":"07325","450551":"07282","451001":"07282","451111":"07282","451113":"07282","451115":"07282","451220":"07282","451221":"07282","451224":"07282","451225":"07282","451228":"07282","451331":"07282","451332":"07282","451335":"07282","451440":"07282","451441":"07282","451442":"07282","451447":"07290","451449":"07282","451551":"07290","451556":"07290","451660":"07282","451666":"07290","451770":"07290","451881":"07290","452001":"0731","452002":"0731","452003":"0731","452005":"0731","452006":"0731","452007":"0731","452009":"0731","452010":"0731","452011":"0731","452012":"0731","452013":"0731","452014":"0731","452015":"0731","452016":"0731","452018":"0731","452020":"0731","453001":"0731","453111":"0731","453112":"0731","453115":"0731","453220":"0731","453331":"0731","453441":"0731","453446":"0731","453551":"0731","453552":"0731","453555":"0731","453556":"0731","453661":"0731","453771":"0731","454001":"07292","454010":"07292","454111":"07292","454116":"07292","454221":"07292","454331":"07292","454335":"07292","454441":"07292","454446":"07292","454449":"07292","454552":"07292","454660":"07292","454665":"07292","454773":"07292","454774":"07292","454775":"07292","455001":"07272","455111":"07272","455115":"07272","455116":"07272","455118":"07272","455221":"07272","455223":"07272","455227":"07272","455332":"07272","455336":"07272","455339":"07272","455440":"07272","455459":"07272","456001":"0734","456003":"0734","456006":"0734","456010":"0734","456221":"0734","456222":"0734","456224":"0734","456313":"0734","456331":"0734","456335":"0734","456337":"0734","456440":"0734","456441":"0734","456443":"0734","456550":"0734","456661":"0734","456664":"0734","456665":"0734","456668":"0734","456770":"0734","456771":"0734","456776":"0734","457001":"07412","457114":"07412","457118":"07412","457119":"07412","457222":"07412","457226":"07412","457331":"07412","457333":"07412","457336":"07412","457339":"07412","457340":"07412","457441":"07412","457550":"07412","457555":"07412","457661":"07392","457770":"07392","457772":"07392","457773":"07392","457775":"07392","457777":"07392","457779":"07392","457882":"07394","457885":"07394","457887":"07394","457888":"07394","457990":"07394","457993":"07392","458001":"07422","458002":"07422","458110":"07423","458113":"07423","458116":"07423","458118":"07423","458220":"07423","458226":"07423","458228":"07423","458330":"07423","458336":"07423","458339":"07423","458389":"07422","458441":"07423","458468":"07423","458470":"07423","458553":"07423","458556":"07422","458558":"07422","458664":"07422","458667":"07422","458669":"07422","458771":"07422","458775":"07422","458778":"07422","458880":"07422","458883":"07422","458888":"07422","458895":"07422","458990":"07422","460001":"07141","460004":"07141","460110":"07141","460220":"07141","460225":"07141","460330":"07141","460440":"07141","460443":"07141","460447":"07141","460449":"07141","460551":"07141","460553":"07141","460554":"07141","460557":"07141","460661":"07141","460663":"07162","460665":"07141","460666":"07141","460668":"07141","461001":"07792","461005":"07574","461110":"07574","461111":"07574","461114":"07574","461115":"07574","461116":"07574","461122":"07574","461221":"07574","461223":"07574","461228":"07574","461331":"07577","461335":"07577","461441":"07577","461446":"07574","461551":"07574","461661":"07574","461668":"07574","461771":"07574","461775":"07574","461881":"07574","461990":"07574","462001":"0755","462002":"0755","462003":"0755","462004":"0755","462008":"0755","462010":"0755","462011":"0755","462016":"0755","462020":"0755","462022":"0755","462023":"0755","462024":"0755","462026":"0755","462027":"0755","462030":"0755","462031":"0755","462033":"0755","462036":"0755","462037":"0755","462038":"0755","462039":"0755","462040":"0755","462041":"0755","462042":"0755","462043":"0755","462044":"0755","462045":"0755","462046":"07482","462047":"0755","462066":"0755","462100":"0755","462101":"0755","462120":"0755","463106":"0755","463111":"0755","464001":"07592","464111":"07592","464113":"07592","464114":"07592","464220":"07592","464221":"07592","464224":"07592","464226":"07592","464228":"07592","464240":"07592","464258":"07592","464331":"07592","464334":"07592","464337":"07592","464551":"07482","464570":"07482","464573":"07482","464651":"07482","464661":"07482","464665":"07482","464668":"07482","464671":"07482","464672":"07482","464770":"07482","464774":"07482","464776":"07482","464881":"07482","464884":"07482","464886":"07482","464986":"07482","464990":"07482","464993":"07482","465001":"07364","465106":"07364","465110":"07364","465113":"07364","465116":"07364","465118":"07364","465220":"07364","465223":"07364","465226":"07364","465227":"07364","465230":"07362","465333":"07364","465335":"07364","465337":"07364","465339":"07364","465441":"07362","465445":"07362","465447":"07362","465449":"07362","465550":"07362","465661":"07372","465667":"07372","465669":"07372","465674":"07372","465677":"07372","465679":"07372","465680":"07372","465683":"07372","465685":"07372","465687":"07372","465689":"07372","465691":"07372","465693":"07372","465697":"07372","466001":"07562","466111":"07562","466113":"07562","466114":"07562","466115":"07562","466116":"07562","466118":"07562","466120":"07562","466125":"07562","466221":"07562","466331":"07562","466445":"07562","466446":"07562","466448":"07562","466554":"07562","466651":"07562","466661":"07562","466665":"07562","470001":"07582","470002":"07582","470003":"07582","470004":"07582","470021":"07582","470051":"07582","470113":"07582","470115":"07582","470117":"07582","470118":"07582","470119":"07582","470120":"07582","470124":"07582","470125":"07582","470221":"07582","470223":"07582","470226":"07582","470227":"07582","470228":"07582","470229":"07582","470232":"07582","470235":"07582","470335":"07582","470337":"07582","470339":"07582","470340":"07582","470441":"07582","470442":"07582","470661":"07812","470663":"07812","470664":"07812","470666":"07812","470669":"07582","470672":"07812","470673":"07812","470675":"07812","470771":"07812","470772":"07812","470775":"07812","470880":"07812","470881":"07812","471001":"07682","471101":"07682","471105":"07682","471111":"07682","471201":"07682","471301":"07682","471311":"07682","471313":"07682","471315":"07682","471318":"07682","471405":"07682","471408":"07682","471411":"07682","471501":"07682","471510":"07682","471515":"07682","471516":"07682","471525":"07682","471606":"07682","471625":"07682","472001":"07683","472005":"07683","472010":"07683","472101":"07683","472111":"07683","472115":"07683","472118":"07683","472221":"07683","472246":"07680","472331":"07683","472336":"07680","472337":"07680","472339":"07683","472442":"07680","472445":"07680","472447":"07683","473001":"07542","473101":"07542","473105":"07542","473110":"07542","473111":"07542","473112":"07542","473113":"07542","473115":"07542","473118":"07542","473222":"07542","473226":"07542","473249":"07542","473287":"07542","473330":"07543","473331":"07543","473332":"07543","473335":"07543","473440":"07543","473443":"07543","473444":"07543","473445":"07543","473446":"07543","473551":"07492","473585":"07492","473638":"07492","473660":"07492","473662":"07492","473665":"07492","473670":"07492","473770":"07492","473774":"07492","473775":"07492","473781":"07492","473793":"07492","473865":"07492","473880":"07492","473885":"07492","473990":"07492","473995":"07492","474001":"0751","474002":"0751","474003":"0751","474004":"0751","474005":"0751","474006":"0751","474007":"0751","474008":"0751","474009":"0751","474010":"0751","474011":"0751","474012":"0751","474015":"0751","474020":"0751","475001":"0751","475002":"0751","475005":"0751","475110":"0751","475115":"0751","475220":"0751","475330":"0751","475335":"07522","475336":"07522","475661":"07522","475671":"07522","475673":"07522","475675":"07522","475682":"07522","475685":"07522","475686":"07522","476001":"07532","476111":"07532","476115":"07532","476134":"07532","476219":"07532","476221":"07532","476224":"07532","476228":"07532","476229":"07532","476332":"07530","476335":"07530","476337":"07530","476339":"07530","476355":"07530","476444":"07532","476554":"07532","477001":"07534","477105":"07534","477111":"07534","477116":"07534","477117":"07534","477222":"07534","477227":"07534","477331":"07534","477332":"07534","477333":"07534","477335":"07534","477441":"07534","477445":"07534","477446":"07534","477447":"07534","477449":"07534","477450":"07534","477555":"07534","477557":"07534","477566":"07534","477660":"07534","480001":"07162","480003":"07162","480105":"07162","480106":"07162","480107":"07162","480108":"07162","480109":"07162","480110":"07162","480111":"07162","480112":"07162","480115":"07162","480221":"07162","480223":"07162","480224":"07162","480331":"07162","480334":"07162","480337":"07162","480338":"07162","480441":"07162","480447":"07162","480449":"07162","480551":"07162","480555":"07162","480557":"07162","480559":"07162","480661":"07692","480667":"07692","480771":"07692","480880":"07692","480881":"07692","480882":"07692","480884":"07692","480886":"07692","480887":"07692","480888":"07692","480990":"07692","480991":"07692","480994":"07692","480996":"07692","480997":"07692","480999":"07692","481001":"07632","481051":"07632","481102":"07632","481105":"07632","481111":"07632","481115":"07632","481116":"07632","481117":"07632","481222":"07632","481224":"07632","481226":"07632","481331":"07632","481332":"07632","481335":"07632","481337":"07632","481441":"07632","481445":"07632","481449":"07632","481551":"07632","481556":"07632","481661":"07642","481662":"07642","481663":"07642","481664":"07642","481665":"07642","481666":"07642","481668":"07642","481672":"07642","481768":"07642","481771":"07642","481776":"07642","481778":"07644","481879":"07644","481880":"07644","481882":"07644","481883":"07644","481884":"07644","481885":"07642","481990":"07644","481995":"07642","481996":"07642","481998":"07642","482001":"0761","482002":"0761","482003":"0761","482004":"0761","482005":"0761","482008":"0761","482009":"0761","482010":"0761","482011":"0761","482020":"0761","482021":"0761","482051":"0761","482056":"0761","483001":"0761","483053":"0761","483105":"0761","483110":"0761","483113":"0761","483119":"0761","483220":"0761","483222":"0761","483225":"07622","483330":"07622","483331":"07622","483332":"07622","483334":"07622","483336":"0761","483440":"07622","483442":"07622","483501":"07622","483504":"07622","483770":"07622","483773":"07622","483775":"07622","483880":"07622","483990":"07622","484001":"07625","484110":"07652","484113":"07629","484114":"07652","484116":"07652","484117":"07652","484120":"07629","484220":"07629","484224":"07652","484330":"07629","484334":"07629","484336":"07629","484440":"07629","484444":"07629","484446":"07629","484447":"07629","484551":"07625","484555":"07625","484660":"07625","484661":"07625","484664":"07625","484665":"07625","484669":"07652","484770":"07652","484771":"07652","484774":"07652","484776":"07652","484881":"07629","484886":"07629","484887":"07629","485001":"07672","485005":"07672","485111":"07672","485112":"07672","485113":"07672","485114":"07672","485115":"07672","485221":"07672","485226":"07672","485331":"07672","485334":"07672","485441":"07672","485446":"07672","485447":"07672","485551":"07672","485661":"07672","485666":"07672","485771":"07672","485772":"07672","485773":"07672","485774":"07672","485775":"07672","485778":"07672","485881":"07672","486001":"07662","486002":"07662","486003":"07662","486004":"07662","486005":"07662","486006":"07662","486111":"07662","486114":"07662","486115":"07662","486117":"07662","486123":"07662","486220":"07662","486223":"07662","486226":"07662","486331":"07662","486333":"07662","486335":"07662","486338":"07662","486340":"07662","486341":"07662","486440":"07662","486441":"07662","486445":"07672","486446":"07662","486447":"07662","486448":"07662","486450":"07662","486550":"07672","486553":"07662","486556":"07662","486661":"07822","486666":"07822","486669":"07805","486670":"07822","486675":"07822","486771":"07822","486775":"07822","486776":"07822","486881":"07805","486882":"07805","486884":"07805","486885":"07805","486886":"07805","486887":"07805","486888":"07805","486889":"07805","486890":"07805","486892":"07805","487001":"07792","487110":"07792","487114":"07792","487118":"07792","487221":"07792","487225":"07792","487330":"07792","487334":"07792","487337":"07792","487441":"07792","487551":"07792","487555":"07792","487661":"07792","487770":"07792","487881":"07792","488001":"07732","488050":"07732","488059":"07732","488220":"07732","488222":"07732","488333":"07732","488441":"07732","488442":"07732","488443":"07732","488446":"07732","488448":"07732","490001":"0788","490006":"0788","490009":"0788","490011":"0788","490020":"0788","490021":"0788","490022":"0788","490023":"0788","490024":"0788","490025":"0788","490026":"0788","490036":"0788","490042":"0788","491001":"0788","491107":"0788","491111":"0788","491221":"0788","491222":"0788","491223":"0788","491225":"0788","491226":"07749","491227":"07749","491228":"07749","491229":"07744","491230":"07749","491331":"0788","491332":"0788","491335":"07824","491336":"07817","491337":"07824","491338":"07824","491340":"07824","491441":"07744","491444":"07744","491445":"07744","491557":"07744","491558":"07744","491559":"07817","491661":"07744","491665":"07744","491666":"07744","491668":"07744","491771":"07749","491881":"07744","491885":"07744","491888":"07744","491993":"07824","491995":"07817","491996":"07817","492001":"0771","492002":"0771","492003":"0771","492004":"0771","492005":"0771","492008":"0771","492009":"0771","492010":"0771","492012":"0771","492013":"0771","492014":"0771","492015":"0771","492016":"0771","492017":"0771","492018":"0771","492099":"0771","492101":"0771","492109":"07707","492112":"07723","493101":"07826","493111":"0771","493113":"07826","493114":"0771","493116":"0771","493118":"07826","493195":"0771","493196":"07826","493221":"0771","493222":"07826","493225":"0771","493228":"07826","493229":"07826","493331":"07826","493332":"07826","493335":"07826","493338":"07826","493344":"07826","493441":"0771","493445":"07723","493448":"07723","493449":"07723","493526":"07826","493551":"07723","493554":"07723","493555":"07723","493558":"07723","493559":"07826","493661":"0771","493662":"07722","493663":"07722","493770":"07722","493773":"07722","493776":"07722","493778":"07722","493881":"0771","493885":"0771","493887":"07707","493888":"07707","493889":"07707","493890":"07707","493891":"07707","493992":"07707","493996":"07707","494001":"07782","494010":"07782","494111":"07864","494114":"07864","494115":"07864","494122":"07864","494221":"07782","494222":"07782","494223":"07782","494224":"07782","494226":"07786","494228":"07786","494229":"07786","494230":"07786","494237":"07781","494331":"07786","494332":"07868","494333":"07868","494334":"07868","494335":"07868","494336":"07868","494337":"07868","494347":"07786","494441":"07856","494442":"07782","494444":"07853","494446":"07853","494447":"07853","494448":"07853","494449":"07856","494450":"07853","494552":"07856","494553":"07856","494556":"07856","494635":"07868","494661":"07781","494665":"07868","494669":"07868","494670":"07868","494771":"07868","494776":"07868","494777":"07868","495001":"07752","495003":"07752","495004":"07752","495006":"07752","495009":"07752","495112":"07752","495113":"07755","495115":"07755","495116":"07752","495117":"08476","495118":"08476","495119":"07759","495220":"07752","495222":"07752","495224":"07755","495330":"07755","495334":"07755","495335":"07755","495442":"07759","495444":"07759","495445":"07759","495446":"07759","495447":"07759","495448":"07759","495449":"07759","495450":"07759","495452":"07759","495454":"07759","495455":"07759","495550":"07752","495551":"07752","495552":"07817","495553":"07817","495554":"07817","495555":"07752","495556":"07817","495557":"07817","495559":"07817","495660":"07817","495661":"07817","495663":"07817","495668":"07817","495669":"07817","495671":"07759","495674":"07759","495677":"07759","495682":"07759","495683":"07759","495684":"07759","495686":"07817","495687":"07817","495688":"07817","495689":"07817","495690":"07817","495691":"07817","495692":"07817","495695":"07817","496001":"07762","496005":"07762","496100":"07762","496107":"07762","496108":"07762","496109":"07762","496111":"07762","496113":"07762","496115":"07762","496116":"07762","496118":"07762","496220":"07762","496223":"07774","496224":"07763","496225":"07763","496227":"07763","496242":"07763","496245":"07763","496330":"07763","496331":"07763","496334":"07763","496336":"07763","496338":"07763","496440":"07762","496445":"07762","496450":"07762","496551":"07762","496554":"07762","496661":"07762","496665":"07762","497001":"07774","497101":"07774","497111":"07774","497114":"07774","497116":"07774","497117":"07774","497118":"07831","497119":"07831","497220":"07831","497223":"07775","497224":"07831","497225":"07775","497226":"07775","497229":"07775","497231":"07775","497235":"07775","497331":"07836","497333":"07775","497335":"07836","497339":"07836","497442":"07836","497446":"07836","497447":"07836","497448":"07836","497449":"07836","497450":"07836","497451":"07836","497553":"07836","497555":"07836","497557":"07836","497559":"07836","497773":"07836","497778":"07836","500001":"040","500002":"040","500003":"040","500004":"040","500005":"08418","500006":"040","500007":"040","500008":"040","500009":"040","500010":"040","500011":"040","500012":"040","500013":"040","500014":"040","500015":"040","500016":"040","500017":"040","500018":"040","500019":"08414","500020":"040","500022":"040","500023":"040","500024":"040","500025":"040","500026":"040","500027":"040","500028":"040","500029":"040","500030":"08418","500031":"040","500032":"08414","500033":"040","500034":"040","500035":"08414","500036":"040","500037":"040","500038":"040","500039":"040","500040":"040","500041":"040","500042":"040","500043":"040","500044":"040","500045":"040","500046":"08414","500047":"040","500048":"08414","500049":"040","500050":"08414","500051":"040","500052":"08418","500053":"040","500054":"040","500055":"08418","500056":"040","500057":"040","500058":"040","500059":"040","500060":"08414","500061":"040","500062":"040","500063":"040","500064":"040","500065":"040","500066":"040","500067":"040","500068":"040","500069":"08414","500070":"08414","500072":"040","500073":"040","500074":"08414","500075":"08418","500076":"040","500077":"08414","500078":"040","500079":"08418","500080":"040","500081":"040","500082":"040","500083":"040","500084":"040","500085":"040","500086":"08414","500087":"08418","500088":"08418","500089":"08418","500090":"08418","500091":"08414","500092":"040","500093":"040","500094":"040","500095":"040","500096":"040","500097":"08414","500098":"040","500100":"040","500101":"08418","500102":"08414","500103":"040","500104":"08414","500107":"040","500108":"08414","500109":"040","500110":"040","500111":"08414","500112":"040","500113":"08418","500114":"040","500115":"08414","501101":"08416","501102":"08416","501106":"08416","501111":"08416","501121":"08416","501141":"08416","501142":"08416","501143":"08416","501144":"08416","501158":"08416","501202":"08416","501203":"08416","501218":"08418","501301":"08418","501359":"08418","501401":"08418","501501":"08416","501502":"08416","501503":"08418","501504":"08418","501505":"08418","501506":"08418","501508":"08418","501509":"08418","501510":"08418","501511":"08414","501512":"08418","502001":"08455","502032":"08455","502101":"08452","502102":"08457","502103":"08457","502107":"08457","502108":"08457","502109":"08452","502110":"08452","502113":"08452","502114":"08457","502115":"08452","502117":"08452","502125":"08452","502130":"08452","502205":"08455","502210":"08455","502220":"08455","502221":"08455","502228":"08455","502246":"08455","502247":"08457","502248":"08452","502249":"08455","502251":"08455","502255":"08452","502256":"08455","502257":"08455","502267":"08457","502269":"08455","502270":"08455","502271":"08452","502273":"08455","502276":"08457","502277":"08457","502278":"08457","502279":"08457","502280":"08457","502281":"08457","502284":"08455","502285":"08455","502286":"08455","502287":"08455","502290":"08455","502291":"08455","502293":"08455","502294":"08455","502295":"08455","502296":"08455","502300":"08455","502301":"08457","502302":"08452","502303":"08452","502305":"08455","502306":"08455","502307":"08455","502310":"08457","502311":"08457","502312":"08457","502313":"08455","502314":"08455","502316":"08452","502318":"08455","502319":"08455","502321":"08455","502324":"08455","502325":"08455","502329":"08455","502331":"08452","502334":"08457","502335":"08452","502336":"08457","502345":"08416","502371":"08455","502372":"08457","502375":"08457","502381":"08452","503001":"08462","503002":"08462","503003":"08462","503101":"08468","503102":"08468","503108":"08468","503110":"08468","503111":"08468","503112":"08468","503114":"08468","503120":"08468","503122":"08468","503123":"08468","503124":"08468","503125":"08468","503144":"08468","503145":"08922","503164":"08462","503165":"08462","503174":"08462","503175":"08462","503180":"08462","503185":"08462","503186":"08462","503187":"08468","503188":"08922","503201":"08462","503202":"08462","503206":"08462","503207":"08462","503212":"08462","503213":"08462","503217":"08462","503218":"08462","503219":"08462","503223":"08462","503224":"08462","503225":"08922","503230":"08922","503235":"08922","503245":"08462","503246":"08462","503301":"08468","503302":"08468","503305":"08468","503306":"08468","503307":"08462","503308":"08462","503309":"08468","503310":"08468","503311":"08462","503321":"08922","503322":"08462","504001":"08732","504002":"08732","504101":"08734","504102":"08734","504103":"08734","504104":"08734","504105":"08734","504106":"08734","504107":"08734","504109":"08734","504110":"08734","504201":"08736","504202":"08734","504203":"08734","504204":"08736","504205":"08734","504206":"08736","504207":"08736","504208":"08736","504209":"08736","504214":"08736","504215":"08736","504216":"08736","504218":"08736","504219":"08736","504220":"08736","504231":"08736","504251":"08736","504272":"08736","504273":"08736","504292":"08733","504293":"08733","504294":"08738","504295":"08733","504296":"08733","504297":"08733","504299":"08733","504301":"08736","504302":"08736","504303":"08736","504304":"08732","504306":"08734","504307":"08732","504308":"08732","504309":"08732","504310":"08734","504311":"08732","504312":"08732","504313":"08733","504323":"08732","504346":"08592","505001":"0878","505002":"0878","505101":"0870","505102":"0870","505122":"0878","505129":"0878","505152":"08728","505153":"08728","505162":"08728","505172":"08728","505174":"08728","505184":"08728","505185":"08728","505186":"08728","505187":"08922","505188":"08728","505208":"08728","505209":"08728","505210":"08728","505211":"08728","505212":"08728","505214":"08728","505215":"08728","505301":"08723","505302":"08723","505303":"08723","505304":"08723","505305":"08723","505306":"08724","505307":"08723","505325":"08462","505326":"08724","505327":"08724","505330":"08724","505331":"08724","505401":"0878","505402":"08723","505403":"08723","505404":"08723","505405":"08723","505415":"08728","505416":"08728","505425":"08724","505445":"0878","505450":"08724","505451":"0878","505452":"08724","505453":"08724","505454":"08724","505455":"08724","505460":"08724","505462":"08724","505466":"08457","505467":"08457","505468":"0878","505469":"0878","505470":"0878","505471":"0870","505472":"08457","505473":"08457","505474":"0878","505475":"0878","505476":"0870","505480":"0870","505481":"08457","505490":"0878","505497":"0870","505498":"0878","505501":"08724","505502":"0878","505503":"08922","505504":"0870","505505":"0878","505514":"08728","505524":"08723","505525":"08922","505526":"08724","505527":"0878","505528":"08457","505529":"08724","505530":"08457","505531":"0878","505532":"08724","506001":"0870","506002":"0870","506003":"0870","506004":"0870","506005":"0870","506006":"0870","506007":"0870","506008":"0870","506009":"0870","506011":"0870","506013":"0870","506015":"0870","506101":"08719","506102":"08719","506103":"08719","506104":"08719","506105":"08719","506112":"08719","506122":"0870","506132":"0870","506134":"08719","506135":"08719","506142":"0870","506143":"08716","506144":"08716","506145":"08716","506146":"08716","506151":"0870","506163":"08719","506164":"0870","506165":"08715","506166":"0870","506167":"08716","506168":"0870","506169":"0870","506170":"0870","506172":"08715","506175":"08716","506201":"08716","506221":"08716","506222":"08716","506223":"08457","506224":"08457","506244":"08716","506252":"08716","506301":"08716","506302":"08716","506303":"08716","506310":"0870","506313":"0870","506314":"0870","506315":"08719","506316":"08716","506317":"08719","506318":"08719","506319":"0870","506324":"08719","506329":"0870","506330":"0870","506331":"0870","506332":"0870","506333":"0870","506342":"0870","506343":"08715","506344":"08715","506345":"0870","506347":"08715","506348":"0870","506349":"08715","506350":"0870","506352":"08715","506355":"08457","506356":"0870","506365":"0870","506366":"0870","506367":"08457","506368":"08719","506369":"0870","506370":"0870","506371":"0870","506381":"08719","506391":"0870","507001":"08742","507002":"08742","507003":"08742","507101":"08743","507103":"08743","507111":"08743","507114":"08744","507115":"08744","507116":"08744","507117":"08744","507118":"08744","507119":"08743","507120":"08744","507122":"08719","507123":"08742","507124":"08743","507125":"08743","507128":"08744","507133":"08744","507136":"08715","507137":"08744","507138":"08743","507140":"08744","507154":"08743","507157":"08742","507158":"08742","507159":"08742","507160":"08742","507161":"08742","507163":"08742","507164":"08742","507165":"08742","507166":"08743","507167":"08742","507168":"08742","507169":"08742","507170":"08742","507182":"08742","507183":"08742","507201":"08742","507202":"08742","507203":"08742","507204":"08742","507208":"08742","507209":"08742","507210":"08719","507211":"08719","507301":"08743","507302":"08742","507303":"08742","507304":"08742","507305":"08742","507306":"08743","507316":"08742","507318":"08742","508001":"08682","508002":"08682","508004":"08682","508101":"08585","508105":"08585","508111":"08585","508112":"08585","508113":"08585","508114":"08682","508115":"08585","508116":"08685","508117":"08585","508126":"08585","508201":"08684","508202":"08682","508204":"08684","508205":"08682","508206":"08684","508207":"08682","508208":"08682","508210":"08682","508211":"08682","508212":"08684","508213":"08684","508214":"08684","508217":"08682","508218":"08684","508221":"08684","508223":"08684","508224":"08684","508233":"08684","508234":"08684","508238":"08684","508243":"08682","508244":"08682","508245":"08682","508246":"08684","508247":"08682","508248":"08682","508250":"08682","508252":"08585","508253":"08585","508254":"08682","508255":"08682","508256":"08682","508257":"08682","508258":"08682","508266":"08682","508277":"08585","508278":"08682","508279":"08684","508280":"08684","508284":"08585","508285":"08585","508286":"08585","508355":"08684","508373":"08682","508374":"08682","508376":"08684","508377":"08682","509001":"08542","509002":"08542","509102":"08540","509103":"08543","509104":"08543","509105":"08543","509106":"08543","509110":"08543","509120":"08543","509125":"08546","509126":"08546","509127":"08546","509128":"08546","509129":"08546","509130":"08543","509131":"08543","509132":"03472","509133":"08546","509135":"08546","509152":"08546","509153":"08546","509201":"08540","509202":"08542","509203":"08540","509204":"08506","509205":"08506","509206":"08543","509207":"08418","509208":"08506","509209":"08540","509210":"08506","509215":"08540","509216":"08418","509217":"08418","509219":"08542","509228":"08418","509235":"08543","509301":"08542","509302":"08540","509311":"08506","509320":"08455","509321":"08418","509324":"08922","509325":"08418","509326":"08540","509327":"08418","509334":"08542","509335":"08416","509336":"08416","509337":"08542","509338":"08416","509339":"08416","509340":"08416","509349":"08540","509350":"08416","509351":"08506","509352":"08506","509353":"08506","509357":"08542","509358":"08418","509360":"08540","509371":"08506","509375":"08540","509376":"08540","509380":"08543","509381":"08543","509382":"08543","509385":"08540","509401":"08540","509406":"08540","509407":"08506","509408":"08418","509409":"08506","509410":"08418","509411":"08506","509412":"08540","515001":"08554","515002":"08554","515003":"08554","515004":"08554","515005":"08554","515101":"08554","515110":"08554","515122":"08554","515123":"08554","515124":"08554","515133":"08554","515134":"08554","515144":"08554","515154":"08554","515159":"08554","515164":"08554","515201":"08554","515202":"08554","515211":"08554","515212":"08554","515231":"08554","515241":"08554","515261":"08554","515271":"08554","515281":"08554","515286":"08554","515291":"08554","515301":"08554","515303":"08554","515305":"08554","515311":"08554","515321":"08554","515331":"08554","515341":"08554","515401":"08554","515402":"08554","515405":"08554","515408":"08554","515411":"08554","515413":"08554","515414":"08554","515415":"08554","515425":"08554","515435":"08554","515445":"08554","515455":"08554","515465":"08562","515501":"08554","515511":"08554","515521":"08554","515531":"08554","515541":"08554","515551":"08554","515556":"08554","515561":"08554","515571":"08554","515581":"08554","515591":"08554","515601":"08554","515611":"08554","515621":"08554","515631":"08554","515641":"08554","515651":"08554","515661":"08554","515671":"08554","515672":"08554","515701":"08554","515711":"08554","515721":"08554","515722":"08554","515731":"08554","515741":"08554","515751":"08554","515761":"08554","515763":"08554","515765":"08554","515766":"08554","515767":"08554","515774":"08554","515775":"08554","515787":"08554","515801":"08554","515803":"08554","515812":"08554","515822":"08554","515832":"08554","515842":"08554","515863":"08554","515865":"08554","515867":"08554","515870":"08554","515871":"08554","515872":"08554","516001":"08562","516002":"08562","516003":"08562","516004":"08562","516005":"08562","516101":"08562","516104":"08562","516105":"08562","516107":"08562","516108":"08562","516110":"08562","516115":"08562","516126":"08562","516127":"08562","516128":"08562","516129":"08562","516130":"08562","516150":"08562","516151":"08562","516152":"08562","516162":"08562","516163":"08562","516172":"08562","516173":"08562","516175":"08562","516193":"08562","516203":"08562","516213":"08562","516214":"08562","516215":"08562","516216":"08562","516217":"08562","516218":"08562","516227":"08562","516228":"08562","516233":"08562","516237":"08562","516247":"08562","516257":"08562","516259":"08562","516267":"08562","516268":"08562","516269":"08562","516270":"08562","516289":"08562","516293":"08562","516309":"08562","516310":"08562","516311":"08562","516312":"08562","516321":"08562","516329":"08562","516330":"08562","516339":"08562","516349":"08562","516350":"08562","516355":"08562","516356":"08562","516359":"08562","516360":"08562","516361":"08562","516362":"08562","516380":"08562","516390":"08562","516391":"08562","516396":"08562","516401":"08562","516411":"08562","516421":"08562","516431":"08562","516432":"08562","516433":"08562","516434":"08562","516439":"08562","516444":"08562","516454":"08562","516464":"08562","516474":"08562","516484":"08562","516501":"08562","516502":"08562","516503":"08562","516504":"08562","516505":"08562","517001":"08572","517002":"08572","517004":"08572","517101":"08572","517102":"08572","517112":"08572","517113":"08572","517123":"08572","517124":"08572","517125":"08572","517126":"08572","517127":"08572","517128":"08572","517129":"08572","517130":"08572","517131":"08572","517132":"08572","517152":"08572","517167":"08572","517172":"08572","517192":"08572","517193":"08572","517194":"08572","517213":"08572","517214":"08572","517234":"08572","517235":"08572","517236":"08572","517237":"08572","517247":"08572","517257":"08572","517277":"08572","517280":"08572","517291":"08572","517297":"08572","517299":"08572","517305":"08572","517319":"08572","517325":"08572","517326":"08572","517350":"08572","517351":"08572","517352":"08572","517370":"08572","517390":"08572","517391":"08572","517401":"08572","517403":"08572","517408":"08572","517414":"08572","517415":"08572","517416":"08572","517417":"08572","517418":"08572","517419":"08572","517421":"08572","517422":"08572","517423":"08572","517424":"08572","517425":"08572","517426":"08572","517429":"08572","517432":"08572","517501":"08572","517502":"08572","517503":"08572","517504":"08572","517505":"08572","517506":"08572","517507":"08572","517520":"08572","517526":"08572","517536":"08572","517541":"08572","517551":"08572","517561":"08572","517569":"08572","517571":"08572","517581":"08572","517582":"08572","517583":"08572","517584":"08572","517586":"08572","517587":"08572","517588":"08572","517589":"08572","517590":"08572","517591":"08572","517592":"08572","517599":"08572","517619":"08572","517620":"08572","517640":"08572","517641":"08572","517642":"08572","517643":"08572","517644":"08572","517645":"08572","517646":"08572","518001":"08518","518002":"08518","518003":"08518","518004":"08518","518005":"08518","518006":"08518","518007":"08518","518010":"08518","518101":"08518","518102":"08518","518112":"08518","518122":"08518","518123":"08518","518124":"08518","518134":"08518","518135":"08518","518145":"08518","518155":"08518","518165":"08518","518166":"08518","518176":"08518","518186":"08518","518196":"08518","518206":"08518","518216":"08518","518217":"08518","518218":"08518","518220":"08518","518221":"08518","518222":"08518","518225":"08518","518301":"08518","518302":"08518","518308":"08518","518313":"08518","518323":"08518","518333":"08518","518343":"08518","518344":"08518","518345":"08518","518346":"08518","518347":"08518","518348":"08518","518349":"08518","518350":"08518","518360":"08518","518380":"08518","518385":"08518","518390":"08518","518395":"08518","518396":"08518","518401":"08518","518405":"08518","518411":"08518","518412":"08518","518422":"08518","518432":"08518","518442":"08518","518452":"08518","518462":"08518","518463":"08518","518464":"08518","518465":"08518","518466":"08518","518467":"08518","518468":"08518","518501":"08518","518502":"08518","518508":"08518","518510":"08518","518511":"08518","518512":"08518","518513":"08518","518523":"08518","518533":"08518","518543":"08518","518553":"08518","518563":"08518","518573":"08518","518583":"08518","518593":"08518","518594":"08518","518598":"08518","518599":"08518","518674":"08518","520001":"03472","520002":"03472","520003":"03472","520004":"03472","520007":"03472","520008":"03472","520010":"03472","520011":"03472","520012":"03472","520013":"03472","520015":"03472","521001":"03472","521002":"03472","521003":"03472","521004":"03472","521101":"03472","521102":"03472","521104":"03472","521105":"03472","521106":"03472","521107":"03472","521108":"03472","521109":"03472","521110":"03472","521111":"03472","521120":"03472","521121":"03472","521122":"03472","521125":"03472","521126":"03472","521130":"03472","521131":"03472","521132":"03472","521133":"03472","521134":"03472","521135":"03472","521136":"03472","521137":"03472","521138":"03472","521139":"03472","521148":"03472","521149":"03472","521150":"03472","521151":"03472","521153":"03472","521156":"03472","521157":"03472","521158":"03472","521162":"03472","521163":"03472","521164":"03472","521165":"03472","521170":"03472","521175":"03472","521178":"03472","521180":"03472","521181":"03472","521182":"03472","521183":"03472","521184":"03472","521185":"03472","521190":"03472","521201":"03472","521202":"03472","521207":"03472","521211":"03472","521212":"03472","521213":"03472","521214":"03472","521215":"03472","521225":"03472","521226":"03472","521227":"03472","521228":"03472","521229":"03472","521230":"03472","521231":"03472","521235":"03472","521241":"03472","521245":"03472","521246":"03472","521247":"03472","521250":"03472","521256":"03472","521260":"03472","521261":"03472","521263":"03472","521286":"03472","521301":"03472","521311":"03472","521312":"03472","521320":"03472","521321":"03472","521322":"03472","521323":"03472","521324":"03472","521325":"03472","521326":"03472","521327":"03472","521328":"03472","521329":"03472","521330":"03472","521331":"03472","521332":"03472","521333":"03472","521340":"03472","521343":"03472","521344":"03472","521345":"03472","521356":"03472","521366":"03472","521369":"03472","521390":"03472","521401":"03472","521402":"03472","521403":"03472","521456":"03472","521457":"03472","522001":"0863","522002":"0863","522003":"0863","522004":"0863","522005":"0863","522006":"0863","522007":"0863","522009":"0863","522015":"0863","522016":"0863","522017":"0863","522018":"0863","522019":"0863","522020":"0863","522034":"0863","522101":"0863","522102":"0863","522111":"0863","522112":"0863","522113":"0863","522124":"0863","522201":"0863","522202":"0863","522211":"0863","522212":"0863","522213":"0863","522233":"0863","522234":"0863","522235":"0863","522236":"0863","522237":"0863","522238":"0863","522239":"0863","522240":"0863","522256":"0863","522257":"0863","522258":"0863","522259":"0863","522261":"0863","522262":"0863","522264":"0863","522265":"0863","522268":"0863","522301":"0863","522302":"0863","522303":"0863","522304":"0863","522305":"0863","522306":"0863","522307":"0863","522308":"0863","522309":"0863","522310":"0863","522311":"0863","522312":"0863","522313":"0863","522314":"0863","522315":"0863","522316":"0863","522317":"0863","522318":"0863","522324":"0863","522325":"0863","522329":"0863","522330":"0863","522341":"0863","522401":"0863","522402":"0863","522403":"0863","522408":"0863","522409":"0863","522410":"0863","522411":"0863","522412":"0863","522413":"0863","522414":"0863","522415":"0863","522421":"0863","522426":"0863","522435":"0863","522436":"0863","522437":"0863","522438":"0863","522439":"0863","522501":"0863","522502":"0863","522503":"0863","522508":"0863","522509":"0863","522510":"0863","522529":"0863","522549":"0863","522601":"0863","522603":"0863","522611":"0863","522612":"0863","522613":"0863","522614":"0863","522615":"0863","522616":"0863","522617":"0863","522619":"0863","522626":"0863","522646":"0863","522647":"0863","522649":"0863","522657":"0863","522658":"0863","522659":"0863","522660":"0863","522661":"0863","522663":"0863","523001":"08592","523002":"08592","523101":"08592","523104":"08592","523105":"08592","523108":"08592","523109":"08592","523110":"08592","523111":"08592","523112":"08592","523113":"08592","523114":"08592","523115":"08592","523116":"08592","523117":"08592","523135":"08592","523155":"08592","523156":"08592","523157":"08592","523165":"08592","523166":"08592","523167":"08592","523168":"08592","523169":"08592","523170":"08592","523171":"08592","523180":"08592","523181":"08592","523182":"08592","523183":"08592","523184":"08592","523185":"08592","523186":"08592","523187":"08592","523190":"08592","523201":"08592","523211":"08592","523212":"08592","523213":"08592","523214":"08592","523223":"08592","523224":"08592","523225":"08592","523226":"08592","523227":"08592","523228":"08592","523230":"08592","523240":"08592","523241":"08592","523245":"08592","523246":"08592","523247":"08592","523252":"08592","523253":"08592","523254":"08592","523260":"08592","523261":"08592","523262":"08592","523263":"08592","523264":"08592","523265":"08592","523270":"08592","523271":"08592","523272":"08592","523273":"08592","523274":"08592","523279":"08592","523280":"08592","523281":"08592","523286":"08592","523291":"08592","523292":"08592","523301":"08592","523302":"08592","523303":"08592","523304":"08592","523305":"08592","523315":"08592","523316":"08592","523320":"08592","523326":"08592","523327":"08592","523328":"08592","523329":"08592","523330":"08592","523331":"08592","523332":"08592","523333":"08592","523334":"08592","523335":"08592","523336":"08592","523346":"08592","523356":"08592","523357":"08592","523367":"08592","523368":"08592","523369":"08592","523370":"08592","523371":"08592","523372":"08592","523373":"08592","524001":"0861","524002":"0861","524003":"0861","524004":"0861","524005":"0861","524101":"0861","524121":"0861","524123":"0861","524124":"0861","524126":"0861","524127":"0861","524129":"0861","524131":"0861","524132":"0861","524134":"0861","524137":"0861","524142":"0861","524152":"0861","524201":"0861","524203":"0861","524221":"0861","524222":"0861","524223":"0861","524224":"0861","524225":"0861","524226":"0861","524227":"0861","524228":"0861","524230":"0861","524234":"0861","524236":"0861","524239":"0861","524240":"0861","524300":"0861","524302":"0861","524303":"0861","524304":"0861","524305":"0861","524306":"0861","524307":"0861","524308":"0861","524309":"0861","524310":"0861","524311":"0861","524312":"0861","524313":"0861","524314":"0861","524315":"0861","524316":"0861","524317":"0861","524318":"0861","524319":"0861","524320":"0861","524321":"0861","524322":"0861","524323":"0861","524324":"0861","524341":"0861","524342":"0861","524343":"0861","524344":"0861","524345":"0861","524346":"0861","524347":"0861","524366":"0861","524401":"0861","524402":"0861","524403":"0861","524404":"0861","524405":"0861","524406":"0861","524407":"0861","524408":"0861","524409":"0861","524410":"0861","524411":"0861","524412":"0861","524413":"0861","524414":"0861","524415":"0861","524421":"0861","530001":"0891","530002":"0891","530003":"0891","530004":"0891","530005":"0891","530007":"0891","530008":"0891","530009":"0891","530011":"0891","530012":"0891","530013":"0891","530014":"0891","530015":"0891","530016":"0891","530017":"0891","530018":"0891","530020":"0891","530022":"0891","530024":"0891","530026":"0891","530027":"0891","530028":"0891","530029":"0891","530031":"0891","530032":"0891","530040":"0891","530041":"0891","530043":"0891","530044":"0891","530045":"0891","530046":"0891","530047":"0891","530048":"0891","530049":"0891","530051":"0891","530052":"0891","530053":"0891","531001":"0891","531002":"0891","531011":"0891","531019":"0891","531020":"0891","531021":"0891","531022":"0891","531023":"0891","531024":"0891","531025":"0891","531026":"0891","531027":"0891","531028":"0891","531029":"0891","531030":"0891","531031":"0891","531032":"0891","531033":"0891","531034":"0891","531035":"0891","531036":"0891","531040":"0891","531055":"0891","531060":"0891","531061":"0891","531075":"0891","531077":"0891","531081":"0891","531082":"0891","531083":"0891","531084":"0891","531085":"0891","531087":"0891","531105":"0891","531111":"0891","531113":"0891","531114":"0891","531115":"0891","531116":"0891","531117":"0891","531118":"0891","531126":"0891","531127":"0891","531133":"0891","531149":"0891","531151":"08922","531162":"08922","531163":"0891","531173":"08922","531219":"0891","532001":"08942","532005":"08942","532122":"08922","532123":"08942","532127":"08922","532148":"08942","532168":"08942","532185":"08942","532186":"08942","532187":"08942","532190":"08942","532195":"08942","532201":"08942","532203":"08942","532211":"08942","532212":"08942","532213":"08942","532214":"08942","532215":"08942","532216":"08942","532218":"08942","532219":"08942","532220":"08942","532221":"08942","532222":"08942","532242":"08942","532243":"08942","532263":"08942","532264":"08942","532284":"08942","532290":"08942","532291":"08942","532292":"08942","532312":"08942","532322":"08942","532401":"08942","532402":"08942","532403":"08942","532404":"08942","532405":"08942","532406":"08942","532407":"08922","532408":"08942","532409":"08942","532410":"08942","532421":"08942","532425":"08942","532426":"08942","532427":"08942","532428":"08942","532429":"08942","532430":"08942","532432":"08942","532440":"08942","532443":"08942","532445":"08942","532455":"08942","532456":"08942","532457":"08942","532458":"08942","532459":"08942","532460":"08942","532461":"08942","532462":"08942","532474":"08942","532484":"08942","533001":"0884","533002":"0884","533003":"0884","533004":"0884","533005":"0884","533006":"0884","533007":"0884","533016":"0884","533101":"0884","533102":"0884","533103":"0884","533104":"0884","533105":"0884","533106":"0884","533107":"0884","533124":"0884","533125":"0884","533126":"0884","533201":"0884","533210":"0884","533211":"0884","533212":"0884","533213":"0884","533214":"0884","533215":"0884","533216":"0884","533217":"0884","533218":"0884","533220":"0884","533221":"0884","533222":"0884","533223":"0884","533228":"0884","533229":"0884","533232":"0884","533233":"0884","533234":"0884","533235":"0884","533236":"0884","533237":"0884","533238":"0884","533239":"0884","533240":"0884","533241":"0884","533242":"0884","533244":"0884","533247":"0884","533248":"0884","533249":"0884","533250":"0884","533251":"0884","533252":"0884","533253":"0884","533254":"0884","533255":"0884","533256":"0884","533260":"0884","533261":"0884","533262":"0884","533263":"0884","533264":"0884","533274":"0884","533284":"0884","533285":"0884","533286":"0884","533287":"0884","533288":"0884","533289":"0884","533290":"0884","533291":"0884","533292":"0884","533293":"0884","533294":"0884","533295":"0884","533296":"0884","533297":"0884","533305":"0884","533306":"0884","533307":"0884","533308":"0884","533309":"0884","533339":"0884","533340":"0884","533341":"0884","533342":"0884","533343":"0884","533344":"0884","533345":"0884","533346":"0884","533347":"0884","533348":"0884","533349":"0884","533350":"0884","533351":"0884","533352":"0884","533353":"0884","533354":"0884","533355":"0884","533401":"0891","533406":"0884","533407":"0884","533408":"0884","533428":"0884","533429":"0884","533430":"0884","533431":"0884","533432":"0884","533433":"0884","533434":"0884","533435":"0884","533436":"0884","533437":"0884","533440":"0884","533444":"0884","533445":"0884","533446":"0884","533447":"0884","533448":"0884","533449":"0884","533450":"0884","533451":"0884","533461":"0884","533462":"0884","533463":"0884","533464":"0884","533468":"0884","533483":"0884","533577":"0884","534001":"08812","534002":"08812","534003":"08812","534004":"08812","534005":"08812","534006":"08812","534007":"08812","534101":"08812","534102":"08812","534111":"08812","534112":"08812","534122":"08812","534123":"08812","534124":"08812","534126":"08812","534134":"08812","534145":"08812","534146":"08812","534156":"08812","534165":"08812","534166":"08812","534176":"08812","534186":"08812","534195":"08812","534196":"08812","534197":"08812","534198":"08812","534199":"08812","534201":"08812","534202":"08812","534204":"08812","534206":"08812","534207":"08812","534208":"08812","534209":"08812","534210":"08812","534211":"08812","534215":"08812","534216":"08812","534217":"08812","534218":"08812","534222":"08812","534225":"08812","534227":"08812","534230":"08812","534235":"08812","534236":"08812","534237":"08812","534238":"08812","534239":"08812","534240":"08812","534243":"08812","534244":"08812","534245":"08812","534247":"08812","534250":"08812","534260":"08812","534265":"08812","534266":"08812","534267":"08812","534268":"08812","534269":"08812","534275":"08812","534280":"08812","534281":"08812","534301":"08812","534302":"08812","534305":"08812","534311":"08812","534312":"08812","534313":"08812","534315":"08812","534316":"08812","534318":"08812","534320":"08812","534324":"08812","534326":"08812","534327":"08812","534328":"08812","534329":"08812","534330":"08812","534331":"08812","534338":"08812","534340":"08812","534341":"08812","534342":"08812","534350":"08812","534401":"08812","534406":"08812","534411":"08812","534416":"08812","534425":"08812","534426":"08812","534427":"08812","534432":"08812","534435":"08812","534437":"08812","534442":"08812","534444":"08812","534447":"08812","534448":"08812","534449":"08812","534450":"08812","534451":"08812","534452":"08812","534455":"08812","534456":"08812","534460":"08812","534461":"08812","534462":"08812","534467":"08812","534475":"08812","535001":"08922","535002":"08922","535003":"08922","535004":"08922","535005":"08922","535006":"08922","535101":"08922","535102":"08922","535124":"08922","535125":"08922","535126":"08922","535128":"08922","535145":"08922","535148":"08922","535160":"08922","535161":"08922","535183":"08922","535204":"08922","535213":"08922","535214":"08922","535215":"08922","535216":"08922","535217":"08922","535218":"08922","535220":"08922","535221":"08922","535240":"08922","535250":"08922","535260":"08922","535270":"08922","535273":"08922","535280":"08922","535281":"08922","535463":"08922","535501":"08922","535502":"08922","535521":"08922","535522":"08922","535523":"08922","535524":"08922","535525":"08922","535526":"08922","535527":"08922","535534":"08922","535546":"08922","535547":"08922","535557":"08922","535558":"08922","535559":"08922","535568":"08922","535573":"08922","535578":"08922","535579":"08922","535580":"08922","535581":"08922","535582":"08922","535591":"08922","535592":"08922","535593":"08922","535594":"08922","560001":"080","560002":"080","560003":"080","560004":"080","560005":"080","560006":"080","560007":"080","560008":"080","560009":"080","560010":"080","560011":"080","560012":"080","560013":"080","560015":"080","560016":"080","560017":"080","560018":"080","560020":"080","560021":"080","560022":"080","560023":"080","560024":"080","560025":"080","560026":"080","560027":"080","560029":"080","560030":"080","560032":"080","560033":"080","560034":"080","560035":"080","560036":"080","560037":"080","560038":"080","560040":"080","560041":"080","560042":"080","560043":"080","560045":"080","560046":"080","560047":"080","560048":"080","560049":"080","560050":"080","560051":"080","560053":"080","560054":"080","560055":"080","560056":"080","560057":"080","560058":"080","560059":"080","560060":"080","560061":"080","560062":"080","560063":"080","560064":"080","560065":"080","560066":"080","560067":"080","560068":"080","560070":"080","560071":"080","560072":"080","560073":"080","560074":"080","560075":"080","560076":"080","560077":"080","560078":"080","560079":"080","560080":"080","560081":"080","560082":"080","560083":"080","560084":"080","560085":"080","560086":"080","560087":"080","560088":"080","560089":"080","560090":"080","560091":"080","560092":"080","560093":"080","560094":"080","560095":"080","560096":"080","560097":"080","560098":"080","560099":"080","560100":"080","560102":"080","560103":"080","560104":"080","560105":"080","560107":"080","560108":"080","560109":"080","560110":"080","560111":"080","560112":"080","560113":"080","560114":"080","560115":"080","560116":"080","560117":"080","560300":"080","560500":"080","561101":"080","561201":"080","561202":"0816","561203":"080","561204":"080","561205":"080","561206":"08156","561207":"08156","561208":"08156","561209":"08156","561210":"08156","561211":"08156","561212":"08156","561213":"08156","561228":"08156","562101":"08156","562102":"08156","562103":"08156","562104":"08156","562105":"08156","562106":"080","562107":"080","562108":"080","562109":"080","562110":"080","562111":"080","562112":"080","562114":"080","562117":"080","562119":"080","562120":"080","562121":"080","562122":"080","562123":"080","562125":"080","562126":"080","562127":"080","562128":"080","562129":"080","562130":"080","562131":"080","562132":"080","562135":"080","562138":"080","562149":"080","562157":"080","562159":"080","562160":"080","562161":"080","562162":"080","562163":"080","562164":"080","562165":"080","563101":"08152","563103":"08152","563113":"08152","563114":"08152","563115":"08152","563116":"08152","563117":"08152","563118":"08152","563119":"08152","563120":"08152","563121":"08152","563122":"08152","563123":"08156","563124":"08156","563125":"08152","563126":"08152","563127":"08152","563128":"08156","563129":"08152","563130":"08152","563131":"08152","563132":"08152","563133":"08152","563134":"08152","563135":"08152","563136":"08152","563137":"08152","563138":"08152","563139":"08152","563146":"08156","563147":"08152","563157":"08152","563159":"08156","563160":"08152","563161":"08152","563162":"08152","563163":"08152","570001":"0821","570002":"0821","570003":"0821","570004":"0821","570005":"0821","570006":"0821","570007":"0821","570008":"0821","570009":"0821","570010":"0821","570011":"0821","570012":"0821","570014":"0821","570015":"0821","570016":"0821","570017":"0821","570018":"0821","570019":"0821","570020":"0821","570022":"0821","570023":"0821","570025":"0821","570026":"0821","570027":"0821","570028":"0821","570029":"0821","570030":"0821","570031":"0821","570032":"0821","570033":"0821","570034":"0821","571101":"0821","571102":"0821","571103":"0821","571104":"0821","571105":"0821","571106":"0821","571107":"0821","571108":"0821","571109":"08226","571110":"0821","571111":"08226","571114":"0821","571115":"08226","571116":"0821","571117":"08226","571118":"0821","571119":"0821","571120":"0821","571121":"0821","571122":"0821","571123":"08226","571124":"0821","571125":"0821","571126":"08226","571127":"08226","571128":"08226","571129":"0821","571130":"0821","571134":"0821","571187":"0821","571189":"0821","571201":"08272","571211":"08272","571212":"08272","571213":"08272","571214":"08272","571215":"08272","571216":"08272","571217":"08272","571218":"08272","571219":"08272","571231":"08272","571232":"08272","571234":"08272","571235":"08272","571236":"08272","571237":"08272","571247":"08272","571248":"08272","571249":"08272","571250":"08272","571251":"08272","571252":"08272","571253":"08272","571254":"08272","571301":"0821","571302":"0821","571311":"0821","571312":"0821","571313":"08226","571314":"0821","571315":"0821","571316":"0821","571320":"08226","571342":"08226","571401":"08232","571402":"08232","571403":"08232","571404":"08232","571405":"08232","571415":"08232","571416":"08232","571417":"08232","571418":"08232","571419":"08232","571421":"08232","571422":"08232","571423":"08232","571424":"08232","571425":"08232","571426":"08232","571427":"08232","571428":"08232","571429":"08232","571430":"08232","571431":"08232","571432":"08232","571433":"08232","571434":"08232","571435":"08232","571436":"08232","571438":"08232","571439":"08226","571440":"08226","571441":"08226","571442":"0821","571443":"08226","571444":"08226","571445":"08232","571446":"08232","571448":"08232","571450":"08232","571455":"08232","571457":"08226","571463":"08232","571475":"08232","571476":"08232","571477":"08232","571478":"08232","571490":"08226","571601":"0821","571602":"0821","571603":"0821","571604":"0821","571605":"08232","571606":"08232","571607":"08232","571610":"0821","571617":"0821","571802":"08232","571807":"08232","571811":"08232","571812":"08232","572101":"0816","572102":"0816","572103":"0816","572104":"0816","572105":"0816","572106":"0816","572107":"0816","572111":"0816","572112":"0816","572113":"0816","572114":"0816","572115":"0816","572116":"0816","572117":"0816","572118":"0816","572119":"0816","572120":"0816","572121":"0816","572122":"0816","572123":"0816","572124":"0816","572125":"0816","572126":"0816","572127":"0816","572128":"0816","572129":"0816","572130":"0816","572132":"0816","572133":"0816","572134":"0816","572135":"0816","572136":"0816","572137":"0816","572138":"0816","572139":"0816","572140":"0816","572141":"0816","572142":"0816","572168":"0816","572175":"0816","572201":"0816","572211":"0816","572212":"0816","572213":"0816","572214":"0816","572215":"0816","572216":"0816","572217":"0816","572218":"0816","572219":"0816","572220":"0816","572221":"0816","572222":"0816","572223":"0816","572224":"0816","572225":"0816","572226":"0816","572227":"0816","572228":"0816","573101":"08172","573102":"08172","573103":"08172","573111":"08172","573112":"08172","573113":"08172","573115":"08172","573116":"08172","573117":"08172","573118":"08172","573119":"08172","573120":"08172","573121":"08172","573122":"08172","573123":"08172","573124":"08172","573125":"08172","573126":"08172","573127":"08172","573128":"08172","573129":"08172","573130":"08172","573131":"08172","573133":"08172","573134":"08172","573135":"08172","573136":"08172","573137":"08172","573141":"08172","573142":"08172","573144":"08172","573162":"08172","573164":"08172","573165":"08172","573201":"08172","573202":"08172","573210":"08172","573211":"08172","573212":"08172","573213":"08172","573214":"08172","573215":"08172","573216":"08172","573217":"08172","573218":"08172","573219":"08172","573220":"08172","573225":"08172","573226":"08172","574101":"0820","574102":"0820","574103":"0820","574104":"0820","574105":"0820","574106":"0820","574107":"0820","574108":"0820","574109":"0820","574110":"0820","574111":"0820","574112":"0820","574113":"0820","574114":"0820","574115":"0820","574116":"0820","574117":"0820","574118":"0820","574119":"0820","574122":"0820","574129":"0820","574141":"0824","574142":"0824","574143":"0824","574144":"0824","574145":"0824","574146":"0824","574148":"0824","574150":"0824","574151":"0824","574153":"0824","574154":"0824","574197":"0824","574198":"0824","574199":"0824","574201":"0824","574202":"0824","574203":"0824","574210":"0824","574211":"0824","574212":"0824","574213":"0824","574214":"0824","574216":"0824","574217":"0824","574218":"0824","574219":"0824","574220":"0824","574221":"0824","574222":"0824","574223":"0824","574224":"0824","574225":"0824","574226":"0824","574227":"0824","574228":"0824","574229":"0824","574230":"0824","574231":"0824","574232":"0824","574233":"0824","574234":"08272","574235":"0824","574236":"0824","574237":"0824","574238":"0824","574239":"0824","574240":"0824","574241":"0824","574242":"0824","574243":"0824","574244":"0820","574248":"0824","574253":"0824","574259":"0824","574260":"0824","574265":"0824","574267":"0824","574274":"0824","574279":"0824","574285":"0824","574313":"0824","574314":"08272","574323":"0824","574324":"0824","574325":"0824","574326":"0824","574327":"0824","574328":"0824","574509":"0824","575001":"0824","575002":"0824","575003":"0824","575004":"0824","575005":"0824","575006":"0824","575007":"0824","575008":"0824","575009":"0824","575010":"0824","575011":"0824","575013":"0824","575014":"0824","575015":"0824","575016":"0824","575017":"0824","575018":"0824","575019":"0824","575020":"0824","575022":"0824","575023":"0824","575025":"0824","575028":"0824","575029":"0824","575030":"0824","576101":"0820","576102":"0820","576103":"0820","576104":"0820","576105":"0820","576106":"0820","576107":"0820","576108":"0820","576111":"0820","576112":"0820","576113":"0820","576114":"0820","576115":"0820","576117":"0820","576120":"0820","576121":"0820","576122":"0820","576124":"0820","576201":"0820","576210":"0820","576211":"0820","576212":"0820","576213":"0820","576214":"0820","576215":"0820","576216":"0820","576217":"0820","576218":"0820","576219":"0820","576220":"0820","576221":"0820","576222":"0820","576223":"0820","576224":"0820","576225":"0820","576226":"0820","576227":"0820","576228":"0820","576229":"0820","576230":"0820","576231":"0820","576232":"0820","576233":"0820","576234":"0820","576235":"0820","576247":"0820","576257":"0820","576282":"0820","576283":"0820","577001":"08192","577002":"08192","577003":"08192","577004":"08192","577005":"08192","577006":"08192","577007":"08192","577101":"08262","577102":"08262","577111":"08262","577112":"08262","577113":"08262","577114":"08262","577115":"08182","577116":"08262","577117":"08262","577120":"08262","577121":"08262","577122":"08262","577123":"08262","577124":"08262","577125":"08262","577126":"08262","577127":"08262","577128":"08262","577129":"08262","577130":"08262","577131":"08262","577132":"08262","577133":"08262","577134":"08262","577135":"08262","577136":"08262","577137":"08262","577138":"08262","577139":"08262","577140":"08262","577144":"08262","577145":"08262","577146":"08262","577160":"08262","577168":"08262","577175":"08262","577179":"08262","577180":"08262","577181":"08262","577182":"08262","577201":"08182","577202":"08182","577203":"08182","577204":"08182","577205":"08182","577211":"08182","577213":"08192","577214":"08182","577215":"08192","577216":"08182","577217":"08192","577218":"08192","577219":"08192","577220":"08182","577221":"08192","577222":"08182","577223":"08192","577224":"08192","577225":"08182","577226":"08182","577227":"08182","577228":"08262","577229":"08182","577230":"08192","577231":"08192","577232":"08182","577233":"08182","577243":"08182","577245":"08182","577301":"08182","577302":"08182","577401":"08182","577411":"08182","577412":"08182","577413":"08182","577414":"08182","577415":"08182","577416":"08182","577417":"08182","577418":"08182","577419":"08182","577421":"08182","577422":"08182","577423":"08182","577424":"08182","577425":"08182","577426":"08182","577427":"08182","577428":"08182","577429":"08182","577430":"08182","577431":"08182","577432":"08182","577433":"08182","577434":"08182","577435":"08182","577436":"08182","577451":"08182","577452":"08182","577453":"08182","577501":"08194","577502":"08194","577511":"08194","577512":"08192","577513":"08192","577514":"08192","577515":"08194","577516":"08192","577517":"08194","577518":"08194","577519":"08194","577520":"08194","577521":"08192","577522":"08194","577523":"08194","577524":"08194","577525":"08192","577526":"08194","577527":"08194","577528":"08192","577529":"08194","577530":"08192","577531":"08194","577532":"08194","577533":"08194","577534":"08192","577535":"08194","577536":"08194","577537":"08194","577538":"08194","577539":"08194","577540":"08194","577541":"08194","577542":"08194","577543":"08194","577544":"08192","577545":"08194","577546":"08194","577547":"08262","577548":"08262","577549":"08262","577550":"08262","577551":"08192","577552":"08192","577553":"08192","577554":"08194","577555":"08194","577556":"08192","577557":"08194","577558":"08194","577566":"08192","577589":"08192","577596":"08194","577597":"08194","577598":"08194","577599":"08194","577601":"08192","580001":"0836","580002":"0836","580003":"0836","580004":"0836","580005":"0836","580006":"0836","580007":"0836","580008":"0836","580009":"0836","580011":"0836","580020":"0836","580021":"0836","580023":"0836","580024":"0836","580025":"0836","580026":"0836","580027":"0836","580028":"0836","580029":"0836","580030":"0836","580031":"0836","580032":"0836","580112":"0836","580114":"0836","580118":"0836","581101":"08375","581102":"08375","581103":"0836","581104":"08375","581105":"0836","581106":"08375","581107":"0836","581108":"08375","581109":"08375","581110":"08375","581111":"08375","581112":"08375","581113":"0836","581115":"08375","581116":"08375","581117":"0836","581118":"08375","581119":"08375","581120":"08375","581121":"08382","581123":"08375","581126":"08375","581128":"08375","581129":"08382","581145":"08375","581148":"08375","581186":"08382","581187":"08382","581193":"08375","581195":"0836","581196":"0836","581198":"08375","581199":"08375","581201":"0836","581202":"08375","581203":"08375","581204":"0836","581205":"08375","581206":"0836","581207":"0836","581208":"08375","581209":"0836","581210":"08375","581211":"08375","581212":"08375","581213":"08375","581237":"08375","581301":"08382","581302":"08382","581303":"08382","581304":"08382","581306":"08382","581307":"08382","581308":"08382","581314":"08382","581315":"08382","581316":"08382","581317":"08382","581318":"08382","581319":"08382","581320":"08382","581321":"08382","581322":"08382","581323":"08382","581324":"08382","581325":"08382","581326":"08382","581327":"08382","581328":"08382","581329":"08382","581330":"08382","581331":"08382","581332":"08382","581333":"08382","581334":"08382","581335":"08382","581336":"08382","581337":"08382","581338":"08382","581339":"08382","581340":"08382","581341":"08382","581342":"08382","581343":"08382","581344":"08382","581345":"08382","581346":"08382","581347":"08382","581348":"08382","581349":"08382","581350":"08382","581351":"08382","581352":"08382","581353":"08382","581354":"08382","581355":"08382","581356":"08382","581357":"08382","581358":"08382","581359":"08382","581360":"08382","581361":"08382","581362":"08382","581363":"08382","581365":"08382","581384":"08382","581396":"08382","581400":"08382","581401":"08382","581402":"08382","581403":"08382","581411":"08382","581412":"08382","581421":"08382","581423":"08382","581440":"08382","581450":"08382","581453":"08382","582101":"08372","582102":"08372","582103":"08372","582111":"08372","582112":"08372","582113":"08372","582114":"08372","582115":"08372","582116":"08372","582117":"08372","582118":"08372","582119":"08372","582120":"08372","582201":"0836","582202":"08372","582203":"08372","582204":"08372","582205":"08372","582206":"08372","582207":"08372","582208":"0836","582209":"08372","582210":"08372","582211":"08372","583101":"08392","583102":"08392","583103":"08392","583104":"08392","583105":"08392","583111":"08392","583112":"08392","583113":"08392","583114":"08392","583115":"08392","583116":"08392","583117":"08392","583118":"08392","583119":"08392","583120":"08392","583121":"08392","583122":"08392","583123":"08392","583124":"08392","583125":"08392","583126":"08392","583127":"08392","583128":"08392","583129":"08392","583130":"08392","583131":"08392","583132":"08392","583134":"08392","583135":"08392","583136":"08392","583137":"08392","583152":"08392","583153":"08392","583154":"08392","583155":"08392","583201":"08392","583203":"08392","583211":"08392","583212":"08392","583213":"08392","583214":"08392","583215":"08392","583216":"08392","583217":"08392","583218":"08392","583219":"08392","583220":"08392","583221":"08392","583222":"08392","583223":"08392","583224":"08392","583225":"08392","583226":"08539","583227":"08539","583228":"08539","583229":"08539","583230":"08539","583231":"08539","583232":"08539","583233":"08539","583234":"08539","583235":"08539","583236":"08539","583237":"08539","583238":"08539","583239":"08392","583268":"08539","583275":"08392","583276":"08392","583277":"08539","583278":"08539","583279":"08539","583280":"08539","583281":"08539","583282":"08539","583283":"08539","583284":"08539","583285":"08539","583287":"08539","584101":"08532","584102":"08532","584103":"08532","584104":"08532","584111":"08532","584113":"08532","584115":"08532","584116":"08532","584118":"08532","584120":"08532","584122":"08532","584123":"08532","584124":"08532","584125":"08532","584126":"08532","584127":"08532","584128":"08532","584129":"08532","584132":"08532","584133":"08532","584134":"08532","584135":"08532","584136":"08532","584138":"08532","584139":"08532","584140":"08532","584143":"08532","584167":"08532","584170":"08532","584202":"08532","584203":"08532","585101":"08472","585102":"08472","585103":"08472","585104":"08472","585105":"08472","585106":"08472","585107":"08472","585201":"08473","585202":"08473","585210":"08472","585211":"08472","585212":"08472","585213":"08472","585214":"08473","585215":"08473","585216":"08473","585217":"08472","585218":"08472","585219":"08473","585220":"08473","585221":"08473","585222":"08472","585223":"08473","585224":"08473","585225":"08472","585226":"08482","585227":"08482","585228":"08472","585229":"08472","585236":"08472","585237":"08473","585265":"08472","585287":"08473","585290":"08473","585291":"08473","585292":"08472","585301":"08472","585302":"08472","585303":"08472","585304":"08473","585305":"08472","585306":"08472","585307":"08472","585308":"08472","585309":"08473","585310":"08472","585311":"08472","585312":"08472","585313":"08472","585314":"08472","585315":"08473","585316":"08472","585317":"08472","585318":"08472","585319":"08473","585320":"08472","585321":"08473","585322":"08472","585323":"08473","585324":"08472","585325":"08472","585326":"08482","585327":"08482","585328":"08482","585329":"08482","585330":"08482","585331":"08482","585353":"08482","585355":"08473","585367":"08472","585401":"08482","585402":"08482","585403":"08482","585404":"08482","585411":"08482","585412":"08482","585413":"08482","585414":"08482","585415":"08482","585416":"08482","585417":"08482","585418":"08482","585419":"08482","585421":"08482","585436":"08482","585437":"08482","585443":"08482","585444":"08482","585445":"08482","585447":"08482","586101":"08352","586103":"08352","586104":"08352","586108":"08352","586109":"08352","586111":"08352","586112":"08352","586113":"08352","586114":"08352","586115":"08352","586116":"08352","586117":"08352","586118":"08352","586119":"08352","586120":"08352","586121":"08352","586122":"08352","586123":"08352","586124":"08352","586125":"08352","586127":"08352","586128":"08352","586129":"08352","586130":"08352","586201":"08352","586202":"08352","586203":"08352","586204":"08352","586205":"08352","586206":"08352","586207":"08352","586208":"08352","586209":"08352","586210":"08352","586211":"08352","586212":"08352","586213":"08352","586214":"08352","586215":"08352","586216":"08352","586217":"08352","587101":"08354","587102":"08354","587103":"08354","587104":"08354","587111":"08354","587112":"08354","587113":"08354","587114":"08354","587115":"08354","587116":"08354","587117":"08354","587118":"08354","587119":"08354","587120":"08354","587121":"08354","587122":"08354","587124":"08354","587125":"08354","587154":"08354","587155":"08354","587156":"08354","587201":"08354","587202":"08354","587203":"08354","587204":"08354","587205":"08354","587206":"08354","587207":"08354","587301":"08354","587311":"08354","587312":"08354","587313":"08354","587314":"08354","587315":"08354","587316":"08354","587330":"08354","587331":"08354","590001":"0831","590003":"0831","590005":"0831","590006":"0831","590008":"0831","590009":"0831","590010":"0831","590011":"0831","590014":"0831","590015":"0831","590016":"0831","590017":"0831","590018":"0831","590019":"0831","590020":"0831","591101":"0831","591102":"0831","591103":"0831","591104":"0831","591106":"0831","591107":"0831","591108":"0831","591109":"0831","591110":"0831","591111":"0831","591112":"0831","591113":"0831","591114":"0831","591115":"0831","591117":"0831","591118":"0831","591119":"0831","591120":"0831","591121":"0831","591122":"0831","591123":"0831","591124":"0831","591125":"0831","591126":"0831","591127":"0831","591128":"0831","591129":"0831","591130":"0831","591131":"0831","591136":"0831","591143":"0831","591147":"0831","591153":"0831","591156":"0831","591173":"0831","591201":"0831","591211":"0831","591212":"0831","591213":"0831","591214":"0831","591215":"0831","591216":"0831","591217":"0831","591218":"0831","591219":"0831","591220":"0831","591221":"0831","591222":"0831","591223":"0831","591224":"0831","591225":"0831","591226":"0831","591227":"0831","591228":"0831","591229":"0831","591230":"0831","591231":"0831","591232":"0831","591233":"0831","591234":"0831","591235":"0831","591236":"0831","591237":"0831","591238":"0831","591239":"0831","591240":"0831","591241":"0831","591242":"0831","591243":"0831","591244":"0831","591246":"0831","591247":"0831","591248":"0831","591254":"0831","591263":"0831","591265":"0831","591287":"0831","591301":"0831","591302":"0831","591303":"0831","591304":"0831","591305":"0831","591306":"0831","591307":"0831","591308":"0831","591309":"0831","591310":"0831","591311":"0831","591312":"0831","591313":"0831","591314":"0831","591315":"0831","591316":"0831","591317":"0831","591340":"0831","591344":"0831","591345":"0831","591346":"0831","600001":"044","600002":"044","600003":"044","600004":"044","600005":"044","600006":"044","600007":"044","600008":"044","600009":"044","600010":"044","600011":"044","600012":"044","600013":"044","600014":"044","600015":"044","600016":"044","600017":"044","600018":"044","600019":"044","600020":"044","600021":"044","600022":"044","600023":"044","600024":"044","600025":"044","600026":"044","600028":"044","600030":"044","600031":"044","600032":"044","600033":"044","600034":"044","600035":"044","600036":"044","600037":"044","600038":"044","600039":"044","600040":"044","600041":"044","600042":"044","600043":"04114","600044":"04114","600045":"04114","600046":"04114","600047":"04114","600048":"04114","600049":"044","600050":"044","600051":"044","600052":"044","600053":"044","600054":"044","600055":"044","600056":"044","600057":"044","600058":"044","600059":"04114","600060":"044","600061":"044","600062":"044","600063":"04114","600064":"04114","600066":"044","600067":"044","600068":"044","600069":"04112","600070":"04114","600071":"044","600072":"044","600073":"04114","600074":"04114","600075":"04114","600076":"044","600077":"044","600078":"044","600081":"044","600082":"044","600083":"044","600084":"044","600085":"044","600086":"044","600087":"044","600088":"044","600089":"04112","600090":"044","600091":"044","600092":"044","600093":"044","600094":"044","600095":"044","600096":"044","600097":"044","600099":"044","600100":"04114","600101":"044","600102":"044","600103":"044","600104":"044","600106":"044","600107":"044","600110":"044","600113":"044","600115":"044","600116":"044","600117":"04114","600118":"044","600119":"044","600120":"044","600122":"04112","600123":"044","600124":"044","600125":"044","600126":"04114","600127":"04114","600128":"04112","600129":"04114","600130":"04114","600131":"04114","600132":"04112","601101":"044","601102":"044","601103":"044","601201":"044","601202":"044","601203":"044","601204":"044","601205":"044","601206":"044","601301":"04112","602001":"044","602002":"044","602003":"044","602021":"044","602023":"044","602024":"044","602025":"044","602026":"044","602105":"044","602106":"04112","602108":"044","602117":"04112","603001":"04114","603002":"04114","603003":"04114","603004":"04114","603101":"04114","603102":"04114","603103":"04114","603104":"04114","603105":"04114","603106":"04112","603107":"04112","603108":"04114","603109":"04114","603110":"04114","603111":"04114","603112":"04114","603127":"04114","603201":"04114","603202":"04112","603203":"04112","603204":"04112","603209":"04114","603210":"04114","603211":"04114","603301":"04114","603302":"04114","603303":"04114","603304":"04114","603305":"04114","603306":"04114","603307":"04114","603308":"04114","603309":"04114","603310":"04114","603311":"04114","603312":"04114","603313":"04114","603314":"04112","603319":"04114","603401":"04114","603402":"04112","603403":"04112","603405":"04114","603406":"04112","604001":"04146","604101":"04146","604102":"04146","604151":"04146","604152":"04146","604153":"04146","604154":"04146","604201":"04146","604202":"04146","604203":"04146","604204":"04146","604205":"04146","604206":"04146","604207":"04146","604208":"04146","604210":"04146","604301":"04146","604302":"04146","604303":"04146","604304":"04146","604305":"04146","604306":"04146","604307":"04146","604401":"04175","604402":"04175","604403":"04175","604404":"04175","604405":"04175","604406":"04175","604407":"04175","604408":"04175","604409":"04175","604410":"04175","604501":"04175","604502":"04175","604503":"04175","604504":"04175","604505":"04175","604601":"04175","605001":"0413","605002":"0413","605003":"0413","605004":"0413","605005":"0413","605006":"0413","605007":"0413","605008":"0413","605009":"0413","605010":"0413","605011":"0413","605013":"0413","605014":"04146","605101":"04146","605102":"04146","605103":"04146","605104":"04146","605105":"04146","605106":"04146","605107":"04146","605108":"04146","605109":"04146","605110":"0413","605111":"04146","605201":"04146","605202":"04146","605203":"04146","605301":"04146","605302":"04146","605401":"04146","605402":"04146","605403":"04146","605501":"04146","605502":"04146","605601":"04146","605602":"04146","605651":"04146","605652":"04146","605701":"04146","605702":"04151","605751":"04151","605752":"04146","605754":"04151","605755":"04146","605756":"04146","605757":"04151","605758":"04146","605759":"04151","605766":"04151","605801":"04151","605802":"04151","605803":"04146","606001":"04142","606003":"04142","606102":"04151","606103":"04142","606104":"04142","606105":"04142","606106":"04142","606107":"04151","606108":"04142","606109":"04142","606110":"04142","606111":"04142","606115":"04151","606201":"04151","606202":"04151","606203":"04151","606204":"04151","606205":"04151","606206":"04151","606207":"04151","606208":"04151","606209":"04151","606213":"04151","606301":"04151","606302":"04142","606303":"04142","606304":"04142","606305":"04151","606401":"04151","606402":"04151","606601":"04175","606603":"04175","606604":"04175","606611":"04175","606701":"04175","606702":"04175","606703":"04175","606704":"04175","606705":"04175","606706":"04175","606707":"04175","606708":"04175","606709":"04175","606710":"04175","606751":"04175","606752":"04175","606753":"04175","606754":"04146","606755":"04175","606801":"04175","606802":"04175","606803":"04175","606804":"04175","606805":"04175","606806":"04175","606807":"04175","606808":"04175","606811":"04175","606901":"04175","606902":"04175","606903":"04175","606904":"04175","606905":"04175","606906":"04175","606907":"04175","606908":"04175","607001":"04142","607002":"04142","607003":"04142","607004":"04142","607005":"04142","607006":"04142","607101":"04146","607102":"04142","607103":"04142","607104":"04142","607105":"04142","607106":"04142","607107":"04146","607108":"04142","607109":"04142","607112":"04142","607201":"04151","607202":"04151","607203":"04146","607204":"04151","607205":"04142","607209":"04146","607301":"04142","607302":"04142","607303":"04142","607308":"04142","607401":"04142","607402":"0413","607403":"0413","607801":"04142","607802":"04142","607803":"04142","607804":"04142","607805":"04142","607807":"04142","608001":"04142","608002":"04365","608102":"04142","608201":"04142","608301":"04142","608302":"04142","608303":"04142","608304":"04142","608305":"04142","608306":"04142","608401":"04142","608501":"04142","608502":"04142","608601":"04142","608602":"04142","608701":"04142","608702":"04142","608703":"04142","608704":"04142","608801":"04142","608901":"04329","609001":"04364","609003":"04364","609101":"04364","609102":"04364","609103":"04364","609104":"04364","609105":"04364","609106":"04364","609107":"04364","609108":"04364","609109":"04364","609110":"04364","609111":"04364","609112":"04364","609113":"04364","609114":"04364","609115":"04364","609116":"04364","609117":"04364","609118":"04364","609201":"04364","609202":"04364","609203":"04364","609204":"04362","609205":"04364","609301":"04364","609302":"04364","609303":"04364","609304":"04364","609305":"04364","609306":"04364","609307":"04364","609308":"04364","609309":"04364","609310":"04364","609311":"04364","609312":"04364","609313":"04364","609314":"04364","609401":"04364","609402":"04364","609403":"04366","609404":"04364","609405":"04366","609501":"04366","609502":"04366","609503":"04366","609504":"04366","609601":"04368","609602":"04368","609603":"04366","609604":"04365","609605":"04368","609606":"04368","609607":"04368","609608":"04366","609609":"04368","609701":"04365","609702":"04365","609703":"04365","609704":"04365","609801":"04364","609802":"04362","609803":"04364","609804":"04362","609805":"04364","609806":"04364","609807":"04362","609808":"04364","609810":"04364","609811":"04364","610001":"04366","610003":"04366","610004":"04366","610005":"04366","610101":"04366","610102":"04366","610103":"04366","610104":"04366","610105":"04366","610106":"04366","610107":"04366","610109":"04366","610201":"04366","610202":"04366","610203":"04366","610204":"04365","610205":"04366","610206":"04366","610207":"04365","611001":"04365","611002":"04365","611003":"04365","611101":"04366","611102":"04365","611103":"04365","611104":"04365","611105":"04365","611106":"04365","611108":"04365","611109":"04365","611110":"04365","611111":"04365","611112":"04365","612001":"04362","612002":"04362","612101":"04362","612102":"04362","612103":"04362","612104":"04362","612105":"04362","612106":"04362","612201":"04366","612202":"04362","612203":"04366","612204":"04362","612301":"04362","612302":"04362","612303":"04362","612401":"04362","612402":"04362","612501":"04362","612502":"04362","612503":"04362","612504":"04362","612601":"04366","612602":"04362","612603":"04366","612604":"04366","612605":"04366","612610":"04366","612701":"04366","612702":"04362","612703":"04362","612801":"04366","612802":"04366","612803":"04366","612804":"04366","612901":"04329","612902":"04329","612903":"04329","612904":"04329","612905":"04329","613001":"04362","613002":"04362","613003":"04362","613004":"04362","613005":"04362","613006":"04362","613007":"04362","613008":"04362","613009":"04362","613010":"04362","613101":"04362","613102":"04362","613103":"04362","613104":"04362","613105":"04362","613201":"04362","613202":"04362","613203":"04362","613204":"04362","613205":"04362","613301":"04322","613303":"04362","613401":"04362","613402":"04362","613403":"04362","613501":"04362","613502":"04362","613503":"04362","613504":"04362","613601":"04362","613602":"04362","613701":"04366","613702":"04366","613703":"04366","613704":"04366","613705":"04366","614001":"04366","614013":"04366","614014":"04366","614015":"04366","614016":"04366","614017":"04366","614018":"04366","614019":"04366","614020":"04366","614101":"04366","614102":"04366","614103":"04366","614201":"04362","614202":"04362","614203":"04362","614204":"04362","614205":"04362","614206":"04362","614207":"04362","614208":"04366","614210":"04362","614211":"04362","614301":"04362","614302":"04366","614303":"04362","614401":"04362","614402":"04362","614403":"04366","614404":"04366","614601":"04362","614602":"04362","614612":"04362","614613":"04362","614614":"04362","614615":"04362","614616":"04322","614617":"04322","614618":"04322","614619":"04322","614620":"04322","614621":"04322","614622":"04322","614623":"04362","614624":"04322","614625":"04362","614626":"04362","614628":"04362","614629":"04322","614630":"04322","614701":"04362","614702":"04366","614703":"04366","614704":"04366","614705":"04366","614706":"04366","614707":"04365","614708":"04366","614710":"04366","614711":"04366","614712":"04365","614713":"04366","614714":"04365","614715":"04366","614716":"04366","614717":"04366","614723":"04362","614738":"04366","614801":"04322","614802":"04362","614803":"04362","614804":"04362","614805":"04322","614806":"04365","614807":"04365","614808":"04365","614809":"04365","614810":"04365","614901":"04362","614902":"04362","614903":"04366","614904":"04362","614905":"04362","614906":"04362","620001":"0431","620002":"0431","620003":"0431","620004":"0431","620005":"0431","620006":"0431","620007":"0431","620008":"0431","620009":"0431","620010":"0431","620011":"0431","620012":"0431","620013":"0431","620014":"0431","620015":"0431","620016":"0431","620017":"0431","620018":"0431","620019":"0431","620020":"0431","620021":"0431","620022":"0431","620023":"0431","620024":"0431","620025":"0431","620026":"0431","620027":"0431","620101":"0431","620102":"0431","621001":"0431","621002":"0431","621003":"0431","621004":"0431","621005":"0431","621006":"0431","621007":"0431","621008":"0431","621009":"0431","621010":"0431","621011":"0431","621012":"0431","621014":"0431","621101":"04328","621102":"04328","621103":"04328","621104":"0431","621105":"0431","621106":"0431","621107":"04328","621108":"04328","621109":"0431","621110":"0427","621111":"0431","621112":"0431","621113":"04328","621114":"04328","621115":"04328","621116":"04328","621117":"04328","621118":"04328","621133":"04328","621202":"0431","621203":"0431","621204":"0431","621205":"0431","621206":"0431","621207":"0431","621208":"0431","621209":"0431","621210":"0431","621211":"0431","621212":"04328","621213":"0431","621214":"0431","621215":"0431","621216":"0431","621217":"0431","621218":"0431","621219":"04328","621220":"0431","621301":"04324","621302":"0431","621305":"0431","621306":"0431","621307":"0431","621308":"0431","621310":"0431","621311":"0431","621312":"0431","621313":"04324","621314":"0431","621315":"0431","621316":"04322","621601":"0431","621651":"0431","621652":"0431","621653":"0431","621701":"04329","621702":"0431","621703":"0431","621704":"04329","621705":"04329","621706":"0431","621707":"04329","621708":"04328","621709":"04329","621710":"04329","621711":"0431","621712":"0431","621713":"04328","621714":"04329","621715":"04329","621716":"04328","621717":"04328","621718":"04329","621719":"04329","621722":"0431","621729":"04329","621730":"04329","621731":"04329","621801":"04329","621802":"04329","621803":"04329","621804":"04329","621805":"04329","621806":"04329","621851":"04329","622001":"04322","622002":"04322","622003":"04322","622004":"04322","622005":"04322","622101":"04322","622102":"0431","622103":"04322","622104":"04322","622201":"04322","622202":"04322","622203":"04322","622204":"04322","622209":"04322","622301":"04322","622302":"04322","622303":"04322","622304":"04322","622401":"04322","622402":"04322","622403":"04575","622404":"04322","622407":"04322","622409":"04322","622411":"04322","622412":"04322","622422":"04322","622501":"04322","622502":"04322","622503":"04322","622504":"04322","622505":"04322","622506":"04322","622507":"04322","622515":"04322","623115":"04567","623120":"04567","623135":"04567","623308":"04567","623315":"04567","623401":"04567","623402":"04567","623403":"04567","623404":"04567","623406":"04567","623407":"04567","623409":"04567","623501":"04567","623502":"04567","623503":"04567","623504":"04567","623512":"04567","623513":"04567","623514":"04567","623515":"04567","623516":"04567","623517":"04567","623518":"04567","623519":"04567","623520":"04567","623521":"04567","623522":"04567","623523":"04567","623524":"04567","623525":"04567","623526":"04567","623527":"04567","623528":"04567","623529":"04567","623530":"04567","623531":"04567","623532":"04567","623533":"04567","623534":"04567","623536":"04567","623537":"04567","623538":"04567","623566":"04567","623601":"04567","623603":"04567","623604":"04567","623605":"04567","623608":"04567","623701":"04567","623703":"04567","623704":"04567","623705":"04567","623706":"04567","623707":"04567","623708":"04567","623711":"04567","623712":"04567","623806":"04567","624001":"0451","624002":"0451","624003":"0451","624004":"0451","624005":"0451","624101":"0451","624103":"0451","624201":"0451","624202":"0451","624204":"0451","624206":"0451","624208":"0451","624210":"0451","624211":"0451","624212":"0451","624215":"0451","624216":"0451","624219":"0451","624220":"0451","624301":"0451","624302":"0451","624303":"0451","624304":"0451","624306":"0451","624307":"0451","624308":"0451","624401":"0451","624402":"0451","624403":"0451","624601":"0451","624610":"0451","624612":"0451","624613":"0451","624614":"0451","624615":"0451","624616":"0451","624617":"0451","624618":"0451","624619":"0451","624620":"0451","624621":"0451","624622":"0451","624701":"0451","624702":"0451","624703":"0451","624704":"0451","624705":"0451","624706":"0451","624707":"0451","624708":"0451","624709":"0451","624710":"0451","624711":"0451","624712":"0451","624801":"0451","624802":"0451","625001":"0452","625002":"0452","625003":"0452","625004":"0452","625005":"0452","625006":"0452","625007":"0452","625008":"0452","625009":"0452","625011":"0452","625012":"0452","625014":"0452","625015":"0452","625016":"0452","625017":"0452","625018":"0452","625019":"0452","625020":"0452","625021":"0452","625022":"0452","625023":"0452","625101":"0452","625102":"04575","625103":"0452","625104":"0452","625105":"0452","625106":"0452","625107":"0452","625108":"0452","625109":"0452","625110":"0452","625122":"0452","625201":"0452","625203":"04546","625205":"0452","625207":"0452","625214":"0452","625218":"0452","625221":"0452","625234":"0452","625301":"0452","625402":"0452","625501":"0452","625503":"0452","625512":"04546","625513":"04546","625514":"0452","625515":"04546","625516":"04546","625517":"04546","625518":"04546","625519":"04546","625520":"04546","625521":"04546","625522":"04546","625523":"04546","625524":"04546","625525":"04546","625526":"04546","625527":"0452","625528":"04546","625529":"0452","625530":"04546","625531":"04546","625532":"0452","625533":"04546","625534":"04546","625535":"0452","625536":"04546","625537":"0452","625540":"04546","625556":"04546","625562":"04546","625579":"04546","625582":"04546","625601":"04546","625602":"04546","625603":"04546","625604":"04546","625605":"04546","625701":"0452","625702":"0452","625703":"0452","625704":"0452","625705":"0452","625706":"0452","625707":"0452","625708":"0452","626001":"04562","626002":"04562","626003":"04562","626004":"04562","626005":"04562","626101":"04562","626102":"04562","626103":"04562","626104":"04562","626105":"04562","626106":"04562","626107":"04562","626108":"04562","626109":"04562","626110":"04562","626111":"04562","626112":"04562","626113":"04562","626114":"04562","626115":"04562","626116":"04562","626117":"04562","626118":"04562","626119":"04562","626121":"04562","626122":"04562","626123":"04562","626124":"04562","626125":"04562","626126":"04562","626127":"04562","626128":"04562","626129":"04562","626130":"04562","626131":"04562","626132":"04562","626133":"04562","626134":"04562","626135":"04562","626136":"04562","626137":"04562","626138":"04562","626139":"04562","626140":"04562","626141":"04562","626142":"04562","626149":"04562","626161":"04562","626188":"04562","626189":"04562","626201":"04562","626202":"04562","626203":"04562","626204":"04562","626205":"04562","626607":"04562","626612":"04562","627001":"0462","627002":"0462","627003":"0462","627004":"0462","627005":"0462","627006":"0462","627007":"0462","627008":"0462","627009":"0462","627010":"0462","627011":"0462","627012":"0462","627101":"0462","627102":"0462","627103":"0462","627104":"0462","627105":"0462","627106":"0462","627107":"0462","627108":"0462","627109":"0462","627110":"0462","627111":"0462","627112":"0462","627113":"0462","627114":"0462","627115":"0462","627116":"0462","627117":"0462","627118":"0462","627119":"0462","627120":"0462","627127":"0462","627133":"0462","627151":"0462","627152":"0462","627201":"0462","627202":"0462","627351":"0462","627352":"0461","627353":"0462","627354":"0462","627355":"0462","627356":"0462","627357":"0462","627358":"0462","627359":"0462","627401":"0462","627412":"04633","627413":"0462","627414":"0462","627415":"04633","627416":"0462","627417":"0462","627418":"0462","627420":"0462","627421":"0462","627422":"0462","627423":"04633","627424":"04633","627425":"0462","627426":"0462","627427":"0462","627428":"0462","627451":"0462","627452":"0462","627453":"0462","627501":"0462","627502":"0462","627601":"0462","627602":"0462","627603":"0462","627604":"0462","627651":"0462","627652":"0462","627654":"0462","627657":"0462","627713":"04562","627719":"04633","627751":"04633","627753":"04633","627754":"04633","627755":"04633","627756":"04633","627757":"04633","627758":"04633","627759":"04633","627760":"04633","627761":"04633","627764":"04633","627802":"04633","627803":"04633","627804":"04633","627805":"04633","627806":"04633","627807":"04633","627808":"04633","627809":"04633","627811":"04633","627812":"04633","627813":"04633","627814":"04633","627818":"04633","627851":"0462","627852":"04633","627853":"04633","627854":"04633","627855":"04633","627856":"04633","627857":"04633","627858":"04633","627859":"04633","627860":"04633","627861":"04633","627862":"04633","627951":"0462","627953":"0462","628001":"0461","628002":"0461","628003":"0461","628004":"0461","628005":"0461","628006":"0461","628007":"0461","628008":"0461","628101":"0461","628102":"0461","628103":"0461","628104":"0461","628105":"0461","628151":"0461","628152":"0461","628201":"0461","628202":"0461","628203":"0461","628204":"0461","628205":"0461","628206":"0461","628207":"0461","628208":"0461","628209":"0461","628210":"0461","628211":"0461","628212":"0461","628213":"0461","628215":"0461","628216":"0461","628217":"0461","628218":"0461","628219":"0461","628229":"0461","628251":"0461","628252":"0461","628301":"0461","628302":"0461","628303":"0461","628304":"0461","628401":"0461","628402":"0461","628501":"0461","628502":"0461","628503":"0461","628552":"0461","628601":"0461","628612":"0461","628613":"0461","628614":"0461","628615":"0461","628616":"0461","628617":"0461","628618":"0461","628619":"0461","628620":"0461","628621":"0461","628622":"0461","628623":"0461","628653":"0461","628656":"0461","628701":"0461","628702":"0461","628703":"0461","628704":"0461","628712":"0461","628714":"0461","628716":"0461","628718":"0461","628720":"0461","628721":"0461","628722":"0461","628751":"0461","628752":"0461","628753":"0461","628801":"0461","628802":"0461","628809":"0461","628851":"0461","628901":"0461","628902":"0461","628903":"0461","628904":"0461","628905":"0461","628906":"0461","628907":"0461","628908":"0461","628952":"0461","629001":"04652","629002":"04652","629003":"04652","629004":"04652","629101":"04652","629102":"04652","629151":"04652","629152":"04652","629153":"04652","629154":"04652","629155":"04652","629156":"04652","629157":"04652","629158":"04652","629159":"04652","629160":"04652","629161":"04652","629162":"04652","629163":"04652","629164":"04652","629165":"04652","629166":"04652","629167":"04652","629168":"04652","629169":"04652","629170":"04652","629171":"04652","629172":"04652","629173":"04652","629174":"04652","629175":"04652","629176":"04652","629177":"04652","629178":"04652","629179":"04652","629180":"04652","629193":"04652","629201":"04652","629202":"04652","629203":"04652","629204":"04652","629251":"04652","629252":"04652","629301":"04652","629302":"04652","629401":"04652","629402":"04652","629403":"04652","629501":"04652","629502":"04652","629601":"04652","629602":"04652","629701":"04652","629702":"04652","629703":"04652","629704":"04652","629801":"04652","629802":"04652","629803":"04652","629804":"04652","629809":"04652","629810":"04652","629851":"04652","629852":"04652","629901":"04652","630001":"04575","630002":"04575","630003":"04575","630005":"04575","630101":"04575","630102":"04575","630103":"04575","630104":"04575","630105":"04575","630106":"04575","630107":"04575","630108":"04575","630201":"04575","630202":"04575","630203":"04575","630204":"04575","630205":"04575","630206":"04575","630207":"04575","630208":"04575","630210":"04575","630211":"04575","630212":"04575","630301":"04575","630302":"04575","630303":"04575","630305":"04575","630306":"04575","630307":"04575","630309":"04575","630311":"04575","630312":"04575","630313":"04575","630314":"04575","630321":"04575","630405":"04575","630408":"04575","630410":"04575","630411":"04575","630501":"04575","630502":"04575","630551":"04575","630552":"04575","630553":"04575","630554":"04575","630555":"04575","630556":"04575","630557":"04575","630558":"04575","630559":"04575","630561":"04575","630562":"04575","630566":"04575","630602":"04575","630606":"04575","630609":"04575","630610":"04562","630611":"04562","630612":"04575","630702":"04575","630709":"04575","630710":"04575","630713":"04575","631001":"04172","631002":"04172","631003":"04172","631004":"04172","631005":"04172","631006":"04172","631051":"04172","631052":"04172","631101":"04172","631102":"04172","631151":"04172","631152":"04172","631201":"044","631202":"044","631203":"044","631204":"044","631205":"044","631206":"044","631207":"044","631208":"044","631209":"044","631210":"044","631211":"044","631212":"044","631213":"044","631301":"044","631302":"044","631303":"044","631304":"044","631402":"044","631501":"04112","631502":"04112","631551":"04112","631552":"04112","631553":"04112","631561":"04112","631601":"04112","631603":"04112","631604":"04112","631605":"04112","631606":"04112","631701":"04175","631702":"04175","632001":"0416","632002":"0416","632004":"0416","632006":"0416","632007":"0416","632008":"0416","632009":"0416","632010":"0416","632011":"0416","632012":"0416","632013":"0416","632014":"0416","632055":"0416","632057":"0416","632058":"0416","632059":"0416","632101":"0416","632102":"0416","632103":"0416","632104":"0416","632105":"0416","632106":"0416","632107":"0416","632113":"0416","632114":"0416","632115":"0416","632201":"0416","632202":"0416","632203":"0416","632204":"0416","632209":"0416","632301":"04175","632311":"04175","632312":"0416","632313":"04175","632314":"04175","632315":"04175","632316":"04175","632317":"04175","632318":"04172","632319":"0416","632326":"04175","632401":"04172","632403":"04172","632404":"04172","632405":"04172","632406":"04172","632501":"04172","632502":"04172","632503":"04172","632504":"04172","632505":"04172","632506":"0416","632507":"04175","632508":"04172","632509":"04172","632510":"04172","632511":"04175","632512":"04175","632513":"04172","632514":"0416","632515":"0416","632516":"0416","632517":"04172","632518":"04175","632519":"0416","632520":"0416","632521":"04172","632531":"04172","632601":"0416","632602":"0416","632603":"0416","632604":"0416","635001":"04343","635002":"04343","635101":"04343","635102":"04343","635103":"04343","635104":"04343","635105":"04343","635106":"04343","635107":"04343","635108":"04343","635109":"04343","635110":"04343","635111":"04342","635112":"04343","635113":"04343","635114":"04343","635115":"04343","635116":"04343","635117":"04343","635118":"04343","635119":"04343","635120":"04343","635121":"04343","635122":"04343","635123":"04343","635124":"04343","635126":"04343","635130":"04343","635201":"04343","635202":"04342","635203":"04343","635204":"04343","635205":"04342","635206":"04343","635207":"04343","635301":"04342","635302":"04342","635303":"04342","635304":"04343","635305":"04342","635306":"04343","635307":"04343","635601":"04577","635602":"04577","635651":"04577","635652":"04577","635653":"04577","635654":"04577","635655":"04577","635701":"04577","635702":"04577","635703":"04175","635710":"04577","635751":"04577","635752":"04577","635754":"04577","635801":"04577","635802":"04577","635803":"0416","635804":"0416","635805":"0416","635806":"0416","635807":"04577","635808":"0416","635809":"0416","635810":"0416","635811":"04577","635812":"04577","635813":"0416","635814":"04577","635815":"04577","635851":"04577","635852":"04577","635853":"04577","635854":"04577","635901":"04577","636001":"0427","636002":"0427","636003":"0427","636004":"0427","636005":"0427","636006":"0427","636007":"0427","636008":"0427","636009":"0427","636010":"0427","636011":"0427","636012":"0427","636013":"0427","636014":"0427","636015":"0427","636016":"0427","636017":"0427","636030":"0427","636101":"0427","636102":"0427","636103":"0427","636104":"0427","636105":"0427","636106":"0427","636107":"0427","636108":"0427","636109":"0427","636110":"0427","636111":"0427","636112":"0427","636113":"0427","636114":"0427","636115":"0427","636116":"0427","636117":"0427","636118":"0427","636119":"0427","636121":"0427","636122":"0427","636138":"0427","636139":"0427","636140":"0427","636141":"0427","636142":"04286","636201":"0427","636202":"04286","636203":"0427","636204":"0427","636301":"04286","636302":"0427","636303":"0427","636304":"0427","636305":"0427","636306":"0427","636307":"0427","636308":"0427","636309":"0427","636351":"0427","636352":"04342","636354":"0427","636401":"0427","636402":"0427","636403":"0427","636404":"0427","636406":"0427","636451":"0427","636452":"0427","636453":"0427","636454":"0427","636455":"0427","636456":"0427","636457":"0427","636458":"0427","636501":"0427","636502":"0427","636503":"0427","636601":"0427","636602":"0427","636701":"04342","636704":"04342","636705":"04342","636803":"04342","636804":"04342","636805":"04342","636806":"04343","636807":"04342","636808":"04342","636809":"04342","636810":"04342","636811":"04342","636812":"04343","636813":"04342","636902":"04343","636903":"04342","636904":"04342","636905":"04342","636906":"04342","637001":"04286","637002":"04286","637003":"04286","637013":"04286","637014":"04286","637015":"04286","637017":"04286","637018":"04286","637019":"04286","637020":"04286","637021":"04286","637101":"0427","637102":"0427","637103":"0427","637104":"0427","637105":"0427","637107":"0427","637201":"04286","637202":"04286","637203":"04286","637204":"04286","637205":"04286","637206":"04286","637207":"04286","637208":"04286","637209":"04286","637210":"04286","637211":"04286","637212":"04286","637213":"04286","637214":"04286","637215":"04286","637301":"0427","637302":"0427","637303":"0427","637304":"0427","637401":"04286","637402":"04286","637403":"04286","637404":"04286","637405":"04286","637406":"04286","637407":"04286","637408":"04286","637409":"04286","637410":"04286","637411":"04286","637412":"04286","637415":"04286","637501":"0427","637502":"0427","637503":"04286","637504":"0427","637505":"04286","638001":"0424","638002":"0424","638003":"0424","638004":"0424","638005":"0424","638006":"04286","638007":"04286","638008":"04286","638009":"0424","638010":"04286","638011":"0424","638012":"0424","638051":"0421","638052":"0424","638053":"0424","638054":"0424","638055":"0424","638056":"0421","638057":"0424","638060":"0424","638101":"0424","638102":"0424","638103":"0421","638104":"0424","638105":"0421","638106":"0421","638107":"0424","638108":"0421","638109":"0424","638110":"0421","638111":"0421","638112":"0424","638115":"0424","638116":"0424","638151":"04324","638152":"0424","638153":"0424","638154":"0424","638181":"04286","638182":"04286","638183":"0427","638301":"0424","638311":"0424","638312":"0424","638313":"0424","638314":"0424","638315":"0424","638316":"0424","638401":"0424","638402":"0424","638451":"0423","638452":"0424","638453":"0424","638454":"0424","638455":"0424","638456":"0424","638457":"0424","638458":"0421","638459":"0421","638460":"0421","638461":"0424","638462":"0421","638476":"0424","638501":"0424","638502":"0424","638503":"0424","638504":"0424","638505":"0424","638506":"0424","638656":"0421","638657":"0421","638660":"0421","638661":"0421","638672":"0421","638673":"0421","638701":"0421","638702":"0421","638703":"0421","638706":"0421","638751":"0421","638752":"0421","638812":"0421","639001":"04324","639002":"04324","639003":"04324","639004":"04324","639005":"04324","639006":"04324","639007":"04324","639008":"04324","639101":"0431","639102":"04324","639103":"0431","639104":"04324","639105":"04324","639107":"04324","639108":"04324","639109":"04324","639110":"04324","639111":"04324","639112":"0431","639113":"04324","639114":"04324","639115":"0431","639116":"04324","639117":"04324","639118":"04324","639119":"04324","639120":"04324","639136":"04324","639201":"0421","639202":"0421","639203":"04324","639205":"04324","639206":"04324","639207":"04324","641001":"0422","641002":"0422","641003":"0422","641004":"0422","641005":"0422","641006":"0422","641007":"0422","641008":"0422","641009":"0422","641010":"0422","641011":"0422","641012":"0422","641013":"0422","641014":"0422","641015":"0422","641016":"0422","641017":"0422","641018":"0422","641019":"0422","641020":"0422","641021":"0422","641022":"0422","641023":"0422","641024":"0422","641025":"0422","641026":"0422","641027":"0422","641028":"0422","641029":"0422","641030":"0422","641031":"0422","641032":"0422","641033":"0422","641034":"0422","641035":"0422","641036":"0422","641037":"0422","641038":"0422","641039":"0422","641040":"0422","641041":"0422","641042":"0422","641043":"0422","641044":"0422","641045":"0422","641046":"0422","641047":"0422","641048":"0422","641049":"0422","641050":"0422","641062":"0422","641101":"0422","641103":"0422","641104":"0422","641105":"0422","641107":"0422","641108":"0422","641109":"0422","641110":"0422","641111":"0422","641112":"0422","641113":"0422","641114":"0422","641201":"0422","641202":"0422","641301":"0422","641302":"0424","641305":"0422","641401":"0421","641402":"0422","641407":"0422","641601":"0421","641602":"0421","641603":"0421","641604":"0421","641605":"0421","641606":"0421","641607":"0421","641652":"0421","641653":"0422","641654":"0421","641655":"0421","641658":"0421","641659":"0422","641662":"0421","641663":"0421","641664":"0421","641665":"0421","641666":"0421","641667":"0421","641668":"0422","641669":"0422","641670":"0421","641671":"0421","641687":"0421","641697":"0422","642001":"0422","642002":"0422","642003":"0422","642004":"0422","642005":"0422","642006":"0422","642007":"0422","642101":"0422","642102":"0421","642103":"0422","642104":"0422","642105":"0422","642106":"0422","642107":"0422","642108":"0422","642109":"0422","642110":"0422","642111":"0421","642112":"0421","642113":"0421","642114":"0422","642117":"0422","642120":"0421","642122":"0421","642123":"0422","642125":"0422","642126":"0421","642127":"0422","642128":"0421","642129":"0422","642130":"0422","642132":"0421","642133":"0422","642134":"0422","642154":"0421","642201":"0421","642202":"0421","642203":"0421","642204":"0421","642205":"0421","642206":"0421","642207":"0421","643001":"0423","643002":"0423","643003":"0423","643004":"0423","643005":"0423","643006":"0423","643007":"0423","643101":"0423","643102":"0423","643103":"0423","643105":"0423","643201":"0423","643202":"0423","643203":"0423","643204":"0423","643205":"0423","643206":"0423","643207":"0423","643209":"0423","643211":"0423","643212":"0423","643213":"0423","643214":"0423","643215":"0423","643216":"0423","643217":"0423","643218":"0423","643219":"0423","643220":"0423","643221":"0423","643223":"0423","643224":"0423","643225":"0423","643226":"0423","643231":"0423","643233":"0423","643236":"0423","643237":"0423","643238":"0423","643239":"0423","643240":"0423","643241":"0423","643242":"0423","643243":"0423","643253":"0423","643270":"0423","670001":"0497","670002":"0497","670003":"0497","670004":"0497","670005":"0497","670006":"0497","670007":"0497","670008":"0497","670009":"0497","670010":"0497","670011":"0497","670012":"0497","670013":"0497","670014":"0497","670017":"0497","670018":"0497","670051":"0497","670101":"0497","670102":"0497","670103":"0497","670104":"0497","670105":"0497","670106":"0497","670107":"0497","670141":"0497","670142":"0497","670143":"0497","670301":"0497","670302":"0497","670303":"0497","670304":"0497","670305":"0497","670306":"0497","670307":"0494","670308":"0497","670309":"0497","670310":"0497","670325":"0497","670327":"0497","670331":"0497","670334":"0497","670353":"0497","670358":"0497","670501":"0497","670502":"0497","670503":"0497","670504":"0497","670511":"04994","670521":"0497","670561":"0497","670562":"0497","670563":"0497","670567":"0497","670571":"0497","670581":"0497","670582":"0497","670591":"0497","670592":"0497","670593":"0497","670594":"0497","670595":"0497","670601":"0497","670602":"0497","670604":"0497","670611":"0497","670612":"0494","670613":"0497","670621":"0497","670622":"0497","670631":"0497","670632":"0497","670633":"0497","670641":"0497","670642":"0497","670643":"0497","670644":"04935","670645":"04935","670646":"04935","670649":"0497","670650":"0497","670651":"0497","670661":"0497","670662":"0497","670663":"0497","670671":"0497","670672":"0497","670673":"0497","670674":"0497","670675":"0497","670676":"0497","670691":"0497","670692":"0497","670693":"0497","670694":"0497","670701":"0497","670702":"0497","670703":"0497","670704":"0497","670705":"0497","670706":"0497","670708":"0497","670721":"04935","670731":"04935","670741":"0497","671121":"04994","671122":"04994","671123":"04994","671124":"04994","671310":"04994","671311":"04994","671312":"04994","671313":"04994","671314":"04994","671315":"04994","671316":"04994","671317":"04994","671318":"04994","671319":"04994","671320":"04994","671321":"04994","671322":"04994","671323":"04994","671324":"04994","671326":"04994","671348":"04994","671351":"04994","671531":"04994","671532":"04994","671533":"04994","671534":"04994","671541":"04994","671542":"04994","671543":"04994","671551":"04994","671552":"04994","673001":"0495","673002":"0495","673003":"0495","673004":"0495","673005":"0495","673006":"0495","673007":"0495","673008":"0495","673009":"0495","673010":"0495","673011":"0495","673012":"0495","673014":"0495","673015":"0495","673016":"0495","673017":"0495","673018":"0495","673019":"0495","673020":"0495","673021":"0495","673027":"0495","673028":"0495","673029":"0495","673032":"0495","673051":"0495","673101":"0495","673102":"0495","673103":"0495","673104":"0495","673105":"0495","673106":"0495","673121":"04935","673122":"04935","673123":"04935","673124":"04935","673301":"0495","673302":"0495","673303":"0495","673304":"0495","673305":"0495","673306":"0495","673307":"0495","673308":"0495","673309":"0495","673310":"0490","673311":"0497","673312":"0497","673313":"0497","673314":"0494","673315":"0495","673316":"0497","673317":"0495","673323":"0495","673328":"0495","673501":"0495","673502":"0495","673503":"0495","673504":"0495","673505":"0495","673506":"0495","673507":"0495","673508":"0495","673509":"0495","673513":"0495","673517":"0495","673521":"0495","673522":"0495","673523":"0495","673524":"0495","673525":"0495","673526":"0495","673527":"0495","673528":"0495","673529":"0495","673541":"0495","673542":"0495","673570":"0495","673571":"0495","673572":"0494","673573":"0495","673574":"0495","673575":"04935","673576":"04935","673577":"04935","673579":"04935","673580":"0495","673581":"04935","673582":"0495","673585":"0495","673586":"0495","673591":"04935","673592":"04935","673593":"04935","673595":"04935","673596":"04935","673601":"0495","673602":"0495","673603":"0495","673604":"0495","673611":"0495","673612":"0495","673613":"0495","673614":"0495","673616":"0495","673620":"0495","673631":"0495","673632":"0494","673633":"0494","673634":"0494","673635":"0494","673636":"0494","673637":"0494","673638":"0494","673639":"0494","673640":"0494","673641":"0494","673642":"0494","673645":"0494","673647":"0494","673655":"0495","673661":"0495","676101":"0494","676102":"0494","676103":"0494","676104":"0494","676105":"0494","676106":"0494","676107":"0494","676108":"0494","676109":"0494","676121":"0494","676122":"0494","676123":"0494","676301":"0494","676302":"0494","676303":"0494","676304":"0494","676305":"0494","676306":"0494","676307":"0494","676309":"0494","676311":"0494","676312":"0494","676317":"0494","676319":"0494","676320":"0494","676501":"0494","676502":"0494","676503":"0494","676504":"0494","676505":"0494","676506":"0494","676507":"0494","676508":"0494","676509":"0494","676510":"0494","676517":"0494","676519":"0494","676521":"0494","676522":"0494","676523":"0494","676525":"0494","676528":"0494","676541":"0494","676542":"0494","676551":"0494","676552":"0494","676553":"0494","676561":"0494","676562":"0494","678001":"0491","678002":"0491","678003":"0491","678004":"0491","678005":"0491","678006":"0491","678007":"0491","678008":"0491","678009":"0491","678010":"0491","678011":"0491","678012":"0491","678013":"0491","678014":"0491","678051":"0491","678101":"0491","678102":"0491","678103":"0491","678104":"0491","678501":"0491","678502":"0491","678503":"0491","678504":"0491","678505":"0491","678506":"0491","678507":"0491","678508":"0491","678510":"0491","678512":"0491","678531":"0491","678532":"0491","678533":"0491","678534":"0491","678541":"0491","678542":"0491","678543":"0491","678544":"0491","678545":"0491","678546":"0491","678551":"0491","678552":"0491","678553":"0491","678554":"0491","678555":"0491","678556":"0491","678557":"0491","678571":"0491","678572":"0491","678573":"0491","678574":"0491","678581":"0491","678582":"0491","678583":"0491","678591":"0491","678592":"0491","678593":"0491","678594":"0491","678595":"0491","678596":"0491","678597":"0491","678598":"0491","678601":"0491","678611":"0491","678612":"0491","678613":"0491","678621":"0491","678622":"0491","678623":"0491","678624":"0491","678631":"0491","678632":"0491","678633":"0491","678641":"0491","678642":"0491","678651":"0491","678661":"0491","678671":"0491","678681":"0491","678682":"0491","678683":"0491","678684":"0491","678685":"0491","678686":"0491","678687":"0491","678688":"0491","678701":"0491","678702":"0491","678703":"0491","678704":"0491","678705":"0491","678706":"0491","678721":"0491","678722":"0491","678731":"0491","678732":"0491","678762":"0491","679101":"0491","679102":"0491","679103":"0491","679104":"0491","679105":"0487","679106":"0487","679121":"0491","679122":"0491","679123":"0491","679301":"0491","679302":"0491","679303":"0491","679304":"0491","679305":"0491","679306":"0491","679307":"0491","679308":"0491","679309":"0491","679313":"0491","679321":"0494","679322":"0494","679323":"0494","679324":"0494","679325":"0494","679326":"0494","679327":"0494","679328":"0494","679329":"0494","679330":"0494","679331":"0494","679332":"0494","679333":"0494","679334":"0494","679335":"0491","679336":"0491","679337":"0491","679338":"0494","679339":"0494","679340":"0494","679341":"0494","679357":"0494","679501":"0491","679502":"0491","679503":"0491","679504":"0491","679505":"0491","679506":"0491","679511":"0491","679512":"0491","679513":"0491","679514":"0491","679515":"0491","679516":"0491","679521":"0491","679522":"0491","679523":"0491","679531":"0487","679532":"0487","679533":"0491","679534":"0491","679535":"0491","679536":"0491","679551":"0491","679552":"0491","679553":"0491","679554":"0491","679561":"0487","679562":"0487","679563":"0487","679564":"0487","679571":"0494","679572":"0494","679573":"0494","679574":"0494","679575":"0494","679576":"0494","679577":"0494","679578":"0494","679579":"0494","679580":"0494","679581":"0494","679582":"0494","679583":"0494","679584":"0494","679585":"0494","679586":"0494","679587":"0494","679591":"0494","680001":"0487","680002":"0487","680003":"0487","680004":"0487","680005":"0487","680006":"0487","680007":"0487","680008":"0487","680009":"0487","680010":"0487","680011":"0487","680012":"0487","680013":"0487","680014":"0487","680020":"0487","680021":"0487","680022":"0487","680026":"0487","680027":"0487","680028":"0487","680101":"0487","680102":"0487","680103":"0487","680104":"0487","680121":"0487","680122":"0487","680123":"0487","680125":"0487","680301":"0487","680302":"0487","680303":"0487","680304":"0487","680305":"0487","680306":"0487","680307":"0487","680308":"0487","680309":"0487","680310":"0487","680311":"0487","680312":"0487","680317":"0487","680501":"0487","680502":"0487","680503":"0487","680504":"0487","680505":"0487","680506":"0487","680507":"0487","680508":"0487","680509":"0487","680510":"0487","680511":"0487","680512":"0487","680513":"0487","680514":"0487","680515":"0487","680516":"0487","680517":"0487","680518":"0487","680519":"0487","680520":"0487","680521":"0487","680522":"0487","680523":"0487","680524":"0487","680541":"0487","680542":"0487","680543":"0487","680544":"0487","680545":"0487","680546":"0487","680551":"0487","680552":"0487","680553":"0487","680555":"0487","680561":"0487","680562":"0487","680563":"0487","680564":"0487","680565":"0487","680566":"0487","680567":"0487","680568":"0487","680569":"0487","680570":"0487","680571":"0487","680581":"0487","680582":"0487","680583":"0487","680584":"0487","680585":"0487","680586":"0487","680587":"0487","680588":"0487","680589":"0487","680590":"0487","680591":"0487","680594":"0487","680596":"0487","680601":"0487","680602":"0487","680604":"0487","680611":"0487","680612":"0487","680613":"0487","680614":"0487","680615":"0487","680616":"0487","680617":"0487","680618":"0487","680619":"0487","680620":"0487","680623":"0487","680631":"0487","680641":"0487","680642":"0487","680651":"0487","680652":"0487","680653":"0487","680654":"0487","680655":"0487","680656":"0487","680661":"0487","680662":"0487","680663":"0487","680664":"0487","680665":"0487","680666":"0487","680667":"0487","680668":"0487","680669":"0487","680670":"0487","680671":"0487","680681":"0487","680682":"0487","680683":"0487","680684":"0487","680685":"0487","680686":"0487","680687":"0487","680688":"0487","680689":"0487","680691":"0487","680697":"0487","680699":"0487","680701":"0487","680702":"0487","680703":"0487","680711":"0487","680712":"0487","680721":"0487","680722":"0487","680724":"0487","680731":"0487","680732":"0487","680733":"0487","680734":"0487","680741":"0487","680751":"0487","682001":"0484","682002":"0484","682003":"0484","682004":"0484","682005":"0484","682006":"0484","682007":"0484","682008":"0484","682009":"0484","682010":"0484","682011":"0484","682012":"0484","682013":"0484","682015":"0484","682016":"0484","682017":"0484","682018":"0484","682019":"0484","682020":"0484","682021":"0484","682022":"0484","682023":"0484","682024":"0484","682025":"0484","682026":"0484","682027":"0484","682028":"0484","682029":"0484","682030":"0484","682031":"0484","682032":"0484","682033":"0484","682034":"0484","682035":"0484","682036":"0484","682037":"0484","682038":"0484","682039":"0484","682040":"0484","682041":"0484","682042":"0484","682050":"0484","682051":"0484","682052":"0484","682301":"0484","682302":"0484","682303":"0484","682304":"0484","682305":"0484","682306":"0484","682307":"0484","682308":"0484","682309":"0484","682310":"0484","682311":"0484","682312":"0484","682313":"0484","682314":"0484","682315":"0484","682316":"0484","682317":"0484","682501":"0484","682502":"0484","682503":"0484","682504":"0484","682505":"0484","682506":"0484","682507":"0484","682508":"0484","682509":"0484","682511":"0484","682551":"04896","682552":"04896","682553":"04896","682554":"04896","682555":"04896","682556":"04896","682557":"04896","682558":"04896","682559":"04896","683101":"0484","683102":"0484","683104":"0484","683105":"0484","683106":"0484","683108":"0484","683110":"0484","683111":"0484","683112":"0484","683501":"0484","683502":"0484","683503":"0484","683511":"0484","683512":"0484","683513":"0484","683514":"0484","683515":"0484","683516":"0484","683517":"0484","683518":"0484","683519":"0484","683520":"0484","683521":"0484","683522":"0484","683541":"0484","683542":"0484","683543":"0484","683544":"0484","683545":"0484","683546":"0484","683547":"0484","683548":"0484","683549":"0484","683550":"0484","683556":"0484","683561":"0484","683562":"0484","683563":"0484","683565":"0484","683571":"0484","683572":"0484","683573":"0484","683574":"0484","683575":"0484","683576":"0484","683577":"0484","683578":"0484","683579":"0484","683580":"0484","683581":"0484","683585":"0484","683587":"0484","683589":"0484","683594":"0484","685501":"04868","685503":"04868","685505":"04868","685507":"04868","685508":"04868","685509":"04868","685511":"04868","685512":"04868","685514":"04868","685515":"04868","685531":"04868","685532":"04868","685533":"0468","685535":"04868","685551":"04868","685552":"04868","685553":"04868","685554":"04868","685561":"04868","685562":"04868","685563":"04868","685565":"04868","685566":"04868","685571":"04868","685581":"04868","685582":"04868","685583":"04868","685584":"04868","685585":"04868","685586":"04868","685587":"04868","685588":"04868","685589":"04868","685590":"04868","685591":"04868","685595":"04868","685601":"04868","685602":"04868","685603":"04868","685604":"04868","685605":"04868","685606":"04868","685607":"04868","685608":"04868","685609":"04868","685612":"04868","685613":"04868","685614":"04868","685615":"04868","685616":"04868","685618":"04868","685619":"04868","685620":"04868","686001":"0481","686002":"0481","686003":"0481","686004":"0481","686005":"0481","686006":"0481","686007":"0481","686008":"0481","686009":"0481","686010":"0481","686011":"0481","686012":"0481","686013":"0481","686014":"0481","686015":"0481","686016":"0481","686017":"0481","686018":"0481","686019":"0481","686020":"0481","686021":"0481","686022":"0481","686041":"0481","686101":"0481","686102":"0481","686103":"0481","686104":"0481","686105":"0481","686106":"0481","686121":"0481","686122":"0481","686123":"0481","686141":"0481","686143":"0481","686144":"0481","686146":"0481","686501":"0481","686502":"0481","686503":"0481","686504":"0481","686505":"0481","686506":"0481","686507":"0481","686508":"0481","686509":"0481","686510":"0468","686511":"0468","686512":"0481","686513":"0481","686514":"0481","686515":"0481","686516":"0481","686517":"0481","686518":"0481","686519":"0481","686520":"0481","686521":"0481","686522":"0481","686531":"0481","686532":"0481","686533":"0481","686534":"0477","686535":"0481","686536":"0481","686537":"0481","686538":"0481","686539":"0481","686540":"0481","686541":"0481","686542":"0481","686543":"0481","686544":"0481","686545":"0481","686546":"0481","686547":"0468","686548":"0481","686555":"0481","686560":"0481","686561":"0481","686562":"0481","686563":"0481","686564":"0481","686571":"0481","686572":"0481","686573":"0481","686574":"0481","686575":"0481","686576":"0481","686577":"0481","686578":"0481","686579":"0481","686580":"0481","686581":"0481","686582":"0481","686583":"0481","686584":"0481","686585":"0481","686586":"0481","686587":"0481","686601":"0481","686602":"0481","686603":"0481","686604":"0481","686605":"0481","686606":"0481","686607":"0481","686608":"0481","686609":"0481","686610":"0481","686611":"0481","686612":"0481","686613":"0481","686616":"0481","686630":"0481","686631":"0481","686632":"0481","686633":"0481","686634":"0481","686635":"0481","686636":"0481","686637":"0481","686651":"0481","686652":"0481","686653":"0481","686661":"0484","686662":"0484","686663":"0484","686664":"0484","686665":"0484","686666":"0484","686667":"0484","686668":"0484","686669":"0484","686670":"0484","686671":"0484","686672":"0484","686673":"0484","686681":"0484","686691":"0484","686692":"0484","686693":"0484","688001":"0477","688002":"0477","688003":"0477","688004":"0477","688005":"0477","688006":"0477","688007":"0477","688008":"0477","688009":"0477","688011":"0477","688012":"0477","688013":"0477","688014":"0477","688501":"0477","688502":"0477","688503":"0477","688504":"0477","688505":"0477","688506":"0477","688521":"0477","688522":"0477","688523":"0477","688524":"0477","688525":"0477","688526":"0477","688527":"0477","688528":"0477","688529":"0477","688530":"0477","688531":"0477","688532":"0477","688533":"0477","688534":"0477","688535":"0477","688536":"0477","688537":"0477","688538":"0477","688539":"0477","688540":"0477","688541":"0477","688555":"0477","688561":"0477","688562":"0477","688570":"0477","688582":"0477","689101":"0468","689102":"0468","689103":"0468","689104":"0468","689105":"0468","689106":"0468","689107":"0468","689108":"0468","689109":"0477","689110":"0468","689111":"0468","689112":"0468","689113":"0468","689115":"0468","689121":"0477","689122":"0468","689123":"0468","689124":"0477","689126":"0477","689501":"0468","689502":"0468","689503":"0468","689504":"0477","689505":"0477","689506":"0477","689507":"0468","689508":"0477","689509":"0477","689510":"0477","689511":"0477","689512":"0477","689513":"0468","689514":"0468","689515":"0468","689520":"0477","689521":"0477","689531":"0468","689532":"0468","689533":"0468","689541":"0468","689542":"0468","689543":"0468","689544":"0468","689545":"0468","689546":"0468","689547":"0468","689548":"0468","689549":"0468","689550":"0468","689551":"0468","689571":"0477","689572":"0477","689573":"0477","689574":"0477","689581":"0468","689582":"0468","689583":"0468","689584":"0468","689585":"0468","689586":"0468","689587":"0468","689588":"0468","689589":"0468","689590":"0477","689591":"0468","689592":"0468","689594":"0468","689595":"0477","689597":"0468","689602":"0468","689611":"0468","689612":"0468","689613":"0468","689614":"0468","689615":"0468","689621":"0468","689622":"0477","689623":"0477","689624":"0477","689625":"0468","689626":"0468","689627":"0477","689641":"0468","689642":"0468","689643":"0468","689644":"0468","689645":"0468","689646":"0468","689647":"0468","689648":"0468","689649":"0468","689650":"0468","689652":"0468","689653":"0468","689654":"0468","689656":"0468","689661":"0468","689662":"0468","689663":"0468","689664":"0468","689666":"0468","689667":"0468","689668":"0468","689671":"0468","689672":"0468","689673":"0468","689674":"0468","689675":"0468","689676":"0468","689677":"0468","689678":"0468","689691":"0468","689692":"0468","689693":"0468","689694":"0468","689695":"0474","689696":"0474","689698":"0468","689699":"0468","689711":"0468","689713":"0468","690101":"0477","690102":"0477","690103":"0477","690104":"0477","690105":"0477","690106":"0477","690107":"0477","690108":"0477","690110":"0477","690501":"0477","690502":"0477","690503":"0477","690504":"0468","690505":"0477","690506":"0477","690507":"0477","690508":"0477","690509":"0477","690510":"0477","690511":"0477","690512":"0477","690513":"0477","690514":"0477","690515":"0477","690516":"0477","690517":"0477","690518":"0474","690519":"0474","690520":"0474","690521":"0474","690522":"0468","690523":"0474","690524":"0474","690525":"0474","690526":"0474","690527":"0477","690528":"0474","690529":"0477","690530":"0477","690531":"0477","690532":"0477","690533":"0477","690534":"0477","690535":"0477","690536":"0474","690537":"0477","690538":"0474","690539":"0474","690540":"0474","690542":"0474","690544":"0474","690546":"0474","690547":"0474","690548":"0477","690558":"0477","690559":"0477","690561":"0474","690571":"0477","690572":"0477","690573":"0474","690574":"0474","691001":"0474","691002":"0474","691003":"0474","691004":"0474","691005":"0474","691006":"0474","691007":"0474","691008":"0474","691009":"0474","691010":"0474","691011":"0474","691012":"0474","691013":"0474","691014":"0474","691015":"0474","691016":"0474","691019":"0474","691020":"0474","691021":"0474","691301":"0474","691302":"0474","691303":"0474","691304":"0474","691305":"0474","691306":"0474","691307":"0474","691308":"0474","691309":"0474","691310":"0474","691311":"0474","691312":"0474","691319":"0474","691322":"0474","691331":"0474","691332":"0474","691333":"0474","691334":"0474","691500":"0474","691501":"0474","691502":"0474","691503":"0474","691504":"0474","691505":"0474","691506":"0474","691507":"0474","691508":"0474","691509":"0474","691510":"0474","691511":"0474","691512":"0474","691515":"0474","691516":"0474","691520":"0474","691521":"0474","691522":"0474","691523":"0468","691524":"0468","691525":"0468","691526":"0468","691527":"0474","691530":"0468","691531":"0474","691532":"0474","691533":"0474","691534":"0474","691535":"0474","691536":"0474","691537":"0474","691538":"0474","691540":"0474","691541":"0474","691543":"0474","691551":"0468","691552":"0468","691553":"0468","691554":"0468","691555":"0468","691556":"0468","691557":"0474","691559":"0474","691560":"0474","691566":"0474","691571":"0474","691572":"0474","691573":"0474","691574":"0474","691576":"0474","691577":"0474","691578":"0474","691579":"0474","691581":"0474","691582":"0474","691583":"0474","691584":"0474","691585":"0474","691589":"0474","691590":"0474","691601":"0474","691602":"0474","695001":"0471","695002":"0471","695003":"0471","695004":"0471","695005":"0471","695006":"0471","695007":"0471","695008":"0471","695009":"0471","695010":"0471","695011":"0471","695012":"0471","695013":"0471","695014":"0471","695015":"0471","695016":"0471","695017":"0471","695018":"0471","695019":"0471","695020":"0471","695021":"0471","695022":"0471","695023":"0471","695024":"0471","695025":"0471","695026":"0471","695027":"0471","695028":"0471","695029":"0471","695030":"0471","695032":"0471","695033":"0471","695034":"0471","695035":"0471","695036":"0471","695038":"0471","695040":"0471","695042":"0471","695043":"0471","695051":"0471","695099":"0471","695101":"0471","695102":"0471","695103":"0471","695104":"0471","695121":"0471","695122":"0471","695123":"0471","695124":"0471","695125":"0471","695126":"0471","695132":"0471","695133":"0471","695134":"0471","695141":"0471","695142":"0471","695143":"0471","695144":"0471","695145":"0471","695146":"0471","695301":"0471","695302":"0471","695303":"0471","695304":"0471","695305":"0471","695306":"0471","695307":"0471","695308":"0471","695309":"0471","695310":"0471","695311":"0471","695312":"0471","695313":"0471","695316":"0471","695317":"0471","695318":"0471","695501":"0471","695502":"0471","695503":"0471","695504":"0471","695505":"0471","695506":"0471","695507":"0471","695508":"0471","695512":"0471","695513":"0471","695521":"0471","695522":"0471","695523":"0471","695524":"0471","695525":"0471","695526":"0471","695527":"0471","695528":"0471","695541":"0471","695542":"0471","695543":"0471","695547":"0471","695551":"0471","695561":"0471","695562":"0471","695563":"0471","695564":"0471","695568":"0471","695570":"0471","695571":"0471","695572":"0471","695573":"0471","695574":"0471","695575":"0471","695581":"0471","695582":"0471","695583":"0471","695584":"0471","695585":"0471","695586":"0471","695587":"0471","695588":"0471","695589":"0471","695601":"0471","695602":"0471","695603":"0471","695604":"0471","695605":"0471","695606":"0471","695607":"0471","695608":"0471","695609":"0471","695610":"0471","695611":"0471","695612":"0471","695614":"0471","695615":"0471","700001":"033","700002":"033","700003":"033","700004":"033","700005":"033","700006":"033","700007":"033","700008":"033","700009":"033","700010":"033","700011":"033","700012":"033","700013":"033","700014":"033","700015":"033","700016":"033","700017":"033","700018":"033","700019":"033","700020":"033","700021":"033","700022":"033","700023":"033","700024":"033","700025":"033","700026":"033","700027":"033","700028":"033","700029":"033","700030":"033","700031":"033","700032":"033","700033":"033","700034":"033","700035":"033","700036":"033","700037":"033","700038":"033","700039":"033","700040":"033","700041":"033","700042":"033","700043":"033","700044":"033","700045":"033","700046":"033","700047":"033","700048":"033","700049":"033","700050":"033","700051":"033","700052":"033","700053":"033","700054":"033","700055":"033","700056":"033","700057":"033","700058":"033","700059":"033","700060":"033","700061":"033","700062":"033","700063":"033","700064":"033","700065":"033","700066":"033","700067":"033","700068":"033","700069":"033","700070":"033","700071":"033","700072":"033","700073":"033","700074":"033","700075":"033","700076":"033","700077":"033","700078":"033","700079":"033","700080":"033","700081":"033","700082":"033","700083":"033","700084":"033","700085":"033","700086":"033","700087":"033","700088":"033","700089":"033","700090":"033","700091":"033","700092":"033","700093":"033","700094":"033","700095":"033","700096":"033","700097":"033","700099":"033","700100":"033","700101":"033","700102":"033","700103":"033","700104":"033","700105":"033","700106":"033","700107":"033","700108":"033","700109":"033","700110":"033","700111":"033","700112":"033","700113":"033","700114":"033","700115":"033","700116":"033","700117":"033","700118":"033","700119":"033","700120":"033","700121":"033","700122":"033","700123":"033","700124":"033","700125":"033","700126":"033","700127":"033","700128":"033","700129":"033","700130":"033","700131":"033","700132":"033","700133":"033","700134":"033","700135":"033","700136":"033","700137":"033","700138":"033","700139":"033","700140":"033","700141":"033","700142":"033","700143":"033","700144":"033","700145":"033","700146":"033","700147":"033","700148":"033","700149":"033","700150":"033","700151":"033","700152":"033","700153":"033","700154":"033","700155":"033","700156":"033","700157":"033","700158":"033","700159":"033","700160":"033","700161":"033","700162":"033","700163":"033","711101":"033","711102":"033","711103":"033","711104":"033","711105":"033","711106":"033","711107":"033","711108":"033","711109":"033","711110":"033","711111":"033","711112":"033","711113":"033","711114":"033","711115":"033","711201":"033","711202":"033","711203":"033","711204":"033","711205":"033","711206":"033","711225":"033","711226":"033","711227":"033","711301":"033","711302":"033","711303":"033","711304":"033","711305":"033","711306":"033","711307":"033","711308":"033","711309":"033","711310":"033","711312":"033","711313":"033","711314":"033","711315":"033","711316":"033","711317":"033","711322":"033","711331":"033","711401":"033","711403":"033","711404":"033","711405":"033","711408":"033","711409":"033","711410":"033","711411":"033","711412":"033","711413":"033","711414":"033","712101":"033","712102":"033","712103":"033","712104":"033","712105":"033","712121":"033","712122":"03222","712123":"033","712124":"033","712125":"033","712134":"0342","712135":"033","712136":"033","712137":"033","712138":"033","712139":"033","712146":"0342","712147":"033","712148":"033","712149":"033","712152":"033","712201":"033","712202":"033","712203":"033","712204":"033","712221":"033","712222":"033","712223":"033","712232":"033","712233":"033","712234":"033","712235":"033","712245":"033","712246":"033","712248":"033","712249":"033","712250":"033","712258":"033","712301":"033","712302":"033","712303":"033","712304":"033","712305":"033","712306":"033","712308":"0342","712310":"033","712311":"033","712401":"033","712402":"0342","712403":"033","712404":"033","712405":"033","712406":"033","712407":"033","712408":"033","712409":"033","712410":"0342","712412":"033","712413":"0342","712414":"033","712415":"033","712416":"033","712417":"033","712501":"033","712502":"033","712503":"033","712504":"033","712512":"0342","712513":"033","712514":"033","712515":"033","712601":"033","712602":"033","712611":"033","712612":"033","712613":"033","712614":"033","712615":"033","712616":"033","712617":"033","712701":"033","712702":"033","712706":"033","713101":"0342","713102":"0342","713103":"0342","713104":"0342","713121":"0342","713122":"0342","713123":"0342","713124":"0342","713125":"0342","713126":"0342","713127":"0342","713128":"0342","713129":"0342","713130":"0342","713131":"0342","713132":"0342","713140":"0342","713141":"0342","713142":"0342","713143":"0342","713144":"0342","713145":"0342","713146":"0342","713147":"0342","713148":"0342","713149":"0342","713150":"0342","713151":"0342","713152":"0342","713153":"0342","713154":"0342","713166":"0342","713201":"0341","713202":"0341","713203":"0341","713204":"0341","713205":"0341","713206":"0341","713207":"0341","713208":"0341","713209":"0341","713210":"0341","713211":"0341","713212":"0341","713213":"0341","713214":"0341","713215":"0341","713216":"0341","713217":"0341","713301":"0341","713302":"0341","713303":"0341","713304":"0341","713305":"0341","713315":"0341","713321":"0341","713322":"0341","713323":"0341","713324":"0341","713325":"0341","713326":"0341","713330":"0341","713331":"0341","713332":"0341","713333":"0341","713334":"0341","713335":"0341","713336":"0341","713337":"0341","713338":"0341","713339":"0341","713340":"0341","713341":"0341","713342":"0341","713343":"0341","713344":"0341","713346":"0341","713347":"0341","713357":"0341","713358":"0341","713359":"0341","713360":"0341","713361":"0341","713362":"0341","713363":"0341","713365":"0341","713369":"0341","713370":"0341","713371":"0341","713372":"0341","713373":"0341","713376":"0341","713378":"0341","713381":"0341","713384":"0341","713385":"0341","713386":"0341","713401":"0342","713403":"0342","713404":"0342","713405":"0342","713406":"0342","713407":"0342","713408":"0342","713409":"0342","713420":"0342","713421":"0342","713422":"0342","713423":"0342","713424":"0342","713426":"0342","713427":"0342","713428":"0342","713502":"0342","713512":"0342","713513":"0342","713514":"0342","713515":"0342","713519":"0342","713520":"0342","721101":"03222","721102":"03222","721121":"03222","721122":"03222","721124":"03222","721125":"03221","721126":"03222","721127":"03222","721128":"03222","721129":"03222","721130":"03222","721131":"03222","721132":"03222","721133":"03222","721134":"03228","721135":"03222","721136":"03222","721137":"03228","721139":"03222","721140":"03222","721143":"03221","721144":"03222","721145":"03222","721146":"03222","721147":"03222","721148":"03222","721149":"03222","721150":"03222","721151":"03228","721152":"03222","721153":"03222","721154":"03222","721155":"03222","721156":"03222","721157":"03222","721158":"03228","721159":"03221","721160":"03222","721161":"03222","721166":"03222","721171":"03228","721172":"03228","721201":"03222","721211":"03222","721212":"03222","721222":"03222","721232":"03222","721242":"03222","721253":"03222","721260":"03222","721301":"03222","721302":"03222","721303":"03222","721304":"03222","721305":"03222","721306":"03222","721401":"03228","721402":"03228","721403":"03228","721404":"03228","721405":"03228","721406":"03228","721420":"03222","721422":"03228","721423":"03228","721424":"03222","721425":"03228","721426":"03222","721427":"03228","721428":"03228","721429":"03228","721430":"03228","721431":"03228","721432":"03228","721433":"03228","721434":"03228","721435":"03222","721436":"03222","721437":"03222","721438":"03228","721439":"03228","721440":"03228","721441":"03228","721442":"03228","721443":"03222","721444":"03228","721445":"03222","721446":"03228","721447":"03228","721448":"03228","721449":"03228","721450":"03228","721451":"03222","721452":"03228","721453":"03228","721454":"03228","721455":"03228","721456":"03228","721457":"03222","721458":"03228","721463":"03228","721467":"03222","721501":"03221","721503":"03221","721504":"03221","721505":"03221","721506":"03221","721507":"03221","721513":"03222","721514":"03221","721515":"03221","721516":"03222","721517":"03221","721601":"03228","721602":"03228","721603":"03228","721604":"03228","721606":"03228","721607":"03228","721624":"03228","721625":"03228","721626":"03228","721627":"03228","721628":"03228","721629":"03228","721631":"03228","721632":"03228","721633":"03228","721634":"03228","721635":"03228","721636":"03228","721637":"03228","721641":"03222","721642":"03228","721643":"03228","721644":"03228","721645":"03228","721646":"03228","721647":"03228","721648":"03228","721649":"03228","721650":"03228","721651":"03228","721652":"03228","721653":"03228","721654":"03228","721655":"03228","721656":"03228","721657":"03228","721658":"03228","721659":"03228","722101":"03242","722102":"03242","722121":"03242","722122":"03242","722132":"03242","722133":"03242","722134":"03242","722135":"03242","722136":"03242","722137":"03242","722138":"03242","722139":"03242","722140":"03242","722141":"03242","722142":"03242","722143":"03242","722144":"03242","722146":"03242","722147":"03242","722148":"03242","722149":"03242","722150":"03242","722151":"03242","722152":"03242","722153":"03242","722154":"03242","722155":"03242","722156":"03242","722157":"03242","722158":"03242","722160":"03242","722161":"03242","722162":"03242","722164":"03242","722173":"03242","722183":"03242","722201":"03242","722202":"03242","722203":"03242","722204":"03242","722205":"03242","722206":"03242","722207":"03242","722208":"03242","723101":"03252","723102":"03252","723103":"03252","723104":"03252","723121":"03252","723126":"03252","723127":"03252","723128":"03252","723129":"03252","723130":"03252","723131":"03252","723132":"03252","723133":"03252","723142":"03252","723143":"03252","723145":"03252","723146":"03252","723147":"03252","723148":"03252","723149":"03252","723151":"03252","723152":"03252","723153":"03252","723154":"03252","723155":"03252","723156":"03252","723201":"03252","723202":"03252","723212":"03252","723213":"03252","723215":"03252","731101":"03462","731102":"03462","731103":"03462","731104":"03462","731121":"03462","731123":"03462","731124":"03462","731125":"03462","731126":"03462","731127":"03462","731129":"03462","731130":"03462","731132":"03462","731133":"03462","731201":"03462","731202":"03462","731204":"03462","731214":"0342","731215":"0342","731216":"03462","731218":"03462","731219":"03483","731220":"03462","731221":"03483","731222":"03483","731223":"03462","731224":"03462","731233":"03462","731234":"03462","731235":"03462","731236":"03462","731237":"03462","731238":"03462","731240":"03462","731241":"03483","731242":"03462","731243":"03462","731244":"03483","731245":"03462","731301":"03462","731302":"03462","731303":"03462","731304":"03462","732101":"03512","732102":"03512","732103":"03512","732121":"03512","732122":"03512","732123":"03512","732124":"03512","732125":"03512","732126":"03512","732127":"03512","732128":"03512","732138":"03512","732139":"03512","732140":"03512","732141":"03512","732142":"03512","732144":"03512","732201":"03512","732202":"03512","732203":"03512","732204":"03512","732205":"03512","732206":"03512","732207":"03512","732208":"03512","732209":"03512","732210":"03512","732215":"03512","732216":"03512","733101":"03522","733102":"03522","733103":"03522","733121":"03522","733123":"03523","733124":"03512","733125":"03523","733126":"03522","733127":"03522","733128":"03523","733129":"03523","733130":"03523","733132":"03523","733133":"03522","733134":"03523","733140":"03522","733141":"03522","733142":"03512","733143":"03523","733145":"03522","733156":"03523","733158":"03523","733201":"03523","733202":"03523","733207":"03523","733208":"03523","733209":"03523","733210":"03523","733215":"03523","734001":"03561","734002":"0354","734003":"0354","734004":"03561","734005":"0354","734006":"03561","734007":"03561","734008":"03552","734009":"0354","734010":"0354","734011":"0354","734012":"0354","734013":"0354","734014":"0354","734015":"03561","734101":"0354","734102":"0354","734103":"0354","734104":"0354","734105":"0354","734201":"0354","734203":"0354","734204":"0354","734209":"0354","734213":"0354","734214":"0354","734215":"0354","734216":"0354","734217":"0354","734218":"0354","734220":"0354","734221":"0354","734222":"0354","734223":"0354","734224":"0354","734226":"0354","734301":"03552","734311":"03552","734312":"03552","734313":"0354","734314":"03552","734315":"03552","734316":"03552","734421":"0354","734423":"0354","734424":"0354","734425":"0354","734426":"0354","734427":"0354","734429":"0354","734434":"0354","734501":"03561","734503":"03552","735101":"03561","735102":"03561","735121":"03561","735122":"03561","735132":"03561","735133":"03561","735134":"03561","735135":"03561","735202":"03561","735203":"03561","735204":"03564","735205":"03561","735206":"03552","735207":"03561","735208":"03564","735209":"03561","735210":"03561","735211":"03582","735212":"03561","735213":"03564","735214":"03564","735215":"03564","735216":"03561","735217":"03564","735218":"03561","735219":"03561","735220":"03564","735221":"03561","735222":"03561","735223":"03552","735224":"03561","735225":"03561","735226":"03564","735227":"03564","735228":"03561","735229":"03561","735230":"03561","735231":"03552","735232":"03561","735233":"03561","735234":"03561","735301":"03582","735302":"03561","735303":"03582","735304":"03582","735305":"03561","736101":"03582","736121":"03582","736122":"03564","736123":"03564","736131":"03582","736133":"03582","736134":"03582","736135":"03582","736145":"03582","736146":"03582","736156":"03582","736157":"03582","736158":"03582","736159":"03582","736160":"03582","736165":"03582","736167":"03582","736168":"03582","736169":"03582","736170":"03582","736171":"03582","736172":"03582","736176":"03582","736179":"03582","736182":"03564","736201":"03564","736202":"03564","736203":"03564","736204":"03564","736205":"03564","736206":"03564","736207":"03582","736208":"03564","737101":"03592","737102":"03592","737103":"03592","737106":"03592","737107":"03592","737111":"03595","737113":"03595","737116":"03592","737120":"03592","737121":"03595","737126":"011","737128":"011","737131":"03592","737132":"011","737133":"03592","737134":"011","737135":"03592","737136":"03592","737139":"011","741101":"03472","741102":"03472","741103":"03472","741121":"03472","741122":"03472","741123":"03474","741124":"03472","741125":"03472","741126":"03472","741127":"03472","741137":"03472","741138":"03472","741139":"03472","741140":"03472","741150":"03472","741151":"03472","741152":"03472","741153":"03472","741154":"03472","741155":"03472","741156":"03472","741157":"03472","741158":"03472","741159":"03472","741160":"03472","741161":"03472","741162":"03472","741163":"03472","741164":"03472","741165":"03472","741166":"03472","741167":"03472","741181":"03472","741201":"03472","741202":"03472","741221":"03472","741222":"03472","741223":"03472","741232":"03472","741234":"03472","741235":"03472","741238":"03472","741245":"03472","741246":"03472","741247":"03472","741248":"03472","741249":"03472","741250":"03472","741251":"03472","741252":"03472","741253":"03472","741254":"03472","741255":"03472","741256":"03472","741257":"03472","741301":"03472","741302":"03472","741313":"03472","741315":"03472","741316":"0342","741317":"03472","741319":"0342","741401":"03472","741402":"03472","741404":"03472","741501":"03472","741502":"03472","741503":"03472","741504":"03472","741505":"03472","741506":"03472","741507":"03472","741508":"03472","741509":"03472","742101":"03483","742102":"03483","742103":"03483","742104":"03483","742113":"03483","742121":"03472","742122":"03483","742123":"03483","742132":"03483","742133":"03483","742134":"03483","742135":"03483","742136":"03483","742137":"03483","742138":"03483","742140":"03483","742147":"03483","742148":"03483","742149":"03483","742151":"03483","742159":"03483","742160":"03483","742161":"03483","742163":"03483","742164":"03483","742165":"03483","742166":"03483","742168":"03483","742174":"03483","742175":"03483","742184":"03483","742187":"03483","742189":"03483","742201":"03483","742202":"03483","742212":"03483","742213":"03483","742223":"03483","742224":"03483","742225":"03483","742226":"03483","742227":"03483","742235":"03483","742236":"03483","742237":"03483","742238":"03483","742301":"03483","742302":"03483","742303":"03483","742304":"03483","742305":"03483","742306":"03483","742308":"03483","742401":"03483","742402":"03483","742404":"03483","742405":"03483","742406":"03483","742407":"03483","742408":"03483","742409":"03483","742410":"03483","743122":"033","743123":"033","743124":"033","743125":"033","743126":"033","743127":"033","743128":"033","743129":"033","743130":"033","743133":"033","743134":"033","743135":"033","743136":"033","743144":"033","743145":"033","743165":"033","743166":"033","743193":"033","743194":"033","743221":"033","743222":"033","743223":"033","743232":"033","743233":"033","743234":"033","743235":"033","743245":"033","743247":"033","743248":"033","743249":"033","743251":"033","743252":"033","743262":"033","743263":"033","743268":"033","743270":"033","743271":"033","743272":"033","743273":"033","743286":"033","743287":"033","743289":"033","743290":"033","743291":"033","743292":"033","743293":"033","743294":"033","743297":"033","743312":"033","743318":"033","743329":"033","743330":"033","743331":"033","743332":"033","743336":"033","743337":"033","743338":"033","743345":"033","743347":"033","743348":"033","743349":"033","743351":"033","743354":"033","743355":"033","743356":"033","743357":"033","743363":"033","743368":"033","743370":"033","743371":"033","743372":"033","743373":"033","743374":"033","743375":"033","743376":"033","743377":"033","743378":"033","743383":"033","743387":"033","743395":"033","743399":"033","743401":"033","743405":"033","743411":"033","743412":"033","743422":"033","743423":"033","743424":"033","743425":"033","743426":"033","743427":"033","743428":"033","743429":"033","743435":"033","743437":"033","743438":"033","743439":"033","743442":"033","743445":"033","743446":"033","743456":"033","743502":"033","743503":"033","743504":"033","743513":"033","743609":"033","743610":"033","743611":"033","743613":"033","743701":"033","743702":"033","743704":"033","743710":"033","743711":"033","744101":"03192","744102":"03192","744103":"03192","744104":"03192","744105":"03192","744106":"03192","744107":"03192","744112":"03192","744201":"03192","744202":"03192","744203":"03192","744204":"03192","744205":"03192","744206":"03192","744207":"03192","744209":"03192","744210":"03192","744211":"03192","744301":"03193","744302":"03193","744303":"03193","744304":"03193","751001":"06755","751002":"06755","751003":"06755","751004":"06755","751005":"06755","751006":"06755","751007":"06755","751008":"06755","751009":"06755","751010":"06755","751011":"06755","751012":"06755","751013":"06755","751014":"06755","751015":"06755","751016":"06755","751017":"06755","751018":"06755","751019":"06755","751020":"06755","751021":"06755","751022":"06755","751023":"06755","751024":"06755","751025":"06755","751026":"06755","751027":"06755","751028":"06755","751029":"06755","751030":"06755","751031":"06755","751032":"06755","751033":"06755","751034":"06755","752001":"06752","752002":"06752","752003":"06752","752004":"06752","752010":"06752","752011":"06752","752012":"06752","752013":"06752","752014":"06752","752015":"06752","752016":"06752","752017":"06752","752018":"06755","752019":"06752","752020":"06755","752021":"06755","752022":"06755","752023":"06755","752024":"03223","752025":"03223","752026":"03223","752027":"06755","752030":"06752","752031":"06755","752032":"06752","752034":"06755","752035":"06755","752037":"06755","752038":"06755","752045":"06752","752046":"06752","752050":"06752","752054":"06755","752055":"06755","752056":"06755","752057":"06755","752060":"06755","752061":"06755","752062":"06755","752063":"03223","752064":"06755","752065":"03223","752066":"06755","752068":"03223","752069":"03223","752070":"03223","752077":"03223","752078":"03223","752079":"03223","752080":"03223","752081":"03223","752082":"03223","752083":"03223","752084":"03223","752085":"03223","752089":"03223","752090":"03223","752091":"03223","752092":"03223","752093":"03223","752094":"03223","752100":"06752","752101":"06755","752102":"06755","752103":"06755","752104":"06752","752105":"06752","752106":"06752","752107":"06752","752108":"06752","752109":"06752","752110":"06752","752111":"06752","752113":"06752","752114":"06752","752115":"06755","752116":"06752","752118":"06752","752119":"06752","752120":"06752","752121":"06752","753001":"0671","753002":"0671","753003":"0671","753004":"0671","753006":"0671","753007":"0671","753008":"0671","753009":"0671","753010":"0671","753011":"0671","753012":"0671","753013":"0671","753014":"0671","753015":"0671","753016":"0671","754001":"06755","754002":"0671","754003":"0671","754004":"06752","754005":"06755","754006":"0671","754007":"0671","754008":"0671","754009":"0671","754010":"0671","754011":"0671","754012":"06755","754013":"0671","754018":"0671","754021":"0671","754022":"0671","754023":"06726","754024":"06726","754025":"0671","754026":"0671","754027":"0671","754028":"0671","754029":"0671","754030":"0671","754031":"0671","754032":"0671","754034":"0671","754035":"0671","754037":"0671","754071":"0671","754082":"06726","754100":"0671","754102":"06724","754103":"06724","754104":"06724","754105":"0671","754106":"06724","754107":"06724","754108":"06724","754109":"06724","754110":"06724","754111":"06724","754112":"0671","754113":"06724","754114":"06724","754119":"06724","754120":"06724","754130":"0671","754131":"0671","754132":"06724","754133":"06724","754134":"06727","754135":"06727","754136":"06724","754137":"06724","754138":"06724","754139":"06724","754140":"06727","754141":"06727","754142":"06727","754143":"06724","754145":"06724","754153":"06727","754160":"06724","754162":"06727","754200":"0671","754201":"0671","754202":"0671","754203":"0671","754204":"0671","754205":"06726","754206":"0671","754207":"06727","754208":"06727","754209":"0671","754210":"06727","754211":"06727","754212":"06727","754213":"06727","754214":"06727","754215":"06727","754216":"06727","754217":"06622","754218":"06727","754219":"06727","754220":"06727","754221":"0671","754222":"06727","754223":"06727","754224":"06727","754225":"06727","754227":"06727","754228":"06727","754231":"06727","754239":"06727","754240":"06727","754244":"06727","754245":"06727","754246":"06727","754248":"06727","754250":"06727","754253":"06727","754289":"06727","754290":"0671","754292":"06727","754293":"0671","754294":"06724","754295":"0671","754296":"06726","754297":"0671","754298":"0671","755001":"06726","755003":"06726","755004":"06727","755005":"06726","755006":"06726","755007":"06726","755008":"06726","755009":"06726","755010":"06726","755011":"06726","755012":"06726","755013":"06726","755014":"06726","755015":"06726","755016":"06727","755017":"06726","755018":"06726","755019":"06728","755020":"06726","755022":"06726","755023":"06726","755024":"06726","755025":"06726","755026":"06726","755027":"06726","755028":"06726","755036":"06726","755043":"06726","755044":"06726","755049":"06726","755050":"06726","755051":"06726","755061":"06727","755062":"06726","756001":"06782","756002":"06782","756003":"06782","756019":"06782","756020":"06782","756021":"06782","756022":"06782","756023":"06782","756024":"06782","756025":"06782","756026":"06782","756027":"06782","756028":"06792","756029":"06782","756030":"06792","756032":"06782","756033":"06782","756034":"06782","756035":"06782","756036":"06782","756037":"06782","756038":"06782","756039":"06782","756040":"06782","756041":"06782","756042":"06782","756043":"06782","756044":"06782","756045":"06782","756046":"06784","756047":"06782","756048":"06782","756049":"06782","756051":"06782","756055":"06782","756056":"06782","756058":"06782","756059":"06782","756060":"06782","756079":"06782","756080":"06782","756081":"06782","756083":"06782","756084":"06782","756085":"06782","756086":"06782","756087":"06782","756088":"06782","756089":"06782","756100":"06784","756101":"06784","756111":"06784","756112":"06784","756113":"06784","756114":"06784","756115":"06784","756116":"06784","756117":"06784","756118":"06784","756119":"06784","756120":"06784","756121":"06766","756122":"06784","756123":"06784","756124":"06784","756125":"06784","756126":"06782","756127":"06784","756128":"06784","756129":"06784","756130":"06784","756131":"06784","756132":"06784","756133":"06784","756134":"06782","756135":"06784","756137":"06784","756138":"06784","756139":"06784","756144":"06784","756162":"06784","756163":"06784","756164":"06784","756165":"06784","756166":"06782","756167":"06784","756168":"06784","756171":"06784","756181":"06784","756182":"06782","757001":"06792","757002":"06792","757003":"06792","757014":"06792","757016":"06792","757017":"06792","757018":"06792","757019":"06792","757020":"06792","757021":"06792","757022":"06792","757023":"06792","757024":"06792","757025":"06792","757026":"06792","757027":"06792","757028":"06792","757029":"06792","757030":"06792","757031":"06792","757032":"06792","757033":"06792","757034":"06792","757035":"06792","757036":"06792","757037":"06792","757038":"06792","757039":"06792","757040":"06792","757041":"06792","757042":"06792","757043":"06792","757045":"06792","757046":"06792","757047":"06792","757048":"06792","757049":"06792","757050":"06792","757051":"06792","757052":"06792","757053":"06792","757054":"06792","757055":"06792","757073":"06792","757074":"06792","757075":"06792","757077":"06792","757079":"06792","757081":"06792","757082":"06792","757083":"06792","757084":"06792","757085":"06792","757086":"06792","757087":"06792","757091":"06792","757092":"06792","757093":"06792","757100":"06792","757101":"06792","757102":"06792","757103":"06792","757104":"06792","757105":"06792","757106":"06792","757107":"06792","758001":"06766","758002":"06766","758013":"06766","758014":"06766","758015":"06766","758016":"06766","758017":"06766","758018":"06766","758019":"06766","758020":"06766","758021":"06766","758022":"06766","758023":"06766","758025":"06766","758026":"06766","758027":"06766","758028":"06766","758029":"06766","758030":"06766","758031":"06766","758032":"06766","758034":"06766","758035":"06766","758036":"06766","758037":"06766","758038":"06766","758040":"06766","758041":"06766","758043":"06766","758044":"06766","758045":"06766","758046":"06766","758047":"06766","758076":"06766","758078":"06766","758079":"06766","758080":"06766","758081":"06766","758082":"06766","758083":"06766","758084":"06766","758085":"06766","758086":"06766","758087":"06766","759001":"06762","759013":"06762","759014":"06762","759015":"06762","759016":"06762","759017":"06762","759018":"06762","759019":"06762","759020":"06762","759021":"06762","759022":"06762","759023":"06762","759024":"06762","759025":"06762","759026":"06762","759027":"06762","759028":"06762","759029":"06762","759037":"06764","759039":"06762","759040":"06764","759100":"06764","759101":"06764","759102":"06764","759103":"06764","759104":"06764","759105":"06764","759106":"06764","759107":"06764","759111":"06764","759116":"06764","759117":"06764","759118":"06764","759119":"06764","759120":"06762","759121":"06762","759122":"06762","759123":"06764","759124":"06764","759125":"06764","759126":"06764","759127":"06764","759128":"06762","759129":"06764","759130":"06764","759132":"06764","759141":"06764","759143":"06764","759145":"06764","759146":"06762","759147":"06764","759148":"06764","759149":"06764","759151":"06762","760001":"06811","760002":"06811","760003":"06811","760004":"06811","760005":"06811","760006":"06811","760007":"06811","760008":"06811","760009":"06811","760010":"06811","760011":"06811","761001":"06811","761002":"06811","761003":"06811","761004":"06811","761005":"06811","761006":"06811","761007":"06811","761008":"06811","761009":"06811","761010":"06811","761011":"06811","761012":"06811","761013":"06811","761014":"06811","761015":"06815","761016":"06815","761017":"06815","761018":"06811","761019":"06811","761020":"06811","761025":"06811","761026":"06811","761027":"06811","761028":"06811","761029":"06811","761030":"06811","761031":"06811","761032":"06811","761035":"06811","761037":"06811","761041":"06811","761042":"06811","761043":"06811","761045":"06811","761052":"06811","761054":"06811","761055":"06811","761100":"06811","761101":"06811","761102":"06811","761103":"06811","761104":"06811","761105":"06811","761106":"06811","761107":"06811","761108":"06842","761109":"06811","761110":"06811","761111":"06811","761114":"06811","761115":"06811","761116":"06811","761117":"06811","761118":"06811","761119":"06811","761120":"06811","761121":"06811","761122":"06811","761123":"06811","761124":"06811","761125":"06842","761126":"06811","761131":"06811","761132":"06811","761133":"06811","761140":"06811","761141":"06811","761143":"06811","761144":"06811","761146":"06811","761151":"06842","761200":"06815","761201":"06815","761206":"06815","761207":"06815","761208":"06815","761209":"06811","761210":"06815","761211":"06815","761212":"06815","761213":"06815","761214":"06815","761215":"06815","761217":"06815","762001":"06842","762002":"06842","762010":"06842","762011":"06842","762012":"06842","762013":"06841","762014":"06841","762015":"06841","762016":"06841","762017":"06841","762018":"06841","762019":"06842","762020":"06841","762021":"06842","762022":"06842","762023":"06841","762024":"06841","762026":"06841","762027":"06842","762028":"06842","762029":"06842","762030":"06841","762100":"06842","762101":"06842","762102":"06842","762103":"06842","762104":"06842","762105":"06842","762106":"06842","762107":"06842","762109":"06842","762110":"06842","762112":"06842","763001":"06852","763002":"06852","763003":"06852","763004":"06852","763008":"06852","764001":"06852","764002":"06858","764003":"06852","764004":"06852","764005":"06852","764006":"06852","764011":"06852","764014":"06852","764020":"06852","764021":"06852","764027":"06852","764028":"06852","764036":"06852","764037":"06852","764038":"06852","764039":"06852","764040":"06852","764041":"06852","764042":"06852","764043":"06852","764044":"06861","764045":"06861","764046":"06861","764047":"06861","764048":"06861","764049":"06858","764051":"06861","764052":"06861","764055":"06852","764056":"06852","764057":"06852","764058":"06852","764059":"06858","764061":"06858","764062":"06856","764063":"06858","764070":"06858","764071":"06858","764072":"06858","764073":"06858","764074":"06858","764075":"06858","764076":"06858","764077":"06858","764078":"06858","764081":"06852","764085":"06858","764086":"06861","764087":"06861","764088":"06858","765001":"06856","765002":"06856","765013":"06852","765015":"06856","765016":"06856","765017":"06856","765018":"06856","765019":"06856","765020":"06856","765021":"06856","765022":"06856","765023":"06856","765024":"06856","765025":"06856","765026":"06856","765029":"06856","765033":"06856","765034":"06856","766001":"06670","766002":"06670","766003":"06670","766011":"06670","766012":"06670","766013":"06670","766014":"06670","766015":"06670","766016":"06670","766017":"06670","766018":"06670","766019":"06670","766020":"06670","766023":"06670","766026":"06670","766027":"06670","766028":"06670","766029":"06670","766031":"06670","766032":"06670","766036":"06670","766037":"06670","766100":"06670","766101":"06670","766102":"06670","766103":"06670","766104":"06678","766105":"06678","766106":"06678","766107":"06678","766108":"06678","766110":"06670","766111":"06678","766118":"06678","767001":"06652","767002":"06652","767016":"06158","767017":"06158","767018":"06158","767019":"06158","767020":"06158","767021":"06652","767022":"06652","767023":"06158","767024":"06652","767025":"06652","767026":"06652","767027":"06652","767028":"06652","767029":"06652","767030":"06652","767032":"06652","767033":"06652","767035":"06652","767037":"06652","767038":"06652","767039":"06652","767040":"06752","767041":"06652","767042":"06652","767045":"06158","767046":"06652","767048":"06652","767060":"06652","767061":"06652","767062":"06158","767065":"06652","767066":"06652","767067":"06652","767068":"06158","767070":"06652","767071":"06652","768001":"0663","768002":"0663","768003":"0663","768004":"0663","768005":"0663","768006":"0663","768016":"0663","768017":"0663","768018":"0663","768019":"0663","768020":"0663","768025":"0663","768027":"06646","768028":"06646","768029":"06646","768030":"06646","768031":"06646","768032":"06646","768033":"06646","768034":"06646","768035":"06646","768036":"06646","768037":"06646","768038":"06646","768039":"06646","768040":"06646","768042":"06646","768045":"06646","768048":"06646","768049":"06646","768050":"06646","768052":"06646","768053":"06646","768102":"06646","768103":"06646","768104":"06646","768105":"0663","768106":"0663","768107":"0663","768108":"02904","768109":"0663","768110":"02904","768111":"06646","768112":"0663","768113":"0663","768115":"06646","768118":"0663","768119":"02904","768121":"02904","768200":"0663","768201":"06645","768202":"06645","768203":"06645","768204":"06645","768210":"0663","768211":"06645","768212":"0663","768213":"06645","768214":"0663","768215":"06645","768216":"06645","768217":"06645","768218":"06645","768219":"06645","768220":"06645","768221":"0663","768222":"0663","768224":"0663","768225":"06645","768226":"06645","768227":"0663","768228":"06622","768233":"06645","768234":"06645","769001":"06622","769002":"06622","769003":"06622","769004":"06622","769005":"06622","769006":"06622","769007":"06622","769008":"06622","769009":"06622","769010":"06622","769011":"06622","769012":"06622","769013":"06622","769014":"06622","769015":"06622","769016":"06622","769042":"06622","769043":"06622","770001":"06622","770002":"06622","770011":"06622","770012":"06622","770013":"06622","770014":"06622","770015":"06622","770016":"06622","770017":"06622","770018":"06622","770019":"06622","770020":"06622","770021":"06622","770022":"06622","770023":"06622","770024":"06622","770025":"06622","770031":"06622","770032":"06622","770033":"06622","770034":"06622","770035":"06622","770036":"06622","770037":"06622","770038":"06622","770039":"06622","770040":"06622","770041":"06622","770042":"06622","770043":"06622","770044":"06622","770046":"06622","770048":"06622","770051":"06622","770052":"06622","770070":"06622","770072":"06622","770073":"06622","770074":"06622","770075":"06622","770076":"06622","781001":"0361","781002":"0361","781003":"0361","781004":"0361","781005":"0361","781006":"0361","781007":"0361","781008":"0361","781009":"0361","781010":"0361","781011":"0361","781012":"0361","781013":"0361","781014":"0361","781015":"0361","781016":"0361","781017":"0361","781018":"0361","781019":"0361","781020":"0361","781021":"0361","781022":"0361","781023":"0361","781024":"0361","781025":"0361","781026":"0361","781027":"0361","781028":"0361","781029":"03622","781030":"0361","781031":"0361","781032":"0361","781034":"0361","781035":"0361","781036":"0361","781037":"0361","781038":"0361","781039":"0361","781040":"0361","781101":"0361","781102":"0361","781103":"0361","781104":"0361","781120":"0361","781121":"0361","781122":"0361","781123":"0361","781124":"0361","781125":"0361","781126":"03624","781127":"0361","781128":"0361","781129":"0361","781131":"03622","781132":"0361","781133":"0361","781134":"0361","781135":"0361","781136":"0361","781137":"0361","781138":"03624","781141":"0361","781150":"0361","781171":"0361","781301":"03666","781302":"03666","781303":"03624","781304":"03624","781305":"03666","781306":"03624","781307":"03666","781308":"03666","781309":"03666","781310":"03624","781311":"03666","781312":"03624","781313":"03666","781314":"03666","781315":"03666","781316":"03666","781317":"03666","781318":"03666","781319":"03666","781320":"03623","781321":"03666","781325":"03666","781326":"03666","781327":"03624","781328":"03666","781329":"03666","781330":"03624","781333":"03624","781334":"03624","781335":"03624","781337":"03624","781338":"03624","781339":"03624","781340":"03624","781341":"03624","781343":"03624","781344":"03624","781346":"03624","781347":"03624","781348":"03624","781349":"03624","781350":"03624","781351":"03624","781352":"03666","781353":"03624","781354":"0361","781355":"03624","781360":"03624","781364":"03624","781365":"0361","781366":"03624","781367":"03624","781368":"03624","781369":"03624","781370":"03624","781371":"03624","781372":"03624","781373":"03624","781374":"03624","781375":"03666","781376":"0361","781377":"03624","781378":"03624","781380":"0361","781381":"0361","781382":"0361","782001":"03672","782002":"03672","782003":"03672","782101":"03672","782102":"03672","782103":"03672","782104":"03670","782105":"03670","782106":"03672","782120":"03672","782121":"03670","782122":"03672","782123":"03672","782124":"03672","782125":"03672","782126":"03672","782127":"03670","782128":"03672","782135":"03672","782136":"03672","782137":"03672","782138":"03672","782139":"03672","782140":"03672","782141":"03672","782142":"03672","782143":"03672","782144":"03672","782401":"0361","782402":"0361","782403":"0361","782410":"03622","782411":"03670","782412":"03670","782413":"03675","782425":"03672","782426":"03672","782427":"03672","782428":"03674","782429":"03674","782435":"03675","782439":"03674","782440":"03674","782441":"03675","782442":"03674","782445":"03674","782446":"03674","782447":"03675","782448":"03675","782450":"03675","782460":"03675","782461":"03675","782462":"03675","782470":"03675","782480":"03675","782481":"03675","782482":"03675","782485":"03675","782486":"03675","782490":"03675","783101":"03663","783120":"03663","783122":"03663","783123":"03663","783124":"03663","783125":"03663","783126":"03663","783127":"03662","783128":"03662","783129":"03663","783130":"03663","783131":"03662","783132":"03663","783133":"03663","783134":"03663","783135":"03662","783301":"03662","783323":"03662","783324":"03662","783325":"03662","783330":"03662","783331":"03661","783332":"03661","783333":"03661","783334":"03662","783335":"03662","783336":"03661","783337":"03662","783339":"03662","783345":"03661","783346":"03661","783347":"03661","783348":"03662","783349":"03661","783350":"03661","783354":"03661","783360":"03661","783361":"03661","783369":"03661","783370":"03661","783371":"03662","783372":"03664","783373":"03661","783375":"03664","783376":"03661","783380":"03664","783381":"03664","783382":"03664","783383":"03664","783384":"03664","783385":"03664","783388":"03664","783389":"03664","783390":"03664","783391":"03664","783392":"03664","783393":"03664","783394":"03664","784001":"03712","784010":"03712","784025":"03712","784026":"03712","784027":"03712","784028":"03712","784101":"03712","784102":"03712","784103":"03712","784104":"03712","784105":"03712","784110":"03712","784111":"03712","784112":"03712","784113":"03711","784114":"03711","784115":"03713","784116":"03713","784117":"03712","784125":"03713","784144":"03713","784145":"03713","784146":"03713","784147":"03713","784148":"03713","784149":"03712","784150":"03712","784153":"03712","784154":"03712","784160":"05872","784161":"05872","784163":"05872","784164":"05872","784165":"05872","784166":"03715","784167":"03715","784168":"03715","784169":"03715","784170":"03715","784171":"03715","784172":"03715","784173":"03715","784174":"03715","784175":"03715","784176":"03715","784177":"03715","784178":"03715","784179":"03715","784180":"03712","784182":"03712","784184":"03715","784189":"03715","784190":"03711","784501":"03712","784502":"03712","784504":"03712","784505":"03712","784506":"03712","784507":"03711","784508":"03711","784509":"03711","784510":"03711","784513":"03711","784514":"03711","784521":"03711","784522":"03711","784523":"03711","784524":"03711","784525":"03711","784526":"03711","784527":"03711","784528":"03711","784529":"03713","785001":"0376","785004":"0376","785006":"0376","785007":"0376","785008":"0376","785009":"0376","785010":"0376","785013":"0376","785014":"0376","785015":"0376","785101":"0376","785102":"03775","785104":"03775","785105":"03775","785106":"03775","785107":"0376","785108":"0376","785110":"03775","785111":"0376","785112":"0376","785601":"03774","785602":"03774","785603":"03774","785609":"03774","785610":"03774","785611":"03774","785612":"03774","785613":"03774","785614":"03775","785615":"03774","785616":"0376","785618":"03774","785619":"03774","785621":"03774","785622":"03774","785625":"03774","785626":"03774","785630":"0376","785631":"0376","785632":"0376","785633":"0376","785634":"0376","785635":"0376","785636":"0376","785640":"03772","785661":"03772","785662":"03772","785663":"03772","785664":"03772","785665":"03772","785666":"03772","785667":"03772","785669":"03772","785670":"03842","785671":"03772","785672":"03772","785673":"03842","785674":"03772","785675":"0373","785676":"0373","785680":"03772","785681":"03772","785682":"03772","785683":"03772","785684":"03772","785685":"03772","785686":"03772","785687":"03772","785688":"03842","785689":"03842","785690":"03842","785691":"03842","785692":"03842","785693":"03842","785696":"03772","785697":"03772","785698":"03842","785699":"03774","785700":"0376","785701":"03772","785702":"03774","785703":"0376","785704":"0376","785705":"03774","786001":"0373","786002":"0373","786003":"0373","786004":"0373","786005":"0373","786006":"0373","786007":"0373","786008":"0373","786010":"0373","786012":"0373","786101":"0373","786102":"0373","786103":"0373","786125":"0374","786126":"0374","786145":"0374","786146":"0374","786147":"0374","786148":"0374","786150":"0374","786151":"0374","786152":"0374","786153":"0374","786154":"0374","786155":"0374","786156":"0374","786157":"0374","786158":"0374","786159":"0374","786160":"0374","786170":"0374","786171":"0374","786173":"0374","786174":"0374","786179":"0374","786181":"0374","786182":"0374","786183":"0374","786184":"0373","786187":"0374","786188":"0374","786189":"0374","786190":"0374","786191":"0373","786192":"0374","786601":"0374","786602":"0373","786610":"0373","786611":"0373","786612":"0373","786613":"0373","786614":"0373","786621":"0373","786622":"0373","786623":"0373","786692":"0373","787001":"05872","787023":"05872","787026":"03753","787031":"05872","787032":"05872","787033":"05872","787034":"03753","787035":"03753","787051":"05872","787052":"03775","787053":"05872","787054":"05872","787055":"05872","787056":"05872","787057":"03753","787058":"05872","787059":"03753","787060":"03753","787061":"03753","787110":"03753","788001":"03842","788002":"03842","788003":"03842","788004":"03842","788005":"03842","788006":"03842","788007":"03842","788009":"03842","788010":"03842","788011":"03842","788013":"03842","788014":"03842","788015":"03842","788025":"03842","788026":"03842","788030":"03842","788031":"03842","788098":"03842","788099":"03842","788101":"03842","788102":"03842","788103":"03842","788104":"03842","788106":"03842","788107":"03673","788108":"03673","788109":"03842","788110":"03842","788111":"03842","788112":"03842","788113":"03842","788114":"03842","788115":"03842","788116":"03842","788117":"03842","788118":"03842","788119":"03842","788120":"03842","788121":"03842","788123":"03842","788126":"03842","788127":"03842","788150":"03844","788151":"03844","788152":"03843","788155":"03844","788156":"03843","788160":"03844","788161":"03844","788162":"03844","788163":"03844","788164":"03844","788165":"03844","788166":"03843","788168":"03844","788701":"03843","788709":"03843","788710":"03843","788711":"03843","788712":"03843","788713":"03843","788719":"03843","788720":"03843","788722":"03843","788723":"03843","788724":"03843","788725":"03843","788726":"03843","788727":"03843","788728":"03843","788733":"03843","788734":"03843","788735":"03843","788736":"03843","788737":"03843","788738":"03844","788781":"03843","788801":"03844","788802":"03844","788803":"03843","788804":"03842","788805":"03842","788806":"03843","788815":"03842","788816":"03842","788817":"03842","788818":"03673","788819":"03673","788820":"03673","788830":"03673","788831":"03673","788832":"03673","788931":"03673","790001":"03782","790002":"03782","790003":"03782","790101":"03780","790102":"03778","790103":"03778","790104":"03794","790105":"03794","790106":"03794","790114":"03782","790116":"03780","791001":"03783","791002":"03777","791003":"03796","791101":"03783","791102":"0360","791103":"03777","791104":"0368","791105":"03777","791109":"0360","791110":"0360","791111":"0360","791112":"0360","791113":"0360","791114":"0360","791118":"03788","791119":"0360","791120":"03788","791121":"0360","791122":"03792","791123":"0360","791125":"0360","792001":"03806","792055":"03808","792056":"03808","792101":"03803","792102":"03806","792103":"03806","792104":"03804","792105":"03806","792110":"03803","792111":"03806","792120":"03808","792121":"03808","792122":"03808","792123":"03808","792129":"03786","792130":"03786","792131":"03786","793001":"0364","793002":"0364","793003":"0364","793004":"0364","793005":"0364","793006":"0364","793007":"0364","793008":"0364","793009":"0364","793010":"0364","793011":"0364","793012":"0364","793014":"0364","793015":"0364","793016":"0364","793017":"0364","793018":"0364","793019":"0364","793021":"0364","793022":"0364","793101":"03622","793102":"03622","793103":"03622","793104":"03622","793105":"03622","793106":"03655","793107":"0364","793108":"0364","793109":"03651","793110":"0364","793111":"0364","793112":"0364","793113":"0364","793114":"03655","793115":"0364","793116":"03622","793119":"03656","793120":"03656","793121":"0364","793122":"03622","793123":"03622","793126":"03656","793150":"03651","793151":"03651","793160":"03651","793161":"03651","793200":"03651","793210":"03651","794001":"03651","794002":"03651","794003":"03651","794005":"03651","794101":"03651","794102":"03651","794103":"03651","794104":"03651","794105":"03651","794106":"03651","794107":"03651","794108":"03651","794109":"03651","794110":"03651","794111":"03651","794112":"03651","794114":"03651","794115":"03651","795001":"0385","795002":"03880","795003":"0385","795004":"0385","795005":"0385","795006":"03878","795007":"03878","795008":"0385","795009":"0385","795010":"03880","795011":"03874","795101":"03848","795102":"03872","795103":"03848","795104":"03878","795105":"03878","795106":"03878","795107":"03880","795112":"03880","795113":"03880","795114":"03880","795115":"03877","795116":"03874","795117":"03874","795118":"03880","795122":"03880","795124":"03874","795125":"03877","795126":"0377","795127":"03872","795128":"03874","795129":"03880","795130":"03848","795131":"03872","795132":"03848","795133":"03874","795134":"03880","795135":"03872","795136":"03880","795138":"03848","795139":"03874","795140":"0385","795141":"03877","795142":"03845","795144":"03845","795145":"03845","795146":"03877","795147":"0377","795148":"03848","795149":"03848","795150":"03878","795159":"0377","796001":"0389","796004":"0389","796005":"0389","796007":"0389","796008":"0389","796009":"0389","796012":"0389","796014":"0389","796015":"03837","796017":"0389","796036":"0389","796070":"03837","796075":"03837","796081":"0389","796091":"03837","796101":"03837","796111":"0389","796161":"03838","796181":"03838","796184":"03838","796186":"03838","796190":"0389","796230":"0389","796261":"03838","796290":"0389","796310":"03838","796320":"03831","796321":"03831","796370":"03838","796410":"0389","796421":"0389","796431":"0389","796441":"0389","796470":"0389","796471":"0389","796501":"0389","796571":"0372","796581":"0372","796691":"0372","796701":"0372","796710":"0372","796751":"0372","796770":"0372","796772":"03835","796810":"03835","796891":"03835","796901":"03835","797001":"0370","797002":"03870","797003":"0370","797004":"0370","797006":"0370","797099":"03860","797101":"03870","797103":"03870","797104":"03867","797105":"03867","797106":"03870","797107":"03865","797108":"03865","797109":"03867","797110":"03870","797111":"03860","797112":"03860","797113":"03862","797114":"03865","797115":"03862","797116":"03862","797117":"03862","797118":"03862","797120":"0370","797121":"0370","798601":"03867","798602":"03869","798603":"03869","798604":"0369","798607":"0369","798611":"03863","798612":"03861","798613":"0369","798614":"0369","798615":"0369","798616":"03861","798618":"0369","798620":"03867","798621":"03869","798622":"03869","798623":"0369","798625":"03869","798627":"03867","799001":"0381","799002":"0381","799003":"0381","799004":"0381","799005":"0381","799006":"0381","799007":"0381","799008":"0381","799009":"0381","799010":"0381","799011":"0381","799012":"0381","799013":"03821","799014":"0381","799015":"0381","799022":"0381","799035":"0381","799045":"0381","799046":"0381","799101":"03821","799102":"0381","799103":"0381","799104":"03821","799105":"0381","799113":"03821","799114":"03821","799115":"0381","799120":"03821","799125":"03823","799130":"0381","799131":"0381","799132":"0381","799141":"03823","799142":"03823","799143":"03823","799144":"03823","799145":"03823","799150":"03823","799153":"03823","799155":"03823","799156":"03823","799157":"03823","799201":"03825","799202":"03825","799203":"03825","799204":"03826","799205":"03825","799207":"03825","799210":"0381","799211":"0381","799212":"0381","799250":"03822","799251":"03822","799253":"03822","799254":"03822","799256":"03822","799260":"03822","799261":"03822","799262":"03822","799263":"03824","799264":"03824","799266":"03826","799269":"03822","799270":"03824","799271":"03822","799273":"03826","799275":"03826","799277":"03824","799278":"03826","799279":"03824","799280":"03824","799281":"03824","799282":"03824","799284":"03826","799285":"03826","799286":"03826","799287":"03826","799288":"03824","799289":"03826","799290":"03824","800001":"0612","800002":"0612","800003":"0612","800004":"0612","800005":"0612","800006":"0612","800007":"0612","800008":"0612","800009":"0612","800010":"0612","800011":"0612","800012":"0612","800013":"0612","800014":"0612","800015":"0612","800016":"0612","800017":"0612","800018":"0612","800019":"0612","800020":"0612","800021":"0612","800022":"0612","800023":"0612","800024":"0612","800025":"0612","800026":"0612","800027":"0612","800028":"0612","800030":"0612","801102":"0612","801103":"0612","801104":"0612","801105":"0612","801106":"0612","801108":"0612","801109":"0612","801110":"0612","801111":"0612","801112":"0612","801113":"0612","801301":"06112","801302":"06324","801303":"06112","801304":"0612","801305":"0612","801306":"06112","801307":"06112","801503":"0612","801505":"0612","801506":"0612","801507":"0612","802101":"06183","802102":"06183","802103":"06183","802111":"06183","802112":"06183","802113":"06183","802114":"06183","802115":"06183","802116":"06183","802117":"06183","802118":"06183","802119":"06183","802120":"06183","802122":"06183","802123":"06183","802125":"06183","802126":"06183","802127":"06183","802128":"06183","802129":"06183","802130":"06183","802131":"06183","802132":"06189","802133":"06183","802134":"06183","802135":"06183","802136":"06183","802152":"06182","802154":"06182","802155":"06182","802156":"06182","802157":"06182","802158":"06182","802159":"06182","802160":"0612","802161":"06182","802162":"06182","802163":"06182","802164":"06182","802165":"06182","802166":"06182","802183":"06182","802201":"06182","802202":"06182","802203":"06182","802204":"06188","802205":"06188","802206":"06182","802207":"06182","802208":"06182","802209":"06182","802210":"06182","802211":"06188","802212":"06188","802213":"06188","802214":"06188","802215":"06188","802216":"06188","802217":"06188","802218":"06188","802219":"06188","802220":"06188","802221":"06188","802222":"06182","802223":"06182","802226":"06188","802301":"06182","802302":"06182","802311":"06182","802312":"06182","802313":"06182","802314":"06182","802316":"06182","802351":"06182","802352":"06182","803101":"06112","803107":"06112","803108":"06112","803109":"06112","803110":"0612","803111":"06112","803113":"06112","803114":"06112","803115":"06112","803116":"06112","803117":"06112","803118":"06112","803119":"06112","803120":"06112","803121":"06112","803201":"0612","803202":"0612","803203":"0612","803211":"0612","803212":"0612","803213":"0612","803214":"0612","803215":"0612","803216":"06112","803221":"0612","803301":"0612","803302":"0612","803303":"0612","803306":"0612","803307":"0612","804401":"0612","804402":"06337","804403":"06114","804404":"0631","804405":"06114","804406":"06114","804407":"06114","804408":"06114","804417":"06114","804418":"06114","804419":"06337","804420":"06114","804421":"06114","804422":"06114","804423":"06114","804424":"06114","804425":"06114","804426":"06337","804427":"06114","804428":"06337","804429":"06114","804432":"06114","804435":"0631","804451":"0612","804452":"0612","804453":"0612","804454":"0612","805101":"06324","805102":"06324","805103":"06324","805104":"06324","805105":"06112","805106":"06324","805107":"06324","805108":"06324","805109":"06324","805110":"06324","805111":"06324","805112":"06324","805113":"06324","805114":"06324","805121":"06324","805122":"06324","805123":"06324","805124":"06324","805125":"06324","805126":"06324","805127":"06324","805128":"0631","805129":"06324","805130":"06324","805131":"0631","805132":"06324","811101":"06341","811102":"06341","811103":"06341","811104":"0612","811105":"06341","811106":"06346","811107":"06341","811112":"06346","811201":"06344","811202":"06344","811211":"06344","811212":"06344","811213":"06344","811214":"06344","811301":"06345","811302":"06346","811303":"06345","811304":"06341","811305":"06345","811307":"06345","811308":"06345","811309":"06346","811310":"06346","811311":"06346","811312":"06345","811313":"06345","811314":"06345","811315":"06341","811316":"06345","811317":"06345","812001":"0641","812002":"0641","812003":"0641","812004":"0641","812005":"0641","812006":"0641","812007":"0641","813101":"0641","813102":"06473","813103":"06424","813104":"06424","813105":"0641","813106":"06424","813107":"06424","813108":"0641","813109":"06424","813110":"06424","813201":"06344","813202":"06424","813203":"0641","813204":"0641","813205":"0641","813206":"06422","813207":"06424","813208":"06436","813209":"06452","813210":"0641","813211":"06424","813212":"06344","813213":"06344","813214":"0641","813221":"06344","813222":"0641","814101":"06434","814102":"06434","814103":"06434","814110":"06434","814111":"06435","814112":"06432","814113":"06432","814114":"06432","814115":"06432","814116":"06432","814118":"06434","814119":"06434","814120":"06434","814131":"06424","814133":"06422","814141":"06434","814142":"06432","814143":"06432","814144":"06434","814145":"06434","814146":"06434","814147":"06422","814148":"06434","814149":"06432","814150":"06432","814151":"06434","814152":"06432","814153":"06422","814154":"06422","814155":"06422","814156":"06422","814157":"06432","814158":"06434","814160":"06422","814165":"06422","814166":"06433","814167":"06434","815301":"06532","815302":"06532","815311":"06532","815312":"06532","815313":"06532","815314":"06532","815315":"06532","815316":"06532","815317":"06532","815318":"06532","815351":"06433","815352":"06433","815353":"06432","815354":"06433","815355":"06433","815357":"06432","815359":"06433","816101":"06436","816102":"06436","816103":"06435","816104":"06436","816105":"06436","816106":"06435","816107":"06435","816108":"06436","816109":"06436","816110":"06436","816115":"06436","816116":"06436","816117":"06435","816118":"06434","816120":"06436","816129":"06436","821101":"06189","821102":"06189","821103":"06189","821104":"06188","821105":"06189","821106":"06189","821107":"06188","821108":"06189","821109":"06189","821110":"06189","821111":"06188","821112":"06188","821113":"06188","821115":"06188","821301":"06188","821302":"06188","821303":"06188","821304":"06188","821305":"06188","821306":"06188","821307":"06188","821308":"06188","821309":"06188","821310":"06188","821311":"06188","821312":"06188","822101":"06562","822102":"06562","822110":"06562","822111":"06565","822112":"06565","822113":"06562","822114":"06561","822115":"06562","822116":"06562","822117":"06562","822118":"06562","822119":"06565","822120":"06562","822121":"06561","822122":"06562","822123":"06562","822124":"06562","822125":"06561","822126":"06562","822128":"06561","822129":"06561","822131":"06562","822132":"06562","822133":"06562","822134":"06561","823001":"0631","823002":"0631","823003":"0631","823004":"0631","823005":"0631","823311":"0631","824101":"0240","824102":"0240","824103":"0240","824111":"0240","824112":"0240","824113":"0240","824114":"0240","824115":"0240","824116":"0631","824118":"0631","824120":"0240","824121":"0240","824122":"0240","824123":"0240","824124":"0240","824125":"0240","824127":"0240","824129":"0240","824143":"0240","824201":"0631","824202":"0240","824203":"0240","824205":"0631","824206":"0631","824207":"0631","824208":"0240","824209":"0631","824210":"0631","824211":"0631","824217":"0631","824219":"0631","824220":"0631","824221":"0631","824231":"0631","824232":"0631","824233":"06114","824234":"0631","824235":"0631","824236":"0631","824237":"0631","824301":"0240","824302":"0240","824303":"0240","824304":"0240","825101":"06553","825102":"06542","825103":"06541","825106":"06532","825108":"06532","825109":"06534","825132":"06534","825167":"06532","825301":"06546","825302":"06546","825303":"06546","825311":"06546","825312":"06546","825313":"06546","825314":"06553","825315":"06546","825316":"06553","825317":"06546","825318":"06534","825319":"06546","825320":"06532","825321":"06541","825322":"06546","825323":"06546","825324":"06532","825325":"06553","825326":"06553","825329":"06532","825330":"06553","825336":"06546","825401":"06541","825402":"06546","825403":"06541","825404":"06541","825405":"06546","825406":"06546","825407":"06534","825408":"06541","825409":"06534","825410":"06534","825411":"06553","825412":"06532","825413":"06534","825414":"06541","825415":"06541","825418":"06534","825421":"06534","826001":"0326","826003":"0326","826004":"0326","826005":"0326","826006":"0326","826007":"0326","826008":"0326","826009":"0326","826010":"0326","826011":"0326","827001":"06542","827003":"06542","827004":"06542","827006":"06542","827009":"06542","827010":"06542","827012":"06542","827013":"06542","827014":"06542","827015":"06542","827016":"06542","827302":"06542","828101":"0326","828103":"0326","828104":"0326","828105":"0326","828106":"0326","828107":"0326","828108":"0326","828109":"0326","828110":"0326","828111":"0326","828112":"0326","828113":"0326","828114":"0326","828115":"0326","828116":"0326","828117":"0326","828119":"0326","828120":"0326","828121":"0326","828122":"0326","828123":"0326","828124":"0326","828125":"0326","828126":"0326","828127":"0326","828128":"0326","828129":"0326","828130":"0326","828131":"0326","828132":"0326","828133":"0326","828134":"06542","828135":"0326","828142":"0326","828201":"0326","828202":"0326","828203":"0326","828204":"0326","828205":"0326","828206":"0326","828207":"0326","828301":"0326","828302":"0326","828303":"06542","828304":"0326","828305":"0326","828306":"0326","828307":"0326","828309":"0326","828401":"0326","828402":"0326","828403":"06542","828404":"06542","829101":"06553","829102":"06553","829103":"06553","829104":"06542","829105":"06553","829106":"06553","829107":"06542","829108":"06553","829109":"06553","829110":"06553","829111":"06542","829112":"06542","829113":"06542","829114":"06542","829116":"06542","829117":"06553","829118":"06553","829119":"06553","829121":"06542","829122":"06553","829123":"06542","829125":"06553","829126":"06553","829127":"06542","829128":"06542","829129":"06553","829130":"06553","829131":"06553","829132":"06542","829133":"06553","829134":"06553","829135":"06553","829143":"06553","829144":"06542","829149":"06542","829150":"06553","829201":"06541","829202":"06565","829203":"06565","829204":"06565","829205":"0651","829206":"06565","829207":"06565","829208":"0651","829209":"0651","829210":"0651","829301":"06542","831001":"0657","831002":"06597","831003":"0657","831004":"0657","831005":"0657","831006":"0657","831007":"0657","831009":"0657","831011":"0657","831012":"06597","831013":"06597","831014":"06597","831015":"0657","831016":"0657","831017":"0657","831019":"0657","831020":"0657","831021":"0657","832101":"0657","832102":"0657","832103":"0657","832104":"0657","832105":"0657","832106":"0657","832107":"06597","832108":"06597","832109":"06597","832111":"0657","832112":"0657","832113":"0657","832301":"0657","832302":"06582","832303":"0657","832304":"0657","832401":"06597","832402":"06597","832403":"06597","832404":"06597","833101":"06597","833102":"06582","833103":"06582","833104":"06582","833105":"06582","833106":"06582","833201":"06582","833202":"06582","833203":"06582","833204":"06582","833212":"06582","833213":"06582","833214":"06582","833215":"06582","833216":"06597","833217":"06582","833218":"06582","833219":"06597","833220":"06597","833221":"06582","833222":"06582","833223":"06582","834001":"0651","834002":"0651","834003":"0651","834004":"0651","834005":"0651","834006":"0651","834007":"0651","834008":"0651","834009":"0651","834010":"0651","834011":"0651","834012":"0651","834013":"0651","834014":"0651","835101":"0651","835102":"0651","835103":"0651","835201":"06525","835202":"0651","835203":"0651","835204":"0651","835205":"0651","835206":"06524","835207":"06524","835208":"06524","835209":"06528","835210":"06528","835211":"06525","835212":"06525","835213":"0651","835214":"0651","835215":"0651","835216":"06582","835217":"0651","835218":"06565","835219":"0651","835220":"06524","835221":"0651","835222":"0651","835223":"06525","835224":"06524","835225":"0651","835226":"06525","835227":"06582","835228":"06525","835229":"06524","835230":"06524","835231":"06526","835232":"06524","835233":"06524","835234":"0651","835235":"06525","835301":"0651","835302":"06526","835303":"0651","835325":"0651","841101":"06152","841201":"06152","841202":"06152","841203":"06154","841204":"06152","841205":"06152","841206":"06152","841207":"06152","841208":"06152","841209":"06152","841210":"06154","841211":"06152","841212":"06152","841213":"06152","841214":"06152","841215":"06152","841216":"06152","841217":"06152","841218":"06152","841219":"06152","841220":"06152","841221":"06152","841222":"06152","841223":"06154","841224":"06152","841225":"06152","841226":"06154","841227":"06154","841231":"06154","841232":"06154","841233":"06154","841234":"06154","841235":"06154","841236":"06154","841237":"06154","841238":"06154","841239":"06154","841240":"06154","841241":"06154","841242":"06154","841243":"06154","841244":"06154","841245":"06154","841286":"06154","841287":"06154","841301":"06152","841302":"06152","841305":"06152","841311":"06152","841312":"06152","841313":"06152","841316":"06152","841401":"06152","841402":"06152","841403":"06152","841404":"06154","841405":"07695","841406":"06154","841407":"07695","841408":"06154","841409":"07695","841410":"06152","841411":"06152","841412":"06152","841413":"06154","841414":"06152","841415":"06152","841416":"06154","841417":"06154","841418":"06152","841419":"06152","841420":"07695","841421":"06152","841422":"06152","841423":"07695","841424":"06152","841425":"07695","841426":"07695","841427":"07695","841428":"07695","841434":"06154","841435":"06154","841436":"06154","841437":"07695","841438":"07695","841439":"06154","841440":"07695","841441":"07695","841442":"06152","841443":"06152","841446":"06154","841447":"06154","841460":"06152","841501":"07695","841502":"06154","841503":"07695","841504":"06154","841505":"07695","841506":"06154","841507":"06154","841508":"07695","841509":"06154","842001":"0621","842002":"0621","842003":"0621","842004":"0621","842005":"0621","842006":"0621","843101":"0621","843102":"0621","843103":"0621","843104":"06224","843105":"0621","843106":"0621","843107":"0621","843108":"0621","843109":"0621","843110":"06224","843111":"0621","843112":"0621","843113":"0621","843114":"06224","843115":"0621","843116":"06226","843117":"06226","843118":"0621","843119":"0621","843120":"0621","843121":"0621","843122":"0621","843123":"0621","843124":"0621","843125":"0621","843126":"0621","843127":"0621","843128":"06222","843129":"0621","843130":"0621","843131":"06222","843301":"06226","843302":"06226","843311":"06226","843312":"0621","843313":"06226","843314":"06226","843315":"06226","843316":"06226","843317":"06226","843318":"06226","843319":"06226","843320":"06226","843321":"0621","843322":"06226","843323":"06226","843324":"06226","843325":"06226","843326":"06226","843327":"06226","843328":"06226","843329":"06222","843330":"06226","843331":"06226","843332":"06226","843333":"06226","843334":"06222","843335":"06222","843360":"0621","844101":"06224","844102":"06224","844103":"06224","844111":"06224","844112":"06224","844113":"06224","844114":"06224","844115":"06224","844116":"06224","844117":"06224","844118":"06224","844119":"06224","844120":"0621","844121":"06224","844122":"06224","844123":"06224","844124":"06224","844125":"06224","844126":"06224","844127":"0621","844128":"06224","844501":"06224","844502":"06224","844503":"06224","844504":"06224","844505":"06224","844506":"06224","844507":"06224","844508":"06224","844509":"06224","845101":"06254","845103":"06254","845104":"06254","845105":"06254","845106":"06254","845107":"06254","845301":"06252","845302":"06252","845303":"06252","845304":"06252","845305":"06252","845306":"06254","845307":"06254","845315":"06252","845401":"06252","845406":"06252","845411":"06252","845412":"06252","845413":"06252","845414":"06252","845415":"06252","845416":"06252","845417":"06252","845418":"06252","845419":"06252","845420":"06252","845422":"06252","845423":"06252","845424":"06252","845425":"06252","845426":"06252","845427":"06252","845428":"06252","845429":"06252","845430":"06252","845431":"06252","845432":"06252","845433":"06252","845434":"06252","845435":"06252","845436":"06252","845437":"06252","845438":"06254","845440":"06252","845449":"06254","845450":"06254","845451":"06254","845452":"06254","845453":"06254","845454":"06254","845455":"06254","845456":"06252","845457":"06252","845458":"06252","845459":"06254","846001":"06272","846002":"06272","846003":"06272","846004":"06272","846005":"06272","846006":"06272","846007":"06272","846008":"06272","846009":"06272","847101":"06272","847102":"06276","847103":"06272","847104":"06272","847105":"06274","847106":"06272","847107":"06272","847108":"06276","847109":"06276","847115":"06272","847121":"06272","847122":"06276","847123":"0621","847201":"06272","847202":"06272","847203":"06272","847204":"06272","847211":"06276","847212":"06276","847213":"06276","847214":"06276","847215":"06276","847222":"06276","847223":"06276","847224":"06276","847225":"06276","847226":"06276","847227":"06276","847228":"06276","847229":"06276","847230":"06276","847231":"06276","847232":"06276","847233":"06272","847234":"06276","847235":"06276","847236":"06276","847238":"06276","847239":"06276","847240":"06276","847301":"06274","847302":"06226","847303":"06272","847304":"06276","847305":"06276","847306":"06276","847307":"06226","847308":"06276","847337":"06276","847401":"06276","847402":"06276","847403":"06276","847404":"06276","847405":"06272","847407":"06276","847408":"06276","847409":"06276","847410":"06276","847411":"06276","847421":"06276","847422":"06272","847423":"06272","847424":"06276","847427":"06272","847428":"06272","847429":"06272","847451":"06473","847452":"06473","848101":"06274","848102":"06274","848113":"06274","848114":"06274","848115":"06274","848117":"06274","848121":"06274","848122":"06274","848125":"06274","848127":"06274","848129":"06274","848130":"06274","848131":"06274","848132":"06274","848133":"06274","848134":"06274","848160":"06274","848201":"06244","848202":"06243","848203":"06244","848204":"06243","848205":"06274","848206":"06274","848207":"06274","848208":"06274","848209":"06274","848210":"06274","848211":"06274","848213":"06272","848216":"06274","848236":"06274","848301":"06274","848302":"06274","848501":"06274","848502":"06274","848503":"06274","848504":"06274","848505":"06274","848506":"06274","851101":"06243","851111":"06243","851112":"06243","851113":"06243","851114":"06243","851115":"06243","851116":"06243","851117":"06243","851118":"06243","851120":"06243","851126":"06243","851127":"06243","851128":"06243","851129":"06243","851130":"06243","851131":"06243","851132":"06243","851133":"06243","851134":"06243","851135":"06243","851201":"06244","851202":"06244","851203":"06244","851204":"06244","851205":"06244","851206":"06244","851210":"06243","851211":"06243","851212":"06244","851213":"06244","851214":"06244","851215":"06244","851216":"06244","851217":"06243","851218":"06243","852101":"06454","852105":"06473","852106":"06478","852107":"06478","852108":"06473","852109":"06473","852110":"06473","852111":"06473","852112":"06476","852113":"06476","852114":"06476","852115":"06476","852116":"06454","852121":"06476","852122":"06454","852123":"06478","852124":"06478","852125":"06473","852126":"06478","852127":"06478","852128":"06476","852129":"06478","852130":"06473","852131":"06473","852132":"06473","852133":"06473","852137":"06473","852138":"06473","852139":"06473","852161":"06244","852201":"06478","852202":"06478","852212":"06478","852213":"06476","852214":"06473","852215":"06473","852216":"06478","852217":"06478","852218":"06473","852219":"06476","852220":"06476","852221":"06478","853201":"0641","853202":"0641","853203":"0641","853204":"06454","853205":"0641","854101":"06452","854102":"06454","854103":"06452","854104":"06452","854105":"06452","854106":"06452","854107":"06452","854108":"06452","854109":"06452","854112":"06452","854113":"06452","854114":"06452","854115":"06452","854116":"06452","854117":"06452","854201":"06454","854202":"06454","854203":"06454","854204":"06454","854205":"06454","854301":"06454","854302":"06454","854303":"06454","854304":"06454","854305":"06454","854306":"06454","854311":"06453","854312":"06453","854315":"06454","854316":"06453","854317":"06452","854318":"06453","854325":"06454","854326":"06454","854327":"06454","854328":"06453","854329":"06453","854330":"06454","854331":"06453","854332":"06453","854333":"07456","854334":"06454","854335":"06453","854336":"06453","854337":"06454","854338":"06473","854339":"06473","854340":"06473","855101":"07456","855102":"06452","855105":"06452","855106":"07456","855107":"07456","855108":"07456","855113":"06452","855114":"06452","855115":"07456","855116":"07456","855117":"07456","900056":"05564","900099":"033","999999":"08462"} \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js new file mode 100644 index 0000000..c55304d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js @@ -0,0 +1,87 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkConfirm = async (data, msgIdSet) => { + const cnfrmObj = {}; + let confirm = data; + confirm = confirm.message.order; + let orderState = confirm.state; + let payments = confirm?.payments; + + let items = confirm.items; + const selectedItems = dao.getValue("onSlctdItemsArray"); + + try { + console.log("Comparing items object with /on_select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + console.log(itemDiff); + itemDiff.forEach((item, i) => { + if(item?.attributes?.length>0){ + let itemkey = `item-${i}-DiffErr`; + cnfrmObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; + } + }); + } catch (error) { + console.log(error); + } + + try { + console.log(`Checking payment object in /confirm api`); + payments.forEach((payment) => { + + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let payment_collected = payment?.collected_by; + let params = payment?.params; + + let tags = payment.tags; + tags.forEach((tag) => { + if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "Buyer_Finder_Fee_Type") { + feeType = val?.value; + } + if (val?.descriptor?.code === "Buyer_Finder_Fee_Amount") { + feeAmount = val?.value; + } + }); + } + if (feeType != dao.getValue("buyerFinderFeeType")) { + cnfrmObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + cnfrmObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); + if (paymentStatus === "PAID" && !params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + cnfrmObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + cnfrmObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; + } + + }); + } catch (error) { + console.log( + `!!Error while checking payment object in /confirm api`, + error + ); + } + + return cnfrmObj; +}; +module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js new file mode 100644 index 0000000..c1130b0 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnInit.js @@ -0,0 +1,68 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnInit = async (data, msgIdSet) => { + const onInitObj = {}; + let onInit = data; + onInit = onInit.message.order; + let quote = onInit?.quote; + let payments = onInit?.payments; + let feeType, feeAmount, settlementDetailsPresent, buyerFinderFeePresent; + + try { + console.log(`Checking payment object in /on_init api`); + payments.forEach((payment) => { + let tags = payment.tags; + let payment_collected = payment?.collected_by; + tags.forEach((tag) => { + if (tag?.descriptor?.code === "Settlement_Details") { + settlementDetailsPresent = true; + if (tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "Counterparty") { + let counterparty = val?.value; + if (payment_collected === "BAP" && counterparty === "BAP") { + onInit.cntrprty = `Counterparty will be BPP when BAP is collecting the payment`; + } + } + }); + } + } + if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { + buyerFinderFeePresent = true; + tag.list.forEach((val) => { + if (val?.descriptor?.code === "Buyer_Finder_Fee_Type") { + feeType = val?.value; + } + if (val?.descriptor?.code === "Buyer_Finder_Fee_Amount") { + feeAmount = val?.value; + } + }); + } + if (feeType != dao.getValue("buyerFinderFeeType")) { + onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + onInitObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); + + if (payment_collected === "BAP" && !settlementDetailsPresent) { + onInitObj.sttlmntDtls = `Settlement details should be sent by BPP in payments/tags when BAP is collecting the payment`; + } + if (!buyerFinderFeePresent) { + onInitObj.sttlmntDtls = `Buyer Finder Fee should be sent by BPP in payments/tags`; + } + }); + } catch (error) { + console.log(`!!Error while checking payment object in /on_init api`, error); + } + + return onInitObj; +}; +module.exports = checkOnInit; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js new file mode 100644 index 0000000..35eef0c --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js @@ -0,0 +1,174 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); + +const checkOnSearch = async (data, msgIdSet) => { + const onSrchObj = {}; + let onSearch = data; + let domain = onSearch.context.domain; + onSearch = onSearch.message.catalog; + + //saving fulfillments + try { + console.log("checking attr"); + console.log(constants.ATTR_DOMAINS.includes(domain)); + } catch (error) { + console.log(error); + } + const fulfillments = onSearch?.fulfillments; + + dao.setValue("fulfillmentsArr", fulfillments); + + try { + console.log(`Saving provider items array in /on_search api`); + if (onSearch["providers"]) { + let providers = onSearch["providers"]; + dao.setValue("providersArr", providers); + providers.forEach((provider, i) => { + let itemsArr = provider.items; + const providerId = provider.id; + + dao.setValue(`${providerId}itemsArr`, itemsArr); + }); + } + } catch (error) { + console.log( + `!!Error while checking providers array in /on_search api`, + error + ); + } + + if (onSearch.hasOwnProperty("providers")) { + const providers = onSearch["providers"]; + for (let i = 0; i < providers.length; i++) { + const provider = providers[i]; + if (provider.hasOwnProperty("locations")) { + const locations = provider.locations; + for (let j = 0; j < locations.length; j++) { + const { id, gps, area_code } = locations[j]; + try { + const [lat, long] = gps.split(","); + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) { + onSrchObj[ + "bpp/provider:location:" + id + ":RGC" + ] = `Reverse Geocoding for location ID ${id} failed for provider with id '${provider?.id}'. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } + } catch (error) { + console.log("bpp/providers error: ", error); + } + } + } + + try { + console.log("Checking provider serviceability"); + + let providerTags = provider?.tags; + if (providerTags) { + providerTags.forEach((tag) => { + if (tag?.descriptor?.code === "serviceability" && tag?.list) { + mandatoryTags = constants.SERVICEABILITY; + let missingTags = utils.findMissingTags( + tag?.list, + "serviceability", + mandatoryTags + ); + if (missingTags.length > 0) { + onSrchObj.mssngTagErr = `'${missingTags}' code/s required in providers/tags for serviceability`; + } + } + }); + } else { + onSrchObj.servcbltyErr = + "serviceability tag is required for a provider in providers/tags"; + } + } catch (error) { + console.log(error); + } + + try { + console.log("Checking item tags"); + let items = provider?.items; + items.forEach((item) => { + let itemTags = item?.tags; + if (itemTags) { + itemTags.forEach((tag) => { + if (tag?.descriptor?.code === "reschedule_terms" && tag?.list) { + mandatoryTags = constants.RESCHEDULE_TERMS; + let missingTags = utils.findMissingTags( + tag?.list, + "reschedule_terms", + mandatoryTags + ); + if (missingTags.length > 0) { + onSrchObj.mssngRescdlTagErr = `'${missingTags}' code/s required in providers/tags for ${tag?.descriptor?.code}`; + } + } + }); + } else { + onSrchObj.reschdlTrmErr = `reschedule_terms tag is required for an item in items/tags`; + } + }); + } catch (error) { + console.log(error); + } + //checking mandatory attributes for fashion and electronics + + // provider.items.forEach((item) => { + // let itemTags = item?.tags; + // let mandatoryAttr = []; + // let attrPresent = false; + // let missingAttr = []; + + // itemTags.forEach((tag) => { + // let { descriptor, list } = tag; + // if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { + + // if (domain === "ONDC:RET12") { + // mandatoryAttr = constants.FASHION_ATTRIBUTES; + // } + // if (domain === "ONDC:RET14") { + // mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; + // } + // if (domain === "ONDC:RET12") { + // mandatoryAttr = constants.FASHION_ATTRIBUTES; + // } + // if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { + // mandatoryAttr = constants.MANDATORY_ATTRIBUTES; + // } + // attrPresent = true; + // missingAttr = utils.findMissingTags( + // list, + // descriptor.code, + // mandatoryAttr + // ); + + // if (missingAttr.length > 0) { + // onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + // } + // } + // if (descriptor?.code === "g2") { + // mandatoryAttr = constants.G2TAGS; + // missingAttr = utils.findMissingTags( + // list, + // descriptor.code, + // mandatoryAttr + // ); + + // if (missingAttr.length > 0) { + // onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; + // } + // } + // }); + // if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { + // onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; + // } + // }); + } + } + + return onSrchObj; +}; +module.exports = checkOnSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js new file mode 100644 index 0000000..9b76377 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSelect.js @@ -0,0 +1,82 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnSelect = async (data, msgIdSet) => { + const onSelectObj = {}; + let onSelect = data; + onSelect = onSelect.message.order; + let quote = onSelect?.quote; + const items = onSelect.items; + let fulfillments = onSelect?.fulfillments; + let ffState, ffId; + dao.setValue("onSlctdItemsArray", items); + const selectedItems = dao.getValue("slctdItemsArray"); + try { + console.log("Checking fulfillment object in /on_select"); + if (fulfillments) { + fulfillments.forEach((fulfillment) => { + ffId = fulfillment?.id; + ffState = fulfillment?.state?.descriptor?.code; + }); + } + + if (ffState === "Non-serviceable" && !data.error) { + onSelectObj.nonSrvcableErr = `Error object with appropriate error code should be sent in case fulfillment is 'Non-serviceable`; + } + } catch (error) { + console.log(error); + } + + try { + console.log("Comparing items object with /select"); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); + + itemDiff.forEach((item, i) => { + let index = item.attributes.indexOf("fulfillment_ids"); + if (index !== -1) { + item.attributes.splice(index, 1); + } + if (item.attributes?.length > 0) { + let itemkey = `item-${i}-DiffErr`; + onSelectObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /select for item with id ${item.index}`; + } + }); + } catch (error) { + console.log(error); + } + + try { + console.log( + "Comparing fulfillment_ids in /items and /fulfillments in /on_select" + ); + items.forEach((item) => { + let fulfillment_ids = item.fulfillment_ids; + let fulfillmentSet = new Set(); + + for (let fulfillment of fulfillments) { + fulfillmentSet.add(fulfillment.id); + } + + let missingIds = []; + + for (let id of fulfillment_ids) { + if (!fulfillmentSet.has(id)) { + missingIds.push(id); + } + } + + if (missingIds.length > 0) { + onSelectObj.missingFlmntIds = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; + } + }); + } catch (error) { + console.log(error); + } + + return onSelectObj; +}; +module.exports = checkOnSelect; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js new file mode 100644 index 0000000..d8417ce --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js @@ -0,0 +1,177 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkOnStatus = (data, msgIdSet) => { + let onStatusObj = {}; + let on_status = data; + let contextTime = on_status.context.timestamp; + let messageId = on_status.context.message_id; + + on_status = on_status.message.order; + let ffState; + let orderState = on_status.state; + let items = on_status.items; + let fulfillments = on_status.fulfillments; + let pickupTime, deliveryTime; + let payments = on_status?.payments; + let invoice = on_status?.documents; + + try { + console.log(`Checking payment object in /on_status`); + payments.forEach((payment) => { + let paymentStatus = payment?.status; + let paymentType = payment?.type; + let params = payment?.params; + + if (paymentStatus === "PAID" && !params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params is required when the payment status is 'PAID'`; + } + if (paymentStatus === "NOT-PAID" && params?.transaction_id) { + onStatusObj.pymntErr = `Transaction ID in payments/params cannot be provided when the payment status is 'NOT-PAID'`; + } + if ( + paymentType === "ON-FULFILLMENT" && + orderState != "Completed" && + paymentStatus === "PAID" + ) { + onStatusObj.pymntstsErr = `Payment status will be 'PAID' once the order is 'Completed' for payment type 'ON-FULFILLMENT'`; + } + }); + } catch (error) { + console.log(error); + } + + try { + fulfillments.forEach((fulfillment) => { + ffState = fulfillment?.state?.descriptor?.code; + console.log( + `Comparing pickup and delivery timestamps for on_status_${ffState}` + ); + //Pending,Packed,Agent-assigned + if (fulfillment.type === "Home-Service") { + if ( + ffState === "Pending" + ) { + + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + if (stop?.time?.timestamp) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + if(invoice) onStatusObj.invoiceErr=`Invoice to be shared on completion of the service` + } + //In transit + + if (ffState === "In-Transit") { + + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + dao.setValue("pickupTime", pickupTime); + if (!pickupTime) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; + } + + if (_.gt(pickupTime, contextTime)) { + onStatusObj.tmstmpErr = `fulfillments/start/time/timestamp cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + if(invoice) onStatusObj.invoiceErr=`Invoice to be shared on completion of the service` + } + + //At-Location + if (ffState === "At-Location") { + + if (orderState !== "In-progress") { + onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + + if (!pickupTime) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; + } else if ( + dao.getValue("pickupTime") && + pickupTime !== dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot change for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + if (stop?.time?.timestamp) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp cannot be provided for fulfillment state - ${ffState}`; + } + } + }); + if(invoice) onStatusObj.invoiceErr=`Invoice to be shared on completion of the service` + } + + //Completed + if (ffState === "Completed") { + + if (orderState !== "Completed") { + onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; + } + fulfillment.stops.forEach((stop) => { + if (stop.type === "start") { + pickupTime = stop?.time?.timestamp; + if (!pickupTime) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp is required for fulfillment state - ${ffState}`; + } else if ( + dao.getValue("pickupTime") && + pickupTime !== dao.getValue("pickupTime") + ) { + onStatusObj.pickupTimeErr = `fulfillments/start/time/timestamp cannot change for fulfillment state - ${ffState}`; + } + } + + if (stop.type === "end") { + deliveryTime = stop?.time?.timestamp; + dao.setValue("deliveryTime", deliveryTime); + + if (!deliveryTime) { + onStatusObj.deliveryTimeErr = `fulfillments/end/time/timestamp is required for fulfillment state - ${ffState}`; + } + if (_.gt(deliveryTime, contextTime)) { + onStatusObj.tmstmpErr = `fulfillments/end/time/timestamp cannot be future dated w.r.t context/timestamp for fulfillment state - ${ffState}`; + } + if (_.gte(pickupTime, deliveryTime)) { + onStatusObj.tmstmpErr = `fulfillments/start/time/timestamp cannot be greater than or equal to delivery timestamp (fulfillments/end/time/timestamp) for fulfillment state - ${ffState}`; + } + } + }); + if(!invoice) onStatusObj.invoiceErr=`Invoice to be shared on completion of the service` + } + } + + }); + } catch (error) { + console.log(`Error checking fulfillments/start in /on_status`); + } + console.log(onStatusObj); + return onStatusObj; +}; + +module.exports = checkOnStatus; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js new file mode 100644 index 0000000..ebe216e --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSearch.js @@ -0,0 +1,78 @@ +const _ = require("lodash"); +const fs = require("fs"); +const path = require("path"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); +const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); + +const checkSearch = async (data, msgIdSet) => { + let srchObj = {}; + let search = data; + let contextTime = search.context.timestamp; + search = search.message.intent; + + try { + console.log("Checking buyer app finder fee in /search"); + + search.tags.forEach((tag) => { + if (tag?.descriptor?.code === "BAP_Terms" && tag?.list) { + tag.list.forEach((val) => { + if (val?.descriptor?.code === "finder_fee_type") { + dao.setValue("buyerFinderFeeType", val?.value); + } + if (val?.descriptor?.code === "finder_fee_amount") { + dao.setValue("buyerFinderFeeAmount", val?.value); + } + }); + } + }); + } catch (error) { + console.log(error); + } + + const stops = data?.message?.intent?.fulfillment?.stops; + let endLocation; + stops.forEach((stop) => { + if (stop.type === "end") { + endLocation = stop?.location; + } + }); + + if (endLocation) { + console.log( + "Checking Reverse Geocoding for `end` location in `fullfilment`" + ); + try { + const [lat, long] = endLocation?.gps.split(","); + const area_code = endLocation?.area_code; + const match = await reverseGeoCodingCheck(lat, long, area_code); + if (!match) + srchObj[ + "RGC-end-Err" + ] = `Reverse Geocoding for \`end\` failed. Area Code ${area_code} not matching with ${lat},${long} Lat-Long pair.`; + } catch (error) { + console.log("Error in end location", error); + } + + // check for context cityCode and fulfillment end location + try { + const pinToStd = JSON.parse( + fs.readFileSync(path.join(__dirname, "pinToStd.json"), "utf8") + ); + const stdCode = data.context?.location?.city?.code.split(":")[1]; + const area_code = endLocation?.area_code; + if (pinToStd[area_code] && pinToStd[area_code] != stdCode) { + srchObj[ + "CityCode-Err" + ] = `CityCode ${stdCode} should match the city for the fulfillment end location ${area_code}, ${pinToStd[area_code]}`; + } + } catch (err) { + console.error("Error in city code check: ", err.message); + } + } + dao.setValue("searchObj", search); + return srchObj; +}; + +module.exports = checkSearch; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js new file mode 100644 index 0000000..eb4c7f2 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvSelect.js @@ -0,0 +1,134 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkSelect = async (data, msgIdSet) => { + const selectObj = {}; + let select = data; + select = select.message.order; + let fulfillments = select?.fulfillments; + let providersArr = dao.getValue("providersArr"); + let fulfillmentsArr = dao.getValue("fulfillmentsArr"); + let itemsArr = select.items; + dao.setValue("slctdItemsArray",itemsArr) + + // provider check + try { + console.log(`Comparing provider object in /select and /on_search`); + if (select.provider) { + onSearchitemsArr = dao.getValue(`${select.provider.id}itemsArr`); + let providerObj = providersArr?.filter( + (prov) => prov.id === select.provider.id + ); + if (!providerObj || providerObj?.length < 1) { + selectObj.prvdrErr = `Provider with id '${select.provider.id}' does not exist in the catalog provided in /on_search`; + } else { + if ( + (!select?.provider?.locations || + select?.provider?.locations?.length < 1) && + providerObj[0]?.locations?.length > 1 + ) { + selectObj.provLocErr = `Provider location is mandatory if provided in the catalog in /on_search`; + } else if (select?.provider?.locations) { + let providerLocArr = select.provider.locations; + let providerLocExists = false; + providerLocArr.forEach((location, i) => { + providerObj[0]?.locations?.forEach((element) => { + console.log(location.id, element.id); + + if (location.id === element.id) providerLocExists = true; + }); + + if (!providerLocExists) { + let itemkey = `providerLocErr${i}`; + selectObj[ + itemkey + ] = `Provider location with id '${location.id}' does not exist in the catalog provided in /on_search`; + } + providerLocExists = false; + }); + } + } + } + } catch (error) { + console.log( + `!!Error while checking provider object in /${constants.LOG_select}`, + error + ); + } + + //item check + try { + console.log(`Comparing item object in /select and /on_search`); + + itemsArr?.forEach((item, i) => { + let itemExists = false; + onSearchitemsArr?.forEach((element) => { + if (item.id === element.id) itemExists = true; + }); + if (!itemExists) { + let itemkey = `itemErr${i}`; + selectObj[ + itemkey + ] = `Item Id '${item.id}' does not exist in /on_search`; + } else { + let itemObj = onSearchitemsArr.filter( + (element) => element.id === item.id + ); + + itemObj = itemObj[0]; + // dao.setValue("selectedItem", itemObj.id); + console.log(itemObj.id); + if ( + !_.every(item.fulfillment_ids, (element) => + _.includes(itemObj.fulfillment_ids, element) + ) + ) { + let itemkey = `flflmntIdErr${i}`; + selectObj[ + itemkey + ] = `Fulfillment ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + if ( + !_.every(item.location_ids, (element) => + _.includes(itemObj.location_ids, element) + ) + ) { + let itemkey = `lctnIdErr${i}`; + selectObj[ + itemkey + ] = `Location ids for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + + if ( + item.parent_item_id!==itemObj.parent_item_id + ) { + let itemkey = `parentItmIdErr${i}`; + selectObj[ + itemkey + ] = `Parent item id ${item.parent_item_id} for item with id '${item.id}' does not match with the catalog provided in /on_search`; + } + + //checking fulfillments + fulfillments.forEach((fulfillment, i) => { + let bppfulfillment = fulfillmentsArr?.find( + (element) => element.type === fulfillment.type + ); + if (!bppfulfillment) { + let itemkey = `flfillmentIDerr${i}`; + selectObj[ + itemkey + ] = `Fulfillment of type '${fulfillment.type}' does not match with the catalog provided in /on_search`; + } + }); + } + }); + } catch (error) { + console.log(error); + } + + return selectObj; +}; +module.exports = checkSelect; + \ No newline at end of file From ed325f2c5d16d0889f0acc426f0a3cfe9477cd27 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 1 Apr 2024 13:53:05 +0530 Subject: [PATCH 189/228] updated --- .../log-verification-utility/utils/logistics/logOnUpdate.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js index f6ab610..b367960 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnUpdate.js @@ -30,6 +30,11 @@ const checkOnUpdate = (data, msgIdSet) => { ); fulfillments.forEach((fulfillment) => { const ffState = fulfillment?.state?.descriptor?.code + let avgPickupTime= fulfillment?.start?.time?.duration; + console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); + if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ + onCnfrmObj.avgPckupErr=`Average Pickup Time ${avgPickupTime} (fulfillments/start/time/duration) mismatches from the one provided in /on_search (${dao.getValue(`${fulfillment?.id}-avgPickupTime`)})` + } if (fulfillment["@ondc/org/awb_no"]) { awbNo = true; } From 6ad68a5bc823a689f29e0b0e6c3484bfb5ce9472 Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Mon, 1 Apr 2024 16:43:02 +0530 Subject: [PATCH 190/228] feat: java auth header --- .../java/ondc/onboarding/utility/Routes.java | 20 +++++++++++++++-- .../java/ondc/onboarding/utility/Utils.java | 22 +++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java index 9d8c9d5..67d94e8 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java @@ -8,9 +8,12 @@ import java.net.http.HttpResponse; import java.security.*; import java.security.spec.InvalidKeySpecException; -import java.util.Arrays; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Base64; +import java.util.Date; import java.util.Map; +import java.util.TimeZone; import com.fasterxml.jackson.databind.JsonNode; import org.json.JSONException; @@ -42,13 +45,26 @@ public class Routes extends Utils{ @Autowired private String gatewayUrl; - private Logger logger = LoggerFactory.getLogger(Routes.class);; + private final Logger logger = LoggerFactory.getLogger(Routes.class);; @GetMapping("/get-keys") public ResponseEntity> getKeys (){ return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(keys); } + @PostMapping("/create-header") + public + String createHeader(@RequestBody JsonNode req) throws Exception { + long created = System.currentTimeMillis() / 1000L; + long expires = created + 300000; + String hashedReq = hashMassage(req.get("value").toString(),created,expires); + String signature = sign(Base64.getDecoder().decode(req.get("private_key").asText()),hashedReq.getBytes()); + String subscriberId = "altiux.com"; + String uniqueKeyId = "c9aa1b41-04e9-43e2-bd89-9ddcdecbf4cf"; + + return "Signature keyId=\"" + subscriberId + "|" + uniqueKeyId + "|" + "ed25519\"" + ",algorithm=\"ed25519\"," + "created=\"" + created + "\",expires=\"" + expires + "\",headers=\"(created) (expires)" + " digest\",signature=\"" + signature + "\""; + } + @PostMapping("/subscribe") public ResponseEntity subscribe(@RequestBody JsonNode subscribeBody) throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException, IOException, InterruptedException { diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java index 063a9e7..ac3083d 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java @@ -5,6 +5,7 @@ import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; @@ -33,17 +34,34 @@ public static CryptoKeyPair generateEncDecKey() throws InvalidKeyException, NoSu return new CryptoKeyPair(kp.getPublic().getEncoded(),kp.getPrivate().getEncoded()); } - public static String fromBase64(byte[] src){ + public static String toBase64(byte[] src){ return Base64.getEncoder().encodeToString(src); } + public static String hashMassage(String req, long created,long expires) throws Exception { + byte[] digest = generateBlakeHash(req); + return """ + (created): %s + (expires): %s + digest: BLAKE-512=%s""".formatted(created,expires, toBase64(digest)); + } + public static byte[] generateBlakeHash(String req) throws Exception { + if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { + Security.addProvider(new BouncyCastleProvider()); + } + MessageDigest digest = MessageDigest.getInstance("BLAKE2B-512", BouncyCastleProvider.PROVIDER_NAME); + digest.reset(); + digest.update(req.getBytes(StandardCharsets.UTF_8)); + return digest.digest(); + } + public static String sign(byte[] privateKey,byte[] message) { // initialise signature variable byte[] signature = new byte[Ed25519.SIGNATURE_SIZE]; // sign the received message with given private key Ed25519.sign(privateKey, 0, message, 0, message.length, signature, 0); - return fromBase64(signature); + return toBase64(signature); } public static byte[] encryptDecrypt(int mode, byte[] challenge_string,byte[] privateKey, byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException { From 58dc0ccf671201c096f0f08addf360f4951e405f Mon Sep 17 00:00:00 2001 From: Pratik Mazumdar <45979935+pratik-mazumdar@users.noreply.github.com> Date: Mon, 1 Apr 2024 16:46:32 +0530 Subject: [PATCH 191/228] Update Readme.md for auth header --- utilities/on_subscibe-service/java/Readme.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/java/Readme.md b/utilities/on_subscibe-service/java/Readme.md index b79b032..d0b337d 100644 --- a/utilities/on_subscibe-service/java/Readme.md +++ b/utilities/on_subscibe-service/java/Readme.md @@ -66,4 +66,13 @@ } ] } -}'``` + }' + ``` + +### Create Auth Header +To generate the auth header kindly use the following curl request: +``` +curl --location 'localhost:8080/create-header' \ +--header 'Content-Type: application/json' \ +--data '{"value":{"abc":"test"},"private_key":"your_signing_private_key"}' +``` From fc97c0c970805a53946b515f27a7e4bef048a8fc Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 2 Apr 2024 10:28:29 +0530 Subject: [PATCH 192/228] updated srv schema --- .../schema/SRV_json_schema/v2/on_search.js | 2 +- .../log-verification-utility/utils/services/srvConfirm.js | 4 ++-- .../utils/services/srvOnStatus.js | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js index cdc8dc8..3d6fb98 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -743,7 +743,6 @@ module.exports = { "parent_item_id", "descriptor", "price", - "quantity", "category_ids", "tags", ], @@ -880,6 +879,7 @@ module.exports = { "category_ids", "item_ids", "time", + "tags" ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js index c55304d..d6e7523 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvConfirm.js @@ -7,7 +7,7 @@ const checkConfirm = async (data, msgIdSet) => { const cnfrmObj = {}; let confirm = data; confirm = confirm.message.order; - let orderState = confirm.state; + let orderState = confirm.status; let payments = confirm?.payments; let items = confirm.items; @@ -37,7 +37,7 @@ const checkConfirm = async (data, msgIdSet) => { let paymentType = payment?.type; let payment_collected = payment?.collected_by; let params = payment?.params; - + let feeType,feeAmount; let tags = payment.tags; tags.forEach((tag) => { if (tag?.descriptor?.code === "Buyer_Finder_Fee" && tag?.list) { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js index d8417ce..b8f00f4 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnStatus.js @@ -11,7 +11,7 @@ const checkOnStatus = (data, msgIdSet) => { on_status = on_status.message.order; let ffState; - let orderState = on_status.state; + let orderState = on_status.status; let items = on_status.items; let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime; @@ -75,7 +75,7 @@ const checkOnStatus = (data, msgIdSet) => { if (ffState === "In-Transit") { if (orderState !== "In-progress") { - onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + onStatusObj.ordrStatErr = `Order status should be 'In-progress' for fulfillment state - ${ffState}`; } fulfillment.stops.forEach((stop) => { if (stop.type === "start") { @@ -103,7 +103,7 @@ const checkOnStatus = (data, msgIdSet) => { if (ffState === "At-Location") { if (orderState !== "In-progress") { - onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; + onStatusObj.ordrStatErr = `Order status should be 'In-progress' for fulfillment state - ${ffState}`; } fulfillment.stops.forEach((stop) => { if (stop.type === "start") { @@ -132,7 +132,7 @@ const checkOnStatus = (data, msgIdSet) => { if (ffState === "Completed") { if (orderState !== "Completed") { - onStatusObj.ordrStatErr = `Order state should be 'Completed' for fulfillment state - ${ffState}`; + onStatusObj.ordrStatErr = `Order status should be 'Completed' for fulfillment state - ${ffState}`; } fulfillment.stops.forEach((stop) => { if (stop.type === "start") { From e0cf6120b293e0e6f9fab6cef7862c4a48de12a3 Mon Sep 17 00:00:00 2001 From: LUCIF680 Date: Mon, 8 Apr 2024 15:18:58 +0530 Subject: [PATCH 193/228] feat: java verify header --- .../java/ondc/onboarding/utility/Routes.java | 26 +++++++++++++++++-- .../java/ondc/onboarding/utility/Utils.java | 9 +++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java index 67d94e8..7991449 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java @@ -57,14 +57,36 @@ public ResponseEntity> getKeys (){ String createHeader(@RequestBody JsonNode req) throws Exception { long created = System.currentTimeMillis() / 1000L; long expires = created + 300000; + logger.info(toBase64(generateBlakeHash(req.get("value").toString()))); + logger.info(req.get("value").toString()); String hashedReq = hashMassage(req.get("value").toString(),created,expires); String signature = sign(Base64.getDecoder().decode(req.get("private_key").asText()),hashedReq.getBytes()); - String subscriberId = "altiux.com"; - String uniqueKeyId = "c9aa1b41-04e9-43e2-bd89-9ddcdecbf4cf"; + String subscriberId = req.get("subscriber_id").asText(); + String uniqueKeyId = req.get("unique_key_id").asText(); return "Signature keyId=\"" + subscriberId + "|" + uniqueKeyId + "|" + "ed25519\"" + ",algorithm=\"ed25519\"," + "created=\"" + created + "\",expires=\"" + expires + "\",headers=\"(created) (expires)" + " digest\",signature=\"" + signature + "\""; } + @PostMapping("/verify-header") + public boolean isValidHeader(@RequestBody JsonNode req) throws Exception { + long currentTimestamp = System.currentTimeMillis() / 1000L; + String authHeader = req.get("header").asText(); + String signature = authHeader.split(",")[5].split("=")[1].replaceAll("\"",""); + long expires = Long.parseLong(authHeader.split(",")[3].split("=")[1].replaceAll("\"","")); + long created = Long.parseLong(authHeader.split(",")[2].split("=")[1].replaceAll("\"","")); + if ((created > currentTimestamp) || currentTimestamp > expires){ + logger.info("Timestamp should be Created < CurrentTimestamp < Expires"); + return false; + } + String hashedReq = hashMassage(req.get("value").toString(),created,expires); + logger.info(hashedReq); + return verify( + fromBase64(signature), + hashedReq.getBytes(), + fromBase64(req.get("public_key").asText()) + ); + } + @PostMapping("/subscribe") public ResponseEntity subscribe(@RequestBody JsonNode subscribeBody) throws NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException, JSONException, IOException, InterruptedException { diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java index ac3083d..cf82e31 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Utils.java @@ -37,6 +37,10 @@ public static CryptoKeyPair generateEncDecKey() throws InvalidKeyException, NoSu public static String toBase64(byte[] src){ return Base64.getEncoder().encodeToString(src); } + public static byte[] fromBase64 (String str) { + return Base64.getDecoder().decode(str); + } + public static String hashMassage(String req, long created,long expires) throws Exception { byte[] digest = generateBlakeHash(req); @@ -64,6 +68,11 @@ public static String sign(byte[] privateKey,byte[] message) { return toBase64(signature); } + public static boolean verify(byte[] signature,byte[] message, byte[] publicKey) { + //verify the given signature with + return Ed25519.verify(signature, 0, publicKey, 0, message, 0, message.length); + } + public static byte[] encryptDecrypt(int mode, byte[] challenge_string,byte[] privateKey, byte[] publicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException { if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { Security.addProvider(new BouncyCastleProvider()); From f3dd8cb2ad8bb1edc8797ce5c9f449f21fd9c2c5 Mon Sep 17 00:00:00 2001 From: Pratik Mazumdar <45979935+pratik-mazumdar@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:21:43 +0530 Subject: [PATCH 194/228] Update Readme.md --- utilities/on_subscibe-service/java/Readme.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/java/Readme.md b/utilities/on_subscibe-service/java/Readme.md index d0b337d..b9f0561 100644 --- a/utilities/on_subscibe-service/java/Readme.md +++ b/utilities/on_subscibe-service/java/Readme.md @@ -74,5 +74,18 @@ To generate the auth header kindly use the following curl request: ``` curl --location 'localhost:8080/create-header' \ --header 'Content-Type: application/json' \ ---data '{"value":{"abc":"test"},"private_key":"your_signing_private_key"}' +--header 'Cookie: connect.sid=s%3AASiu2zTqhIjkxj8OGpBcEk9MUjWPKWhy.i%2FMc29ueVdeXM96cLCESAVB5ul2yfVrZviJDEKHKVA0' \ +--data-raw '{"value":{"test":"test"}}, +"subscriber_id" : "abc.com", +"unique_key_id" : "ukid", +"private_key":"private_key"}' +``` + +To Verify Auth Header +``` +curl --location 'localhost:8080/verify-header' \ +--header 'Content-Type: application/json' \ +--header 'Cookie: connect.sid=s%3AASiu2zTqhIjkxj8OGpBcEk9MUjWPKWhy.i%2FMc29ueVdeXM96cLCESAVB5ul2yfVrZviJDEKHKVA0' \ +--data-raw '{"value":{"test":"test"}},"public_key":"public_key","header":"Signature keyId=\"abc.com|ukid|ed25519\",algorithm=\"ed25519\",created=\"1712239689\",expires=\"1712539689\",headers=\"(created) (expires) digest\",signature=\"Gy5wiiJYGeNOBsiXJKo4OF7fSKR65zkxa/FJjgBgenmRplhq9vNewz/ivXDFegSnrdQK9U9T19Ta55J7Aa6RBw==\"" +}' ``` From a68eb98b14dc397017d73c38de7e57a10d54f5df Mon Sep 17 00:00:00 2001 From: Tanya Madaan Date: Sat, 13 Apr 2024 17:58:48 +0530 Subject: [PATCH 195/228] QR code generation utility updated --- .../deep-links/qr_code_generator/__init__.py | 2 +- .../__pycache__/__init__.cpython-311.pyc | Bin 323 -> 0 bytes .../__pycache__/core.cpython-311.pyc | Bin 3705 -> 0 bytes .../assets/ondc-network-vertical.png | Bin 0 -> 12999 bytes .../qr_code_generator/constants/mapping.py | 10 +++++ .../deep-links/qr_code_generator/core.py | 40 ++++++++++-------- .../deep-links/qr_code_generator/logo.png | Bin 47774 -> 0 bytes utilities/deep-links/qr_generate.py | 35 +++++++++++---- utilities/deep-links/readme.md | 39 +++++++++-------- utilities/deep-links/requirements.txt | 2 + 10 files changed, 85 insertions(+), 43 deletions(-) delete mode 100644 utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc delete mode 100644 utilities/deep-links/qr_code_generator/__pycache__/core.cpython-311.pyc create mode 100644 utilities/deep-links/qr_code_generator/assets/ondc-network-vertical.png create mode 100644 utilities/deep-links/qr_code_generator/constants/mapping.py delete mode 100644 utilities/deep-links/qr_code_generator/logo.png create mode 100644 utilities/deep-links/requirements.txt diff --git a/utilities/deep-links/qr_code_generator/__init__.py b/utilities/deep-links/qr_code_generator/__init__.py index 751f3de..51c03f7 100644 --- a/utilities/deep-links/qr_code_generator/__init__.py +++ b/utilities/deep-links/qr_code_generator/__init__.py @@ -1 +1 @@ -from .core import generate_deep_link, generate_qr_code \ No newline at end of file +from .core import generate_deep_link, generate_qr_code, bulk_read \ No newline at end of file diff --git a/utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc b/utilities/deep-links/qr_code_generator/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 03e3ab7466373f13646a04ffd6281eb2ee261e98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 323 zcmZ`!Jxc>Y5Z&DisDVJRuokSYh})$S8&k(ZY|<>t?I=t32L1=RTB*?>#83$5dkaO!V$qM+Y++fqr6RkNoE~3+H0eA zkc-%K9zss?dbzkd?Xq41vhZjDY&cP)fk&yCEIwSb5IOp$d{`SA)0rB?2gy$4a}Oo@%68BO$F+@xf1(idI7TsCw@B5gUTk zJ2U4#&f}hQ=G=4cmtL<6LHlRhZ?VK7^bazrH(PD+It+siBqEVYpeX5W2`Xue+NkQ9 zJ!-dbbddNKT3Ij4v*yG<-`N65^U9r%YDGf)Zbd*YvSE2A~_h*Di`Er#0b9u<~wu0!z;t z%Q-4bmFfmIR>>fXo&f)|h72&0D%o2|Y7^0R4}lbVFI?+xXrb#WR@9Itq;3mIK@@~kXk3o3Bymbp zLzkz=$M_XZN=TZ7)sTYcu!2)@d_qd56PVBlB3lSwO5N;A1nN3TxAu1CV)GInWIQ07&WO$&+uB%b9JtlW;N8c@#H z-KcnBH*?>+mMA@d@WZF(0OZjNZ_nSo{NKF1?(H+Yefh}>?fS)~yO-7nbvj_sfifMa zbnM?a`|xbllCLNK68>ZO57U2|hPi%d%mCOiZgh<2!!K#)FMm>Y4Z>UWRC}F1X3)pV z^syJd{blztc#DUsJ*+82jU9LGrwpZ2^YP}>!UC2A#p{C*{Ts;Ha{d+@(YN;rYd)(@ zw0oX04U$s5wVnZydIB0fYiQMaiWZ56R@1BmR~;`pYKv&GAy>4C_AUAe?Eb8wLC&7F zmz;Il=KkI60F+HT?9z(N7Tc;Zg@Cr{q&LwzL~hIZmOXTqE;Z$XCTdr!+#I8kz^S!G zUwxFdy+y}n+5b}_E4p)ztV26emj!u|U2Ln*L{FeTd@EaKz`h)(^*7Myy)wM-lhMM# zwc3z@Y}UGxbAnamyuZ`3j;wRerXAcxERsBEwYPlDW|_UMd!N-A_~)W81JT#Q*<@1- zXVdyF=bSC)$}*+Sx=zh~md(1dY-?0P{4k}iW~%x)OSSq0YF7JI)Q_|e>l6qLAf*%P zMre0M^jmrVttg?;U8H@qO9g!0Id=gIY6e%}-bqR=VepLpBW# z^Vb&eE*r1OJd_$DS4#03plaI;)!65x1dgRZW;44rm**^cLO`Ub!cFLR1@IENpbYWj zcurVJXuPEIeN9=hZ>Xwp1Zyiws-f+)oWj=587?8u%OrokB3a@Uxhz1PXv2yklY*xx zxO&IoX60KkRmxzKos|_4E7#z5WS^5XlbKBj@gzWEz0!=mj6OqW}NNntKBr-8} zEq1}=1W}AZ=@d*lDJ)^rMPSVGsp$Z|n^@5ll6Os7PGcyoa|v0{Oxp5I4g8@z+TQ;mp-QWbKA-IT>nA<{!Ku^w(UVq_XGEu zd;Ox$^%`7nnd_}^t_O}a$NG4|p>qL)3zWIQ_rA6V$+cu@_4%1XQumD+zOjP6(%!kz z^RTD*W4(RAXdfuBuxVS@{Y){a`v(mFK!L9KJ04`$vc*Z=-*5Q)3-mVV-d%8#uJ;RE z8h?CoQ+OQKdrum@C-u&g1@1*#$8W9|Pd)m$H1p`3-gVsQI{sDH=B=kkwvOmsXZ5yW zqiwjr5V?2O?i4SUR?0mmzFOJJ>HZPJKVogrbM(;%CE?M~=BcfZzn3II=mQb0LEZ zmAO!Lz12(LD0ttzbRXJAHpaILUU1&B@6=`h0K7VP+Tc!?xziQS`@-G1OJm) z+1CfJ&h;Byf0^qC+BeX)84wJ;+6@tKcZ!?xpl>~c7hLvlf6#G(v46)fFb-16AwUOR z3dz={{mR8~?Tjp{5NmezwyJyp807!~?F5hufE8H^xwcrhH!J>jxN}KaTuI>b$_yY# zPEhXv*tSy?RYBgo^;A$-x%I6eciws`$d$LA3UcPH=X-Y`&w=}xuJwg&yKSE>@7wmU T)bVZ90G($j@ZNiXrQH7j)68Rj diff --git a/utilities/deep-links/qr_code_generator/assets/ondc-network-vertical.png b/utilities/deep-links/qr_code_generator/assets/ondc-network-vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..cf967083f6e48e8761aa4a53a10de2bbc0d25710 GIT binary patch literal 12999 zcmZvDbyQSe)Hc!$LkmMU4AKJ9-QC^YjUXT}14Dy!r*wCTGIR(?i!?|IIE0|oJNkRS z_pfiQxoe)g*V%E;y7%0>&wh5SmWCo8HYGL^5)z)WlAI0_(lY?!z{W&JNCY9)ONhT` zzB-CBNDb4#Bg6@+qqMp-5>j(A&b>7n;vCCM$=DYOiOBEo@od9^HV6rc&rDfPS}(}r zv;ZStZ}IC>__q*l(Bz9y>D;cj0@9$jZ>v@~myAkB$eu>Bhu#Ufyj#9cWGUsP1jUj@ znWr+?lo%gUXSRUc&OiJtJec~>8hEyrQ_!zlc<$)vnPWPWf7v^8neQ{egFE>D{ee-f zC(^O3H89hSJ28pbTGcQIB!g3S*&}|EfCL6Go{FX4e#C;*Hhn^6xi3Sb8(^RmA1EcF z_?b+C1demMLXD3Lhe^g2!C+tbK^%|Io-o6ZS@L_*2}t)<~K`Artl!-F5Kc;RCC#TJnWh!_jZPoaq(W^A(J^`_O3A{f{K ztTbhJ;j`xFH3gxPgIJ~qvGy52Gy{0?vAbR}B3SW?P6IY`{P|M&upPi^Q}#+U@yIhH zDT+wQ5QPSbXj2f6LQ}R8EY=z+9%C01#KIyB@N0U@GyO>h#$XdY9OWIOMMg{pc!q^h4HHi~MUd+lrnL!nE~Q9qT2sx)LnISqg>>l zf~|q0v~_@wM2K05_AcBYBl-yV2Mabxh>~J?aCgbVtYe!sGV=CyMnm@2z?l9CZ;Jp?)+WQ<6F{ZK}&>@G22&eI%nS`eu<^MGkDG#=mA=C`Uwg3PE>?v6Mtp1B7 z$SR|rFd7Re2C%aKC$R!pXA_PP7e*<{gUz2uV~PLg!bpzdjSZORSAkGwbM}FGpyUmJwGOe=9Hi)3v$F<><8Im*nk&P$aXF0KOWE9Y{T+D zNjm(J-vleQ1r~h5z{vADUsZV{(a5dvUY^~QuW&@4-rCr4t+cKhr4z(G05!bX-3zDv z6moaGJx%<5z7#z_pOg~~48uxMTQHMDV?b4~qj<*6xAp zgm+cH?C+)5BL_p9~Q=T|Teh zO(aLO=T$EJp+`(y)aHjItMK0?=wdA;M0t>)H*c!2vR-fx-cC8~vC6TT@@;%tY?;c$ z+$Ce=vw?>?Rhw&j)O+|<<0*MB%ZS$Q^}BH^ zBwo8v&ejfbse3c~G z+%T7}k;7|EkxQ|*lrkgFw1NsoE$!wD$B-yF#3PcnC*`<54>atv8{Cg0pc|<354gl%~cKK2?<~?TtX_H)05$dG6Gu zbonn2Ffn{fTG}n+8g2e1g%^-6Q2hRb?(Y#^8*sO{Fh313dd1G#m#^7;On3l%37yT~ zj}$aUEhvtK>9H6G_`^RXuqK2yWH}jFQVD5A0Lao*Y$sEZ438RP?oN=FULLC6L*+kASNGC@bo}!_Ic0V-yJoFAaA~+P}~7r9gePUMG+@Y&=nAMT?G>tEi3=r!4-SDJ2u@ zsK?TGXSMP%QoAY9_iMBspxDWX^x(`%-n}7)JeIC(YeZ#Q-y|iVT z4(F@-bNfwv?@L)7h$u^iI}CyquPW>Oar}0@HyQe%xpnsYW;X&SEK%B6_UCNgN7x3` zP7W_WGSi=XVsHWy4X0ciC)y)g|L`75^Hh5VU?gnXAv;I( zHK>W~qj3*T3`btN;6_U{Pi>BnQ|s>s2Xj8D)iDWGyz#ZVBNdZiiSayXC}sx z@e=F*XHIp z2L52s%+9 zMp#N7N#dx+8%XYFOU62SWZf7I#dn0chuQ~>V$92agcxidheJ8Ez~Lp8QPYvLnv+j^ zq>F4scgM|yIs~bt#LD4j>z$gMmHZra{`7%mvc;`mfq~ZF3pu){b+b`wa z;xvH@a{^KO&Xi?!m9OCiMv^*pWts+N;8|*VsxL6ESdF3BmI8|Pa9jg7b9BFjEx2>2 zR?vkLxU;jkzX$7efozlQGJP9?>D!+}ZeMdW;|&%TPIQ;GpK=xZ8)dpt$dv27uxK|o zprJBKYNLQBP=yI-IGs%icl0nF(@t2p5DP7;h~jz72_U+-S^9!7hk^}({+$8fF3*DUK(#u zgpnV9pHXIaqLC38CLA5Ix$bN-d&c;B-hWS;QF9*)s^c`L(V4KA_?* zzl|a~i2mJEw-=AYm8PD-E6tOe#!~-pcTNR2j$&PVHw>S9y}q}(dijLWFNI&CI24AW zySSYE{N3{1$=P{;OS1QwDflS-$Wc-Is||L*M3J&tvYbXbvc|~}?fU`W`BpFWh=-H= z@^aFwP}6vWIjZI&5%rAfUt;Ma54(fj51%N^IOMj->0{00$YbQymJMsP4`x1S4z9skoSUeT|pgv67$hPH~o<_kLIqn|fYQU)PKmJL+Oh z4|@ECxpdapK|&0tI+SPPqF0FH*nXjMQ_xuYpseHmzp*51!h6)vd(2HU>Mji1VW_=&sNq?pP7+Hy^w6a?9Vq#{t z8BH>$5OhJkxcoye`YnCQAI2IS8c0ocUN=1LvfaS8T&~gXEc>LP5)WG@zmknir0FN! z339{~a>)8&?6x|S3C+(Xi_JqH-N}9YBK{Is_L7ULM)c>?O^21SbIcEZxy7C*Mo@|+ zZmf0(wi^(!gnK(yrHC@n32B}uJ2p^2d=;)ibg0IlRt3AA#;oL_dj3D0u4wyLo%hsi zWS0Z`eD=yQE2HJpHniP&0haTxuv;W<)Oo|2{kZY5amK{cFOBjQdbeI}!=FP%PnHjB zBofjSxpzkTB7&UuKX>^}kREPI(wcU7jBX7?@r0R`7)wF-vc2x#sBvtFRdT=J)>@rl z%d)%LTQ#0f$_iX$S6%80?UEmnow`wR@<>fmUK&-8vVl*hGp+Hljg(|o?tN98gbuk9 z6aBnPZMLC>Is?O4K-pT1OmgK0Bx}n{q@1cFDS=+sCq#Qg!#|&KUD#Hj41&5B}K#*M^v!JDJSA%^zEgdt9b%0xVJY zFER5a-!Zp6EsvTuHTS8%q>C?lz=ZA0e|g*uC+xkr!F)OsxdN1?fUM%dJ3_go@S=HQvh-VVu$KUBD`G$E2Jo3Gy zK><_kf?{FFf9$0}FF&gdn8T1u&>c$@l%QjA1*A^t_|5Jt1R8@M_%Z0`J{t|{6W?vu zD8Fu@JJjaqxi&GcBNy}!xeV(;aq2g8ReDM5Is|F-Aa9UiUIjYGlq%9Fh%^Pi5h^w) zKL6qQsogSjcb>5VMwOY(1>VzU0tKPNTf<^jV4Nx0*>6P-rW9OM;@0+eQLb>zXgj*)jspwCi>Amy&MUr%YyW`dG zTT^~XX*y**;l=i+6xOeL*^}g&Qymfo74F=tj}9ARi944b>SOs^%j`x)M#S^UQl)Bh zs)-nM%98S|rOfoegsDLLao;t*50W|ytHgsX&!ZnGy<64vnxoc6+jfs+b>RzWXcW2C z>`JAd@@}+~o|ZDP*RJ7VKN`H+s1x=nkVQ75Qh=VvpCmiPl8=RWmTBUvY zXlx>SWGRRsbfnmvA;<*l`<==W}^1tf`b+==U7#a}=xj+eynWFdsYoNe7E z{F?PjckhR+z6=lYc*<2&H|KV5)xt?Q#H{%=d`@C8el9Ix_dYYs+jMG_jwn=Cy;-s` z)Tgp2nkS%Ypn#SM;Sbl{2MJ)|Y$Y0tjJ>SNrR%goWZh~(WtiVMOzbo_jcI9yi-Z=l z*Xbkwtlh)g+{)u^>o}YTZtI-x^^KU0-^z)=1rAel&Fi_Fl6o#(VYKP^S38`X>E_DG z=rLYA3u&mK9511)BzW#l@mFA{=eXDC&K)}x(M~VZTPy5CrO)$#iIv;s=A?;3cNnm_ImgSg@C89vn$zVuwE2I^#^!=7WtyBxO1Nk%H_QHzwOlan8D(1J0K0aOzh+sBzR*HiXAvPm zXjP=ytHI;IOOB{>rsLqrbN2(x5#vb9IQfm{j1QQUrb8JcCP`ZKt}1?xLeujOYKEm2 zZKsLVQs%-O#IzPdL}fli;IG^Uamn4eMiEoNgT3=^j=w{1`c1|PUU3OM^E_(+z-B>c zHEq?z=VzXTn)k$PQwga9Y9CIN2Bt~2MQ17MIN-1gM%As9rcASuTfRi?&PC1V$%I!7 zGI0Esmu}M1%LW)G$vraW@#Dx|_lFAI-@=lLQnJAEIMG(Wc#h-CzGgavaDZ0N@z!%a z4o}cz(|DN#(U)I{M&}t)kNR^aZC|fn2Q~4iqs!mub=rhL?8_SaW3>rsm^ao<9m%rs z?CXVBW+OyiCtyKycEu_)YbM}KeV7VA+Rj_8cXvT$#?q~{>WH=;2YixUU+PPCuFwX$gcLk95GIUO;J1-_tH=RG zia$!1)lZt>Qt2&p+MI^X;Qx}X`)ZiDlk0%u3QLb2guznN%Bg&1!tDQSWPmHScIzwm zx4M5v@iG;lssJbbg!7CF6xTOK!fFYGtk%D<{HSqDEfNaQ+g-9B?h3!=U2v(D6)497 zgxk1~ZRD?$dwwQc7UCjCgVlIP`@iS%$$skr;`UPVDVMhu$mP_s5U@|r)Z=<^x5rp1 z^QNtoV;MGy9p=)EXbjH>l3mkjs*)Mka^v#EG}+Q88+)_bd?tB~K_LIK|^ z5@AB~G&i7I1ICH0d^L4^o!!x9R(TL5-kyCqEuj|X-gv+ED9r17w?y-#bo8OmfK{g<&8&{sS(|JTCLsEPQDwQ#e2Vjq5F@YW z=g%aT4u!S9)q`xIii2m-Ra@a7mP0$EEe4bup-%HjUKMsGr&m6q;neE;OCAjYcY%;+ z)x5Wtb&q2j0$$W$r?HkYXpFsx&(D0ayza1q4mzAY$q=fhAj1zW3gHDTM5TkgT%$c0 zzp_cJe-EwnHt_VBEyT%VtWmGAw_#xcN|sGEIF$@D6RMq@1|QBnMju;Pj&_7`PIU~H z<6JG*-NYzbS-6uYRb{M`J-c)RyjtB@;*gihm`hFQ1pq~bo|_}^VBtjmS^5b&RllD ztR**BR%gK{bxDDpRO-)cM3GyE;@Ws{9eN2voM*3hm8f1=EWb6s{>30Ppgaa0Qx?Gz zwl#`wv7>T%^J}Q`&TANv^+6i(%T|^+X;ABB#3VK?l3d9>VNt4qwt+bv&pZ3)3t}Ul zduQ`A=o+_-^d$!fnIkO_k6k*MKmSfL7wU8Cw?y^I1Szq~`E*DU5@goir)NUF7pP8i#R4L~I6nC9OUb9b z3E9w$IVq=NDxru{Q-^EjF}^l1j*& zD8D{5f2{xvhz&2ElW)&IR6I-i4!x);hC26oMQptCL~__O{kU|oL8{ms&{9oR zVbkbj7o9;o@z2?UIeHINOZOl=)E8AVtYhY45&x`oCc%eciCy;9=y#_H z7n~C}ST84yqwE$NZ?yROkPDn257pKJmyqVMshn<_If`i<&Qk1{sy?5!SEgJh&XPhpmR_eC#lCgeG3r)(&3{G_!Yg6gxhnufn>Qe<+2=@Me}Cay_HZ%;?zdInSFt zjBr4C)KH4Wls+3*pTFDfVgJ2E-O-0sU~^HdcW)gQ0X&_0X(M}XnUv$IP`TUKdNIo? zE!vZX@!}IiR+v#>q4)=R**mzFbq#Q5R=X}u-^1;KKBvpm-?Zw|H zUM6Ah#OjYI&BU5NujBUfsPGT^k(>zB^4ko;^I!sEe%M&hFTccnKN7whRU9o#CSS+x z$%yx1gm3K0*^Q!x18|f9^zUpKyw9fwf*y}~4~w=pC~8}N9$g5aS<&VQkt7$0E_k$t zFitfjd^%hyw6pO*wkXVV{5_$DG41GQ?m*Av1{}1Zl1-=P`b97}*2dNs8bG_|>w~Sc z&X%nV!|o1M0!ifNLScGBv~=iN=X+V$^0`T>ZNbT&O^70}j8?*4!uIpqJ#u32yXPqO zWdeaV%zHH7-w*G!z(tJwZ{*BG*_U^Q*E;|Q>6MG5bc2>80|+u=#p>-7QYzCh30-hn<9&t3IWsxzEYfViSlEqBZ7XBKw3JW3R=VBX zLN+o|^$cJ7x6@l;qz^+OgE`7w-c|xc;*FYN@w$@A#mmzxQ6@@c`T{#KvhBCQmVzC? z>cK~!lkK}YLbM2rU_pZ}RNa_zTbU=jgdcf!VHp*SeGj_N&n$XOY2s&>%x3RrDzAoZ zTg6O8ZBY{e7aN5pzf~r~r;Z(a0~|~<*zR{IzuVX7e)i`)QDZ1Ib+jOxePGv(&DJ7J z556tTrH*gC*x{|#1fjFM?vx`F3LK~Tz&ZJUCRl-F z1e@1~MT3~li?k6(>zdntr0iLe5Xqudi1G&@t=!Dm8dJiAx}1hj9SI)g{aBa}RjWMk zY49>@1_KGA{EB22-hAR@L3Pq|_dHQ467RgDLZg@*0{$|#3v~WsRO|SQB z?p*(U;}icjbDi|2S97*Jj6xbFetHz0`ov%TP>L` zAXi~S+AE|#zf?kT;xPw#JieqsQA^;%JPF*^fWH;ve4^CCDavST8G^s{;^tV!Xq12B z1{h#G38qcZza?)C3>B36dZpK|MV9J}qdGdyBA^P1ln`Fqk(7^>b-eqZg*Nr})ym7u ztv32zPY^YEZc4bVb!i*>;J>=*J}8VYFK6=e^Rs&Rb1nSlw&|k&go%mCYC2y;IOr!` z*zGokeSPfEkla)@FUt7%h-aZ_@D*GC!!J|6fPiE+11+t$Si~%Bs!MN}=Q`wmR5EjO z6U}~57F?}S5>8)9R2a}_4Te1-t6+;wF_2MSoN$|x#nmka#0}adC;Lk|ldZWt9jC3R(|OWH`AwX)Pf+J3C*5vAHK!RaXyWS%$@C zl1*y=w6U?V3yV!`r;&T5<;BE8gh(QCuD*VJz{AT`OI>cHJ?p#F*xOqPa*u*t3#}DT z|dCju!?vN=%qGVBzkLF}dj1rHxwxHMN;`ZaHv8UpJn~6}&-D&2)*z@CKHOBI4 zGym@y+2SD`Eem+=iVWB5ftw{pn8_dNR^^hW@!q z9c8gr((D9&>h0;F)D-(&{^qvo>U@(naMPchkFPFfxg6uuN#n;PPrn`2NZ;S~S=)%H z43|(@lAuaTJ^Xr~4B{%)dD31K78>Vd+IGK7nbX}Q3;A`Xzu!|$2pM0Jh{30BAtJQd z8%v!q6KZd7zeOw^I^{_u9g2KZ+r;&(@rIbGK)Yin^vht8h{VrX{+wQsMN zqFU>WnvplL=;yI9GkV!|E37W|#wT*OSeWF&d~-hVUC*yA^2Wq(QaDrC>xj7gHZkM} zgd(vA9v|*9-g_J$pJ;0vSA&dOY)A3!8>m_+#|pkMaMg!D;N-n@Z((y2FCn`f4SNbX zI(|KeSz$YWeSf$46mXoYcWCm`ZRKs}Mi|xU>AEL6-LvOBR&U#6O3MnUkQubRP2_;Q zp2(2l#=e~|l|bnVzMLlUFfcnc_q|V~+7AGu0);25grA!DE;bHcXFJ0MVFei(x_T|4>at@y_FU=p0-fztMlk( zqqq7)&NGf^5xe(G=0vEeSSTznY)FW|$Ut6i!ywU;J)FD%K5Ne&xB}w#*Mlx>#=dbi z9ar&qD-m@2ZS!710)90MXA6_o^%0_ZeWi^ke2|!#U9I`*KOUaq(W5THxpz-Uj>rB(VzA|1wOA=dE?FR+y zPmlK<-+0_scgDXpqb)ett`2JOJ{biB2&@y_HJI$!%jZ{GUQCSq$LX1|;o)MOwX(=}q$qjD{EP-y>?aSp% zSyk1TjMUf!eJ!gI>dP*@vYL4^e3Wvto>SZHR$N`bqG?d~n7q?HoVQ8tNw9hw@W_giZ9E~rW9_@0nvE>!G|30(qQCPfS zpcnSpgUSyS=N6=mCTM4>x!pg8v^tGh)lT!#!w)NKGw3^&pTLzAQ0-zPf^HzAVuDs? z4?Wxmqb6d`)SSslJeE>$DC7}BUS}hvN9?~HiDs~*&IWkL@QxmJ4`^=7HUTVpa}f)o zJ8N=XesO=D;~0E@i|vDj9$(o*(;|V{icx#NkZ*Wa@yay?pFTk1gETqJJqYs{`6^{d+9pC#{dWJ@Wg zx|kSt*tfM7mOKGjn(b`5l^Xg6*~OK3?T%g;HP*$s@r4rokzgw)>4?QNgZ5}80cE_==UlIGu+%>B0nh>eP{l}Z?%BdpBhu<@Z zq!Z0rIfd@9Pv%uDlUfD_6(BSTCTw_5 z2-AFiVfmlqQ*D(re-&c)?NVgfOv*)vqrA~HPOF6lbI%;Y4wH|6D2Y;((^$qc-=9gH zD)$@pi#c%-DPlSU=v~X3ng}cNed1b1P)RdqB%jO>?|!~SOXI$-(PZut4qbN?p2#%- zQEI(uCx@%r5w8j(aDl@BXPEIYw!w2-xn3YKxQ23AApfY^Z6Vi)mN1Z%D4EK$>sfVm z^+axA$=kjSA7<}|=W0zEd9X_**Hfr6GzPs-VMs0NQM?y_}+B zrQ6;*p|&g+cQjw)n;#jfBG5! zwR&+Tns#%z4@_kMVBbaTZ&F^TgIPSd&c03fO%v!)yWFl>2Wh{+ceV$U; zI6XZx(-~)*KuVVIQoX7|2B%$md_g=%zbXKN{&ueNXnFIEtv+Kpq#^zfjx)wP2Bp0* ze;+a;tsWsR65>A!W-*MALK~F@C(U{;O3AQ3eOj8xnv}%4N~;)oxd^^7W5+^vewQX0 zIBiG*p-fH8npo%)6;~)2N^#xCe2Aq{mVN|@b>VlSqvh~g9WhU}acR*(IKpSjQ{A&>*|Hqd!?Z5LLfJW5QPKx)-U1 zM=%U{yseZRr+?0-UifFya*s|Drr4D>dCGe5yNSp%LSlbIQA(Fn$Q~YMGKw?>kjr$E?V5#b(+!El#b9f z%_P%5pwu6qd-Z{{c(}^Bhm44#2CIbr`L(mkjb^B8RY24n*d>(hu*P#n8rCUgM6a-X zz~*;OLiNRzaWa#OzYgsft0&92)nRg8fdU> z1#EsFMNP&|m;V?=si*x7^&)0oNB4V7BxJz@=F}w?S(s_}D<&R!Zf?zOgIn=O;Bj>& zhiT5Lx>mgWb%>)xwX<`}c>9MWOO6-cGBI0Y2WxT915Nurp9~O}>iS17l{+Q!Y+uBazlx<@EngEi(UW48a`! zXDp=88A9mxkF+e&E{EBnKrs>+^bMQ-jYsV5P6b6YochN!k6Ox3Ek;12G1`wMo`jp9 z?}ukH|D}nwaIC)ym$!(3g7xJv$%vxiz=r$?I#HGI?vK=+FL?IY=7C-?y-Mo0YT_?fDndpGyJu5Tltpo8U0^K zJaJo#z>NQJ+-)lYGylUXx4j6A*wsOd!A6ZlVD^7_3N;RaziBX~5an1$KKF1N;R#bH z7NHqMfS`z}d{fCu!urL7&|6#c%1itzYOYvZ10*L8@^X-2Fr2A`iH3vz-wYt={Mu5OWB@cWq7iBt z{lAbJ#FD@dZV9Stf>I!+P#75pilu=n+LVpx5eP!`2y7!E24Ler1@r0fVKPLkO+kOV z36zc0WN^rm3%5~y0Ay)fF=#`)!l`TEVWwLvxEH<#h+x2m=(Z`S3!ODL#+nyP%t&l4 zig-q~Df?Ck1T2gqo|{BKau7{n4Do_uQ})#h5Y0vuaR>R|ZU_*tKZ3YB3(*ZB2BPVQ z5P#D|^gR%eB_RfE5Liol4XP*LNnnwNCkcV0Tw06R+CnRu^hp@7Brxc?31W8$5L#{!_D)N5-Y1D@Lk+5C}x3sPI+;1R`n!fe7jD5Carp z!)|X7C;+7RR{Eod(H5G-!(g)Z=<{)qDg`N11Pcq(LcF)5g3KKz0vUxn3m?Z6UKBGb zK0A1PCwcKZSy#jSOjp7lh9nN`Psupk__`CV2iCI4l zdz*PI3vpLkxpv8)N~%$-y2jm14={Qgj47<)nK}!eB7!W}CfelN-p+R{9+@kxeT&tC zd)N4t9@@jB=8Z*f*rkGEdaC|hk2mQP$b2Y&o?`^SQJ(=Qf~!)86ygIzM6L&#H=-d~d$+jHs?nD}a4*N7)ZlRpD7iMg63ykT%CG+ix) zxGSzSs8gB;9KD=QEj<*3yKH3%--zFMNTVx1#e6FcJ{?EGB<2w}$*z0mZYx30rtV&(2s@m4Dbx zgt8TBp10;7*1T2ICpvh8thvfPv^ck-1xBP83#Cm1rjBdmp!AWd52YxquD zw=n;)%YnD?b;_ z%rd*?xiM8iO2mV)*ez~qY9>ZJKwGc)kRKj+gnJ4M1vnHC9S+;J6s_94`av?n&F!?W?yWBUA%R zw^7qHw$~0f3$pP{u4fEA$O; zMutgSE^GaYYwMSUXrw6WK480#a5vjwgnjdmNA^^0N92%{W1aqU|35S)sQ*E&C6hda z1d1+7m@-MepDn07+GGUHzDxz?fDS|~|CAoG!^@JTUk9|Z>S5WButYb)pc?_l-4K$p zz*hmS{dCMeF_(~==p5*Zw22!-RXacPf+qCy+%hlc{zrZ)l6_e-rSdhM@ewGpP#YRM z)xACa5SZ}HbQ5&+2EJY^Ll#yK8fng+8iy3lA-I7dsg4l>?0Yz}wvYC{6+!ml0QQTg zIJG5e3K#>Sl}L(F(|tBVezyZ){S!@deuFoPn$pQthQ}dRWV!^|x!j{?KQ3u*0c2MZ z`Y(~uJ)gan!puH`Hr}kA{0XlKn?oo9V^W19?d!uKt3#kB^`@zWBPb<695H2ahUB`J z1-<~eCWS(*<`G&qtZADdmoGr-2@Eq+2W`OC+nt z#nrOu6Dfi=io0wwtWi^dQ`u4D(tlSWjZ=UA19>%Z!TYzS#Q^35X^~fS#RA$`>tH5k z&;i5R;kFh$<_P)>7(2T|f8S4@Gj~Y{m;zUU<7N?|0D0rLD@e!ydmG*qW+n^TI2^Fs zeG32Y2+9nMc~R3J_^NW|FL?l)h;Coxgz8-2W`SBl$d4SR?&<|gfi_ABA=krxa3G>m z6l^i$w1f4;exQIa!VvaZM8=JLQ`h(It#8481fVyAc6U5lFK?<|0D}yPOZ^??OoHtE z0qiRL2+9HQK1_a_D8^es3t|f0ksgI>n8v~IOMT1=K_xbW>Ogv z==H-yF(N7X;?bsVKlp9H1i>+axjXR2sWvju$m;=~QT7=`%Z(AAL|&YSOgTU+h(Q~= z$QlV#6fv+6+21!zwq)Qk&}e{6w|00me+0crq#`Ng9p%#{4nklekSkyHa0lb|v^hX` zC8YNtoA4TWGa& z0Xqo=ZsnJ$K%x%-kF`%)KrE)R?}4J9ia{i+jFG^Cjwp!~omFc`2+R*zikpAb}p{(547Mu(28524a09Wt(M1t-~b6(5?Rb7{tX>7 z0m!TPC4fL9fINcTe72#%jS>(76go)5Ikz%zs8G_SC!jMv83525v?06qK+kRwfdUrQ zNJNuvMjlAt^gS(c4*-xv+^+F6Ilg}b5#>85P(Z+A7FVHNe+=fXxWij z0wImygI`y90~&y2(%z>B(Ie{y?5gQCg{#lB0Cr^0Z$4Xn1oxf#a~l+Jq%bBjxN{SC zv>XY0XYG`JFaSQ04mS7_3XB70w$Q8 z4I{P|fsHk??Z42at31S7AvxsfIXy-p=1@_w17PZB2FGXG%A1_abga~U_hvx>xk3Ww_r-Zo5GUu zvmEp?5Z-^ACQHna)2U~K0Dy}Wu(>b!QTOL0W(P=s*-;~bZ7oL|fL%sgVB`}(y@V7A0cNVCQXX*n;1d&ke>?LIkPKhj zUoqG6!KHx!_)0ecPCEi?(-IH9n%)`(9PsTiM+yS7jTF+ZRw44+F*mdUifsm9VZHvd zKVr98onZ!OXW0g(96;05k_0~c3OgnNWmBY?90MpAxn~`B9fLk30BtM}FiA^Rc(VZ} zx7Rdg{dD_fdj`}+XX}x#FdU#&JRW>x1FHvi=b=%(H#@)5B{p zEMa(?c4`AT)s6%BA}nkoYP>lBPNtd|_4-tx`diQGB9m^|q|#1)Khzro@+YM0U=TMe z4#0@zmHlFH&5^z;J+R!oiqHzQJ^-Ddu`XXE8mOvL-_fSW+5l7nYHYIdwJhA70nMKh zAdI!%0N4~>%~fD(kV1ftTEQ)b8r z^p-(rZ$O;jNWq0TQW;1ryR~y4 z*vNytTSmZVQvi5L8d40i0!A~~-U)F7WzJBYcGq~j{Duq7xSe_P83V>p*5J1yZ@wEw zPQ6D80y@-wMjZPgX>YW-l%mrBOV~#WyqglccYXnm^*@3Ffd|%m!(`4Ws~&li0-dib z|3{IUvy&{QsuBGkEdf$E-$HX!P3&tlw|8z_9CU#pZVZ=7+j>&-Z)@m=7NM7L_!(&h zXoHOri~hE40(6{5)O+6qjN~ibIc=TjO%!2FrjMTjeR*z#TMgPCu&KkNeFqKjlGPMv z=B(C>0^O9tQzM{OF#y#AqDcF18I}YffOMSz84d{797?0`NK*1DN`9)TVw0JVL# z-lxk;un_nNK;{HC>kFWYE*v~8IfH%#?6Ic+)^7kA1RjFJ*a0iVyIvye0YO4FHkpp@ z9{|nE7g6YCU}L|dU1LE8-=KEg4cQH_Je}iGpTy78-^dX%f>UlA0XgAk&4)!xcXeQ% z8QT2V3-}x+MP1gC&t(9O+<~t5mLI@$CQNYRjD+6E!Vx0Zi9jRkHo-pgJIO$ly3=fr zeE^m>_K{g5C6%IVKuGrpfiAR#5y%h9w9C1$`kUR~h1y!A07+%#seZ1|4n%VRE+b;> zj{SkDEcV|}6-X9fqFXC83P>6oE+K;m;NzaeBqU3rr+ z!oVG<8T5Yu4I(&W224AN0hwn*pk@?pj%B^BFOynS+3)M? z^i$-a=G2%?==aZUGNVHTW>W32JGbn?-F=5sJ@06O!Z**!=(3pn^^Ko< zw$dcZlUj zv3@48=rUAZ6644{;6k|1j_HfjI-OJ#BKB$^gkK%a-1wLSGfGYjPl(?%QLm>JnX6i(Y?J?55d=8m+x%MGh+03*wuUE zP2;LpHZ$`7-eX_8rm)W6->$rII1ya;WLu2{ME`r>sKC1ekDrn`#eQSP2fqtn#fLWH z5oGW9?2U^l!BK28jloA$BrCD3om&&V~HB#kKSzrF90-w@ip&+wu&(UG@j5|qxNQ~n|*)`XtmX-m7d z_Z9%ns65r}eOM9@Arnit{YwFSeS*CC%*G|(ZvLh76t>uTbj$U$@8FH_W`g-9Li*%~ z4!KYvjZ&Ur+<3q2kf%S1dQbdyY8tgTlMU!Cw<1ELC&LzqnA z{bv|tfz7yVEqneQy$Z@^p0LHIrTmML&W+2*C@bPai%Bf}3e@|8Ylp~t-5r4&B4gzQ zKVF9Dd+X+kkWjt5_L54+MMdQaqTr;yuax{N@ucDA&bA3B&`5^kQ_oH}{B9&4H6N2K zv3evO(U$s%S$ZJ2Vd(!;>fO2H1RD8ofLKS}k#`hCr-v8gt{t1b->*eolEC?dF)@&L zCy7@@Eg>PCXmF?sMz#N@AkSmPOp`y|Fq_xdRk!XjG3!TK|6|+z>p7=i?CZmlTXcdK z#VNB@61;!tuJ0c_9N&I@(*s34kKfc&hLV<`R9y~VZas7`1HvQx3gzVDw0 z3xKjj1-NqvD@e<$$4XW-`JK(%eyLCkbI4vbm+RJ9-zmR8EnGdn)|jeHx#FG}w!)5k z(vz*I=iITvb&73z-YZb3suX=qF+xza^*^28z}4!rXflw9QubPr7?Pil$PU~LN!40S zH=cggO>$lWUF9vkXR)hHveIm0Q+1~B>6Xbpoja9IKO&K;=Sy$OO%Bp5R2__Ua7c5lFP%BXUP1 z$ZEjl*VRS*ah&P9(8&E3m|mv2c1YgKkJ$7x>x(+V(}}z{o01}WJn0!c#jBH_lb*P< z?x(93wZPs5@?)Wi{QlOEL?3Ify8F~wI|IbPe|0`bgLJ~{@J@V+aHI3jMKDr=VzS=f zcj-U9)a|%zmu4sTYsUccV|{Nfpd>`)MA!wPX8~lT zQCg5|o(Ne&e|5>qSYwJae#U&=<4+(jeKY|?_RR^oKeyIdlw!g-JALdq_=z&?om)Lu zFgQ(@H6e5*)#5Z}SM;^!m6bzebK0^CxRq~72>Ft0od3cZefIEluutYRr4@%bz=x?) z@kw?T5=i`djoR2gnlrm;=Wp46vQje7)dX#P6iB@*xN^Fh84-%lFD6;Nr#ZHguE>GU zy)Ep#fA;+Jq~`u+VfzX5vc}3N_dDlb)3s^xDZ9w}H!Ra|E~muT6f{{(>%2nG9j&~W z3njjJVr+faKlw*g?`g#tX@8tn)T_|$sGQd)YDv=j$-skibc%c#B3`vEVKQ751Nmlo$HCf^k8M2D%>zdg=#@z59JKke1+jlE5=TnKNdawFDRfQ#K*VYRnqTHHAY$Z3J9<9CC$`PSP zB2*;AIkbo)6=O8J3VX+q{TV5fmMGlXdSkg-srElxXgc3?+I8C(*-YEh%Ws6jHb28K zpEvO-)U$ZCI*f4m=X;EV-KMP}1?gG$TsUH;U!JeC)}_}Y87VK>cHs&y)aT4@+RjXH zMGH(`_AeiiG^MUgt=q#p(~4Sd@JHvJv8BPs16A3Y=XZUpP;IpJ8sB|l^=P8Y@Y(yX zSp#XT*cY?O@q=Tk{P!#+`_ zi}QC2Q)!Y(+S*(C84qH=p1Msk672m;_~hHtTT&A9MqQU&drIk>5u1*6O21ITPe;)r zOw#?!WFP;C`0#(}nCpKc`wcPOf|#Kb%m>#%vZG|6xeF;6#D4sG!NfrNg0DGhAn2sC zR-=TdjgJ1l!$5ItK1u)TAo?BtU!qu}uT6mgzdg$5y4KLScuIKKEZ{3>;LYI(}*q#d_)*x6_7Jxa}$M*B70MHu6#TgJ}9%lUWzZCQs?zCkL z*C_6FDRkH&v3b0exp6Lsxz=m(`E0z*hl4H-H~LDcjYj+Kr~2r*%%1Q^zd|!jGX(e2{|Hq(Mt)%#SH5;YL?m>I9vSn$b8Cm z-6{Q>>Pm~V{p2Nh%8VIlZdLp!LKd<-%Mxf1$CPSDlT--1mb5xmH-lazC``w6-Mb zG*Z0o=4pk^a#R0~`G%3@A47(s7{l9sDOE__@{ANNoz_<6)`N+)vk_a{Um2VkZO}fl zHhYf!%C*;W*1s41@#xak{V2!yQX>qv;IMMc?_P^oBW>=*e?2_)FsF^XmW{^|`xJc@ z=hMBO!ww1E+UAOxh2Cljad%WeSIbof)c7C7v+VA2eFpvx$Cb*O!*cyC^!jXNtre)# zv1j`Jn;#FFgxztL_ z4w3!MIHM%xI*+==4^~pGMZFtuSldsPl2|rL@cFD3>0>8XcX5)z?0or8MlY4tX-I#I zY+5d|vR<;`$+ug^)drVEE7lu^35@an+a17RM_@F(LET6>c342VX?@E!=G7rvG554RS4zmV@UBWyu#I7@4;5;J0;<=6x9QgyyzOpo zAI7=_#(|abvb?ajd@n}hbNuLJWzl_X^Rs922uy}9Z9 z`$FY(@q(+-xz|)LR&O;VVcCy%Fb9s>6Gm)pJkY7Zj=1GJ#gK7fq5z8R#n;n>7qaARiD!7 zd-CLQ-)4RKTU zqT?={d{DAQ)Xl|`?p#CcmReZ38L|0VL+x{8-Nb@~etH@o$?F+5vJ6i12I67L`PbF+ zqi%mQI4v4d?59N5V_W5w-$r0M6o6HyeWE_8S(bZ_=kCZuslBF86F&cej({U_`{krMbi=VW85V=(x zK%QX!zc4Gz)r3JOXEN?*45z#+7X3%p*|he)aiL}-+Q)7}jv6-a%x*Hb#6N1AOnd-T zi8%fpeP(|z&UaGdy*Fvrud>A5LdE#b31;K!3MFna9wsR| zEkE5;yDY92)~+ZK!{4J}#vqKBCvWqe)YfzXKvp>sFr6`w!_gK^qa>~?nyU~pd}3?S zfy5MO=49NvNQ7L0<*k*V1P1Ci!*`p2)Z9`-R3WZB|F=ql$LNd1j#*m$I}8I^MO6RG=^Pd&=)GT@ zsms=!<%gj;U7hgdvr^A-FPoyA4`23r3_rPGyIXX*!{8D_eX8Z@ z*|?=L$5gN0tjFW2E4$l(>RSq0=&9_4Ed6jhJCTh06Dyiu&LxYJJleBdUr%yR=-XVT zP`aKjqXu5uLbeNm=|qq7`~OT+^j;4Q#x!mk72lb1?PL5R^3BsB^Pfmc24(DbZBO%P zWTTed?=WN0M@Z>LG=UIXTixdCPcjH!)Z%drE5qqB7_s$&Otf%KX#uAYwOb|Lb#t1w z?wm6R&`4gbII;K~wIC#_sMhFRTkYCVA8K4baJ_xtta%PZ} zs+WTCGE+tGwGpB8zIlXs@Fd>3@3x?0irtf)@<5-Ehz}5HX^a$xQ zZb$Bet3OQ5j`Od6rO$W%MJsG6F`7Jk%zOp$bjnhfI8&a;JlE~Q5}unyz}Yy0TEt0a&~r_>%0af0=FVD5j-HjsuyPP zXaUSLXp){8xZ{6O49735`EcxpdZRzL8!`l#S@~ccagvW===XH&3w3!rvj$v~Qz5>p z_8GSxW0H38p5HqezE8AW^@_RWY*ythzT5IAfe+wr=<;2eU+I^?U`o82xc-Y z*EeMGR+c5Ly{MBzJtjH0KI?`j@VOfCOHadR^o#`$zyd@IiJ*lgDzeVXK!~INj(Aja z>|>`P`t&dU$r}WH+nP#{KAi|^shX$CJb-yB>m!hbCqbvha|VZ1!U zxs*8EU@`W%hB5NCg6I92%uF68Z!VgW9PTjSN8}pK-qq2)z>5Z!)LTCYKm!|)F5vhV zY1`3uva?_dpM|5>>d-+`Hz-XCJ8)N@zfG0>cE zEM|w=i>KNdAX9B7Z#Pq+CclLSPyl~q+&bWKoUP+T78 zZ{)=XQY|V$-CC!LW{6({%kb<($%hSlz>;ra#_SK|dD+e7WSkC!mX_l9R^4fWDB{x$ z`>~Q*^{<7+6gzPUu&22~GwU#{vAX@}bDP6%1X}=)6J^$L%71l>1@)3mznFRR zh*_qs5{u@InQGeDw<~WVCrdji09%*oer?8{Mci6{{G@+6>-<^Oim;m0*0#masP|uV z>B?Un_nwYCjdkc4gBr*vdM(7T`e62!G0?CmQ~IE>4j`E9?ru1^$I+6tH*DZ8Y0W;+ zF#lwG+yb}Ts@|G7R+6onk4uM}GhTWx5!@YS?Eb{sosvrsgaoSY zfZ68dbU8=jNA-peyErAbt^AKuJvhO%U0U|7E>6LfruO3o0wJ|K+g0C4kz|Qd^T(Tq zjjQ<0e1?>`O?NOzw$#u*N&qOXPv?plszslOL<+CDw-Cb-VvW6eM+?&(2wETc)a8ua zX%xR@c$oqs`e;iLC{1KE0jk*o)opCMsTRXAW&zB!CXMymd^k}VUS2-(x1A1Qb~t8`zsS6c=(mxeA07A)u)Q~C{- zRnYq^-!?ghUD`x1yt0$QRZ7j9$j!8%ipRRYJqdt1*9%YwTp!>WS%kS8N4XHDt%%Uj z(Ae16=lQI^H4N#UgQ`3+J}uV~q2m_&<%19J$`6y$-Bl1;H6+EZm);|xO{Zvh>#ufI zLU0nYmMDd^KxL(D*LFJk-WiI|@$y8^eNsf+ci-GAT;r$To9vOS*XirM_cvr=S<4O- zN!GCkZnu4;f-IsLyy!w9t_h>=8*hy6Vw0MsG7f&`vNX-lOeiZE0);$YL-;5ND_p}f{s`GGc!M{TsYJOtKxhjglC3FsP#6l!TqMihx z^GDbgn$k=fMP<9;;oyJW_R&jceiUUrG3oe#kO7YOkZac_!(7l-qPJKDJxnzvo7Njm z-lUo!PP7$jb~r` zSGTzxh51{+`>*ut>|&;kvYu%c4n`kh1r=awgAr6ggRk4&?Ku(%jn~s<=Pe~<15w%z=nt%&i!UAM zoYG2XKy=>5%~ioRNm_4KroxT(4I*zFYqDKr*3B$$c^T4~KiPoI{ohU5w>1=cG`htZ zE)Lusj!Fw3?sTVJ){~RA76e=%}1G>o-!vF7}d$@ z&r{(&!S*Vgiz8B02FWx--U8b^_p#P!YA!JjR=RA39S#4Sjo;ZLlAyk_3_M8Fni2ZL zfcWI@4X!t{3IOtlBY5)Xx69-@A0HI~;dAJs5mO;IzQ@=5a)^`oT$YV7I1p&cJ%Jz{X3ZdAF06cp0OY za^oT=pTc!CpRX<+D><(m%}kh4d7o2Z?N!lF3jHqC>P|YztXu|(b=s+-zB$gRvo?6w z(ZM6O=F(HsUh0T>RbE^*Ld_3{5;W-Vf=`4x(`jrry>a~mdM+%?ocghv8mpJ9oQFqt zWS#dc=8xz#3=Fv1|Gm#$4l&D*4`0E*3%B^wAluymr}aQD`(lA3$R28R7R?q#P^a99 z7v`^CxwLaEWC*rpIBhXN`MCP!95~va2&{(bpFcG@mN-8#77URi+6%bNKz&gsA7-1f z>=4d7;mpIV921VcWZzh=xJ@`XA zN#nQ8`*7}`tM>qK{Z>Cte29W|%bbVU{xkQqE%rI=9pt;HqsnO7OrZ3t4MW!%$k}>a zZUkdjT%zpbmAmYc(w-FbYC>HsIugZFngukL1+3LxF{=r$ z(}Paz>VQ8~sKxhP_?GrIParsFx@9>-sFyHQwU_vftZkWNW&Ot@$Fe(>;=Ala{&94EFUT%@aRy+u1nYLuZpVFd??+s%A*%qW#6qP?7Z^j zqJCqf+(+lGIM@+qZz6#H$y}E8iS5h!jcn?D;7L zH>hkfARgqgrE}2NfPuhNv|eV)MC%~3oZz(t;Xqhk7}_OCt4~0`*%@P$C6@LudU}kA z4?OtseHX*G385BT=p&R^4TfFN;jnL7Tf49LJ9E27Mc6b!gk=&sTmL`G5Hrl;D-gwG zn{PJ*8LIs#E0c^Y-7yMy^9x9B*?u*w%)w1 zkWi+Ih%TI_PwZ#giF0AVykJhJUaA{5K@y-t7SGnv_TNj#sJ=MXK~8a#m;bHoCdhVC7?^mjz_-biJ74Zl2H z@t^7y7(eR0Pu3z#LpQh%Mt0R%-LdNOXM5@`pkgoaH_m&pKN=xkpYQk8HFte1h);St z#K;A0(3B%s7q)T9jzOte?(mGYja6MsH&dHXdZ|8u?R@76b$H|)rFki5|1IRthnNRG zKaH+O^~24ftr)$Z=qjrz@wrCEB_$wGRa4(UmrE#8rvN0H*n)EF|LQT#>p{tN&rOz$Fd98zw ztb=MOOnZ+IAxdeVxvof)ikn*=2RVRgt0jqmpVS;B1D%;eA(?GDx^e_;2}*!GjQ%d~ z7-yQ%fZf-lu#YxYn`2hiP;z@V+sO2L;MaoWVDVDT=Uj6(0D#P;4O0{ zb|%tz0OZKnaGq#ohE}OHo~-5ctD>R?-L;`Kc3MG)$63Sdw?p6YnN889@Ewxron4(* zxnm@(PF>){oZh6aWdVM^1E*fsn3rT7{CpM_r1h17_3h3Z8~2@*qpl-3`0t5X%Y+%A z3Ka0Z0`&O(_4F%6Sqx6HD3-|uK8s1YJ%$_9<_fQ~3dlV^oStVEIPtU53l*!xaFTG! zz(s!La33XT_lJB$7*sWBNL1yCd6iYr`V1bL)vJ&0dUrc8(i*vyfBwIbZ~R~6>!(P7 zyWxs??KgLWwz>Jwy}pHYeFvVb0%mwXIPcbMNCADVTS&L z5VTo9MnuKVx6G@JMTHb>Wq)?Ya^T_Xtoh{iTe!7f_u68}DxRl(YMiDGU09AMMeT4^ zAnE4fXAQ7vK!5#J^ezhq8p&OorFsn21eHq?3wd3JUWz{lO;1dGk#x&Hu{7pgB-Q!i ze$G`4E`0aR&#alogd%Sz={2tT1uu`6T&DlI;%uvbDL;{&%r41%ooJdVy>Ki$E!ZK( zX5322(y|~#hTAyEF?m?K-1u0STHIN8GfLGeKYozmm>;$(; zBy;SA$0Ed9^yF%mlV?3FI&e0}WwFNU7+!4EOV$TFnI@kS{nxa^R#qeASJHSL;{K~g zxPlj}vK;MZ2|Q+6pje`c#zkw61H;nQ=E8a*rfT6m!rkceX%W-fTIDRDdwR1AE&&qJ zMKSQCu=YD&KG#UCe}MJZ$0R1}6Y`b(C~;m8t$b-|9-B?hiRGnQv*wk$Pg<9vy=P)I ze+}}x%L}?#lV{JaHctIAqQ-IhetxY3Y4uW5<@3+JKSpt41?`-`zim0!(=k+&_>J`w_z98H?g*!BC-edP)y{;L4&6 zxG3K6C8}w?@N4{`cuyhbD$}+5bM2buSw}6OsOXC%L}~2Oe*eEt#O%AXETj)`Emwbw zmOIw+f7M%iE}hs`AnT2jfn~NKby^^_57HM0Y3vG=NpO~rW91912K zr!6@Uyxd;Y7p1f6u7JSLugihz)2Xf1BYHtzVta%Y-e=4% z7YKTwCy5BUIY@2oX3GoqJFXQfHnFc#(L^nhaA~A~lMJ$13V>P{< zzWz>_j+gLz?9WLCJuj9Qt&w6TjS&NOr-9#SPA4r9KMdZp$sTy7?xt<7CS!O$U6s6P zWAFw*XkYW%cWy`9TD*F1V)17H<(+x&xo1eVX%qL(AX(=IzKI>ZtVr`J8Q8np3-gZ5 zWd_{V&{Znda%vjb2ohJ*Esn`4^ix=!AM>oNS3SZ;X%Bfp6s?lZ_bXE1wVn3LH}`Bm ziGl9K15(wTq_=t@-A1m9&Z#Fc*{6y;w-~-=8RJX<01bavJ+N&dIt>Wu_PIleP0#Swwr6 zo4B*hkk`UrSh1ZPx_Wwe7k^C65BbBIYG3h)S^-~rx2kdc!re%Ox|17IlaQf*0*wfT3^HJL1*Hpg} z!=HjACe=UcdW_fYdMqu`_G?f^e1h^}IW=$XE8Sa%5v!wlq$H;|aurYdJH>Ex z-D4Gtv^b$BldS+sz!rj|`n*~ci=`u?W51XhCWa5^5NOm8nMZI-UIKuo72T>HEG z;Jt^sURhHuYN6xPZxi3ir{uSVN6{r#RaKc$Jm|bIg?_G6FZU5tHxhlnl-^V*fH8Dw z=oqs@T;Q5Jhj@k}WbE(tk+rC$%&%z#AJj~gunough^?)=sFbLyCDQ}B;*b4yanwSp z{@T{jMgB48%JzauS|+7e3wEm#_=yr)j&@w~f1sf@wJ(srIzP2{mLb`?64SumB10wp zSme=n8LUz{=VxQ!U#{k;S85gak`H!aM6O>8Sd^!ILlc~N5O|#ULRZddN{%0&Y^m!E z-}*x<07^?S7ToRHA+!&lmphCuju@SLFiRjpV@Df`UY-D5o-jq($D}1%_6_+UCTjL| z$Lef9gJ9scD&V!@U%V_vAh6`sX)DC@eJ4(yEl&|O%HfPI>9ACnxA1f9Xb+gsT2V0c zgyqQ)>_5g{Ms{81hBiVAiMJhjMV=E0IQgv&(xqhn`)nDq-0U4UP}#K4?~C6|ndQqS zW16{TQuveBRG2^)hdR6LSibsP#IfiEH>l|w-)%geRVCYZFC081GwJi0PJjL7qkhGV`dnmh^V`nL0_M|dQK%z^ zuHhH=3IQG&{J*f_gcZv4r_AOOIx09oqG1aW*$@cZi_Ef|y))|b{FfdVWZ4ftr0}v_ zr)K@VW$4b)033mq{q=#QtIxb+%z3SwzLUN$#NbX^qldRkluDa5rZk_gB1jZHhgt@2 zo6M)uh}h=(?9IaYuBE=7sJySra%H#m21RNUatDHq1u5S!&S|r;qY__Ub{F*SRu<#` zX7a6L=coo;UXV}p4bm#F#B-$ZNd>RZI=g9Jvml2iUMcF zYCTfk6!Nh=;qCcq_l=5u1FQu*al?ji%;Faa97~5t?K<#9c>(Fo*$4j*Q(qa-))s6X z+^x7qJ zK3V#1UH`O923OJi*g4&!RBHx%v1iXr*EqxS+$=`=$vH&i7CJ7zYGa;Z?#0xQm7czq zYfMMj{#z+xec=V*e+8vIne5J~YXn(v{5a|27geyi{%&AQVjt^2_kUIES5{9Xkd<}N zdaGNb0gqMNPrQdymAyz2#3hVQE54;M*i{&Qr}P^8km?k-b+Xyx4MK)BKHUW8*-_S; zW~3u?EdM`n&~hAy5ghR|s#jCUz!{~BULhIY-g531dUili7t;BihB7^k-uzZ8lHWnu z)*?viI!m2;*{kWBaVO^MiUCuJVjNkF-#)3p)%>z9mzpzHB%2%sADu!+?R(>WYosIV zNb~gFxXlUhuxzn({B~ogle#66u{D$fD{qNauzZU?x(_0Y9#l7E(5|={qVjsEN9lGH zxLt(bYO!=3f$pg!@*gJ567L~DoBw|pF}11Z?~T0~Dq`H5*w?0AX?a>s=LGsC3)gd2 zPj9s_aONMTD?PZHfzyodUJoc9kF#FyD7Z<5mYKXx- zAcmRve3S70F9A1}!BQsElMEDM8IQ)aM5hR6t?lp_$mjZ;rzS33X>DdJv106t^7 zda(E0!W#icgEH_Uz<(hu^lI&l3&XE+HEhHZHbX$HT2~Gmz4UEHUsbW1;l7qy|171~PknRM_-(YUj)V#!k1Wz7w+2(aL{$Eao4AYXnOF@&73 zh4U>Yw2|p;dLBKOTkgce9=w-dtp$(?+$0L2oftL!%+lSI-+Z=u8xAd*1VMckQ1-nkFYk z5{s7U9r*8glrnONf2go>4xXkooN36q992jcanaGfds%4;FrF%TyZXOW$R8S4mSf-L zRXA9Jax$5ES6UwH{n}5=?XeVolk%w?+0egVe|CyM2L@RF@!o2q+ozJQdGFudRSqR`Q!HbnbWa0L#@?)&@*7D@ zR=Yh#6rtHE`*=ykq#ee^% z0fAM^Zxm#wB4izLlei$Bt+QOAHeM53`T0Y86f1Rqv`a1yuG&xu!NiN;es`8@FD_Km zC5Yd_Dyhm^?a39=!*xi>Fh$Wk_TAcR@xbQUq*C@fbI;gI0bTU}Zb|jY9H$c*dcZ-l z<}hLI3QMoE^XAn7F3+C;@R!CqzTVmWFM%|ip*ySsnq2oy_%|hDT&7LD(7w2?!9l={ zc~y2Y3;ve@1?_dfNyIV%<)i(4mnumxA%&|amSJn9AZE$CA!ZuDBn6suzUy^A#N#c(L%wSSEc^8-E*Gz8Aj2oQ0 zdEf&3xzpwF6t%005hDRhaob+NiBpK>*NtM> z8iCV9(SguMf3^Ak%=Y|2F0nkglS?RW8Y+{{411)=dXIE_}?YRy$|Cn+L zjq&ccMRoG3iWF!MiMH3tczP?VlNF^C5WS-lzvM%- zlQ%DDJ8lBK#?MF-_uE)Yb|=42F1n9}dH{C3@gQHPtCfE?My(>%1_4U<4UB-R-^H&u z*JB}K*P4pfUX{Js0>IiYK~X^FYYK{`T#-02uw3KC&+NOuhgC$D5UbKe_P4i-tP|gr zd;$-CudTESGGZ+VZhKwCJVJ*j21|w&{6_jnt+`7V%BC5vpEghhTwEXFE}97r1cbyB z{C8{GGmhL+8rl*pIy5HF*ix}-bC!PS~T2* z)1c=sN2T=ZmmJSYCLasU`1)Q)=k3|g*Y{-x#81_G6Ia&OyXB8Gq$UF5OJqn6Uk%F@ z)5r@v779r%0;(2Y@ZzBT*!h`*G}n|5vevS^hmtdvk87p@pOBK4m9__{B}bnicpUvAM;WbaztinkfnLsr7K?FO3fuGG zTZPwD%ppL)8VvLR9*plgi?gVvBy{&HSW4!oP;9C)QTnnDFJBz>;;QYHW*4bV510o! znqqXR*m98balQ#AwAK=U0kYG`XhB08?m%I=HS z^^b0D+?`5ui`w3AH#eUuxUqN9Zi)Ur1fvAw5VlP+e@~H5CsCJ?c7-@tb^|)a?`M|8 zvSfUMzTk)ECORkJ7j0Sd@;YXvML#tFh2=A3$FD{V_b+~iq1eI_n_jcq(CLJTOq0g4 zG0v_8KFqF&2d6(i_J0y$xc^ifc=3=!2NG)15j-WUTVA8c6ZfXiYP%;+9VbrF=oy9! zz#|}Ax0P3*vo4^i+#K$+r=?DnVG0AS(FXf7?**p+LvR*9t7cV3Dw~+mH^$A(Oge@H zpav*xq!Yx3lkq}4dv!_x}N*)zLuC|)g1Z-VXaD$B% zs=mV-$6Y_Ju1vZN;eMZ-5TSwN`JKbbtsPif@G-^W(L%meC9tl&EB%2t(KusZ?dI~a<3afgI^^{Ph~!VY>~RY` znz374<-cw1i}H&}`aSSKCe*b1UU}#4no!8aKy*;o@3gU5p}a}DylEv_OYcVhhE3J* zht|)x(b92tC%`*ISa_5Wc)9F5QNrI_7iIw1x5xz9uPU%k67_=g|U&2)$GC|Pt%V| zI&Xm<{EU^wnw$NRh%N1JVk*GP&DBGPu|ENrTrdRi7kvUp&ag^>hh&ED8jssJltT7s zKf^7ry-f$%t@SV$!xDYao3LSZ(u<0ovoM z0SO4W8`by9jNEa&PE8su%>2Sn61JX>*wfdh4ZBzZq#VsuFd20kV3Uj8k6k43Eq+s1 zj?^tE7|sfwS^&T<)f*6Y%uvOes?veIWSKyAhHZ+jdst*<21-KD^HIJe zN0p=@(MzBkc&-h(?tl8iW%d=C_2DYS>O`E(U zEov?dGnB7iYbU>6JA!NDmbtd)MVRYBCFh!L2M?#O+X@`}UVcq+9WD(LzA1yK(?XuW z8VrQ1o8NKLJU(vJA{~v9Im#6!Z}c~}du6b3I1c3DL~6@_44`}wR7Re5(N};Tl~wcg zwkEC|vcqH&(9km%dR}g#xjy_RoMU{W&3`T^0SJ0A5ddm0kZ|}3_g$WS=Yvc|$&kQJ zRA(xq0YkZRbPhhiy38GPQQsSK;!y8#JXj`(@gR|<>J{r8y zZ%i1E$g{zNv_3o(rc?EtXN%f@j`*gT195-e_dha9yk~D!TU7W6Q;l>#{}L|7yiF1d zKwJt)Yz*ya;7+Bd7D(X~Y5?CG-65MNBS2&l7>HvR@>z&05;%Yh30zR?BXeeL~TTO;|TJDf!xrC(nKXg@B=>lN0s# zh_KX?NNA_v<$xj{&&uCy3;WYZ&4kmN(y7zUSoqVOx$g?urM0I*B>)M8A>L0ASjb|U zJd@)sWmQG!ji40p$Fd=KWF8Sx(pv=1PSR`;Zj2h~uQU0|X|m4HM1YE8fA);=HW-+T z0`rszm)y|#_JTK*OB%mvI#(PZIfjZOY^9wngsw-}8n6T>OIo@lT65jEmMmO)Cr$(n zV)~s(#6x~xw0`)6%F3jU&i&SeJdFOc+`t@)pc@+2j!#T|1E3?d9UCTn18}Bf3(vM? zGtyEfVAQEwR?Ua2HYYV~gS0Pi^B3 zV@3Ys)f-L!;K94)dlHgnLD_hiiF!nKDUS=FLgOho9Bz-t%CMs$NI+A`dXyZvZzS{n zu?(Fw;Ndf!(wc_UUF6Nn4;__Cac{?7lmYqI{wlR=#VK)Q6I*BuaoZS9jjAye?w-5r+!K#V%}RZz^P=m(zuWXV)gvZt2nYeAA_d!-_d*bFa~eFfqnl8 z$@48ucmXzP+LiUuiFXE1xfd);8e3o-{UBh{g`qct=E!bk7&g}>-uDfQ;nuA!1(wr0 zSRI(|yR$|;$h|!N{s||ed$nI*)tjz}%PyUWNll^#)Tja1hZn&B&r?=Ck9z7qUumdO zOvVsc4&X2o096DB5N_3F9xF?N=L;R%PupW@vUfLlXi9pi%m^3DGb!JC65~wdX%vgX z9zxG`lVo2>)TJ$1_a!hWra?UfkXYGO)?Y3#b2QAh^mlO;N~Gt|c7q({PC#zNMGumoL-p!U4~1dR_c+$@A43)cIg zpQ}^7I97uykfk7ge;|2E(rpKro(GpMA4rFA;Q*aBrFl;T6Z=+26t)F1%dzF2U7d_^~3GUjZFn`Y1rx%0!Ztr>}HKcwOBYvVd2P()2QNIF+S= zHIK2mM=Ge_(Q#d*LU|;e^V7CangI*_>mLVm0RvB+FI?ixm&XBEI8Sy3Lhula{7ufT zXN6#oQe)~V!HczA7Q5mg;ZGlNYYg`gB8VmPL^ceYyTXxg!z3STqef>fZvT8j)&ulj zGjoeFll}%&*`5AWah^zly*G|e`7P1~ktg{W!Fy*1r=*iaI|yTpJ-E8LYGT}xeReZ; z^Vn0gRjkI;;4!mF##BWjn_OdZ|P z-u4N3iv_X@l>VW%xnYg$o`h{RY4FQ40fs;e5oTr3>#0_tK8oIn=?AR0QZetZI{p5a zAh)Uv`l`v2gp=w#IJ)@AaPdd{E(+7t)I04!iV#4KTX{N#=t>g&sO;9QQ55HAwxB zk8VdUkhl0JQ%5ep6{5H&B(nNI(#=|p6+-4yhikhi#L32pObpi$%|oe!#Y3@4RTu3+ z_WE2lPc)Nc-CVTbn;dK#$M$Nrz*>h3$-IE@^AGSG@0<_wCLP9;R=q!a(2MvKXK|5a zU+D!Kh1m4imn@xCIWRxZZaN3jOH#9TIC@xnob9$< z0D=yr=;AgF6paP-7zYh9@k~E~=z^)eC2_irxG(SW4fh(}&J%F_StEyayhhy$Bo^-4 zIZxej(3m>eTpi;G)G7Lp+lv0W4G!k1GMQ1dfDbPe5U2>Xdq;jqbYx&YKlCIU(Kf;l zQfQ(?*Bf%*Z{LjMZGmjE^=41lctb)=K<&@Q*Noet<4ay-6K?hz9lpzTFb+fTcK#-H z*y$tx{*(wa*I|wqH%Lq+dAiKL(Y>W0{EFq&oue~--?*{_%XzrOPs>W~{Jh$%ymUlm zz-p{zHT4^U^@!e~q)@cY*or^oZZ=uN;u!f}B=Ry$9x1?1yH-)^W_`AiEB3wG51uxV zx!AS7d@d?5Ehaf=nHX251$V79+>PSKz65v%Ur@_{V@oq#MuaG{t)`r+deh8 zsV$ZH1bfULy!3k;g-NtY7O>CYQ3oH;En+@m+t4DTOf-8=u_qAvd^aO57FWwL=Ds|x zjbi4K$pRp~PJC6>YElc4nNq3vH>_frMm7 zK~|DN>C!B{F{CE~rMP#KNrZN`YZ=0=LFS@B|I+xAG?JkNwa}6mER-Af^98e3FLmm1 zx!N${)4317utO-9%La-1oNHj0>?HuN4=?h9pJwPOTkqj=9hp669#wSw4`46{r~*aI zgDKzJ<pFnwo|e91`%rglz9? zR0DDxXaY@0@ z>NL|q-cq4_SE6oN2{R~6+u-jPh21si_uV9JS(kY2y$M~Q2<-g}ZQPHQNH>Dv6*Cza zzZ+3xC}{Ockxf&bPX7(3Eml3BmguwWeP%n!+Q*XI!fN(T8ST-`8^c%|D!Zy5DZt+7Z|!a{lP(ExIV|wt2enPeVFIAz0OM{>HW9lk+EbNS-+6x4xKgF)5{;9B zC`3EG`i`)``vT!}>w$-Nu{c*@*}U{47l}?)-E~P7SVoRyVw-7VCxApKkP)wnUgVBN|GM(bEaHMz(Q}N;b`w9Gk zho%--XWX2AG6kW4J1K-X-6Vyg+bskRn>UX>yLxaU?foKjGa|=fQ|mfXcTSAOE@||( z9#sZ>Mv_5~7uc-Nx;zeF>y5^>gx>58sPGdgN0F2oC zUE%QrW;#F09h0|TIF|T#M{U>8Ttq|ozcEsy(Aw z(gz@szzOTjQVrKwdk4&}?<`sffBuc|xh600s*=qYV#X>`Bl`7BHqE^d|U0}M;Y zHM9o$;dBV%ek;(jAZHv`TH=Bfg6zkK+jWoTT%&Wl=f+oNOSo^w!evUiqTSHPN`EzI-y#Tm;6--1gjG+lIb1vRSiJPedRo%JzJ>y;67RQ zf@T6Zx2OdsDW^6~O$ZBBPTCdEr;j&O*Mxs(BInw5Gd7y-rl~536Ak#4HGugEpt7VV z@#<5R68$Z?CBb~y!J*_lw|?qAl%8gB4Bd1RXcW^)nNT~^B42XYpa~Tr-uBBo?l~hj?Nh|8u~N|3JeSD{OJRwi9heqg56L6$!Y#Hp!ehf_Qd(HU-P2?1*=olS@eTqNma&8J#)|JJVwR^2>e_hzTwqJYZc17_Yl6_sKa;jnRZ;>KA(UX zvGP0$O6L0^BNxHc&myQX#-8-!w*GLauJfnlE_0Ly=?w zeiAvBOZ6@H7+(PcX)9dzLc9$g!xnPCi#a>Uqo&t_&c8JRGov%I-0N!6bCiA+$?``E z>LjnP_D}_XCACe#gbb!-7;R4mpqQxR!rn)%7d6mU>&7>qqj}pCS_^@;&8d~cEy&;; zuzNOvHihWr_8Lz{oH*Nt|8eB?UxgzszRGDONsr$I20c^olq|sClxw~r_T=yz)n`|d zZ1DZsTgop&2o$Ec+vV`poVX1cu!r4?Z$Rtiyfc0!xCAi5=QDX@aAc^K<7|+H4dDz3 z!5i}y>5DDotyKz`lS@Em2CPk|5MYwqL*wqAMJD@S)l*-hIm-`o2LBoAyK|JE+ z%-1Ii+PG6@^p)Min+~lW?I@GWyC__xhRUDWS(0v}9JC3|;QxcD@xKtoGj$m|-Z=G# za0k?J2!|FLK}Zyo%J3s$2~%w36a*@kCLB2wO)5<|%O?H^@axGFq0yo5eRCY-eu*DF zY|nMW6Gs3OOUvBkIaM#w{_?QGlTKy-3E^|_#R1gFS?O``)R7`dyjTzJ+(nuD_{w+{sv>0f2B>5Hwg)Zu2zI0~53PZ)K&lEN&63Wx>-l zyJ(haV^9ODGYY8ee0|Uq!f$j(00!+>S>uK?;BR)!-NYf$+Us7&WQbZyPjGoD_y*w`#>H@AFG| zG0*m>+aK?va3#3KIb{E%wAKG(M%H%^XyU$Wsq(>n=G{2xJVH&n_>(VGPpdg_uJ({g0I)fo{p=Jm5I0xqa}F8+Y&HWGBh<}fJ!;&& z+6H07y!)_sP9`;e*LNtAqCI7Mlj1j{8_GCZ^>HZuXX)zyEFB(AYW8SU6Kq{gKjhNh zns=HIU?=|Ov`v$ldmtWu>Mq>ta6QHnJXL{KN8#>5Iy6@Ifff$}cb#PGC!Y*v$;7Du z$fRATwG4~)c>P8(K^RainQtCeoX(#r0m$qyBO52R1o@$CCEJFw2U~*bW#O4;7j=y} znBYI#%Q8F%l`z}x6w@$zA~6M;CY-aDC@NfRPezlK$B6oJMM~-9Fedn?FhbdQtpq&# zkVCRt+E*RC{j(k2|D=M>1?c8*=fJ$zOV948z4F!R$uqrE5mVXJ^-8MJYzSNHCPx(v z`xMPuGqtGoa|&MdrIh;-Gl`m^~A1%M=f` zayEDNj5av&WCU6(z3t!{g>}3@m6ZWlKcbo#!Y9DOoM3zWrtX!;avGeI&bW`eQgnvL zAq&ACxC{JT9N|E2=qlLs$>tPP+$rYFONr#57>FMWxNXn%ZHU557AUPulIGY=E&0zj ze^!J-@6?y(s<8#}PN6hfT+>nuEx6jp;$s;BvuvSQYVzIoB?WG58Efo+kb;=rsYXQr$^mU_MkyPCd*7tYF zn=a?y;p}K81YL>niPQ`Vv12MXux$L| zU6}as4nH0YnPW2FVNG~PP;L5~V*~MV1!25~mex}I{1uo$^)&Ha>;F*O7dhx%fBC{$ zMhq>FHdZou_KGgT#CxfV6Y-7@Lj~$~`LaF`))hA<1vYYro&`LRDdiBemk5L?v4U2S~KiZ?5^rTU>DbB}Nobg7N& zA9nHqoq9e28RzME9Xd$5Vl46NV~Bu{8_6ojx{Yh^xAoW}8csPphf(h%>6nfQUD)=G z<~d~!u1fiLW~GA{-ZvEh3U2;k1Aw2y9LiRa?}9b&i&q*$Hwgli;&dG_uYy9`6l~Wb zavlPcr%n?9w-FLCHe@KE;@x`c1n6kj1^Bktc(M&Q|h0h0N^+8G286XSk zw!zi1bCEieSKfFw$gCrhh<|(3nV4O^_N;!XUi20<+uC~n;(xYCz{kJN3RR{X=m~VY z!4M$OA*_S$kTB}{tGmU`pG(4MjqpT-LQ5u_2dEjKulh58++|(c>)z$!0qfUj-oHPu zeq=8eQX94S*l>TAnqrt_R>dBI(`7{MK;ti4iR3K+U#$x7*OQq{#fJkl(og5Thb2;{ zIPB3T-iOtymi-18c;2LvnjZku`+Cbp9U64D`baxb!s;ylR+0ukhWVDcx?}!UW+Gb$ zUo(4Vcn@(jv%k>bk(ezIy{Sw&qz86Fi3Kln9L_4_T3re3smG1KDpZ=AIvpI`gML}Q{}g_wP1xQ_y`~#w z@}#*vmDJy)Wn6|nGD}_uh}gOblOmPA01-kZKAU75h#|H6<~SI?lO^~OK{z`~(~;-Y zl~$y7mNrnS9oTxq7#ufRAP>TQ96hwT>}u~smC`1A=P@IzqVq>XM$~N4A>FAM+F~;= zs044hFhB3up=DRtl?>cE9c|9z38qPkjL(QOyXqaH)$(Of^|QCnVRt!Yde6x_TXf+H zgN=^b!jS&Q`{*bIs&&Vec(XxMiA=VxGpU;`@^=xo@^9C_k&}d6`yD&a%*5=uw-qOo zg}&dyB)5c~9?#zR@Jf&@k2UU&W`t~P$#g<&h1VsIcf7M`b5@!l90YBPZFXcz^rv_N ziHd6gXG))8m)^ppOowq;!H|(vRXH)$cuegySV4{wQCkUn2;81CBB2la!fA(bxJse% z70gdL+HOQw51)H4cu1)2z{9zMeMa^jaEsqzlz8Za<$P>Cu>w-z*MFB^6{=_8g?Qty z)#N!-_QVG{h~e{n`i*@D9I?ea(ek|yi!+*ZANmaHX2F#t_uUNr%abC|r#bMCS@F3! zs7RWMegnIZ^%oEv-YfbV^*3#bF&Iq{wzHImI4w4-W-|N3R_TM0N2Lz}r^C4*hdE>r z(31tVKf8Bt8+8b^|2ZKnkp$sxKr*y1s*h~yUmRn^yN6>0)zt?9F^dVEIUiQ5G!e3; z`7B^6RylHzev5$#x=KZMgOV>aX>+CY{|-ncXQ%Oa^Ic@!Ca75dT9-SfXy9BDt++3v*Da%t!g)@*a}o?p;P_y^jV zay^eiG8?#BLh49YONX}$7Cd7++h~PaTl1@t)X%f4oa{V3)s)}B5u9Pwzp%vI{j{Vt4vXT4Mo0s9c%+Q+7pskTEtyVG`DzVm9>yXO-gB%lgiAL{OWAn&2AkvEel)gBFflQ z1fz^|Y1)_2siCD1dPvU6E=BCEdNHlhJe4<5b-{&%WlyUa~K=RBJM z!_VU&pGx75kN%eE;b)`11F!VR+hi)625w1eBd63JA0F|#+>(IMh^?lgh@&tOz)&lr z1~1bF&T|<;&lAy@2UCB3jx?bQzSKq@#n9DSNwO~t@EH#rQ+~WU6*<534fbrRNRB6H zoQhww@@1Hp7ZWs;PH)u{fx*d?xK9|_qUZg_KljPm>e45VP6TTW%!Ir3&e6WiEb;Vx-+h@H}BNQ zM5taw1&>4U206UrYW>Rwu{WN&V$nobryR?4khUj|fZ6~*DGnoO{1Fy^H&OEDO%!ba zaaFcxv5I`i$NmK9OkCSN<$VE?3U}F2m@o#a`}O2{)Y_9_#s1W(=_cqZ7wK7K4uf0m zYi!}M4d@73)%chc#*tjjkN4XcYmP7aw1V)FU^R=%Nb*9ywjBL@o(tEMG}Z^9N)bQIFZn+~ME+ATV9fvH|` zvxcJghu6~l#-#lYZ5D(Qwzsln;!hCVuA>_u415h9FzsyU`UR%;?ATi2=Y605NIv!t zz-{dHy!81mf-d=i-DHg*Uc7eh7s=NZ{=_JJ0Qh@TF6_V38o%5C9*lsVxPJgF#cr6zli6koOv)OVZx;z6pzV>AsFMPNAHX zFb?Q`1i4~0jgdwzYO=hT+I?XP(iJ4!Foq+Q#{$iIrc*RL>deiO-D4MZ~Vc$AwNxoVy)rIu0C5*g^x z5g(noj?zVgFyU!y&+vR_DWnueNR+b)6E2pZD7kPXtGr~RTNRqI!m08ZUZn^0N9DiP zPy&n0da%Oe%xdFa%$#V}AJr+j*wKhxy_Zr^rXp>6|cyc?j3_fe}P=N_i7S)45VD2I(0aUKpuB|GT^tWLB+ zuYGm%B5mY67qU7rrs2|chnN)@;H*WnwENuuh|MK>Y{e8Du0)XgyyMTBjC>jM)jAQ; zkHz-z=WF|%ViFcqp=$d8XiKP-iHq1D#0I3T;RLe2pxT4iG`^`R1WkH2UllpchIb5W050d38^Os;B~Np*nL(TMrqT`u{8&j(nT|Is6s7* zoK?!z=~F1ufJfZULQOy@CUr=R1Djsf%m*x}a3bdsV~~8g3_{R4|5^x$AcpojNKeRd zPaewOn8-nePQ+bcM+N&V0<`tC5bjuGb#c#h`FJtG1qrANpCMTt=8X*_$jWJHQik;2 z5ct-lA~(g;;5Y~qOdd-rffrr)R_kSotG8-2off_JMrVOgtv&48RCPl^v5_qKgs#2Z3X3~N_fW`LP9w?f@&X@J>qM8 z)g<0@!8kOangkZH!ohQ#fo1W?Rj+Zawo*v%XtU*0mES3?wiyftNP z_D(em7HzCX#}w(>)poSwA9&jrp(gEL0u*3a`oM*4@`pFa1Wb;HKPNs5+<$2~^yg&A7xY=I zF2qAJGYANQNgCpmnYmJTSZ*pcB(G@Hv7Ok>t|V{Gi5k35vk8f!YOVTa2m5P*fgQ0- zr`sw=y|C}!e>zS(;LWc~?r1Furl)yGMvYqFmc-JAaj*hP)uM*;d3)d7<)_KJ?%h23 zrflDQfUn{34j6QNm#0GZE3X$}d~S`iy<}B<_(THTX~@1vrJrXy%tpnvVtNaP5BcGa zylLvh9choR?HBM-xwC$j8~DEHP5{c9iL8cjFy_>N{bn?wCpxIp9)it@f$en36uIOo zcO7`LcS?8od6Kr+?Mz_e9xW7;!uwN82^KNo1DfYf)#gKYW!gq}cMN&!8Ck%j(%FsR zr={!lx54+9}?O>u$H0SO9&y>uG6JH)Ssfbu`u^ssz7>e~}`C)HWI+TkBaC38eJ zjL(Tol%9@umfo}J`1k{ZM0T1N?~QBy-D+C^1FpNq+}HlMUkr=Dp=oxlMhBQa6ay=Z zXd{tz8#WFlxkh!fNb&kM4j*91K=t_?=03iiIsQMRL`hc_ovoYH3hNb=k@~~pH2>o) zk;-NrMTxl2ta-Pxg+0@M2^fbZY-s4xAojpNMVV_6~VK@9Hr|5J5FVN9+{H z8**&9XtOdb!BpEgYEH`H4ujr(jNeHwv6#Eg3QOdUile@CQm{PC3l@zI<6N>TF!seksUuhRtm9vbLL?6BB~xj9I}vhs*7TLV?^I|)y@YM5dVx=Qm8sG z#mCsh)*v;fPH87-&8#>GB@ag;1NS4u-nscG5LS-5O*QXi9(I`XiEWtdF6kM@Vx}BE za)sI5ksPch4IPJa^7%rnn6s-7^Q;K{0+7BCf<^x&M*;<3Al84~j3q%uO3o&jxhXYC zK3tT*`msQcy-%LA0&V6a$s1$pC*q)au6BO<-x=@8d*0`W0`Iw=*#uK3BF$~=j>+67 z382$WU+gP8Dq}X`?r!3xe`RCfWvVc)tzi z?s7#GLptAiKe`Bv90PTjip=|oIo5vg16)zVg%vKHrqJ*PXWd{*0jM(D3uG4>10@?X z#)B(1?Qc>K1SJX~^GP$su$TZ>j%SUjF%{-F*Q>FZg zL_EUvjp;|n00mQz)vRoYKh7Q$SiF9X&{(E1Hm3A`DlwW9gw=l2vgI~R=e z%f-Ur$>V^36R4{c9Ixuq`s_6&OrF^O$x-n@lQK2E1NbQlmNASnCyK+ui-yVYC-lQ& z7q?}L9ASbg>EtR{ldT_e2`qhg{nJ^@lM2-*L`a7_-lA=N`J#@H=vTiXCnlh&oTSy- zn^#hym=Fw@IF|c1p9;`|T}(sJ>)`h17{L}agVNf&*sz5*cC4EIp1sYw|N zXi3}GIs7nS4Xehb7(m`2!hv`5@rstTe{-iSA0SjYWK&!{sC$@bPLSb^CoxAQfz;b> zWPJS`E3zh~p1?D0oMT&j;JkFGBgd@S;2yoHeFv6-%Z|xHL1ywQ+c@~At~dQ+^HcsN zC5G5{%C9R;$xoJWkMI5ACts20gIjmV(G?y9v?k??>~`(jcQj{vU~{B!U;$hCC6+uz zHwR}%7-QAdFME&6lrk+<$~b^OJg`+rJ*8-EK^ap!m1Xx6m{u3?70H{fp7j(w({JZ% zrcR)wi!<<6#}ub4<4*eyaBPJhH(+dj??z<`%lfS*fq-juKY8klC}Mk#dqy0sAb{=E!Yx%#hdJC_sfFrt^|I4#JCPaB!F(BZE^ z$zyK%MX9+6izTP?Q$?Id->08(qCpEXn<_TNzk2wX>^$Y1s}%){33G^9?7$s}|CBhS zQj#9x&Mj%%2<`aTZ?(QE(2wb58i-F)4(A)63>Q=b{jx<{sG=zRlp=QoF2TWIJTx3; z_>(_`yO0J(_S;zQK$8IAe@`G!6 zJ~mLs!I2G89k9&fbSrIZZY-DQQcXW|+G3Lp{jo`1IVo|C_o`UCMk<&q18Ch(*P$&I zZqUBfZ~G5KHc9Va8f}%p52rp7fW=Rlv-Y`ml(U2F85U~ls#kQJ!}V{?F$;bZlWHuNVWQ;PMcedQIyqo3B!0w9J|{lnt}2XH=a z9C*kDZ9PcQ^80P%lB801I{%+#`8#s^g0J!X)3`k^w-w2OKh`AJ*PMzlB)}VWzkhWv zOOvl(+-{s&TYUWe^N#l)uw0@dDSHRpGmBscjftbLt_YScttcO$Rl4&4a~6y$i(6{x zz-_e9hrub8f`J&#hi%7B)0>qaFYPz6Z?ir44=J?_OJ0`}#V5(x^Pq!?(}J~?xVmxf zrE6@r)8d}fiG8A9)n(tzGLMUB%fC*Rk&4jA(`h{JL-cuGC5Rh6!73MV1fQ)`k&w_% z8rUagCIWqf*);_~ZPRq%8@T?S3w{GFyQ{@M%w!bxAjuk=H0-8neDF>09{BF-C`f;h z>5%y``cRfL87y|`0bZ!2j~;1Ib$4Mlta4GajEOm^ViPzExL+ggMS3#&5WHgO^=o8W zTKibYMn#pmlG&zES{DxeYUL$?a=am9vCWgk4#tItVx7B9Hoe1xVZMya zvph{7e;{ZHlAi#YvBq^#NCFV6LHJpT#xHU5`<;uqAGP3g1$y{o2a z*rkh)ME^kH2{y)p91y|$Z`eklBzl=}YxC>NyYpvm(U_e=iYZ^E+owpX=WxQ9Ts?=k<=C%@+T2fh!E4^S>q# zOn;6eTqtO^`uClHEj&KCbNzoLvKkp4qgvmXfxmyC&my7t=7#)TMTAHJjGw0S^uL#e zn0(nN`S;QZHeD~`&eLfxv-9&xxBFIhHorB3Zh-m)EE{dLOw< zjk3#_qcVes2a=IjL+I?8jeX&5e0+@&+`5@LIXPR4qqcSG%Vl23Zr4M9$2iN>P5ua( zO}0rFr@0WhX_a=6yH||;%Cd5{Vg4d-$Lfk%$<>u>S!pSb7HiWyL82@77}d4Pe-@mn zc;+HJ2Kd}!pkZL3c)VC$a**Q}Z#9u6=Vp{H$=-ee%WCjDm}_SCSAD(u>q;bS55b`K zPM@3$%S-r&RBV*NX?JvI337sD}IXUN6R?33b*zJyw4!62Pd8{YM zd@qYq-w6ol8e4uUt*$OHZ1b9adbqaTX!ij++@367QM_YfD!9FkH`?s=Nc{HggLCII zpQWYc@K?s?qMDj-DJ;4Y=fJxh|KA)-JiNTqU*M1=nD`gUtEy7&x)pYWx0|=-wT+7o zXG>;}t2<@n_$xnun67Aq+#l3FRCrFlq+WaMT8*xfha>{#tb z7XA)a!CO8yE!14ia_#9^6)`13b|bQBnkClYn4d$#!{dqP<6WE-qW)?76WIzF7#NU2 zYB*}sX8ya;N4~i{HqWySxz#4eq(lH*zg^>WrgI15se=OxopGzwjp?u5PrrV>BQ(3i z@IA=(dbjV6o-OLOV(;B)wkPlVu$RgRxxlI8<@c+`&FbW~o*0^Rb-R8t66^k!o2$ZY zHI@eg*-*luSJ(7zBkTP_gsU<~K7;xRsnL*3*F_Emcyp^?msPuCu(!9TYG=n}X>C3F zXudy2?EYuS^bo@;4QGfK$o@}E(;`lPW1Z9IqklgYRb5_Pazn~D)sBGnj+Zqq3t0ib zfQbCEiH{)}t-Ho$S7!OLx}su=pVO?XHsuH2?DeGB|7+|k$j zN{4`el(dvccf-;R5)x9q~QPR_xE{TKl^I$iJ7_QoS8Fc z&dgjs#hd$0t=WN(-vZICgiC#4(BPM}cqDYJ8tIyU{ARK0w_51tUkzvS90yS2k0(Ih z95EUg8Y1>rB?y(@M5Q-1>At&$o9+aAOXTa$($-GAEF$O78Xp!iFaJ`?dZ@sV!B8;O z)FepLBL%@ogn%A)6W?c17r*YC|M>C+`?Z4u&A3dWrE34$KmsQl8(Za-i?g>X-%YWS z>(DaxZ(_zhTJJE&;gxgd&kqaPGEZWze>6LuUZLvso;(S=ZOpO@B;+yc$UxSb zaCG~ykd^?q-&{jjQp&0jzKO1&H?_RVs&xGa+S!)q@P<1pF8C{G5AN4(k!GP#z`V_^ z$O41t&F{V0U*yO4E32!&%hEr7wp?NT^3_c=TF^<{6irbLz=ac5A#>t$Au}p-#l^)N zvkvPDn9(#CE5#wIhZ_GRVyygQyO~qUjfY0<(ta;$RK2x~X75-HZHb0qyF}J3Nl)IKz@<_5{>wMr_ ztkq(JT+Qf7^Nt|3Xfx|QR{2*vea~E`w9U-&PfIVcu3sOzT}mql*^yrh#Ou`%*3$`| zWoBmLbG>CAt*LV()-m9Yz6jqUADkS2mCD?}hmp9y+O;Y+A{}+$w#@!PpZ@%vu;Z(b z5Y1}(XDaYWn@VzTIwlJ0Eke{TGtu?HtoQG?wh%O5ik_)nT{4X16?o5oWH1PatC7ZT zx(}qv($Qn+gleSq7QG8>l1U3`-Z>j;31S9xV2S-{xDxjYjMjpFfo<{v;eH zkFN3zZ?ZCpioy}Z?912eIuB!H5vdd6R_R`o6jOP-#z$69bH4nj&T8RYc-m&b`d&+}3tgO&zJ~Q? zZxK!9nz`(E)smMaJ(ay~Yg{&0Fz6%`0~3=ZHC(%X;eN~h)kIN>U$2~2Kr8yDw4#Fi z&V<_y{O%*3`uC@&Uh(lixFvs1mUpvuBRhQ$)96e?=?qzBMHMmA&KEkoHSWAOjKWvu z_&&Qz#0t&L-4_&?4aXte-pr~99KJp1JdE#XTh)9OdG(_^u$6-D;x~e$Fr%0-E~|m) zI{Hn#G=qjp3cc_>9x?VQl(CNC?U$`@Q;&Z%SYa7QsbX$l7!rgv_#T=Yf2MZ5UQ6H` z`eFfTgk-`;1?eB!*xRdx5itpc_6Fsgz8Wi#)`ek{!DgwXqQqPg@*BCDG&sFk>4tJ# zhIJW(Hx;rsaRtF=#+P(mF``DcSuUjBnGc7K&eB?KkycWVVG_D6whmopAaY!w>DZ#V$I^_)pLcIO_+khqGD^I}XPS>jg0B6QqeN;v`C?{j`ZPm+LNye}Ee;YBh8#o}5sI)94pW7@ zppdm|^Z`orBnRYEck8?t^j_y)&_{C8`((rgN?q!vb+x*sto8KXgbTp^+At?#_7*+2 zM&F*x4*6RC38|(;e>nIvs+C2t**2LR%Fz~n{1qqiAv^^z-9O!?~L z1R3vO7j0fVIA`4TTQAo<7BdgnQMwd|motbpSja%-zeJKw^-gmcZXEKTB{>o;_bVVA zIcGN7oVphhEeue>_O;yg{E*d@(B)J&WU^r6tGKlw(7a+L_rQtlsTcqxw{`N$w zgoUs%p{ca2y&^$A=7BsRU0}`i_3|HcEn2L4&1f;1Aly|qWBfs-1j;*Bi;_<$hvEbJ z8;kU6uLjnvc{ zPcv7as06(%rjS+b$;i!RL5ZlC>OpvpzAQb}MEe}A3Mh5U^Sdm3N*yhf7pjG8HZ-+N0&M%FEV z7xTV6@#Lc-qWw`3V}@4O((wlnA@Z$@$6t;!+0)7_w-(@ zXHtyNtVRL2^zSwC9=e164~ItSlKyri?&3W zgoM&toaY}Mk_1tmlN9Su1;@-d4#*HQ$gsu;S_bkO;tg1c@tsE;?NKlhHS*MiqRx1B zjF&sS39Vk&pSkaDbBtk-UVADd-A@;aOczJfk|MV4-q>7E8SPie{L)uJ=)`BfOYr;CY+|3b$B6I##f3) z(q7VTP35=Gm?>vqtz9?In3v3cw6~>ckm)L$mBq$Vbd7;Pb|o(s3V~>jps|9*;{__p zdwN+vYXys2B0TYQuqTpds_Er4&7{9sh*<;_kQ!9i5e6mmTi{d0o)c@gJ?{Dzc)p+R zo&IQ-Y9`G+FpN4D=<(WVqDXuDR(d_$(eZWZb|j=%Tn8PaifdZpcL6;q%*f!5B7*t3 z;XC9>>d!os#UA-(t+MGIDFEBePTW+Cw!{B0{lPG>-$&o9h~CXSv*%+*%{S>HbSfFF zvV=t?CH~4U;?5UP`^DW1@71`^7s-9lY9i_yaOiHD)y6?W;2wu34fjlm;Sf9Y1H!9@ zpUJ)sq>c}Zu{CLReMqoFqTlwC1#(3+%_EMm*L$87uCJ0F zI0r??;(N;?r>BSTq(P;h>^z}t=2B^@?~G1zv;DD5X-Ckdp!E6P#|$?CbD0GX?~bm) z1c_ePA46}sDpjZWx-NIKbqZ?sxZg?Ji_T{xXY%pw!pMlnU;-#2R^Ax7caR z9=aYu2Isp-^?Q1#@Skd_`1m!|X=XCPh#U@oPpc>Rg^xk=uw5%Ec>ASHIEif-qY~W4>jJ>0k;h-v>}^w{OMti~Q1ZSfFJ6C58Sbb^U>Rv^-s551 z69ZG)x>r;>-15?batMqbNP$oX03Te{hYne!>tnTKBDL>-F>@HO1hEEOh6 zYiR%Z<-mChjH2navs)(u8HljJ%MP;ppf^7A?r(S!t;~G-mRe21zG+wXO1Czo5$Z`; zWb>PNSCIWDh4XA%uPYgMPxgA@qsItnq$J*o@MK-|(fmJBo)S9#!B$FbC zlLZzMs6K=FkiNldtcNPVZ3FQN$J?wwFlkvlFHrH(wk0(_ed21!^Xmv-8m4a#BSMHt zwUWLPD}KsO`qLU8c;3EMn10guL89p~va^Jdh=iD;t^B1{VUc0f_F(_Rn`{~e-ko5) zf7@tdZ1g@`cbPRNIWb0;{g}D4v#$!ZRfv%Nw_;jOLt73=zR4b;`EYn2^9@%MH@@w_ zh3uy06FdgY3(X1t8Og%g@^3#_`!NMv9WCUEP+1wL_?A$?CmFIQdqQ54`z;lDJ($#k zSUN`wo?|(7!^+}1xcGvhnAG%^bU}PFw_Q((qLKw*zAK1+Kg7EHb89DF`3Li6(t|O_ za;kO4od(fZ9}WisrJRoPcEldketJEv{-eb?SM)gLasZPbrTk)W%LLvP1EgAc+3l!)LZ9KR2J{& ztE!e*4V6JV%4V>~?eD1f*lrfa?;DA`vJM)nuPRuhF7&je*~kZ~4pr2F^%q~B0f}*j zpUIUOhklL!G&OYsk1yBkJa*;8F-O`>u2KZ&XgSU5#%-TUvrtz zOVYdZ9B7cApZZ}R(L3+cV@MGe|9p`Gz}uv~hy={ZnW^%h*y0aH0nu_IcUH_geGsFa z>ilIe5hf@VUx;3E@ZN{@7_^3Z02snIMhgG7X4J4Ohe=&jbJRyYoOC!P`uO`Q%b?9e zcQAOMP~n*ZzvcBECoFU3cD}~oAamnsp@XTV-8be!UVi$2Xy(HK<(qd&G%k*wW zfO6%LYv{E}lW6Cl(jyEa?UK2xF#J}Ke9+`Y#mT}l`H9!IK$V>v&bN^j&#>LUFP{+&V&gwGK9b&HR!uN z?F2`3znAi4f`2>*u?EH&#;E1pDq_pR*bd9cx-IuBAF%=__qJYaTBp{9&Ois z>OYDv04@@K#o0#d!2lYmf};herLMRaQcL6D_2ieQ7Id;T7P@O((8jLH2DxZ~my+Ar z*W|Du16Y$ z)vVo%fDVdc=Y8oVM(!9uS!H(QWJ4QZvAJheZifcE;nuUjt~l zL1&Zo-n&wfsz@BBJA5Ukg>E;@tfJB7aVHkK@kFqLCSpY(qOMM>y1FXW_~Yu$7c`!v z|88l`dPQN#6)!1_m;oc`Y-9(_QItSH(2dRCSG?M+v?hGBG)2|*bT(kM^3*wk#e0|row!Z<>CT%Oz@U# zGME_rul297o%)))UuO{{74e4~13%6l%b8qRxD= z%@zY)kk@X?gXFV2?a!!dF{!;N$UR>u<5|AoonotVwMkT#XP2skzUnoy)klWmTXKJ> zsd;mP!vL9i5??9ggy$W3O=xuz+T|z(OC^Q1okQ5dUfsRvQE>sL(kJ6${N=t?OOekfl@9>i{`CTn{0fu#FMey#?CK$7 z7dhG|@#rv#VLo*Y}P_NO#RCL7yf{%Er^<#H<~X(2I!Eg&i=6qmp_H*I?z^ zX9A;jZeg;GI_sPbim~f4f0pmzVq^1GiB4GLERjJ`g$5mZ<&`KFO~yISley%1_|hU6 z3}53~db`F*fzjnXXh4Ix$UBNN6lP-q!4@2DkkEO;pN7pZ;{S6bu!&bgUA=o4v{~BO zE7@0QL>J4Sz9eG*nFY_#1mTEr(zA9uZP?r99{Wob-!irhjY8@q zbSoV=dJ(P^IK(9~iqjpiMD}puGDCk!#+^(rEvN{Yl)x z(RI=O{=ZRr1W8&5>E5&+(V@4DB}wE$t5~Ne*^T6JO24R1ug2ytrpAfj8ibxO9jgo61n=S!|CIG*OFm2DF=_*JGOCoPQ1OG zUi{-R4jGK&uhy8vlrhp{qHn@S{(iA-Q*xgSDjM*f-g2Q6k`FPxMGm$I#GKB{AN?>{ zwC>ZVe1-3IbA|ng@YJ6Zx>!i!i;-7Y$d^K}DMX&_=N8-Hoi%1=2u3Rtafq{khR&m% z!q%4N;hWXA?ny@BDTKt=VNVNd<)h%p`SmtGA~(6@-C&%5I+Jj0^g&j@@L+btC|UWf zQJWj7^N*$^Zjt3nYk?LXrC6gxF2xul42;BNuC9oypv>(yE1B;!LiS(9Lov>x{H>QE z#p2TahTC#`$_z5xFH@*fQss#nm{ScXBF{;taRGZ zVAw_nJ{F&#VROtKDUKSffq8iKth)b3*N19WIaGBc2T<~j7OW73CSIwBmI|kl)A1)=a#Pc4yJ-deD@}4JOe1OnKpSWvlku?rq3DfFUHv8D&*72JSEenHSJ@Fh z?=fdzdnY{3J1=MdpiQ^V1K*WB87X`yAdcW7ayJLp6Z@`9k(BcKxtr4tXcz10U`{p( z#>1p030|0Fyflwc;DI(0$updYp_ZSRy<8OcT=;zNb!ZqUp=b_rr8|9dWHu_RYcf2G zEIK?8fqX`}+{a7Wl-{*j7&A0K87SPg{C&_>EhgdXHkXfT4w!2F@97Zvr%3`jms z0&Zwy^5PPA6t_g4I$$jhe^URVSsfp~DbILs*rVikb~Ns!L=jfJdx@3;-o0f7Oo7Nj zdMU4GT5luPGmE}QkM;yg$L!^OX2j-&U+!AU=88C%`kyR#-bK;b8-J$!K#@i(;*?Rq znMa;S5@}JAo)|EKKxBGHp|965aF2d2lMPCNA1&G$UoDZxKBIhT=jFXjif(=3q9JQo zIqWRyt7;V=!}>Kb$wT3bC9!43_37NlC4Vro7n-`_wA|AzNLDnPuBb{=4(nA2Yh4P- zJw86^wjFR`g#Ln-7Z=;BKMD%D9MXT$bV}E*$y(9Z0K{@T5r*H}6kgK?B0QK(Tb+IF zuX!GFzd=JC6>4Kn+Y!a&{vHfck)=4tk0z$y zTM@nTto6n_X>veYx_NU*`XB^zDNt`Kdn z03J#U*N0~b`+1U79Ld)0HIwPZUBnY%!r{j(Q&jYiBcG$*lLs9v`2XNjq-;{k4SV)F zHcvEa)_*<8|2POnnGjrO{?Q=$+`uYJ9l$#V6tMSZyA@<2p%*$Uf>5X`1t!T1;jW(l z$nUT*_d4IhrF|CsRQ-`7^PIpH&bQW6$so#lEr2nBzJ)fc1wYWhPub;^9Iye?y8?bg@Iq@9HF9K!gT!2^NeZ%q5P_POT=(>+KPj1VJQNz` zqaR^(qSte<%EeD@rKT^I14?8_>FE*yc%!^gzee(voODs0d&)WnL~7hG<;b%8cWo{4 zWy7YX`_i+qS-!f)*5we5OaWP0ZF560;^#c{g51U(iph=BtvGe&-H*mJ8ZgCp&uW6c zM#tU_4$k^}TKL-F!VYzJmfL1046ClQ&ueXJ^7z44M|(fGvPtO=z679!$Tfw<1@X8zvza%ND6-x*%>W zgFkRVxK;K3{W!-Cao6+_WABNrflp0tdM?*MRSrx^XRRnso=*Z z+fyw19_n5f{^a@nFi(zP-Qm@VNJE-)OnQpdkY2QfkrAtO0Yv>##{Ez6Cs4s`e|(Hx zyuv53OkY|m+e&8?B1T=#w>UXxY@~bZ2v-vv+T4;?y_LU&W3EAFJRimlH_)eXtp=GT zrksyT2Fl0QY7`$ZQcgcMyE=Dcum>;E@wgt+j@oCPJ*HgPW8I^d7Omc4P0m#rXISq{uQha`l zuez4p_Scw@n;$rji+}?z#X!r4@@Bzw-acqkF0p7Z%lTM8J8RQ%$dn^pUi#x-^WHy4 z9CYec${68T4WOoXNm~_RJs|9j-o3Z8KhPZQ=5G_NJhwnF@ze(nH9VEU{C6^uP>eWd zvg+w}g7a-l6_H0JODKll`FJ9lNeY^Gi2Oo-nfW~*uZmc0p7RB+UR@B;c{wp$_ll{9 z(uu`l_zgUjNkf&aJ0f$0u~6%Ni8LnP-k@^44#GP3wEXj`_imBG#Y6EO0_4PS?-7{2 zm{u#~_@<7u#-5u6?w%_x_iSsy!XJM7+EAgR-7z#TyUn|p4ai6>Gob-&ajF1Zz36XreHpTAMvl%j?>;6FRM7ytt zaW|_={I~4c`^&+1bN;{qf6a?_Txdtgz2gV%nDvMCON+Mdgbp{J{xT8^IpglZYxSR( zmAO%aUw7{2l@R&izcRpu6TUv-L;r82)fG#q>V+epLa=u~ z(FojG2_xH+$ypIVa?TvCV7SNs`kLG7BogeWqp#00_`OdG4tfPl_uAT3>R_K*3Sm`y<IK?wbzv~Aml4a-5R%{o_&j-6aLE*KW8{K{}MEc=R8jU zQ^$~(oD=+~g0b9(6>jq|3%RWz`eq0F`Y@{^uWO7LO&m?XZ@e2R*ht|ZuAo~+vgjAm6{B7~G?#bgw z>nQ!5T9&^R{3Xc&R_o{<;P1nNek|NAXGvc0KQfF;&N2S$qVPD@V#-AIFFGq_I*aLR z;BO00L+1Mf8Ub90fA}g_qnFNv!158Zgjdv|MXecs+w>>izcqBdrum0i>2YHE*Zc?n zoCUKdl+qhG1Lnv6cJ>u6b~mkQ&Hk^4Una^~<{v%iSlr{1zK&Ca^uL(1Nr&mI3a93S z{?T!e%6w6}Hswg5rsVs@Br~ zU{MoqJ4^nhmp=q@cWe1g;4bz*Qk3Z}Cg*+r{l#RwKQMGur!Bev8ig?5N5=I%LL>jHVX82grRd(b`-c>Wg`<_a2mZtJHKzzHM$^NomoMS^j<$jvEL=lDIciDo z=wd24Y1weq9yR(+cym8iiMWf;szeF#pU<*bo^M#^&Isa4VEd)IkXtzANx2a z{uvect$i$5h`IKf_h{ey3KJmrwfAt#p9Wy~wzCBm9Q**kyR4!8V}So9O`ArVruQ8z zfZWr><5~U$0He0qE->Q|0Qd#?>Oax|)FnjADAZ$I0Dhq7&5i|FXJY*BMKU3nY$QNd#g*mC|~Mm5Li_2t zJHXRMqC=ADIAUOL0xqG40p-lX=n?UMujLI`w$iKjbdEj;EOBjO|H$X>0WcRcQ+rN; zUqNuBzIKuh@Qc@G*Vui41K6oXUkZHt7>2R3BbE2S!u}z^A0aqpVZtE|G)(d#=Lmq2 z2BPznX$KPE6Y8BtA;x%Af37TC#(4` z0DExpDnAa88!H1I6gcsg0l?MXfsH0u1bd)L;AeiU$cYDxtC*weD}LC+@Y)}R1 z_`t{AB^$GRcL2~%{qClWD#!wh?2fvZsb=PIfd&&!5~>+x3_xflO=1!N&K|O@-8Ab1 zFp6upd|LnrWK(+S@1ej+1@I@yi0?HBj-!$t1sE%rt7^i<* z#$6yAH-)ugY7PfzSk~noRcp!mjsYY%sCby?8v_6yH=A{^Gd<7{D>7w_1MmxS($YF! z15hP5@21jGP5_#!HYX<5-kt%DO{pfLTA~C1lzGe6w>Ro^l>tk#1I^^xj|70Fldg=` z(*wRTYyj?{;o*_51_0JsWF7&>wYpk>#EULpbj z*m=t~glhvSS%Ad;v6(q6py8FSR!DctJ%Bo_6`2D*Z|myv*4N?y#4v_wV=RFGp6>HZ zRzu_&CUCvVg7_}s2ms~ELqkm)>t$a6SWg?Tv5q|v0Gm>CFn;@6gHs4-5OvWsn3=-_ z_?vajiM3rg%W#2$(ejO02|ci@IVy7{SEC&Rdidp-5EyC6$mxH_Mh&g7zr+Eqij2cC zW~GPufN{QWWJEAM;}8sJ$m>i?z^CyyCUAq~?gc)b&DnuXe?Iw$jWr?!Hs!Z?(TctN zT%8oS`B$N*KEAurp_>eBSJ0*@pt!+BOv|ajm6k%}%L)YitWSIEjSB!H`5DD!h>|8kxwC41i@_8DnjIEdey=>?{C@1spkZYEZG8I7VPvmOE+iR@+MffRg%TJEElQ zDF#0+z4qt_dr1K3Og;8eZYs-o1eDJ!AX1P*bO2OZHBN%Fy&{7PD4#S;*FzZ-12A*- zoB)Gk*M2%eDCfz*hB%rC53pn?dtR$0^J0h+m|T6gF&^LpPC(&{^O}`q-ZDbyfVaQL zGwF{Q;M`Eup5#g@VsW?h<`?i)fg zn>oc>3J?I0XskZVgn;Xg0@NuV()H1x*t87S{koLq#HVx@Ix(B-q?$Q(LIp0tH!shQ zZHAxOVy(zYXLL0cv;zQlQ^qHI(Pcth>bGO;98(`D0Vro`Q;XDPgzg$JD|)DAfCQx< zlrv+^$K_a#(+iO5#!Elh&A9`>GBn}>4LnZVTCpreWzwZ83P8y)5{on=ySXmgz~J9Y zNxz3C!U5%7*=+u#DcRj;cX|D9s{-u6RkN;poUGyUXp_X!eDU1_i!pTo2q^XjW5F_| z#22tIe!`I(`H15HWlUgPfit9nt@W<2Jap+gWuqPa6dQQIrHg6EeyHAZ_gn$GG`G}2 zi%G9LCJ%tJ=g#U5A}gkoSmj&qg}|@R;wBs! zBYqa$A>a=@P&a=uCI$f1Y2PmrH?Yc{VvfX}&&HR$22g zK>(QLs_oP}joxT1dPl%7U7#BBp}k)S07~Ax^q2S8ciX}?@|xjTHW>q#rI;n>yL$Bl zUK|R`?+2P82TB-2LF?pBt$Y;b(3K@O4NtgB!xq(1lr1fC)`J_VEmAV+JYN=se_akc@| z&WPb%8cYBXVk`4;@Oa`e^K234)qcT7-^Tj@AF%0&datyYzh{$e@jJA6=77-*<=ioH*TfaCr zTP;+rb6G6Q=RYh^y_FEJxOCwIfKxrx0pkr9qL#1~Bbz)oO;p6!0~df^e(%`2L&BT7 z)a9lCEufL&b#jY4L7=4pZ~%+A@haF3ReK(Pl7Kl~sUMGm+|o=8t_Z!%=tGSVmdk~4 zb&SdV6GZez>D4<>K+cwMlMixau@{=RIlwY5W;VVd2++-hV2|Y{8>x@pqT?OB{$8t; znB>Ps9>FLV8*iuJByfo&nr5a%q-U`nzFy4twlc-d5+QLx`uKRL2J?WmPoGn!HzO_) zG3lMY`@9Wf2Wq$6{@zV>JxGwqa&?qTsc_pG>?$3VIGB`I-tT#%In#aY+;1|COkY@5XNiKZW zU+7g`p5C(hD|i?*mEUTD;IiLy+o95^IO;W*mO4}f7vC(TIynY$%$uAadMcpkrM-+n z_8m+s+5Id4wiaR}TogbMzBun%LnE$D&M)%$SS?&{9$$3#Wd9CEg)FzS%I4;!J}~){ z^cOa{@tu^X1^He4;*#y}y+yr#yy>dnzj}UIZgUczh$8>l%ke3fYU5`MYVt>~d?%B? z9x7zCcP!8j6>{5*_60`_+W2abZ7#yr%Sy{(@%$B@Z&%$PXS1775cvP+50-arG5We_ UBu_mZ Date: Wed, 17 Apr 2024 12:01:52 +0530 Subject: [PATCH 196/228] added val --- .../log-verification-utility/index.js | 4 +- .../schema/B2B_json_schema/v2/on_confirm.js | 1 + .../schema/B2B_json_schema/v2/on_search.js | 5 + .../schema/B2B_json_schema/v2/on_status.js | 1 + .../schema/SRV_json_schema/v2/on_search.js | 1 - .../v1.2/confirmSchema.js | 6 + .../v1.2/updateSchema.js | 45 +--- .../services/cbCheck.service.js | 11 +- .../utils/b2b/b2bOnSearch.js | 40 +++- .../utils/constants.js | 4 +- .../utils/mergeSort.js | 205 +++++++++--------- .../utils/validateLogUtil.js | 10 +- 12 files changed, 174 insertions(+), 159 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/index.js b/utilities/logistics-b2b/log-verification-utility/index.js index 1d6bf54..096c6f0 100755 --- a/utilities/logistics-b2b/log-verification-utility/index.js +++ b/utilities/logistics-b2b/log-verification-utility/index.js @@ -19,7 +19,7 @@ try { fs.readdir(logpath, (err, files) => { try { if (err) { - console.log(`Some error occurred while reading files from ${path}`); + console.trace(`Some error occurred while reading files from ${path}`); } else if (!files.length) { console.log(`${path} folder is empty!!`); } else { @@ -27,7 +27,7 @@ try { validateLog(domain, logpath); } } catch (error) { - console.log(`Error while reading logs folder`, error); + console.trace(`Error while reading logs folder`, error); } }); } catch (error) { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index e6ae899..f4e848f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -308,6 +308,7 @@ module.exports = { properties: { code: { type: "string", + enum: ["Pending"] }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index edec1b2..1b76961 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -1,3 +1,5 @@ +const constants = require("../../../utils/constants"); + module.exports = { $id: "http://example.com/schema/onSearchSchema", type: "object", @@ -698,6 +700,7 @@ module.exports = { properties: { code: { type: "string", + enum: constants.FULFILLMENT_STATE }, }, required: ["code"], @@ -720,6 +723,7 @@ module.exports = { properties: { currency: { type: "string", + enum: constants.CURRENCY }, value: { type: "string", @@ -751,6 +755,7 @@ module.exports = { properties: { code: { type: "string", + enum: constants.FULFILLMENT_STATE }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 2c63409..40af184 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -760,6 +760,7 @@ module.exports = { }, label: { type: "string", + enum:["PROFORMA_INVOICE","Invoice","INVOICE"] }, }, required: ["url", "label"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js index 3d6fb98..9047c69 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -724,7 +724,6 @@ module.exports = { "id", "parent_item_id", "descriptor", - "creator", "price", "category_ids", "fulfillment_ids", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 96402ac..99a8d12 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -908,6 +908,12 @@ module.exports = { }, value: { type: "string", + const: { + $data: + "/search/0/message/intent/@ondc~1org~1payload_details/value/value", + }, + errorMessage: + "order price mismatches from /search", }, }, required: ["currency", "value"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 4701275..44bcb8e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -374,49 +374,6 @@ module.exports = { ], }, }, - provider: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - }, - required: ["name"], - }, - address: { - type: "object", - properties: { - name: { - type: "string", - }, - locality: { - type: "string", - }, - city: { - type: "string", - }, - state: { - type: "string", - }, - area_code: { - type: "string", - }, - }, - - required: [ - "name", - "locality", - "city", - "state", - "area_code", - ], - }, - }, - required: ["descriptor", "address"], - }, order: { type: "object", properties: { @@ -485,7 +442,7 @@ module.exports = { required: ["id", "weight"], }, }, - required: ["items", "provider", "order"], + required: ["items", "order"], }, updated_at: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js b/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js index 3ef2327..c2b9555 100755 --- a/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js +++ b/utilities/logistics-b2b/log-verification-utility/services/cbCheck.service.js @@ -4,9 +4,14 @@ const vl = require("../utils/validateLogUtil"); const fs = require("fs"); const validateLog = async (domain, dirPath) => { - console.log("Inside Log Validation Service...", dirPath); - const logsPath = path.join(__dirname, "..", dirPath); - await vl.validateLogs(domain, logsPath); + try { + console.log("Inside Log Validation Service...", dirPath); + const logsPath = path.join(__dirname, "..", dirPath); + await vl.validateLogs(domain, logsPath); + } catch (error) { + console.trace("Error",error) + } + }; module.exports = { validateLog }; \ No newline at end of file diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 72b9b68..5149483 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -62,6 +62,32 @@ const checkOnSearch = async (data, msgIdSet) => { } } + try { + console.log("Checking provider serviceability"); + + let providerTags = provider?.tags; + if (providerTags) { + providerTags.forEach((tag) => { + if (tag?.descriptor?.code === "serviceability" && tag?.list) { + mandatoryTags = constants.SERVICEABILITY; + let missingTags = utils.findMissingTags( + tag?.list, + "serviceability", + mandatoryTags + ); + if (missingTags.length > 0) { + onSrchObj.mssngTagErr = `'${missingTags}' code/s required in providers/tags for serviceability`; + } + } + }); + } else { + onSrchObj.servcbltyErr = + "serviceability tag is required for a provider in providers/tags"; + } + } catch (error) { + console.log(error); + } + //checking mandatory attributes for fashion and electronics provider.items.forEach((item) => { @@ -72,8 +98,10 @@ const checkOnSearch = async (data, msgIdSet) => { itemTags.forEach((tag) => { let { descriptor, list } = tag; - if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { - + if ( + descriptor?.code === "attribute" && + constants.ATTR_DOMAINS.includes(domain) + ) { if (domain === "ONDC:RET12") { mandatoryAttr = constants.FASHION_ATTRIBUTES; } @@ -83,7 +111,12 @@ const checkOnSearch = async (data, msgIdSet) => { if (domain === "ONDC:RET12") { mandatoryAttr = constants.FASHION_ATTRIBUTES; } - if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { + if ( + domain === "ONDC:RET1A" || + domain === "ONDC:RET1B" || + domain === "ONDC:RET1C" || + domain === "ONDC:RET1D" + ) { mandatoryAttr = constants.MANDATORY_ATTRIBUTES; } attrPresent = true; @@ -114,7 +147,6 @@ const checkOnSearch = async (data, msgIdSet) => { onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; } }); - } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index fd51519..522d5ac 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -119,7 +119,7 @@ module.exports = Object.freeze({ "Fashion", "BPC", "Electronics", - "Home & Decor", + "Home & Kitchen", "Pharma", "Agriculture", "Mobility", @@ -161,6 +161,7 @@ module.exports = Object.freeze({ ], FULFILLMENT_STATE: [ "Pending", + "Packed", "Searching-for-Agent", "Agent-assigned", "Out-for-pickup", @@ -178,6 +179,7 @@ module.exports = Object.freeze({ "RTO-Disposed", "Cancelled", ], + CURRENCY:["INR","AUD","USD","SGD"], CANCELLATION_TAGS_CODES:["rto_event","precancel_state"], CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by","fulfillment_state","updated_at"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js index d0c9cab..b8ab1b6 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/mergeSort.js @@ -2,114 +2,117 @@ const fs = require("fs"); const path = require("path"); const constants = require("./constants"); -const sortMerge = (domain, directory, destination) => { - flowErrObj = {}; - try { - var mergedlogs = []; - files = fs.readdirSync(directory); + const sortMerge = (domain, directory, destination) => { - let map; - switch (domain) { - case "logistics": - map = constants.LOG_SORTED_INDEX; - break; - case "b2b": - map = constants.B2B_SORTED_INDEX; - break; - case "services": - map = constants.SRV_SORTED_INDEX; - break; - } - - mergedlogs = files.reduce((acc, item) => { - // Skip processing if the file name matches "merged.json" or "log_report.json" - if (item === "merged.json" || item === "log_report.json") { - return acc; + flowErrObj = {}; + try { + var mergedlogs = []; + + files = fs.readdirSync(directory); + + let map; + switch (domain) { + case "logistics": + map = constants.LOG_SORTED_INDEX; + break; + case "b2b": + map = constants.B2B_SORTED_INDEX; + break; + case "services": + map = constants.SRV_SORTED_INDEX; + break; } - try { - if (item.match(/\.json$/)) { - let data = fs.readFileSync(`${directory}/${item}`); - data = JSON.parse(data); - const context = data.context; - if (!context || !context.action) { - console.log( - `Error in file ${item}: Missing 'context' or 'action' property` - ); - return acc; // Skip this data and continue with the next iteration - } - const { action } = data.context; - - if (!acc[action]) { - acc[action] = []; - } - - acc[action].push(data); + + mergedlogs = files.reduce((acc, item) => { + // Skip processing if the file name matches "merged.json" or "log_report.json" + if (item === "merged.json" || item === "log_report.json") { return acc; } - } catch (error) { - console.log(`Error in file ${item}`); - console.trace(error); - } - }, {}); - - let oldLogs; - if(fs.existsSync(destination)){ - oldLogs = fs.readFileSync(destination, 'utf8'); - } - - oldLogs = oldLogs ? JSON.parse(oldLogs) : {}; - mergedlogs = { ...oldLogs, ...mergedlogs }; - - // Sort the arrays within each action based on context.timestamp - for (const action in mergedlogs) { - const array = mergedlogs[action]; - if (array.length > 1) { - array.sort( - (a, b) => - new Date(a.context.timestamp) - new Date(b.context.timestamp) - ); + try { + if (item.match(/\.json$/)) { + let data = fs.readFileSync(`${directory}/${item}`); + data = JSON.parse(data); + const context = data.context; + if (!context || !context.action) { + console.log( + `Error in file ${item}: Missing 'context' or 'action' property` + ); + return acc; // Skip this data and continue with the next iteration + } + const { action } = data.context; + + if (!acc[action]) { + acc[action] = []; + } + + acc[action].push(data); + return acc; + } + } catch (error) { + console.log(`Error in file ${item}`); + console.trace(error); + } + }, {}); + + let oldLogs; + if(fs.existsSync(destination)){ + oldLogs = fs.readFileSync(destination, 'utf8'); } - } - - // Sort the mergedlogs object based on the first element of each array's context.timestamp - const sortedmergedlogs = {}; - Object.keys(mergedlogs) - .sort( - (a, b) => - new Date(mergedlogs[a][0].context.timestamp) - - new Date(mergedlogs[b][0].context.timestamp) - ) - .forEach((key) => { - sortedmergedlogs[key] = mergedlogs[key]; - }); - - // Assign the sorted data back to mergedlogs - mergedlogs = sortedmergedlogs; - - Object.entries(mergedlogs).forEach(([action], i, entries) => { - const curAction = action; - if (map.includes(curAction)) { - const curIndex = map.indexOf(curAction); - if (i != curIndex) { - console.log( - `Flow incorrect- current action: ${action}, Current Index:${i}, Index in correct flow:${curIndex}` + + oldLogs = oldLogs ? JSON.parse(oldLogs) : {}; + mergedlogs = { ...oldLogs, ...mergedlogs }; + + // Sort the arrays within each action based on context.timestamp + for (const action in mergedlogs) { + const array = mergedlogs[action]; + if (array.length > 1) { + array.sort( + (a, b) => + new Date(a.context.timestamp) - new Date(b.context.timestamp) ); - flowErrObj[ - 0 - ] = `Incorrect Flow as per context/timestamps - (${Object.keys( - mergedlogs - )})`; - } } - }); - - fs.writeFileSync(destination, JSON.stringify(mergedlogs)); - return flowErrObj; - } catch (err) { - console.log(`Error while running merging log files, ${err}`); - console.trace(err); - } -}; + + // Sort the mergedlogs object based on the first element of each array's context.timestamp + const sortedmergedlogs = {}; + Object.keys(mergedlogs) + .sort( + (a, b) => + new Date(mergedlogs[a][0].context.timestamp) - + new Date(mergedlogs[b][0].context.timestamp) + ) + .forEach((key) => { + sortedmergedlogs[key] = mergedlogs[key]; + }); + + // Assign the sorted data back to mergedlogs + mergedlogs = sortedmergedlogs; + + Object.entries(mergedlogs).forEach(([action], i, entries) => { + const curAction = action; + if (map.includes(curAction)) { + const curIndex = map.indexOf(curAction); + if (i != curIndex) { + console.log( + `Flow incorrect- current action: ${action}, Current Index:${i}, Index in correct flow:${curIndex}` + ); + flowErrObj[ + 0 + ] = `Incorrect Flow as per context/timestamps - (${Object.keys( + mergedlogs + )})`; + + } + } + }); + + fs.writeFileSync(destination, JSON.stringify(mergedlogs)); + return flowErrObj; + } catch (err) { + console.log(`Error while running merging log files, ${err}`); + console.trace(err); + } + }; + module.exports = { sortMerge }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js index c9b6d71..e3da942 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/validateLogUtil.js @@ -17,9 +17,13 @@ const validateLogs = async (domain, dirPath, outputDestination = "") => { console.log("MERGE FILE PATH", mergefile); ErrorObj["Flow Error"] = sortMerge(domain, dirPath, mergefile); - // Log Validation - await Validate(domain, mergefile, msgIdSet, ErrorObj); - // console.log("ERROR object in validateLogUtil", ErrorObj); + try { + // Log Validation + await Validate(domain, mergefile, msgIdSet, ErrorObj); + // console.log("ERROR object in validateLogUtil", ErrorObj); + } catch (error) { + console.trace("Error", error); + } // Cleaning output report let log = clean(ErrorObj); From 158f999e662e7d37a45d308080d4fed36b80d4b9 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 23 Apr 2024 13:39:55 +0530 Subject: [PATCH 197/228] updated srv schema --- .../schema/SRV_json_schema/v2/confirm.js | 46 +++++++------------ .../schema/SRV_json_schema/v2/init.js | 15 +----- .../schema/SRV_json_schema/v2/on_cancel.js | 15 +----- .../schema/SRV_json_schema/v2/on_confirm.js | 15 +----- .../schema/SRV_json_schema/v2/on_init.js | 15 +----- .../schema/SRV_json_schema/v2/on_select.js | 15 ++++++ .../schema/SRV_json_schema/v2/on_status.js | 15 +----- .../schema/SRV_json_schema/v2/select.js | 22 +++++++-- 8 files changed, 53 insertions(+), 105 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js index 960a8ef..f02031b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js @@ -37,7 +37,7 @@ module.exports = { }, version: { type: "string", - const: "2.0.0" + const: "2.0.0", }, bap_id: { type: "string", @@ -103,7 +103,7 @@ module.exports = { }, status: { type: "string", - enum: ["Created"] + enum: ["Created"], }, provider: { type: "object", @@ -155,28 +155,11 @@ module.exports = { }, required: ["count"], }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, }, - required: ["selected", "measure"], + required: ["selected"], }, }, - required: [ - "id", - "parent_item_id", - "fulfillment_ids", - "quantity", - ], + required: ["id", "fulfillment_ids", "quantity"], }, }, billing: { @@ -331,7 +314,6 @@ module.exports = { }, required: ["start", "end"], }, - }, required: ["label", "range"], }, @@ -351,13 +333,17 @@ module.exports = { required: ["person"], }, }, - required: [ - "type", - "location", - "contact", - "time", - "customer", - ], + if: { properties: { type: { const: "end" } } }, + then: { + required: [ + "type", + "location", + "contact", + "time", + "customer", + ], + }, + else: { required: ["type"] }, }, }, }, @@ -432,7 +418,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["id", "quantity", "price"], + required: ["id"], }, }, required: ["title", "price", "item"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js index 91e3182..9d3598b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/init.js @@ -149,25 +149,12 @@ module.exports = { }, required: ["count"], }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, }, - required: ["selected", "measure"], + required: ["selected"], }, }, required: [ "id", - "parent_item_id", "fulfillment_ids", "quantity", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js index 4b31e31..effdfab 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js @@ -182,25 +182,12 @@ module.exports = { }, required: ["count"], }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, }, - required: ["selected", "measure"], + required: ["selected"], }, }, required: [ "id", - "parent_item_id", "fulfillment_ids", "quantity", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js index 3baf482..864db57 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -164,25 +164,12 @@ module.exports = { }, required: ["count"], }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, }, - required: ["selected", "measure"], + required: ["selected"], }, }, required: [ "id", - "parent_item_id", "fulfillment_ids", "quantity", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js index 9d34634..b3aa5b3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js @@ -154,25 +154,12 @@ module.exports = { }, required: ["count"], }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, }, - required: ["selected", "measure"], + required: ["selected"], }, }, required: [ "id", - "parent_item_id", "fulfillment_ids", "quantity", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js index 56b03f8..d94fe48 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js @@ -139,6 +139,21 @@ module.exports = { type: "string", }, }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, time: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js index f3f3c2a..68e1e52 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js @@ -159,25 +159,12 @@ module.exports = { }, required: ["count"], }, - measure: { - type: "object", - properties: { - unit: { - type: "string", - }, - value: { - type: "string", - }, - }, - required: ["unit", "value"], - }, }, - required: ["selected", "measure"], + required: ["selected"], }, }, required: [ "id", - "parent_item_id", "fulfillment_ids", "quantity", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js index 61b45eb..7eb4279 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/select.js @@ -137,8 +137,23 @@ module.exports = { type: "string", }, }, + quantity: { + type: "object", + properties: { + selected: { + type: "object", + properties: { + count: { + type: "integer", + }, + }, + required: ["count"], + }, + }, + required: ["selected"], + }, }, - required: ["id", "parent_item_id", "location_ids"], + required: ["id", "location_ids"], }, }, fulfillments: { @@ -186,10 +201,7 @@ module.exports = { required: ["start", "end"], }, days: { - type: "array", - items: { - type: "string", - }, + type: "string", }, }, required: ["label", "range"], From dbebce630295f2c7f5d5da765d997720226907de Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 24 Apr 2024 17:06:46 +0530 Subject: [PATCH 198/228] added b2b validations --- .../schema/B2B_json_schema/v2/on_cancel.js | 1 + .../schema/B2B_json_schema/v2/on_confirm.js | 3 + .../schema/B2B_json_schema/v2/on_init.js | 1 + .../schema/B2B_json_schema/v2/on_search.js | 1 + .../schema/B2B_json_schema/v2/on_select.js | 5 + .../schema/B2B_json_schema/v2/on_status.js | 1 + .../schema/B2B_json_schema/v2/on_update.js | 1 + .../utils/b2b/b2bOnConfirm.js | 75 ++++++++++ .../utils/b2b/b2bOnInit.js | 38 ++++- .../utils/b2b/b2bOnSearch.js | 137 +++++++++++++++++- .../utils/b2b/b2bSelect.js | 5 + .../utils/b2b/msgValidator.js | 4 +- .../utils/constants.js | 7 +- 13 files changed, 270 insertions(+), 9 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js index 097447c..61e7d5a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js @@ -70,6 +70,7 @@ module.exports = { }, ttl: { type: "string", + const:"PT30S" }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index f4e848f..02ee8dd 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -84,6 +84,7 @@ module.exports = { }, ttl: { type: "string", + const:"PT30S" }, }, required: [ @@ -318,6 +319,7 @@ module.exports = { }, type: { type: "string", + enum:["Delivery","Self-Pickup"] }, tracking: { type: "boolean", @@ -507,6 +509,7 @@ module.exports = { }, }, }, + additionalProperties: false, required: [ "id", "@ondc/org/provider_name", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index daa224a..274b811 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -85,6 +85,7 @@ module.exports = { ttl: { type: "string", format: "duration", + const:"PT30S" }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 1b76961..b6a93f7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -276,6 +276,7 @@ module.exports = { properties: { code: { type: "string", + enum: constants.VALIDCOUNTRYCODES }, }, required: ["code"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index a8d8371..2934ed2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -84,6 +84,7 @@ module.exports = { }, ttl: { type: "string", + const:"PT30S" }, }, required: [ @@ -229,6 +230,9 @@ module.exports = { id: { type: "string", }, + type: { + type: "string", + }, "@ondc/org/provider_name": { type: "string", }, @@ -325,6 +329,7 @@ module.exports = { }, }, }, + additionalProperties: false, required: [ "id", "@ondc/org/provider_name", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 40af184..5aa50a5 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -69,6 +69,7 @@ module.exports = { }, ttl: { type: "string", + const:"PT30S" }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js index cc79a88..a06269a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -68,6 +68,7 @@ module.exports = { }, ttl: { type: "string", + const:"PT30S" }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js index e69de29..0c074e1 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js @@ -0,0 +1,75 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnConfirm = async (data, msgIdSet) => { + const onConfirmObj = {}; + let onConfirm = data; + onConfirm = onConfirm.message.order; + let quote = onConfirm?.quote; + let payments = onConfirm?.payments; + let rfq = dao.getValue("rfq"); + + try { + console.log(`Checking payment object in /on_confirm api`); + payments.forEach((payment) => { + let type = payment?.type; + let collectedBy = payment?.collected_by; + let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; + let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; + + if (type === "PRE-FULFILLMENT" && collectedBy === "BPP" && rfq) { + if (!payment.uri) { + onConfirmObj.msgUri = `Payment gateway link (uri) should be sent by BPP in case of prepaid orders`; + } + if (!payment?.tags) { + onConfirmObj.msngPymntags = `/payments/tags are required for prepaid payments collected by BPP`; + } else { + payment?.tags.forEach((tag) => { + let paymentTagsSet = new Set(); + if (tag?.descriptor?.code === "BPP_payment") { + if (tag?.list) { + tag.list.forEach((val) => { + + + paymentTagsSet.add(val?.descriptor?.code); + }); + let missingTags = []; + + for (let tag of constants.BPP_PAYMENT_TAGS) { + if (!paymentTagsSet.has(tag)) { + missingTags.push(tag); + } + } + + if (missingTags.length > 0) { + onConfirmObj.missingPymntTags = `${missingTags} are required in BPP_payment tag in /payments/tags`; + } + } + } else { + onConfirmObj.msngPymntags1 = `BPP_payment tag is missing in /payments/tags`; + } + }); + } + } + if (feeType != dao.getValue("buyerFinderFeeType")) { + onConfirmObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; + } + if ( + parseFloat(feeAmount) != + parseFloat(dao.getValue("buyerFinderFeeAmount")) + ) { + onConfirmObj.feeTypeErr = `Buyer Finder Fee amount mismatches from /search`; + } + }); + } catch (error) { + console.log( + `!!Error while checking providers array in /on_Confirm api`, + error + ); + } + + return onConfirmObj; +}; +module.exports = checkOnConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index c98e5e6..2ae02bd 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -9,14 +9,50 @@ const checkOnInit = async (data, msgIdSet) => { onInit = onInit.message.order; let quote = onInit?.quote; let payments = onInit?.payments; - + let rfq = dao.getValue("rfq"); try { console.log(`Checking payment object in /on_init api`); payments.forEach((payment) => { + let type = payment?.type; + let collectedBy = payment?.collected_by; let feeType = payment["@ondc/org/buyer_app_finder_fee_type"]; let feeAmount = payment["@ondc/org/buyer_app_finder_fee_amount"]; + if (type === "PRE-FULFILLMENT" && collectedBy === "BPP" && !rfq) { + if (!payment.uri) { + onInitObj.msgUri = `Payment gateway link (uri) should be sent by BPP in case of prepaid orders`; + } + if (!payment?.tags) { + onInitObj.msngPymntags = `/payments/tags are required for prepaid payments collected by BPP`; + } else { + payment?.tags.forEach((tag) => { + let paymentTagsSet = new Set(); + if (tag?.descriptor?.code === "BPP_payment") { + if (tag?.list) { + tag.list.forEach((val) => { + + + paymentTagsSet.add(val?.descriptor?.code); + }); + let missingTags = []; + + for (let tag of constants.BPP_PAYMENT_TAGS) { + if (!paymentTagsSet.has(tag)) { + missingTags.push(tag); + } + } + + if (missingTags.length > 0) { + onInitObj.missingPymntTags = `${missingTags} are required in BPP_payment tag in /payments/tags`; + } + } + } else { + onInitObj.msngPymntags1 = `BPP_payment tag is missing in /payments/tags`; + } + }); + } + } if (feeType != dao.getValue("buyerFinderFeeType")) { onInitObj.feeTypeErr = `Buyer Finder Fee type mismatches from /search`; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 5149483..87e5fc6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -7,6 +7,7 @@ const { reverseGeoCodingCheck } = require("../reverseGeoCoding"); const checkOnSearch = async (data, msgIdSet) => { const onSrchObj = {}; let onSearch = data; + let citycode = onSearch?.context?.location?.city?.code; let domain = onSearch.context.domain; onSearch = onSearch.message.catalog; @@ -18,6 +19,7 @@ const checkOnSearch = async (data, msgIdSet) => { console.log(error); } const fulfillments = onSearch?.fulfillments; + const payments = onSearch?.payments; dao.setValue("fulfillmentsArr", fulfillments); @@ -25,8 +27,13 @@ const checkOnSearch = async (data, msgIdSet) => { console.log(`Saving provider items array in /on_search api`); if (onSearch["providers"]) { let providers = onSearch["providers"]; + dao.setValue("providersArr", providers); providers.forEach((provider, i) => { + console.log(citycode, provider?.creds); + if (citycode === "std:999" && !provider.creds) { + onSrchObj.msngCreds = `Creds are required for exports in /providers`; + } let itemsArr = provider.items; const providerId = provider.id; @@ -66,8 +73,18 @@ const checkOnSearch = async (data, msgIdSet) => { console.log("Checking provider serviceability"); let providerTags = provider?.tags; + let providerTagSet = new Set(); if (providerTags) { - providerTags.forEach((tag) => { + providerTags.forEach((tag, j) => { + if (providerTagSet.has(tag?.descriptor?.code)) { + let itemKey = `duplicatePrvdrTag${j}`; + onSrchObj[ + itemKey + ] = `${descriptor?.code} is a duplicate tag in /providers/tags`; + } else { + providerTagSet.add(tag?.descriptor?.code); + } + if (tag?.descriptor?.code === "serviceability" && tag?.list) { mandatoryTags = constants.SERVICEABILITY; let missingTags = utils.findMissingTags( @@ -80,9 +97,24 @@ const checkOnSearch = async (data, msgIdSet) => { } } }); - } else { - onSrchObj.servcbltyErr = - "serviceability tag is required for a provider in providers/tags"; + } + + let missingTags = []; + + for (let tag of constants.ON_SEARCH_PROVIDERTAGS) { + if (!providerTagSet.has(tag)) { + missingTags.push(tag); + } + } + + if (missingTags.length > 0) { + onSrchObj.missingPRVDRTags = `${missingTags} are required in /providers/tags`; + } + + if (domain === "ONDC:RET10" || domain === "ONDC:RET11") { + if (!providerTagSet.has("FSSAI_LICENSE_NO")) { + onSrchObj.fssaiErr = `For food businesses, FSSAI_LICENSE_NO is required in providers/tags`; + } } } catch (error) { console.log(error); @@ -91,13 +123,81 @@ const checkOnSearch = async (data, msgIdSet) => { //checking mandatory attributes for fashion and electronics provider.items.forEach((item) => { + let payment_ids = item.payment_ids; + let fulfillment_ids = item.fulfillment_ids; let itemTags = item?.tags; let mandatoryAttr = []; let attrPresent = false; let missingAttr = []; - itemTags.forEach((tag) => { + try { + console.log( + "Comparing fulfillment_ids in /items and /fulfillments in /on_search" + ); + + let fulfillment_ids = item.fulfillment_ids; + let fulfillmentSet = new Set(); + + for (let fulfillment of fulfillments) { + fulfillmentSet.add(fulfillment.id); + } + + let missingIds = []; + + for (let id of fulfillment_ids) { + if (!fulfillmentSet.has(id)) { + missingIds.push(id); + } + } + + if (missingIds.length > 0) { + onSrchObj.missingFlmntIds = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; + } + } catch (error) { + console.log(error); + } + + try { + console.log( + "Comparing payment_ids in /items and /payments in /on_search" + ); + + let paymentSet = new Set(); + + for (let payment of payments) { + paymentSet.add(payment.id); + } + + let missingIds = []; + + for (let id of payment_ids) { + if (!paymentSet.has(id)) { + missingIds.push(id); + } + } + + if (missingIds.length > 0) { + onSrchObj.missingpymntIds = `Payment id/s ${missingIds} in /items does not exist in /payments`; + } + } catch (error) { + console.log(error); + } + let itemTagsSet = new Set(); + itemTags.forEach((tag, i) => { let { descriptor, list } = tag; + + if ( + itemTagsSet.has(descriptor?.code) && + descriptor?.code !== "price_slab" + ) { + let itemKey = `duplicateTag${i}`; + onSrchObj[ + itemKey + ] = `${descriptor?.code} is a duplicate tag in /items/tags`; + } else { + itemTagsSet.add(descriptor?.code); + } + if ( descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain) @@ -142,7 +242,34 @@ const checkOnSearch = async (data, msgIdSet) => { onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; } } + if (descriptor?.code === "origin") { + list.forEach((tag) => { + if (tag.descriptor.code === "country") { + const alpha3Pattern = /^[A-Z]{3}$/; + console.log("origin", alpha3Pattern.test(tag?.value)); + if (!alpha3Pattern.test(tag?.value)) { + onSrchObj.originFrmtErr = `Country of origin should be in a valid 'ISO 3166-1 alpha-3' format e.g. IND, SGP`; + } else { + if (!constants.VALIDCOUNTRYCODES.includes(tag?.value)) { + onSrchObj.originFrmtErr1 = `'${tag?.value}' is not a valid 'ISO 3166-1 alpha-3' country code`; + } + } + } + }); + } }); + + let missingTags = []; + + for (let tag of constants.ON_SEEARCH_ITEMTAGS) { + if (!itemTagsSet.has(tag)) { + missingTags.push(tag); + } + } + + if (missingTags.length > 0) { + onSrchObj.missingPymntTags = `'${missingTags}' tag/s required in /items/tags`; + } if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index 9a0539f..5f91243 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -12,6 +12,11 @@ const checkSelect = async (data, msgIdSet) => { let fulfillmentsArr = dao.getValue("fulfillmentsArr"); let itemsArr = select.items; dao.setValue("slctdItemsArray",itemsArr) + let rfq = false; + + if(select?.provider?.ttl) rfq = true + + dao.setValue("rfq",rfq) // provider check try { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index ce96288..4c49fc4 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -35,8 +35,8 @@ const b2bVal = (element, action, msgIdSet) => { case "confirm": return checkConfirm(element, msgIdSet); - // case "on_confirm": - // return checkOnConfirm(element, msgIdSet); + case "on_confirm": + return checkOnConfirm(element, msgIdSet); // case "update": // return checkUpdate(element,msgIdSet); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 522d5ac..1d019a8 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -189,6 +189,11 @@ module.exports = Object.freeze({ B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"], G2TAGS:["time_to_ship","cancellable","tax_rate"], + VALIDCOUNTRYCODES:["IND","SGP","AUS","ARE","USA","GBR"], + BPP_PAYMENT_TAGS:["signature","dsa","ttl"], + ON_SEEARCH_ITEMTAGS:["g2","g3","back_image","origin","price_slab"], + ON_SEARCH_PROVIDERTAGS:["serviceability","seller_id","seller_terms"], + //services SRV_FULFILLMENT_TYPE:["Home-Service","Store-Service"], @@ -197,6 +202,6 @@ module.exports = Object.freeze({ SRV_ORDER_STATE:["Created","Accepted","In-progress","Completed","Cancelled","Pending"], GPS_PATTERN: "^(-?[0-9]{1,3}(?:.[0-9]{6,15})?),( )*?(-?[0-9]{1,3}(?:.[0-9]{6,15})?)$", SERVICEABILITY:["location","category","type","val","unit"], - RESCHEDULE_TERMS:["fulfillment_state","reschedule_eligible","reschedule_fee","reschedule_within"] + RESCHEDULE_TERMS:["fulfillment_state","reschedule_eligible","reschedule_fee","reschedule_within"], }); From de82d6124e030274ac997b81bc4668e4fbb77291 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 24 Apr 2024 17:27:37 +0530 Subject: [PATCH 199/228] added b2b val --- .../utils/b2b/b2bOnSearch.js | 59 +++++++++++++++---- .../utils/b2b/b2bOnStatus.js | 3 +- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 87e5fc6..571a5b0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -30,6 +30,7 @@ const checkOnSearch = async (data, msgIdSet) => { dao.setValue("providersArr", providers); providers.forEach((provider, i) => { + console.log(citycode, provider?.creds); if (citycode === "std:999" && !provider.creds) { onSrchObj.msngCreds = `Creds are required for exports in /providers`; @@ -108,7 +109,8 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingTags.length > 0) { - onSrchObj.missingPRVDRTags = `${missingTags} are required in /providers/tags`; + let itemKey = `missingPRVDRTags-${i}-err` + onSrchObj[itemKey] = `${missingTags} are required in /providers/tags`; } if (domain === "ONDC:RET10" || domain === "ONDC:RET11") { @@ -121,10 +123,11 @@ const checkOnSearch = async (data, msgIdSet) => { } //checking mandatory attributes for fashion and electronics - - provider.items.forEach((item) => { + let locations = provider.locations; + provider.items.forEach((item,k) => { let payment_ids = item.payment_ids; let fulfillment_ids = item.fulfillment_ids; + let location_ids= item.location_ids let itemTags = item?.tags; let mandatoryAttr = []; let attrPresent = false; @@ -151,12 +154,40 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingIds.length > 0) { - onSrchObj.missingFlmntIds = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; + let itemKey = `missingFlmntIds-${k}-err` + onSrchObj[itemKey] = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; } } catch (error) { console.log(error); } + try { + console.log( + "Comparing location_ids in /items and /providers/locations in /on_search" + ); + + + let locationSet = new Set(); + + for (let loc of locations) { + locationSet.add(loc?.id); + } + + let missingIds = []; + + for (let id of location_ids) { + if (!locationSet.has(id)) { + missingIds.push(id); + } + } + + if (missingIds.length > 0) { + let itemKey = `missingLoc-${k}-err` + onSrchObj[itemKey] = `Location id/s ${missingIds} in /items does not exist in /providers/locations`; + } + } catch (error) { + console.log(error); + } try { console.log( "Comparing payment_ids in /items and /payments in /on_search" @@ -177,7 +208,8 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingIds.length > 0) { - onSrchObj.missingpymntIds = `Payment id/s ${missingIds} in /items does not exist in /payments`; + let itemKey = `missingpymntIds-${k}-err` + onSrchObj[itemKey] = `Payment id/s ${missingIds} in /items does not exist in /payments`; } } catch (error) { console.log(error); @@ -190,7 +222,7 @@ const checkOnSearch = async (data, msgIdSet) => { itemTagsSet.has(descriptor?.code) && descriptor?.code !== "price_slab" ) { - let itemKey = `duplicateTag${i}`; + let itemKey = `duplicateTag${k}`; onSrchObj[ itemKey ] = `${descriptor?.code} is a duplicate tag in /items/tags`; @@ -227,7 +259,8 @@ const checkOnSearch = async (data, msgIdSet) => { ); if (missingAttr.length > 0) { - onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + let itemKey = `mssngAttrErr-${k}-err` + onSrchObj[itemKey] = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; } } if (descriptor?.code === "g2") { @@ -239,7 +272,8 @@ const checkOnSearch = async (data, msgIdSet) => { ); if (missingAttr.length > 0) { - onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; + let itemKey = `missingTagErr-${k}-err` + onSrchObj[itemKey] = `'${missingAttr}' required for 'g2' tag in items/tags`; } } if (descriptor?.code === "origin") { @@ -251,7 +285,8 @@ const checkOnSearch = async (data, msgIdSet) => { onSrchObj.originFrmtErr = `Country of origin should be in a valid 'ISO 3166-1 alpha-3' format e.g. IND, SGP`; } else { if (!constants.VALIDCOUNTRYCODES.includes(tag?.value)) { - onSrchObj.originFrmtErr1 = `'${tag?.value}' is not a valid 'ISO 3166-1 alpha-3' country code`; + let itemKey = `originFrmtErr1-${k}-err` + onSrchObj[itemKey] = `'${tag?.value}' is not a valid 'ISO 3166-1 alpha-3' country code`; } } } @@ -268,10 +303,12 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingTags.length > 0) { - onSrchObj.missingPymntTags = `'${missingTags}' tag/s required in /items/tags`; + let itemKey = `missingItemTags-${k}-err` + onSrchObj[itemKey] = `'${missingTags}' tag/s required in /items/tags`; } if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { - onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; + let itemKey = `attrMissing-${k}-err` + onSrchObj[itemKey] = `code = 'attribute' is missing in /items/tags for domain ${domain}`; } }); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js index bdb1ef6..9950b43 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnStatus.js @@ -17,6 +17,7 @@ const checkOnStatus = (data, msgIdSet) => { let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; let payments = on_status?.payments; let invoice = on_status?.documents; + let rfq= dao.getValue("rfq") try { console.log(`Checking payment object in /on_status`); @@ -70,7 +71,7 @@ const checkOnStatus = (data, msgIdSet) => { } } }); - if(invoice) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up for Non RFQ Flow.` + if(invoice && !rfq) onStatusObj.invoiceErr=`/documents (Invoice) is not required before order is picked up for Non RFQ Flow.` } //Order-picked-up From 44b6a3a38abd1a4afa1701dac16aedfe1f31977d Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 24 Apr 2024 18:07:48 +0530 Subject: [PATCH 200/228] updated b2b vals --- .../utils/b2b/b2bInit.js | 24 +++++++++++++------ .../utils/b2b/b2bOnInit.js | 9 +++++++ .../utils/b2b/b2bOnSearch.js | 2 +- .../utils/b2b/b2bOnSelect.js | 6 +++++ .../utils/b2b/b2bSelect.js | 13 +++++++--- 5 files changed, 43 insertions(+), 11 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js index dfe3580..a5e0f59 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bInit.js @@ -6,22 +6,32 @@ const utils = require("../utils"); const checkInit = (data, msgIdSet) => { const initObj = {}; let init = data; + let citycode = init?.context?.location?.city?.code; init = init.message.order; let items = init.items; + let fulfillments = init.fulfillments; const selectedItems = dao.getValue("onSlctdItemsArray"); try { - console.log("Comparing items object with /on_select"); + console.log("Comparing items and fulfillments object with /on_select"); + fulfillments.forEach((fulfillment, i) => { + let fulfillmentTags = fulfillment?.tags; + + if (citycode === "std:999" && !fulfillmentTags) { + selectObj.fullfntTagErr = `Delivery terms (INCOTERMS) are required for exports in /fulfillments/tags`; + } + }); + const itemDiff = utils.findDifferencesInArrays(items, selectedItems); console.log(itemDiff); itemDiff.forEach((item, i) => { - if(item?.attributes?.length>0){ - let itemkey = `item-${i}-DiffErr`; - initObj[ - itemkey - ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; - } + if (item?.attributes?.length > 0) { + let itemkey = `item-${i}-DiffErr`; + initObj[ + itemkey + ] = `In /items, '${item.attributes}' mismatch from /on_select for item with id ${item.index}`; + } }); } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js index 2ae02bd..362842c 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnInit.js @@ -6,11 +6,20 @@ const utils = require("../utils"); const checkOnInit = async (data, msgIdSet) => { const onInitObj = {}; let onInit = data; + let citycode = onInit?.context?.location?.city?.code; onInit = onInit.message.order; let quote = onInit?.quote; + let fulfillments= onInit.fulfillments let payments = onInit?.payments; let rfq = dao.getValue("rfq"); + fulfillments.forEach((fulfillment, i) => { + let fulfillmentTags = fulfillment?.tags; + + if (citycode === "std:999" && !fulfillmentTags) { + selectObj.fullfntTagErr = `Delivery terms (INCOTERMS) are required for exports in /fulfillments/tags`; + } + }); try { console.log(`Checking payment object in /on_init api`); payments.forEach((payment) => { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index 571a5b0..f1c6cdb 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -114,7 +114,7 @@ const checkOnSearch = async (data, msgIdSet) => { } if (domain === "ONDC:RET10" || domain === "ONDC:RET11") { - if (!providerTagSet.has("FSSAI_LICENSE_NO")) { + if (!providerTagSet.has("FSSAI_LICENSE_NO") && citycode!=="std:999") { onSrchObj.fssaiErr = `For food businesses, FSSAI_LICENSE_NO is required in providers/tags`; } } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 56642d3..34b0eb7 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -6,6 +6,7 @@ const utils = require("../utils"); const checkOnSelect = async (data, msgIdSet) => { const onSelectObj = {}; let onSelect = data; + let citycode = onSelect?.context?.location?.city?.code; onSelect = onSelect.message.order; let quote = onSelect?.quote; const items = onSelect.items; @@ -19,6 +20,11 @@ const checkOnSelect = async (data, msgIdSet) => { console.log("Checking fulfillment object in /on_select"); if (fulfillments) { fulfillments.forEach((fulfillment) => { + let fulfillmentTags = fulfillment?.tags; + + if (citycode === "std:999" && !fulfillmentTags) { + onSelectObj.fullfntTagErr = `Delivery terms (INCOTERMS) are required for exports in /fulfillments/tags`; + } ffId = fulfillment?.id; ffState = fulfillment?.state?.descriptor?.code; }); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index 5f91243..a547af9 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -6,17 +6,19 @@ const utils = require("../utils"); const checkSelect = async (data, msgIdSet) => { const selectObj = {}; let select = data; + let citycode = select?.context?.location?.city?.code; select = select.message.order; let fulfillments = select?.fulfillments; + let providersArr = dao.getValue("providersArr"); let fulfillmentsArr = dao.getValue("fulfillmentsArr"); let itemsArr = select.items; - dao.setValue("slctdItemsArray",itemsArr) + dao.setValue("slctdItemsArray", itemsArr); let rfq = false; - if(select?.provider?.ttl) rfq = true + if (select?.provider?.ttl) rfq = true; - dao.setValue("rfq",rfq) + dao.setValue("rfq", rfq); // provider check try { @@ -108,6 +110,11 @@ const checkSelect = async (data, msgIdSet) => { //checking fulfillments fulfillments.forEach((fulfillment, i) => { + let fulfillmentTags = fulfillment?.tags; + + if (citycode === "std:999" && !fulfillmentTags) { + selectObj.fullfntTagErr = `Delivery terms (INCOTERMS) are required for exports in /fulfillments/tags`; + } let bppfulfillment = fulfillmentsArr?.find( (element) => element.id === fulfillment.id ); From d278c3432a99b80ab64ca69edab4cf8298764432 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 25 Apr 2024 10:49:53 +0530 Subject: [PATCH 201/228] updated b2b schema and business vals --- .../schema/B2B_json_schema/v1/confirm.js | 6 +- .../schema/B2B_json_schema/v1/init.js | 6 +- .../schema/B2B_json_schema/v1/on_confirm.js | 6 +- .../schema/B2B_json_schema/v1/on_search.js | 6 +- .../schema/B2B_json_schema/v1/on_status.js | 6 +- .../schema/B2B_json_schema/v1/select.js | 6 +- .../schema/B2B_json_schema/v2/confirm.js | 6 +- .../schema/B2B_json_schema/v2/init.js | 6 +- .../schema/B2B_json_schema/v2/on_cancel.js | 15 ++--- .../schema/B2B_json_schema/v2/on_confirm.js | 6 +- .../schema/B2B_json_schema/v2/on_init.js | 6 +- .../schema/B2B_json_schema/v2/on_search.js | 12 +--- .../schema/B2B_json_schema/v2/on_select.js | 6 +- .../schema/B2B_json_schema/v2/on_status.js | 6 +- .../schema/B2B_json_schema/v2/select.js | 6 +- .../v1.2/onCancelSchema.js | 63 ++++++++++++------- .../utils/b2b/b2bOnSearch.js | 61 +++++++++++------- .../utils/constants.js | 3 +- 18 files changed, 102 insertions(+), 130 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js index 7406994..fc43706 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/confirm.js @@ -604,11 +604,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js index 36e4048..601c138 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/init.js @@ -471,11 +471,7 @@ module.exports = { properties: { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js index d6fef76..268838d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_confirm.js @@ -656,11 +656,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js index 461cb7c..d19c740 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_search.js @@ -132,11 +132,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, }, required: ["id", "type"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js index 4d202a2..462b745 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/on_status.js @@ -600,11 +600,7 @@ module.exports = { const: { $data: "/on_confirm/0/message/order/payments/0/type", }, - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, collected_by: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js index 8e18120..ed4c820 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v1/select.js @@ -364,11 +364,7 @@ module.exports = { properties: { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 952da95..5cf1cb6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -634,11 +634,7 @@ module.exports = { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index ce1c1f2..3c1c33e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -493,11 +493,7 @@ module.exports = { properties: { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js index 61e7d5a..52d8029 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js @@ -70,7 +70,7 @@ module.exports = { }, ttl: { type: "string", - const:"PT30S" + const: "PT30S", }, }, required: [ @@ -546,9 +546,6 @@ module.exports = { items: { type: "object", properties: { - id: { - type: "string", - }, params: { type: "object", properties: { @@ -560,6 +557,9 @@ module.exports = { }, amount: { type: "string", + const: { $data: "4/quote/price/value" }, + errorMessage: + "should be updated to updated quote price - ${4/quote/price/value}", }, }, required: ["currency", "amount"], @@ -570,11 +570,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum: constants.B2B_PAYMENT_TYPE, const: { $data: "/on_confirm/0/message/order/payments/0/type", @@ -700,7 +696,6 @@ module.exports = { }, }, required: [ - "id", "params", "status", "type", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js index 02ee8dd..b0584db 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_confirm.js @@ -663,11 +663,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js index 274b811..0e0cf5e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_init.js @@ -599,11 +599,7 @@ module.exports = { properties: { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, const: { $data: "/select/0/message/order/payments/0/type" }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index b6a93f7..828207a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -134,11 +134,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum: constants.B2B_PAYMENT_TYPE }, collected_by:{ type: "string", @@ -1016,11 +1012,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum: constants.B2B_PAYMENT_TYPE }, collected_by:{ type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js index 2934ed2..d262c46 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_select.js @@ -471,11 +471,7 @@ module.exports = { properties: { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index 5aa50a5..d2e850a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -608,11 +608,7 @@ module.exports = { }, type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, const: { $data: "/on_confirm/0/message/order/payments/0/type", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index 87ba678..af598a3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -382,11 +382,7 @@ module.exports = { properties: { type: { type: "string", - enum: [ - "PRE-FULFILLMENT", - "ON-FULFILLMENT", - "POST-FULFILLMENT", - ], + enum : constants.B2B_PAYMENT_TYPE, }, }, required: ["type"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 4f4e201..9ad4b3e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -210,7 +210,6 @@ module.exports = { }, required: ["price", "breakup"], isQuoteMatching: true, - }, fulfillments: { @@ -233,10 +232,7 @@ module.exports = { properties: { code: { type: "string", - enum: [ - "Cancelled", - "RTO-Initiated" - ], + enum: ["Cancelled", "RTO-Initiated"], }, }, required: ["code"], @@ -265,21 +261,27 @@ module.exports = { properties: { start: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start"], }, timestamp: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, }, @@ -354,7 +356,6 @@ module.exports = { }, }, isLengthValid: true, - }, }, required: ["gps", "address"], @@ -386,21 +387,27 @@ module.exports = { properties: { start: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, end: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, required: ["start"], }, timestamp: { type: "string", - pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", - errorMessage:"should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format" + pattern: + "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", + errorMessage: + "should be in RFC 3339 (YYYY-MM-DDTHH:MN:SS.MSSZ) Format", }, }, }, @@ -475,7 +482,6 @@ module.exports = { }, }, isLengthValid: true, - }, }, required: ["gps", "address"], @@ -553,7 +559,7 @@ module.exports = { properties: { time: { required: ["range"] }, }, - required: [ "person", "location", "contact"], + required: ["person", "location", "contact"], }, end: { @@ -588,7 +594,7 @@ module.exports = { }, ], }, - payment: { + payments: { type: "object", properties: { "@ondc/org/collection_amount": { @@ -610,6 +616,19 @@ module.exports = { $data: "/on_confirm/0/message/order/payment/collected_by", }, }, + params: { + type: "object", + properties: { + amount: { + type: "string", + }, + currency: { + type: "string", + }, + }, + required: ["amount", "currency"], + }, + time: { type: "object", properties: { @@ -718,7 +737,7 @@ module.exports = { "provider", "fulfillments", "billing", - "payment", + "payments", "@ondc/org/linked_order", "created_at", "updated_at", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index f1c6cdb..c733ca7 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -30,7 +30,6 @@ const checkOnSearch = async (data, msgIdSet) => { dao.setValue("providersArr", providers); providers.forEach((provider, i) => { - console.log(citycode, provider?.creds); if (citycode === "std:999" && !provider.creds) { onSrchObj.msngCreds = `Creds are required for exports in /providers`; @@ -109,12 +108,15 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingTags.length > 0) { - let itemKey = `missingPRVDRTags-${i}-err` + let itemKey = `missingPRVDRTags-${i}-err`; onSrchObj[itemKey] = `${missingTags} are required in /providers/tags`; } if (domain === "ONDC:RET10" || domain === "ONDC:RET11") { - if (!providerTagSet.has("FSSAI_LICENSE_NO") && citycode!=="std:999") { + if ( + !providerTagSet.has("FSSAI_LICENSE_NO") && + citycode !== "std:999" + ) { onSrchObj.fssaiErr = `For food businesses, FSSAI_LICENSE_NO is required in providers/tags`; } } @@ -124,10 +126,10 @@ const checkOnSearch = async (data, msgIdSet) => { //checking mandatory attributes for fashion and electronics let locations = provider.locations; - provider.items.forEach((item,k) => { + provider.items.forEach((item, k) => { let payment_ids = item.payment_ids; let fulfillment_ids = item.fulfillment_ids; - let location_ids= item.location_ids + let location_ids = item.location_ids; let itemTags = item?.tags; let mandatoryAttr = []; let attrPresent = false; @@ -154,8 +156,10 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingIds.length > 0) { - let itemKey = `missingFlmntIds-${k}-err` - onSrchObj[itemKey] = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; + let itemKey = `missingFlmntIds-${k}-err`; + onSrchObj[ + itemKey + ] = `Fulfillment id/s ${missingIds} in /items does not exist in /fulfillments`; } } catch (error) { console.log(error); @@ -166,7 +170,6 @@ const checkOnSearch = async (data, msgIdSet) => { "Comparing location_ids in /items and /providers/locations in /on_search" ); - let locationSet = new Set(); for (let loc of locations) { @@ -182,8 +185,10 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingIds.length > 0) { - let itemKey = `missingLoc-${k}-err` - onSrchObj[itemKey] = `Location id/s ${missingIds} in /items does not exist in /providers/locations`; + let itemKey = `missingLoc-${k}-err`; + onSrchObj[ + itemKey + ] = `Location id/s ${missingIds} in /items does not exist in /providers/locations`; } } catch (error) { console.log(error); @@ -208,8 +213,10 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingIds.length > 0) { - let itemKey = `missingpymntIds-${k}-err` - onSrchObj[itemKey] = `Payment id/s ${missingIds} in /items does not exist in /payments`; + let itemKey = `missingpymntIds-${k}-err`; + onSrchObj[ + itemKey + ] = `Payment id/s ${missingIds} in /items does not exist in /payments`; } } catch (error) { console.log(error); @@ -259,8 +266,10 @@ const checkOnSearch = async (data, msgIdSet) => { ); if (missingAttr.length > 0) { - let itemKey = `mssngAttrErr-${k}-err` - onSrchObj[itemKey] = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; + let itemKey = `mssngAttrErr-${k}-err`; + onSrchObj[ + itemKey + ] = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; } } if (descriptor?.code === "g2") { @@ -272,8 +281,10 @@ const checkOnSearch = async (data, msgIdSet) => { ); if (missingAttr.length > 0) { - let itemKey = `missingTagErr-${k}-err` - onSrchObj[itemKey] = `'${missingAttr}' required for 'g2' tag in items/tags`; + let itemKey = `missingTagErr-${k}-err`; + onSrchObj[ + itemKey + ] = `'${missingAttr}' required for 'g2' tag in items/tags`; } } if (descriptor?.code === "origin") { @@ -285,8 +296,10 @@ const checkOnSearch = async (data, msgIdSet) => { onSrchObj.originFrmtErr = `Country of origin should be in a valid 'ISO 3166-1 alpha-3' format e.g. IND, SGP`; } else { if (!constants.VALIDCOUNTRYCODES.includes(tag?.value)) { - let itemKey = `originFrmtErr1-${k}-err` - onSrchObj[itemKey] = `'${tag?.value}' is not a valid 'ISO 3166-1 alpha-3' country code`; + let itemKey = `originFrmtErr1-${k}-err`; + onSrchObj[ + itemKey + ] = `'${tag?.value}' is not a valid 'ISO 3166-1 alpha-3' country code`; } } } @@ -303,12 +316,16 @@ const checkOnSearch = async (data, msgIdSet) => { } if (missingTags.length > 0) { - let itemKey = `missingItemTags-${k}-err` - onSrchObj[itemKey] = `'${missingTags}' tag/s required in /items/tags`; + let itemKey = `missingItemTags-${k}-err`; + onSrchObj[ + itemKey + ] = `'${missingTags}' tag/s required in /items/tags`; } if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { - let itemKey = `attrMissing-${k}-err` - onSrchObj[itemKey] = `code = 'attribute' is missing in /items/tags for domain ${domain}`; + let itemKey = `attrMissing-${k}-err`; + onSrchObj[ + itemKey + ] = `code = 'attribute' is missing in /items/tags for domain ${domain}`; } }); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 1d019a8..57a04a3 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -191,8 +191,9 @@ module.exports = Object.freeze({ G2TAGS:["time_to_ship","cancellable","tax_rate"], VALIDCOUNTRYCODES:["IND","SGP","AUS","ARE","USA","GBR"], BPP_PAYMENT_TAGS:["signature","dsa","ttl"], - ON_SEEARCH_ITEMTAGS:["g2","g3","back_image","origin","price_slab"], + ON_SEEARCH_ITEMTAGS:["g2","g3","back_image","origin"], ON_SEARCH_PROVIDERTAGS:["serviceability","seller_id","seller_terms"], + B2B_PAYMENT_TYPE:["PRE-FULFILLMENT","ON-FULFILLMENT"], //services From 180bfdfa06f88e317ad2c04009e07255c14be19c Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 25 Apr 2024 10:55:02 +0530 Subject: [PATCH 202/228] updated --- .../schema/B2B_json_schema/v2/on_status.js | 1 + .../schema/B2B_json_schema/v2/on_update.js | 1 + .../log-verification-utility/schema/B2B_json_schema/v2/select.js | 1 + .../schema/logistics_api_json_schema/v1.2/cancelSchema.js | 1 + .../schema/logistics_api_json_schema/v1.2/onSupportSchema.js | 1 + .../schema/logistics_api_json_schema/v1.2/statusSchema.js | 1 + .../schema/logistics_api_json_schema/v1.2/supportSchema.js | 1 + .../schema/logistics_api_json_schema/v1.2/trackSchema.js | 1 + .../schema/logistics_api_json_schema/v1.2/updateSchema.js | 1 + 9 files changed, 9 insertions(+) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js index d2e850a..cfc45e4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_status.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onStatusSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js index a06269a..62e9145 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_update.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onUpdateSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index af598a3..b54f9ed 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/selectSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js index 5e38d72..3d6166e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/cancelSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js index ce2c9d3..36add54 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSupportSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/onSupportSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js index 779d729..a6837da 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/statusSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/statusSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js index 474fa1a..9e9fd12 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/supportSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/supportSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js index 0f9d5b3..2dbc121 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/trackSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/trackSchema", type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 44bcb8e..e9fee7d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); const { PCC_CODE, DCC_CODE, From f2bfd955b4a7a747451b3192fdfc3770ee740059 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 25 Apr 2024 11:29:08 +0530 Subject: [PATCH 203/228] fixed bugs --- .../schema/SRV_json_schema/v2/on_select.js | 2 +- .../schema/logistics_api_json_schema/v1.2/updateSchema.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js index d94fe48..367a83f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_select.js @@ -310,7 +310,7 @@ module.exports = { required: ["descriptor", "list"], }, }, - required: ["type", "location", "time", "tags"], + required: ["type", "location", "time"], }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index e9fee7d..689c6f6 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -1,4 +1,4 @@ -const constants = require("../../../utils/constants"); + const { PCC_CODE, DCC_CODE, From ffbf5e5c2ea006a16e593f029d76f35f1af91875 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 25 Apr 2024 14:51:55 +0530 Subject: [PATCH 204/228] added logistics vals --- .../utils/constants.js | 1 + .../utils/logistics/logConfirm.js | 21 +++++++- .../utils/logistics/logOnCancel.js | 52 ++++++++++++++++--- .../log-verification-utility/utils/utils.js | 10 ++++ 4 files changed, 75 insertions(+), 9 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index 57a04a3..b0cb711 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -181,6 +181,7 @@ module.exports = Object.freeze({ ], CURRENCY:["INR","AUD","USD","SGD"], CANCELLATION_TAGS_CODES:["rto_event","precancel_state"], + RTO_EVENT_TAGS:["retry_count","rto_id","cancellation_reason_id","cancelled_by"], CANCELLATION_TAGS_LIST:["retry_count","rto_id","cancellation_reason_id","sub_reason_id","cancelled_by","fulfillment_state","updated_at"], FASHION_ATTRIBUTES : ["brand","colour","size","gender","material"], ELECTRONICS_ATTRIBUTES: ["brand","model"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 9872852..72dbacd 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -8,6 +8,7 @@ const checkConfirm = (data, msgIdSet) => { let confirm = data; const contextTimestamp= confirm.context.timestamp let version = confirm.context.core_version; + let missingTags =[]; let onSearchProvArr = dao.getValue("providersArr"); confirm = confirm.message.order; let rts; @@ -71,7 +72,9 @@ const checkConfirm = (data, msgIdSet) => { let fulfillments = confirm.fulfillments; let p2h2p = dao.getValue("p2h2p"); - fulfillments.forEach((fulfillment) => { + let fulfillmentTagSet = new Set(); + fulfillments.forEach((fulfillment,i) => { + let fulfillmentTags = fulfillment?.tags; let avgPickupTime= fulfillment?.start?.time?.duration; console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ @@ -81,6 +84,22 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); if (rts === "yes" && !fulfillment?.start?.instructions?.short_desc) { cnfrmObj.instructionsErr = `fulfillments/start/instructions are required when ready_to_ship = 'yes'`; } + reqFulTags = ["rto_action","state"] + //checking tags + if (fulfillmentTags) { + fulfillmentTags.forEach((tag) => { + let { code, list } = tag; + fulfillmentTagSet.add(code); + }) + + missingTags= utils.findRequiredTags(fulfillmentTagSet,reqFulTags) + if (missingTags.length > 0) { + let itemKey = `missingFlmntTags-${i}-err`; + cnfrmObj[ + itemKey + ] = `'${missingTags}' tag/s required in /fulfillments/tags`; + } + } }); try { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index a0ac04c..43b7a54 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -18,7 +18,7 @@ const checkOnCancel = (data, msgIdSet) => { let items = on_cancel.items; let fulfillments = on_cancel.fulfillments; let RtoPickupTime; - + let missingTags = []; const created_at = on_cancel.created_at; const updated_at = on_cancel.updated_at; @@ -51,9 +51,11 @@ const checkOnCancel = (data, msgIdSet) => { ); selectedItem = selectedItem[0]; } - + let fulfillmentTagSet = new Set(); try { - fulfillments.forEach((fulfillment) => { + fulfillments.forEach((fulfillment, i) => { + let fulfillmentTags = fulfillment?.tags; + ffState = fulfillment?.state?.descriptor?.code; console.log( `Comparing pickup and delivery timestamps for on_cancel_${ffState}` @@ -102,7 +104,7 @@ const checkOnCancel = (data, msgIdSet) => { if (!fulTags) { onCancelObj.msngflfllmntTags = `fulfillments/tags are required in case of RTO (rto_event, precancel_state)`; } else { - let rtoID, reasonId,preCnclState; + let rtoID, reasonId, preCnclState; fulTags.forEach((tag) => { if (tag.code === "rto_event") { @@ -123,13 +125,12 @@ const checkOnCancel = (data, msgIdSet) => { } }); } - if(tag.code === "precancel_state"){ - + if (tag.code === "precancel_state") { const lists = tag.list; lists.forEach((list) => { if (list.code === "fulfillment_state") { preCnclState = list.value; - + if (!constants.FULFILLMENT_STATE.includes(preCnclState)) { onCancelObj.preCnclStateErr = `${preCnclState} is not a valid precancel state in fulfillments/tags`; } @@ -161,9 +162,44 @@ const checkOnCancel = (data, msgIdSet) => { } } } + + //checking tags + let rtoEventTagSet = new Set(); + if (fulfillmentTags) { + fulfillmentTags.forEach((tag, i) => { + let { code, list } = tag; + fulfillmentTagSet.add(code); + if (code === "rto_event") { + list.forEach((childTag) => { + rtoEventTagSet.add(childTag.code); + }); + + missingTags = utils.findRequiredTags( + rtoEventTagSet, + constants.RTO_EVENT_TAGS + ); + if (missingTags.length > 0) { + let itemKey = `missingRtoEventTags-${i}-err`; + onCancelObj[ + itemKey + ] = `'${missingTags}' tag/s required in rto_event tag in /fulfillments/tags`; + } + } + }); + missingTags = utils.findRequiredTags( + fulfillmentTagSet, + constants.CANCELLATION_TAGS_CODES + ); + if (missingTags.length > 0) { + let itemKey = `missingFlmntTags-${i}-err`; + onCancelObj[ + itemKey + ] = `'${missingTags}' tag/s required in /fulfillments/tags`; + } + } }); } catch (error) { - console.trace(`Error checking fulfillments/start in /on_cancel`,error); + console.trace(`Error checking fulfillments/start in /on_cancel`, error); } return onCancelObj; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/utils.js b/utilities/logistics-b2b/log-verification-utility/utils/utils.js index 5859a05..333c536 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/utils.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/utils.js @@ -408,7 +408,16 @@ function findDifferencesInArrays(array1, array2) { return differences; } +const findRequiredTags=(list,mandatory)=>{ + let missingTags = []; + for (let id of mandatory) { + if (!list.has(id)) { + missingTags.push(id); + } + } + return missingTags; +} const findMissingTags = (list, code, mandatoryAttr) => { const encounteredAttr = []; list.map(({ descriptor, value }) => { @@ -448,5 +457,6 @@ module.exports = { findDifferencesInArrays, grocery_categories_id, fnb_categories_id, + findRequiredTags, findMissingTags, }; From 478377de9eb1769e63d6bd570637fa23e79ceac5 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 29 Apr 2024 14:12:43 +0530 Subject: [PATCH 205/228] updated checks --- .../schema/SRV_json_schema/v2/confirm.js | 1 - .../schema/SRV_json_schema/v2/on_cancel.js | 17 ++-- .../schema/SRV_json_schema/v2/on_confirm.js | 20 ++--- .../schema/SRV_json_schema/v2/on_init.js | 81 ++++++++++++++++--- .../schema/SRV_json_schema/v2/on_status.js | 23 +++--- .../schema/SRV_json_schema/v2/on_update.js | 19 +++-- .../v1.2/onCancelSchema.js | 4 +- .../v1.2/updateSchema.js | 2 +- .../utils/constants.js | 6 +- .../utils/logistics/logOnCancel.js | 7 +- 10 files changed, 130 insertions(+), 50 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js index f02031b..f40d20b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/confirm.js @@ -464,7 +464,6 @@ module.exports = { required: [ "amount", "currency", - "transaction_id", "bank_account_number", "virtual_payment_address", ], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js index effdfab..af9e254 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_cancel.js @@ -379,13 +379,16 @@ module.exports = { required: ["name"], }, }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], + if: { properties: { type: { const: "end" } } }, + then: { + required: [ + "type", + "location", + "contact", + "time" + ], + }, + else: { required: ["type"] }, }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js index 864db57..b3bd0a1 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_confirm.js @@ -360,14 +360,16 @@ module.exports = { required: ["name"], }, }, - required: [ - "id", - "type", - "location", - "time", - "contact", - "person", - ], + if: { properties: { type: { const: "end" } } }, + then: { + required: [ + "type", + "location", + "contact", + "time" + ], + }, + else: { required: ["type"] }, }, }, rateable: { @@ -452,7 +454,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["id", "quantity", "price"], + required: ["id"], }, tags: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js index b3aa5b3..3126ae4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_init.js @@ -38,7 +38,7 @@ module.exports = { }, version: { type: "string", - const: "2.0.0" + const: "2.0.0", }, bap_id: { type: "string", @@ -158,11 +158,7 @@ module.exports = { required: ["selected"], }, }, - required: [ - "id", - "fulfillment_ids", - "quantity", - ], + required: ["id", "fulfillment_ids", "quantity"], }, }, billing: { @@ -314,7 +310,6 @@ module.exports = { }, required: ["start", "end"], }, - }, required: ["label", "range"], }, @@ -355,7 +350,13 @@ module.exports = { required: ["descriptor", "list"], }, }, - required: ["type", "location", "contact", "time", "tags"], + if: { properties: { type: { const: "end" } } }, + then: { + required: ["type", "location", "contact", "time"], + }, + else: { + required: ["type"], + }, }, }, }, @@ -430,7 +431,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["id", "quantity", "price"], + required: ["id"], }, tags: { type: "array", @@ -481,6 +482,65 @@ module.exports = { }, required: ["price", "breakup", "ttl"], }, + cancellation_terms: { + type: "array", + items: { + type: "object", + properties: { + fulfillment_state: { + type: "object", + properties: { + descriptor: { + type: "object", + properties: { + code: { + type: "string", + }, + }, + required: ["code"], + }, + }, + required: ["descriptor"], + }, + cancel_by: { + type: "object", + properties: { + duration: { + type: "string", + }, + }, + required: ["duration"], + }, + cancellation_fee: { + type: "object", + properties: { + amount: { + type: "object", + properties: { + value: { + type: "string", + }, + }, + required: ["value"], + }, + percentage: { + type: "string", + }, + }, + }, + reason_required: { + type: "boolean", + }, + }, + required: [ + "fulfillment_state", + "cancel_by", + "cancellation_fee", + "reason_required", + ], + }, + }, + payments: { type: "array", items: { @@ -589,10 +649,11 @@ module.exports = { "provider", "locations", "items", + "cancellation_terms", "billing", "fulfillments", "quote", - "payments" + "payments", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js index 68e1e52..51048e4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_status.js @@ -356,13 +356,16 @@ module.exports = { required: ["name"], }, }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], + if: { properties: { type: { const: "end" } } }, + then: { + required: [ + "type", + "location", + "contact", + "time" + ], + }, + else: { required: ["type"] }, }, }, }, @@ -437,7 +440,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["id", "quantity", "price"], + required: ["id"], }, tags: { type: "array", @@ -609,8 +612,8 @@ module.exports = { updated_at: { type: "string", format: "date-time", - not: { const: { $data: "/confirm/0/message/order/created_at" } }, - errorMessage: "should not be same as 'created_at'", + not: { const: { $data: "1/created_at" } }, + errorMessage: "should not be same as 'created_at - ${1/created_at}'", }, }, required: [ diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js index b217a7a..854461c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_update.js @@ -368,13 +368,16 @@ module.exports = { required: ["name"], }, }, - required: [ - "type", - "location", - "time", - "contact", - "person", - ], + if: { properties: { type: { const: "end" } } }, + then: { + required: [ + "type", + "location", + "contact", + "time" + ], + }, + else: { required: ["type"] }, }, }, rateable: { @@ -438,7 +441,7 @@ module.exports = { required: ["currency", "value"], }, }, - required: ["id", "price"], + required: ["id"], }, tags: { type: "array", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 9ad4b3e..28c8054 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -594,7 +594,7 @@ module.exports = { }, ], }, - payments: { + payment: { type: "object", properties: { "@ondc/org/collection_amount": { @@ -737,7 +737,7 @@ module.exports = { "provider", "fulfillments", "billing", - "payments", + "payment", "@ondc/org/linked_order", "created_at", "updated_at", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 689c6f6..9c5ef84 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -174,7 +174,7 @@ module.exports = { }, short_desc: { type: "string", - const: { $data: "/confirm/0/message/order/fulfillments/0/end/instructions/short_desc" } + const: { $data: "/confirm/0/message/order/fulfillments/0/start/instructions/short_desc" } }, long_desc: { type: "string", diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index b0cb711..c5b76b1 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -195,7 +195,11 @@ module.exports = Object.freeze({ ON_SEEARCH_ITEMTAGS:["g2","g3","back_image","origin"], ON_SEARCH_PROVIDERTAGS:["serviceability","seller_id","seller_terms"], B2B_PAYMENT_TYPE:["PRE-FULFILLMENT","ON-FULFILLMENT"], - + PRECANCEL_BEFORE_RTO:["Pending", + "Packed", + "Searching-for-Agent", + "Agent-assigned", + "Out-for-pickup"], //services SRV_FULFILLMENT_TYPE:["Home-Service","Store-Service"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js index 43b7a54..8779050 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnCancel.js @@ -19,6 +19,7 @@ const checkOnCancel = (data, msgIdSet) => { let fulfillments = on_cancel.fulfillments; let RtoPickupTime; let missingTags = []; + let rtoID, reasonId, preCnclState; const created_at = on_cancel.created_at; const updated_at = on_cancel.updated_at; @@ -104,7 +105,7 @@ const checkOnCancel = (data, msgIdSet) => { if (!fulTags) { onCancelObj.msngflfllmntTags = `fulfillments/tags are required in case of RTO (rto_event, precancel_state)`; } else { - let rtoID, reasonId, preCnclState; + fulTags.forEach((tag) => { if (tag.code === "rto_event") { @@ -190,6 +191,10 @@ const checkOnCancel = (data, msgIdSet) => { fulfillmentTagSet, constants.CANCELLATION_TAGS_CODES ); + + if(missingTags.includes("rto_event") && constants.PRECANCEL_BEFORE_RTO.includes(preCnclState)){ + missingTags= missingTags.filter(item => item!=='rto_event') + } if (missingTags.length > 0) { let itemKey = `missingFlmntTags-${i}-err`; onCancelObj[ From 304b23e98e86a969f9282491383b7e156d0ab146 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 1 May 2024 18:10:35 +0530 Subject: [PATCH 206/228] added b2b vals --- .../schema/B2B_json_schema/v2/cancel.js | 8 ++- .../schema/B2B_json_schema/v2/confirm.js | 14 +++-- .../schema/B2B_json_schema/v2/init.js | 3 ++ .../schema/B2B_json_schema/v2/on_cancel.js | 20 +++++++ .../schema/B2B_json_schema/v2/select.js | 3 ++ .../schema/SRV_json_schema/v2/on_search.js | 5 +- .../schema/SRV_json_schema/v2/search.js | 2 +- .../utils/b2b/b2bCancel.js | 16 ++++++ .../utils/b2b/b2bConfirm.js | 23 +++++++- .../utils/b2b/b2bOnSearch.js | 10 +++- .../utils/b2b/b2bOnSelect.js | 24 +++++++++ .../utils/b2b/b2bSelect.js | 11 +++- .../utils/b2b/b2bonCancel.js | 40 ++++++++++++++ .../utils/b2b/msgValidator.js | 12 ++++- .../utils/constants.js | 2 + .../utils/services/srvOnSearch.js | 52 ------------------- 16 files changed, 173 insertions(+), 72 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bCancel.js create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bonCancel.js diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js index 55a5e8b..2a4bc9f 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/cancel.js @@ -1,3 +1,4 @@ +const constants = require("../../../utils/constants"); module.exports = { $id: "http://example.com/schema/cancelSchema", type: "object", @@ -95,16 +96,13 @@ module.exports = { const: { $data: "/on_confirm/0/message/order/id" }, }, cancellation_reason_id: { - order_id: { - type: "string", - }, + type: "string", + enum: constants.BAP_CANCELLATION_CODES, }, - }, additionalProperties: false, required: ["order_id", "cancellation_reason_id"], }, }, required: ["context", "message"], - }; diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js index 5cf1cb6..7054857 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/confirm.js @@ -108,7 +108,8 @@ module.exports = { not: { const: { $data: "3/context/transaction_id" }, }, - errorMessage:"Order ID must not be the same as Transaction ID - ${3/context/transaction_id}." + errorMessage: + "Order ID must not be the same as Transaction ID - ${3/context/transaction_id}.", }, state: { type: "string", @@ -211,6 +212,7 @@ module.exports = { }, value: { type: "string", + minLength: 1, anyOf: [ { const: { @@ -435,6 +437,7 @@ module.exports = { }, value: { type: "string", + minLength: 1, anyOf: [ { const: { @@ -634,7 +637,7 @@ module.exports = { type: { type: "string", - enum : constants.B2B_PAYMENT_TYPE, + enum: constants.B2B_PAYMENT_TYPE, const: { $data: "/select/0/message/order/payments/0/type" }, }, collected_by: { @@ -777,7 +780,7 @@ module.exports = { properties: { code: { type: "string", - enum: constants.TERMS + enum: constants.TERMS, }, }, }, @@ -790,12 +793,13 @@ module.exports = { properties: { code: { type: "string", - enum: constants.B2B_BPP_TERMS + enum: constants.B2B_BPP_TERMS, }, }, }, value: { type: "string", + minLength: 1, }, }, required: ["descriptor", "value"], @@ -827,7 +831,7 @@ module.exports = { "payments", "created_at", "updated_at", - "tags" + "tags", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js index 3c1c33e..f39d1e7 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/init.js @@ -204,6 +204,7 @@ module.exports = { }, value: { type: "string", + "minLength": 1, anyOf: [ { const: { @@ -452,6 +453,7 @@ module.exports = { }, value: { type: "string", + "minLength": 1 }, }, if: { @@ -537,6 +539,7 @@ module.exports = { }, value: { type: "string", + "minLength": 1 }, }, required: ["descriptor", "value"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js index 52d8029..86f4807 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_cancel.js @@ -110,6 +110,8 @@ module.exports = { properties: { id: { type: "string", + const: { $data: "/cancel/0/message/cancellation_reason_id" }, + errorMessage:`does not match the cancellation reason id in /cancel` }, }, required: ["id"], @@ -118,6 +120,24 @@ module.exports = { type: "string", }, }, + allOf: [ + { + if: { + properties: { + cancelled_by: { const: { $data: "4/context/bpp_id" } }, + }, + }, + then: { + properties: { + reason: { + properties: { + id: { enum: constants.BPP_CANCELLATION_CODES }, + }, + }, + }, + }, + }, + ], required: ["reason", "cancelled_by"], }, provider: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js index b54f9ed..f14095e 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/select.js @@ -208,6 +208,7 @@ module.exports = { }, value: { type: "string", + "minLength": 1 }, }, required: ["descriptor", "value"], @@ -339,6 +340,7 @@ module.exports = { }, value: { type: "string", + "minLength": 1 }, }, if: { @@ -421,6 +423,7 @@ module.exports = { }, value: { type: "string", + "minLength": 1 }, }, required: ["descriptor", "value"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js index 9047c69..686c044 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -255,7 +255,7 @@ module.exports = { }, }, }, - required: ["holidays"], + required: ["frequency"], }, }, required: ["label", "schedule"], @@ -789,7 +789,6 @@ module.exports = { "code", "short_desc", "long_desc", - "images", ], }, location_ids: { @@ -878,7 +877,7 @@ module.exports = { "category_ids", "item_ids", "time", - "tags" + "tags", ], }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js index 25333cc..c6bfada 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/search.js @@ -226,7 +226,7 @@ module.exports = { }, }, }, - required: [ "fulfillment", "payment", "tags"], + required: [ "fulfillment", "tags"], }, }, required: ["intent"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bCancel.js new file mode 100644 index 0000000..7ac4a2d --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bCancel.js @@ -0,0 +1,16 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkCancel = async (data, msgIdSet) => { + const cancelObj = {}; + let cancel = data; + cancel = cancel.message; + let bap_cancel=false + + if(cancel.order_id && cancel.cancellation_reason_id) bap_cancel=true + dao.setValue("bap_cancel",bap_cancel) + return cancelObj; +}; +module.exports = checkCancel; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js index e374b99..e449491 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bConfirm.js @@ -9,7 +9,7 @@ const checkConfirm = async (data, msgIdSet) => { confirm = confirm.message.order; let orderState = confirm.state; let payments = confirm?.payments; - + let orderTags = confirm?.tags let items = confirm.items; const selectedItems = dao.getValue("onSlctdItemsArray"); @@ -69,6 +69,27 @@ const checkConfirm = async (data, msgIdSet) => { ); } + try { + console.log("Checking order tags"); + + if(orderTags){ + orderTags.forEach(tag=>{ + const {descriptor,list}= tag + if(descriptor.code==='bap_terms'){ + list.forEach(listTag=>{ + let enums=["Y","N"] + const {descriptor,value}= listTag; + if(descriptor.code==='accept_bpp_terms' && !enums.includes(value) ){ + cnfrmObj.invalidVal=`Invalid value for 'accept_bpp_terms' tag in order/tags/bap_terms` + } + }) + } + }) + } + } catch (error) { + console.log(error); + } + return cnfrmObj; }; module.exports = checkConfirm; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js index c733ca7..5291700 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSearch.js @@ -10,7 +10,7 @@ const checkOnSearch = async (data, msgIdSet) => { let citycode = onSearch?.context?.location?.city?.code; let domain = onSearch.context.domain; onSearch = onSearch.message.catalog; - + let domCode = domain.split('ONDC:')[1]; //saving fulfillments try { console.log("checking attr"); @@ -95,6 +95,14 @@ const checkOnSearch = async (data, msgIdSet) => { if (missingTags.length > 0) { onSrchObj.mssngTagErr = `'${missingTags}' code/s required in providers/tags for serviceability`; } + tag?.list.forEach(list=>{ + const {descriptor,value} = list; + if(descriptor.code==='category'){ + if(!value.startsWith(domCode)){ + onSrchObj.srvcCatgryErr=`Serviceability category must be defined for the same domain code as in context - ${domCode}` + } + } + }) } }); } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 34b0eb7..4e07e7d 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -6,6 +6,7 @@ const utils = require("../utils"); const checkOnSelect = async (data, msgIdSet) => { const onSelectObj = {}; let onSelect = data; + let error = onSelect.error let citycode = onSelect?.context?.location?.city?.code; onSelect = onSelect.message.order; let quote = onSelect?.quote; @@ -14,8 +15,11 @@ const checkOnSelect = async (data, msgIdSet) => { let ffState, ffId; let deliveryQuoteItem = false; let deliveryCharge = 0; + let outOfStock = false; dao.setValue("onSlctdItemsArray", items); const selectedItems = dao.getValue("slctdItemsArray"); + + if(error && error.code ==='40002') outOfStock= true; try { console.log("Checking fulfillment object in /on_select"); if (fulfillments) { @@ -56,11 +60,14 @@ const checkOnSelect = async (data, msgIdSet) => { try { console.log(`Checking quote object in /on_select api`); + quote?.breakup.forEach((breakup, i) => { let itemPrice = parseFloat(breakup?.item?.price?.value); let available = Number(breakup?.item?.quantity?.available?.count); let quantity = breakup["@ondc/org/item_quantity"]; + + if ( breakup["@ondc/org/title_type"] === "delivery" && breakup["@ondc/org/item_id"] === ffId @@ -92,7 +99,24 @@ const checkOnSelect = async (data, msgIdSet) => { ] = `@ondc/org/item_quantity for item with id ${breakup["@ondc/org/item_id"]} cannot be more than the available count (quantity/avaialble/count) in quote/breakup`; } }); + + + items.forEach(item=>{ + let itemId= item?.id + let itemQuant = item?.quantity?.selected?.count + quote?.breakup.forEach(breakup=>{ + + if(breakup['@ondc/org/title_type']==='item' && breakup['@ondc/org/item_id']===itemId){ + if(itemQuant===breakup['@ondc/org/item_quantity'].count && outOfStock == true){ + onSelectObj.quoteItemQuantity=`In case of item quantity unavailable, item quantity in quote breakup should be updated to the available quantity` + } + if(itemQuant!==breakup['@ondc/org/item_quantity'].count && outOfStock == false){ + onSelectObj.quoteItemQuantity=`Item quantity in quote breakup should be equal to the items/quantity/selected/count` + } + } + }) + }) if (!deliveryQuoteItem && ffState === "Serviceable") { onSelectObj.deliveryQuoteErr = `Delivery charges should be provided in quote/breakup when fulfillment is 'Serviceable'`; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js index a547af9..5b92003 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bSelect.js @@ -6,6 +6,8 @@ const utils = require("../utils"); const checkSelect = async (data, msgIdSet) => { const selectObj = {}; let select = data; + let rfq = false; + if (select?.context?.ttl!=='PT30S') rfq = true; let citycode = select?.context?.location?.city?.code; select = select.message.order; let fulfillments = select?.fulfillments; @@ -14,9 +16,9 @@ const checkSelect = async (data, msgIdSet) => { let fulfillmentsArr = dao.getValue("fulfillmentsArr"); let itemsArr = select.items; dao.setValue("slctdItemsArray", itemsArr); - let rfq = false; - if (select?.provider?.ttl) rfq = true; + + dao.setValue("rfq", rfq); @@ -70,6 +72,11 @@ const checkSelect = async (data, msgIdSet) => { console.log(`Comparing item object in /select and /on_search`); itemsArr?.forEach((item, i) => { + let itemTags = item?.tags; + + if(itemTags && !rfq){ + selectObj.itemTagErr=`items/tags (BUYER TERMS) should not be provided for Non-RFQ Flow` + } let itemExists = false; onSearchitemsArr?.forEach((element) => { if (item.id === element.id) itemExists = true; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bonCancel.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bonCancel.js new file mode 100644 index 0000000..ca9b3d7 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bonCancel.js @@ -0,0 +1,40 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils"); + +const checkOnCancel = async (data, msgIdSet) => { + const onCancelObj = {}; + let onCancel = data; + let bap_id = onCancel.context.bap_id; + let bpp_id = onCancel.context.bpp_id; + onCancel = onCancel.message.order; + let quote = onCancel?.quote; + // let payments = onCancel?.payments; + // let rfq = dao.getValue("rfq"); + let bap_cancel = dao.getValue("bap_cancel"); + + + if (bap_cancel && onCancel?.cancellation?.cancelled_by !== bap_id) { + onCancelObj.cancelledByErr = `In case of buyer cancellation, cancellation/cancelled_by should be bap_id`; + } + + if(!bap_cancel && onCancel?.cancellation?.cancelled_by !== bpp_id){ + onCancelObj.cancelledByErr1 = `In case of seller cancellation, cancellation/cancelled_by should be bpp_id`; + } + try { + console.log("Checking refund element in quote in /on_cancel"); + let refundPresent = false; + quote?.breakup.forEach((breakup) => { + if (breakup["@ondc/org/title_type"] === "refund") refundPresent = true; + }); + + if (!refundPresent) + onCancelObj.rfndPresent = `A refund line item needs to be included in the quote breakup to reimburse certain charges from the quote.`; + } catch (error) { + console.log("ERROR", error); + } + + return onCancelObj; +}; +module.exports = checkOnCancel; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js index 4c49fc4..2963431 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/msgValidator.js @@ -3,6 +3,8 @@ const checkInit = require("./b2bInit"); const checkSelect = require("./b2bSelect"); const checkOnInit = require("./b2bOnInit"); const checkOnConfirm = require("./b2bOnConfirm"); +const checkCancel = require("./b2bCancel"); +const checkOnCancel = require("./b2bonCancel"); const checkOnSelect = require("./b2bOnSelect"); const checkOnSearch = require("./b2bOnSearch"); const checkOnUpdate = require("./b2bOnUpdate"); @@ -38,6 +40,12 @@ const b2bVal = (element, action, msgIdSet) => { case "on_confirm": return checkOnConfirm(element, msgIdSet); + case "on_cancel": + return checkOnCancel(element, msgIdSet); + + case "cancel": + return checkCancel(element, msgIdSet); + // case "update": // return checkUpdate(element,msgIdSet); @@ -45,8 +53,8 @@ const b2bVal = (element, action, msgIdSet) => { // return checkOnUpdate(element,msgIdSet) case "on_status": - return checkOnStatus(element,msgIdSet) + return checkOnStatus(element, msgIdSet); } return busnsErr; }; -module.exports = { b2bVal }; \ No newline at end of file +module.exports = { b2bVal }; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index c5b76b1..ce5ed55 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -200,6 +200,8 @@ module.exports = Object.freeze({ "Searching-for-Agent", "Agent-assigned", "Out-for-pickup"], + BPP_CANCELLATION_CODES:["002","005","011","012","013","014","015","018","019","022","998"], + BAP_CANCELLATION_CODES:["001","003","006","009","010","023","999"], //services SRV_FULFILLMENT_TYPE:["Home-Service","Store-Service"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js index 35eef0c..2b9901b 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/services/srvOnSearch.js @@ -114,58 +114,6 @@ const checkOnSearch = async (data, msgIdSet) => { } catch (error) { console.log(error); } - //checking mandatory attributes for fashion and electronics - - // provider.items.forEach((item) => { - // let itemTags = item?.tags; - // let mandatoryAttr = []; - // let attrPresent = false; - // let missingAttr = []; - - // itemTags.forEach((tag) => { - // let { descriptor, list } = tag; - // if (descriptor?.code === "attribute" && constants.ATTR_DOMAINS.includes(domain)) { - - // if (domain === "ONDC:RET12") { - // mandatoryAttr = constants.FASHION_ATTRIBUTES; - // } - // if (domain === "ONDC:RET14") { - // mandatoryAttr = constants.ELECTRONICS_ATTRIBUTES; - // } - // if (domain === "ONDC:RET12") { - // mandatoryAttr = constants.FASHION_ATTRIBUTES; - // } - // if (domain === "ONDC:RET1A"||domain === "ONDC:RET1B"||domain === "ONDC:RET1C"||domain === "ONDC:RET1D") { - // mandatoryAttr = constants.MANDATORY_ATTRIBUTES; - // } - // attrPresent = true; - // missingAttr = utils.findMissingTags( - // list, - // descriptor.code, - // mandatoryAttr - // ); - - // if (missingAttr.length > 0) { - // onSrchObj.mssngAttrErr = `'${missingAttr}' attribute/s required in items/tags for ${domain} domain`; - // } - // } - // if (descriptor?.code === "g2") { - // mandatoryAttr = constants.G2TAGS; - // missingAttr = utils.findMissingTags( - // list, - // descriptor.code, - // mandatoryAttr - // ); - - // if (missingAttr.length > 0) { - // onSrchObj.missingTagErr = `'${missingAttr}' required for 'g2' tag in items/tags`; - // } - // } - // }); - // if (constants.ATTR_DOMAINS.includes(domain) && !attrPresent) { - // onSrchObj.attrMissing = `code = 'attribute' is missing in /items/tags for domain ${domain}`; - // } - // }); } } From 28f2b2cd6f78a9924aec8fb90adf1a38caec735a Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Thu, 2 May 2024 15:29:19 +0530 Subject: [PATCH 207/228] updated schema --- .../schema/B2B_json_schema/v2/on_search.js | 2 + .../schema/SRV_json_schema/v2/on_search.js | 50 ++----------------- .../utils/constants.js | 6 ++- 3 files changed, 10 insertions(+), 48 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js index 828207a..31c141d 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/B2B_json_schema/v2/on_search.js @@ -342,6 +342,7 @@ module.exports = { }, value: { type: "string", + minLength: 1, }, }, required: ["descriptor", "value"], @@ -864,6 +865,7 @@ module.exports = { }, value: { type: "string", + minLength: 1, }, }, required: ["descriptor", "value"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js index 686c044..a44d928 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -208,8 +208,7 @@ module.exports = { "name", "code", "short_desc", - "long_desc", - "images", + "long_desc" ], }, rating: { @@ -500,53 +499,9 @@ module.exports = { "code", "short_desc", "long_desc", - "images", + "images" ], }, - creator: { - type: "object", - properties: { - descriptor: { - type: "object", - properties: { - name: { - type: "string", - }, - contact: { - type: "object", - properties: { - name: { - type: "string", - }, - address: { - type: "object", - properties: { - full: { - type: "string", - }, - }, - required: ["full"], - }, - phone: { - type: "string", - }, - email: { - type: "string", - }, - }, - required: [ - "name", - "address", - "phone", - "email", - ], - }, - }, - required: ["name", "contact"], - }, - }, - required: ["descriptor"], - }, price: { type: "object", properties: { @@ -789,6 +744,7 @@ module.exports = { "code", "short_desc", "long_desc", + "images" ], }, location_ids: { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index ce5ed55..b44bd09 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -190,7 +190,11 @@ module.exports = Object.freeze({ B2B_BPP_TERMS:["buyer_id_code","buyer_id_no","max_liability","max_liability_cap","mandatory_arbitration","court_jurisdiction","delay_interest","accept_bpp_terms"], ATTR_DOMAINS:["ONDC:RET12","ONDC:RET14","ONDC:RET1A","ONDC:RET1B","ONDC:RET1C","ONDC:RET1D"], G2TAGS:["time_to_ship","cancellable","tax_rate"], - VALIDCOUNTRYCODES:["IND","SGP","AUS","ARE","USA","GBR"], + VALIDCOUNTRYCODES:["IOT","USA", "CAN", "GBR", "FRA", "DEU", "ITA", "AUS", "IND", "CHN", "JPN", + "ESP", "BRA", "RUS", "MEX", "KOR", "IDN", "TUR", "SAU", "IRN", "ARG", + "NLD", "CHE", "SWE", "BEL", "AUT", "NOR", "DNK", "FIN", "POL", "ZAF", + "EGY", "NGA", "KEN", "ETH", "GHA", "UGA", "TZA", "MAR", "DZA", "CMR", + "ZMB", "ZWE", "MOZ", "GRC", "PRT", "CZE", "HUN", "SGP", "ISR", "ARE"], BPP_PAYMENT_TAGS:["signature","dsa","ttl"], ON_SEEARCH_ITEMTAGS:["g2","g3","back_image","origin"], ON_SEARCH_PROVIDERTAGS:["serviceability","seller_id","seller_terms"], From 85ad29bb061a53ebf201838051a92322e6da0fd0 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 3 May 2024 17:22:08 +0530 Subject: [PATCH 208/228] updated checks --- .../schema/SRV_json_schema/v2/on_search.js | 3 +- .../v1.2/cancelSchema.js | 1 + .../v1.2/confirmSchema.js | 1 + .../v1.2/initSchema.js | 1 + .../v1.2/onCancelSchema.js | 39 +++++++++- .../v1.2/onConfirmSchema.js | 1 + .../v1.2/onInitSchema.js | 1 + .../v1.2/onSearchSchema.js | 1 + .../v1.2/onStatusSchema.js | 74 +++++++++++-------- .../v1.2/onUpdateSchema.js | 63 ---------------- .../v1.2/updateSchema.js | 1 + .../utils/b2b/b2bOnConfirm.js | 20 +++++ .../utils/b2b/b2bOnSelect.js | 5 +- .../utils/constants.js | 4 +- 14 files changed, 112 insertions(+), 103 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js index a44d928..5800583 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/SRV_json_schema/v2/on_search.js @@ -743,8 +743,7 @@ module.exports = { "name", "code", "short_desc", - "long_desc", - "images" + "long_desc" ], }, location_ids: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js index 3d6166e..a5d7b95 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/cancelSchema.js @@ -87,6 +87,7 @@ module.exports = { }, cancellation_reason_id: { type: "string", + enum: constants.LBNP_CANCELLATION_CODES }, }, required: ["order_id", "cancellation_reason_id"], diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 99a8d12..54c99a4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -299,6 +299,7 @@ module.exports = { }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js index ab464d0..8ee02c0 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/initSchema.js @@ -143,6 +143,7 @@ module.exports = { }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js index 28c8054..a589e44 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onCancelSchema.js @@ -120,14 +120,40 @@ module.exports = { cancellation: { type: "object", properties: { - cancelled_by: { type: "string" }, reason: { type: "object", properties: { - id: { type: "string", enum: CANCELLATION_CODE }, + id: { + type: "string", + const: { $data: "/cancel/0/message/cancellation_reason_id" }, + errorMessage:`does not match the cancellation reason id in /cancel` + }, }, + required: ["id"], + }, + cancelled_by: { + type: "string", }, }, + allOf: [ + { + if: { + properties: { + cancelled_by: { const: { $data: "4/context/bpp_id" } }, + }, + }, + then: { + properties: { + reason: { + properties: { + id: { enum: constants.LSP_CANCELLATION_CODES }, + }, + }, + }, + }, + }, + ], + required: ["reason", "cancelled_by"], }, items: { type: "array", @@ -186,6 +212,7 @@ module.exports = { }, breakup: { type: "array", + minItems:1, items: { type: "object", properties: { @@ -214,6 +241,7 @@ module.exports = { fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { @@ -577,10 +605,13 @@ module.exports = { properties: { time: { required: ["timestamp"] }, }, - required: ["time"], + required: ["time","location"], + }, + end: { + required: ["location"], }, }, - required: ["id", "type", "state", "start"], + required: ["id", "type", "state", "start","end"], }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js index f7e7d48..3b4c5d3 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onConfirmSchema.js @@ -275,6 +275,7 @@ module.exports = { }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js index 7b1e2fc..7f2e23b 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onInitSchema.js @@ -191,6 +191,7 @@ module.exports = { }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js index 30a361c..c7e6210 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onSearchSchema.js @@ -314,6 +314,7 @@ module.exports = { }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js index 8591436..e1d6cd2 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onStatusSchema.js @@ -190,6 +190,7 @@ module.exports = { }, breakup: { type: "array", + minItems:1, items: { type: "object", properties: { @@ -214,10 +215,10 @@ module.exports = { }, required: ["price", "breakup"], isQuoteMatching: true, - }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { @@ -354,7 +355,6 @@ module.exports = { }, }, isLengthValid: true, - }, }, required: ["gps", "address"], @@ -480,7 +480,6 @@ module.exports = { }, }, isLengthValid: true, - }, }, required: ["gps", "address"], @@ -528,36 +527,47 @@ module.exports = { }, }, - if: { properties: { type: { const: "Delivery" } } }, - then: { - properties: { - start: { + allOf: [ + { + if: { properties: { type: { const: "Delivery" } } }, + then: { properties: { - time: { required: ["range"] }, - }, - required: ["time", "person", "location", "contact"], - }, + start: { + properties: { + time: { required: ["range"] }, + }, + required: ["time", "person", "location", "contact"], + }, - end: { - properties: { - time: { required: ["range"] }, + end: { + properties: { + time: { required: ["range"] }, + }, + required: ["time", "person", "location", "contact"], + }, }, - required: ["time", "person", "location", "contact"], + required: [ + "id", + "type", + "state", + "tracking", + "start", + "end", + ], }, - }, - required: ["id", "type", "state", "tracking", "start", "end"], - }, - else: { - properties: { - start: { + else: { properties: { - time: { required: ["timestamp"] }, + start: { + properties: { + time: { required: ["timestamp"] }, + }, + required: ["time"], + }, }, - required: ["time"], + required: ["id", "type", "state", "start"], }, }, - required: ["id", "type", "state", "start"], - }, + ], }, }, payment: { @@ -647,9 +657,9 @@ module.exports = { collected_by: { const: "BAP", }, - status:{ - const:"PAID" - } + status: { + const: "PAID", + }, }, }, @@ -659,12 +669,12 @@ module.exports = { collected_by: { const: "BAP", }, - status:{ - const:"NOT-PAID" - } + status: { + const: "NOT-PAID", + }, }, }, - required: ["type", "collected_by","status"], + required: ["type", "collected_by", "status"], }, billing: { type: "object", diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js index 3fbd07b..b2d2f6a 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/onUpdateSchema.js @@ -283,39 +283,6 @@ module.exports = { }, required: [], - allOf: [ - { - if: { properties: { code: { const: "1" } } }, - then: { - properties: { - short_desc: { - minLength: 10, - maxLength: 10, - pattern: "^[0-9]{10}$", - errorMessage: - "should be a 10 digit number", - }, - }, - }, - }, - { - if: { - properties: { - code: { enum: ["2", "3", "4"] }, - }, - }, - then: { - properties: { - short_desc: { - maxLength: 6, - pattern: "^[a-zA-Z0-9]{1,6}$", - errorMessage: - "should not be an empty string or have more than 6 digits", - }, - }, - }, - }, - ], }, }, }, @@ -374,36 +341,6 @@ module.exports = { type: "string", }, }, - required: ["code"], - allOf: [ - { - if: { properties: { code: { const: "3" } } }, - then: { - properties: { - short_desc: { - maxLength: 0, - errorMessage: "is not required", - }, - }, - }, - }, - { - if: { - properties: { code: { enum: ["1", "2"] } }, - }, - then: { - properties: { - short_desc: { - maxLength: 6, - pattern: "^[a-zA-Z0-9]{1,6}$", - errorMessage: - "should not be an empty string or have more than 6 digits", - }, - }, - required: ["short_desc"], - }, - }, - ], }, }, }, diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js index 9c5ef84..eee905c 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/updateSchema.js @@ -143,6 +143,7 @@ module.exports = { }, fulfillments: { type: "array", + minItems:1, items: { type: "object", properties: { diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js index 0c074e1..8129eec 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js @@ -8,11 +8,31 @@ const checkOnConfirm = async (data, msgIdSet) => { let onConfirm = data; onConfirm = onConfirm.message.order; let quote = onConfirm?.quote; + let prvdrLocation = onConfirm?.provider?.locations let payments = onConfirm?.payments; + let fulfillments = onConfirm?.fulfillments let rfq = dao.getValue("rfq"); + prvdrLocation=prvdrLocation[0] + try { + console.log("Checking fulfillments in /on_confirm"); + fulfillments.forEach(fulfillment=>{ + let stops = fulfillment?.stops + + stops.forEach(stop=>{ + if(stop?.type==='start'){ + if(stop?.location?.id!==prvdrLocation?.id){ + onConfirmObj.strtlctnErr=`fulfillments/start/location/id - ${stop?.location?.id} is not matching with the provider location id - ${prvdrLocation?.id} provided in /on_search` + } + } + }) + }) + } catch (error) { + console.log("ERROR",error); + } try { console.log(`Checking payment object in /on_confirm api`); + payments.forEach((payment) => { let type = payment?.type; let collectedBy = payment?.collected_by; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js index 4e07e7d..589e1d3 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnSelect.js @@ -112,7 +112,10 @@ const checkOnSelect = async (data, msgIdSet) => { onSelectObj.quoteItemQuantity=`In case of item quantity unavailable, item quantity in quote breakup should be updated to the available quantity` } if(itemQuant!==breakup['@ondc/org/item_quantity'].count && outOfStock == false){ - onSelectObj.quoteItemQuantity=`Item quantity in quote breakup should be equal to the items/quantity/selected/count` + onSelectObj.quoteItemQuantity1=`Item quantity in quote breakup should be equal to the items/quantity/selected/count` + } + if(itemQuant>breakup['@ondc/org/item_quantity'].count && outOfStock==false){ + onSelectObj.outOfStockErr=`Error object with appropriate error code should be sent when the selected item quantity is not available` } } }) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/constants.js b/utilities/logistics-b2b/log-verification-utility/utils/constants.js index b44bd09..73f5d66 100755 --- a/utilities/logistics-b2b/log-verification-utility/utils/constants.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/constants.js @@ -196,7 +196,7 @@ module.exports = Object.freeze({ "EGY", "NGA", "KEN", "ETH", "GHA", "UGA", "TZA", "MAR", "DZA", "CMR", "ZMB", "ZWE", "MOZ", "GRC", "PRT", "CZE", "HUN", "SGP", "ISR", "ARE"], BPP_PAYMENT_TAGS:["signature","dsa","ttl"], - ON_SEEARCH_ITEMTAGS:["g2","g3","back_image","origin"], + ON_SEEARCH_ITEMTAGS:["g2","g3","origin"], ON_SEARCH_PROVIDERTAGS:["serviceability","seller_id","seller_terms"], B2B_PAYMENT_TYPE:["PRE-FULFILLMENT","ON-FULFILLMENT"], PRECANCEL_BEFORE_RTO:["Pending", @@ -206,6 +206,8 @@ module.exports = Object.freeze({ "Out-for-pickup"], BPP_CANCELLATION_CODES:["002","005","011","012","013","014","015","018","019","022","998"], BAP_CANCELLATION_CODES:["001","003","006","009","010","023","999"], + LBNP_CANCELLATION_CODES:["007","996"], + LSP_CANCELLATION_CODES:["008","011","012","013","014","015","016","017","020","021","997"], //services SRV_FULFILLMENT_TYPE:["Home-Service","Store-Service"], From 48b94da115dec2bafdc1d97f562881b971df26e2 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Fri, 3 May 2024 17:47:05 +0530 Subject: [PATCH 209/228] updated --- .../utils/logistics/logOnStatus.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js index 7ec4271..ea36292 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnStatus.js @@ -16,6 +16,8 @@ const checkOnStatus = (data, msgIdSet) => { let fulfillments = on_status.fulfillments; let pickupTime, deliveryTime, RtoPickupTime, RtoDeliveredTime; let paymentStatus = on_status?.payment?.status; + let trackingEnabled= false; + if (on_status.state === "Complete" && payment.type === "ON-FULFILLMENT") { if (paymentStatus !== "PAID") { @@ -51,15 +53,21 @@ const checkOnStatus = (data, msgIdSet) => { try { fulfillments.forEach((fulfillment) => { ffState = fulfillment?.state?.descriptor?.code; + let fulfillmentTags= fulfillment?.tags console.log( `Comparing pickup and delivery timestamps for on_status_${ffState}` ); - if ( fulfillment.type === "Prepaid" || fulfillment.type === "CoD" || fulfillment.type === "Delivery" ) { + + if(fulfillmentTags){ + fulfillmentTags.forEach(tag=>{ + if(tag.code==='tracking') trackingEnabled = true + }) + } if ( categoryId === "Immediate Delivery" && fulfillment.tracking !== true && ffState!=='Cancelled' @@ -81,6 +89,9 @@ const checkOnStatus = (data, msgIdSet) => { } } if (ffState === "Order-picked-up") { + if(!trackingEnabled){ + onStatusObj.trackingTagErr=`tracking tag to be provided in fulfillments/tags` + } if (orderState !== "In-progress") { onStatusObj.ordrStatErr = `Order state should be 'In-progress' for fulfillment state - ${ffState}`; } From c62cd9ba6ecbb279307857a3a5c5f38529c1ca7f Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Mon, 6 May 2024 14:25:46 +0530 Subject: [PATCH 210/228] minor updates to logistics --- .../v1.2/confirmSchema.js | 6 -- .../utils/logistics/logConfirm.js | 77 ++++++++++++------- .../utils/logistics/logSearch.js | 4 +- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js index 54c99a4..b8cb4a4 100644 --- a/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js +++ b/utilities/logistics-b2b/log-verification-utility/schema/logistics_api_json_schema/v1.2/confirmSchema.js @@ -909,12 +909,6 @@ module.exports = { }, value: { type: "string", - const: { - $data: - "/search/0/message/intent/@ondc~1org~1payload_details/value/value", - }, - errorMessage: - "order price mismatches from /search", }, }, required: ["currency", "value"], diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js index 72dbacd..e726f24 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logConfirm.js @@ -6,13 +6,13 @@ const utils = require("../utils.js"); const checkConfirm = (data, msgIdSet) => { let cnfrmObj = {}; let confirm = data; - const contextTimestamp= confirm.context.timestamp + const contextTimestamp = confirm.context.timestamp; let version = confirm.context.core_version; - let missingTags =[]; + let missingTags = []; let onSearchProvArr = dao.getValue("providersArr"); confirm = confirm.message.order; let rts; - let linkedOrder = confirm["@ondc/org/linked_order"] + let linkedOrder = confirm["@ondc/org/linked_order"]; if (confirm?.updated_at > contextTimestamp) { cnfrmObj.updatedAtErr = `order/updated_at cannot be future dated w.r.t context/timestamp`; } @@ -73,27 +73,34 @@ const checkConfirm = (data, msgIdSet) => { let p2h2p = dao.getValue("p2h2p"); let fulfillmentTagSet = new Set(); - fulfillments.forEach((fulfillment,i) => { + fulfillments.forEach((fulfillment, i) => { let fulfillmentTags = fulfillment?.tags; - let avgPickupTime= fulfillment?.start?.time?.duration; -console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); - if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ - cnfrmObj.avgPckupErr=`Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search` + let avgPickupTime = fulfillment?.start?.time?.duration; + console.log( + avgPickupTime, + dao.getValue(`${fulfillment?.id}-avgPickupTime`) + ); + if ( + avgPickupTime && + dao.getValue(`${fulfillment?.id}-avgPickupTime`) && + avgPickupTime !== dao.getValue(`${fulfillment?.id}-avgPickupTime`) + ) { + cnfrmObj.avgPckupErr = `Average Pickup Time (fulfillments/start/time/duration) mismatches from the one provided in /on_search`; } if (fulfillment["@ondc/org/awb_no"] && p2h2p) awbNo = true; if (rts === "yes" && !fulfillment?.start?.instructions?.short_desc) { cnfrmObj.instructionsErr = `fulfillments/start/instructions are required when ready_to_ship = 'yes'`; } - reqFulTags = ["rto_action","state"] + reqFulTags = ["rto_action", "state"]; //checking tags if (fulfillmentTags) { fulfillmentTags.forEach((tag) => { let { code, list } = tag; fulfillmentTagSet.add(code); - }) + }); - missingTags= utils.findRequiredTags(fulfillmentTagSet,reqFulTags) - if (missingTags.length > 0) { + missingTags = utils.findRequiredTags(fulfillmentTagSet, reqFulTags); + if (missingTags.length > 0) { let itemKey = `missingFlmntTags-${i}-err`; cnfrmObj[ itemKey @@ -104,32 +111,44 @@ console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); try { console.log("checking linked order in /confirm"); + let orderPrice = 0; + let orderItems = linkedOrder?.items; - let orderWeight =linkedOrder?.order?.weight?.value; + orderItems.forEach((item) => { + console.log(parseFloat(item?.price?.value)); + orderPrice += parseFloat(item?.price?.value); + }); + if(orderPrice>dao.getValue('orderPrice')){ + cnfrmObj.ordrPrice=`Linked order price value - ${orderPrice} cannot be more than the one provided in /search in Payload details - ${dao.getValue("orderPrice")}` + } + let orderWeight = linkedOrder?.order?.weight?.value; const unit = linkedOrder?.order?.weight?.unit; - if(unit === 'kilogram'){ - orderWeight = orderWeight*1000; + if (unit === "kilogram") { + orderWeight = orderWeight * 1000; } - let totalUnitWeight=0; + let totalUnitWeight = 0; let quantityUnit; - linkedOrder?.items.forEach(item=>{ - let quantity = item?.quantity?.measure?.value - quantityUnit = item?.quantity?.measure?.unit - if(quantityUnit === 'kilogram'){ - quantity = quantity*1000; + linkedOrder?.items.forEach((item) => { + let quantity = item?.quantity?.measure?.value; + quantityUnit = item?.quantity?.measure?.unit; + if (quantityUnit === "kilogram") { + quantity = quantity * 1000; } - const count = item?.quantity?.count - - const unitWeight = (quantity*count) - totalUnitWeight+=unitWeight; - }) + const count = item?.quantity?.count; + + const unitWeight = quantity * count; + totalUnitWeight += unitWeight; + }); - console.log(totalUnitWeight,orderWeight); - if(totalUnitWeight.toFixed(2)!=orderWeight.toFixed(2) && quantityUnit!== 'unit'){ - cnfrmObj.weightErr=`Total order weight '${orderWeight}' does not match the total unit weight of items '${totalUnitWeight}'` + console.log(totalUnitWeight, orderWeight); + if ( + totalUnitWeight.toFixed(2) != orderWeight.toFixed(2) && + quantityUnit !== "unit" + ) { + cnfrmObj.weightErr = `Total order weight '${orderWeight}' does not match the total unit weight of items '${totalUnitWeight}'`; } } catch (error) { console.log(error); diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js index 2144d35..e566ac6 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logSearch.js @@ -11,7 +11,9 @@ const checkSearch = async (data, msgIdSet) => { let search = data; let contextTime = search.context.timestamp; search = search.message.intent; - + let linkedOrder = search['@ondc/org/payload_details'] + let orderPrice = linkedOrder?.value?.value + dao.setValue("orderPrice",orderPrice) const { start: { location: startLocation }, end: { location: endLocation }, From 518b75f0917ab4a36a7a8f3f301f335efc61fac1 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Tue, 7 May 2024 17:11:17 +0530 Subject: [PATCH 211/228] added validations --- .../utils/b2b/b2bOnConfirm.js | 5 ++ .../utils/logistics/logOnTrack.js | 47 +++++++++++++++++-- .../utils/logistics/logTrack.js | 14 ++++++ .../utils/logistics/msgValidator.js | 4 ++ 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 utilities/logistics-b2b/log-verification-utility/utils/logistics/logTrack.js diff --git a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js index 8129eec..b34b265 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/b2b/b2bOnConfirm.js @@ -6,6 +6,7 @@ const utils = require("../utils"); const checkOnConfirm = async (data, msgIdSet) => { const onConfirmObj = {}; let onConfirm = data; + let errorObj = onConfirm.error; onConfirm = onConfirm.message.order; let quote = onConfirm?.quote; let prvdrLocation = onConfirm?.provider?.locations @@ -14,6 +15,10 @@ const checkOnConfirm = async (data, msgIdSet) => { let rfq = dao.getValue("rfq"); prvdrLocation=prvdrLocation[0] + if(onConfirm.state==='Cancelled' && !errorObj){ + onConfirmObj.errObj=`Error object is missing in case of PO rejection` + } + try { console.log("Checking fulfillments in /on_confirm"); fulfillments.forEach(fulfillment=>{ diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js index 27566c1..81df795 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js @@ -9,19 +9,60 @@ const checkOnTrack = (data, msgIdSet) => { let contextTimestamp = on_track?.context?.timestamp; on_track = on_track?.message?.tracking; + let tags = on_track?.tags; + if (tags) { + tags.forEach((tag) => { + if (tag?.code === "order") { + tag?.list.forEach((listTag) => { + if ( + listTag?.code === "id" && + listTag?.value != dao.getValue("trackOrderId") + ) { + onTrackObj.orderIdErr = `Order Id in /track and /on_track does not match`; + } + }); + } + + if (tag?.code === "config") { + tag?.list.forEach((listTag) => { + let attrVal; + if (listTag?.code === "attr") { + attrVal = listTag?.value; + } + if (listTag?.code === "type" && listTag?.value === "live_poll") { + if (!on_track?.location?.gps) + onTrackObj.locationErr = `tracking/location/gps is required for live_poll`; + if (attrVal !== "tracking.location.gps") + onTrackObj.attrErr = `attr value should be 'tracking/location/gps' for live_poll`; + } + + if (listTag?.code === "type" && listTag?.value === "deferred") { + if (!on_track?.url) + onTrackObj.locationErr = `tracking/url is required for non hyperlocal tracking`; + if (attrVal !== "tracking.url") + onTrackObj.attrErr = `attr value should be 'tracking/url' for deferred tracking`; + } + }); + } + }); + } else { + onTrackObj.tagsErr = `Tags should be provided in /on_track`; + } if (on_track?.location?.updated_at > contextTimestamp) { onTrackObj.updatedAtErr = `tracking/location/updated_at cannot be future dated w.r.t context/timestamp`; } - if (on_track?.location?.time?.timestamp > contextTimestamp) { onTrackObj.lctnTimeAtErr = `tracking/location/time/timestamp cannot be future dated w.r.t context/timestamp`; } - console.log(on_track?.location?.updated_at, on_track?.location?.time?.timestamp); - if(on_track?.location?.updated_at < on_track?.location?.time?.timestamp){ + console.log( + on_track?.location?.updated_at, + on_track?.location?.time?.timestamp + ); + if (on_track?.location?.updated_at < on_track?.location?.time?.timestamp) { onTrackObj.updatedAtLctnErr = `tracking/location/time/timestamp cannot be future dated w.r.t tracking/location/updated_at`; } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logTrack.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logTrack.js new file mode 100644 index 0000000..d68d898 --- /dev/null +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logTrack.js @@ -0,0 +1,14 @@ +const _ = require("lodash"); +const dao = require("../../dao/dao"); +const constants = require("../constants"); +const utils = require("../utils.js"); + +const checkTrack = (data, msgIdSet) => { + let trackObj = {}; + let track = data; + + let trackId = track.message.order_id; + dao.setValue("trackOrderId", trackId); +}; + +module.exports = checkTrack; diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js index 08ab857..c08e1ae 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/msgValidator.js @@ -7,6 +7,7 @@ const checkOnUpdate = require("./logOnUpdate"); const checkUpdate = require("./logUpdate"); const checkOnStatus = require("./logOnStatus"); const checkOnCancel = require("./logOnCancel"); +const checkTrack = require("./logTrack"); const checkOnTrack = require("./logOnTrack"); const checkSearch = require("./logSearch"); const _ = require("lodash"); @@ -46,6 +47,9 @@ const logisticsVal = async (element, action, msgIdSet) => { case "on_track": return checkOnTrack(element, msgIdSet); + + case "track": + return checkTrack(element, msgIdSet); } return busnsErr; }; From 91bc2973e35d6dc70e5e7a92661e4123efba74b6 Mon Sep 17 00:00:00 2001 From: Abhinav Goyal Date: Wed, 8 May 2024 12:21:57 +0530 Subject: [PATCH 212/228] added checks --- .../utils/logistics/logOnConfirm.js | 5 +++++ .../utils/logistics/logOnTrack.js | 10 +++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js index 2a8d35f..795e7f0 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnConfirm.js @@ -33,11 +33,16 @@ const checkOnConfirm = (data, msgIdSet) => { try { console.log(`checking start and end time range in fulfillments`); fulfillments.forEach((fulfillment) => { + let ffState= fulfillment?.state?.descriptor?.code let avgPickupTime= fulfillment?.start?.time?.duration; console.log(avgPickupTime,dao.getValue(`${fulfillment?.id}-avgPickupTime`)); if(avgPickupTime && dao.getValue(`${fulfillment?.id}-avgPickupTime`) && avgPickupTime!==dao.getValue(`${fulfillment?.id}-avgPickupTime`)){ onCnfrmObj.avgPckupErr=`Average Pickup Time ${avgPickupTime} (fulfillments/start/time/duration) mismatches from the one provided in /on_search (${dao.getValue(`${fulfillment?.id}-avgPickupTime`)})` } + + if(fulfillment?.start?.time?.timestamp){ + onCnfrmObj.flflmentTmstmpErr=`Pickup timestamp cannot be provided when the fulfillment is in '${ffState}' state` + } if(categoryId==='Immediate Delivery' && fulfillment.tracking !== true){ onCnfrmObj.trckErr= `tracking should be enabled (true) for hyperlocal (Immediate Delivery)` } diff --git a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js index 81df795..909e88e 100644 --- a/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js +++ b/utilities/logistics-b2b/log-verification-utility/utils/logistics/logOnTrack.js @@ -23,25 +23,25 @@ const checkOnTrack = (data, msgIdSet) => { } }); } - + let attrVal; if (tag?.code === "config") { tag?.list.forEach((listTag) => { - let attrVal; + if (listTag?.code === "attr") { attrVal = listTag?.value; } if (listTag?.code === "type" && listTag?.value === "live_poll") { if (!on_track?.location?.gps) - onTrackObj.locationErr = `tracking/location/gps is required for live_poll`; + onTrackObj.locationErr = `tracking.location.gps is required for live_poll`; if (attrVal !== "tracking.location.gps") - onTrackObj.attrErr = `attr value should be 'tracking/location/gps' for live_poll`; + onTrackObj.attrErr = `attr value should be 'tracking.location.gps' for live_poll`; } if (listTag?.code === "type" && listTag?.value === "deferred") { if (!on_track?.url) onTrackObj.locationErr = `tracking/url is required for non hyperlocal tracking`; if (attrVal !== "tracking.url") - onTrackObj.attrErr = `attr value should be 'tracking/url' for deferred tracking`; + onTrackObj.attrErr = `attr value should be 'tracking.url' for deferred tracking`; } }); } From 8d564f6eb961b7bd192253a92bca4d3dface57de Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 9 May 2024 17:24:31 +0530 Subject: [PATCH 213/228] fix: crypto package --- utilities/ondc-crypto-sdk-nodejs/package-lock.json | 4 ++-- utilities/ondc-crypto-sdk-nodejs/package.json | 4 ++-- utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/utilities/ondc-crypto-sdk-nodejs/package-lock.json b/utilities/ondc-crypto-sdk-nodejs/package-lock.json index cc52f23..5c1d83e 100644 --- a/utilities/ondc-crypto-sdk-nodejs/package-lock.json +++ b/utilities/ondc-crypto-sdk-nodejs/package-lock.json @@ -1,12 +1,12 @@ { "name": "ondc-crypto-sdk-nodejs", - "version": "1.0.4", + "version": "2.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "ondc-crypto-sdk-nodejs", - "version": "1.0.4", + "version": "2.0.0", "license": "ISC", "dependencies": { "libsodium-wrappers": "^0.7.11", diff --git a/utilities/ondc-crypto-sdk-nodejs/package.json b/utilities/ondc-crypto-sdk-nodejs/package.json index 5da8a00..90ddf9c 100644 --- a/utilities/ondc-crypto-sdk-nodejs/package.json +++ b/utilities/ondc-crypto-sdk-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "ondc-crypto-sdk-nodejs", - "version": "1.0.4", + "version": "2.0.0", "description": "A crypto utility for exposing signing and verification functions by ONDC", "main": "lib/index.js", "types": "lib/index.d.ts", @@ -8,7 +8,7 @@ "test": "echo \"Error: no test specified\" && exit 1", "build": "tsc", "run": "tsc && node lib/index.js", - "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", + "format": "prettier --write \"src/**/*.ts\" \"lib/**/*.js\"", "lint": "tslint -p tsconfig.json", "prepare": "npm run build", "prepublishOnly": "npm run lint", diff --git a/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts b/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts index 17ffc39..f6a24ff 100644 --- a/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts +++ b/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts @@ -98,7 +98,7 @@ const verifyMessage = async ({ signedString, signingString, publicKey }: IVerify const verifyHeader = async ({ headerParts, body, publicKey }: IVerifyHeader) => { const { signingString } = await createSigningString({ - message: JSON.stringify(body), + message: body, created: headerParts?.created, expires: headerParts?.expires, }); From 468f45bcc776f7542f9d4711f42a324db31bc47b Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 16 May 2024 09:03:10 +0530 Subject: [PATCH 214/228] fix: npm crypto package --- .DS_Store | Bin 8196 -> 8196 bytes .../ondc-crypto-sdk-nodejs/package-lock.json | 4 ++-- utilities/ondc-crypto-sdk-nodejs/package.json | 2 +- .../ondc-crypto-sdk-nodejs/src/types/index.ts | 4 ++-- .../src/utility/index.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.DS_Store b/.DS_Store index 2428609d3145ccc800b318fe537a46663547dda1..ec27d074a32fc092fa236281f3ac128f81448ec2 100644 GIT binary patch delta 77 zcmZp1XmQwZScq}^WFLV-HSy|dQwtphBSYg_9ffL3BLf`;Q&WrDT22m8Wqs?Q`0SkA hy!_6|F~ahUU6Tuh#5PY7E@j!wCh?tR^FI-GW&oK=7r+1j delta 55 zcmZp1XmQwZSZK1hK&gn4xv7qVv8iRPjzYDik%5kaiJ8gdD+0!oO+ Date: Tue, 21 May 2024 15:53:10 +0530 Subject: [PATCH 215/228] fix: issue in header. header parsing failed issue resolved --- utilities/signing_and_verification/php/src/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/signing_and_verification/php/src/index.php b/utilities/signing_and_verification/php/src/index.php index b1b2936..07d265d 100644 --- a/utilities/signing_and_verification/php/src/index.php +++ b/utilities/signing_and_verification/php/src/index.php @@ -62,7 +62,7 @@ function create_authorisation_header(string $request_body, string $created = nul $subscriber_id = $_ENV['SUBSCRIBER_ID']; $unique_key_id = $_ENV['UNIQUE_KEY_ID']; - $header = "Signature keyId=\"$subscriber_id|$unique_key_id|ed25519\",algorithm=\"ed25519\",created=\"$created\",expires=\"$expires\",headers=\"($created) ($expires) digest\",signature=\"$signature\""; + $header = "Signature keyId=\"$subscriber_id|$unique_key_id|ed25519\",algorithm=\"ed25519\",created=\"$created\",expires=\"$expires\",headers=\"(created) (expires) digest\",signature=\"$signature\""; return $header; } From d5306259b7f0ca22b49873bf0cb7a9da965ed36c Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 24 May 2024 02:47:43 +0530 Subject: [PATCH 216/228] fix: Node js crypto utilities and added IGM utility --- utilities/ondc-igm-sdk/.gitignore | 3 + utilities/ondc-igm-sdk/.prettierrc | 5 + utilities/ondc-igm-sdk/jestconfig.json | 7 + utilities/ondc-igm-sdk/package.json | 46 ++ utilities/ondc-igm-sdk/src/.DS_Store | Bin 0 -> 6148 bytes .../ondc-igm-sdk/src/constants/endpoints.ts | 5 + .../ondc-igm-sdk/src/igmManager/.DS_Store | Bin 8196 -> 8196 bytes .../src/igmManager/Issue/index.ts | 5 + .../src/igmManager/Issue/service.ts | 116 +++ .../igmManager/controller/igm.controller.ts | 51 ++ .../src/igmManager/interfaces/igm.types.ts | 48 ++ .../src/igmManager/interfaces/issue.types.ts | 161 ++++ .../igmManager/interfaces/issueBase.types.ts | 189 +++++ .../src/igmManager/interfaces/manager.type.ts | 65 ++ .../src/igmManager/manager/buyer/index.ts | 54 ++ .../src/igmManager/manager/logistics/index.ts | 50 ++ .../src/igmManager/manager/seller/index.ts | 91 ++ .../igmManager/middleware/requestValidator.ts | 46 ++ .../src/igmManager/routes/igm.routes.ts | 56 ++ .../services/buyerServices/index.ts | 277 +++++++ .../src/igmManager/services/igm.services.ts | 44 + .../services/logisticsServices/index.ts | 418 ++++++++++ .../services/sellerServices/index.ts | 544 ++++++++++++ utilities/ondc-igm-sdk/src/index.ts | 3 + utilities/ondc-igm-sdk/src/shared/cityCode.ts | 778 ++++++++++++++++++ utilities/ondc-igm-sdk/src/shared/contents.ts | 58 ++ .../ondc-igm-sdk/src/utils/commonFunction.ts | 7 + .../ondc-igm-sdk/src/utils/httpRequest.ts | 92 +++ utilities/ondc-igm-sdk/src/utils/posApi.ts | 32 + .../src/utils/schema/OnIssueStatus.schema.ts | 170 ++++ .../ondc-igm-sdk/src/utils/schema/index.ts | 16 + .../src/utils/schema/issue.schema.ts | 263 ++++++ .../src/utils/schema/issueStatus.scehma.ts | 63 ++ .../utils/schema/logistics.issue.schema.ts | 137 +++ .../utils/schema/logistics.onIssue.schema.ts | 137 +++ .../src/utils/schema/on_issue.schema.ts | 72 ++ .../src/utils/validator.schema.ts | 16 + utilities/ondc-igm-sdk/tsconfig.json | 12 + utilities/ondc-igm-sdk/tslint.json | 3 + 39 files changed, 4140 insertions(+) create mode 100644 utilities/ondc-igm-sdk/.gitignore create mode 100644 utilities/ondc-igm-sdk/.prettierrc create mode 100644 utilities/ondc-igm-sdk/jestconfig.json create mode 100644 utilities/ondc-igm-sdk/package.json create mode 100644 utilities/ondc-igm-sdk/src/.DS_Store create mode 100644 utilities/ondc-igm-sdk/src/constants/endpoints.ts rename .DS_Store => utilities/ondc-igm-sdk/src/igmManager/.DS_Store (76%) create mode 100644 utilities/ondc-igm-sdk/src/igmManager/Issue/index.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/Issue/service.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/controller/igm.controller.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/interfaces/igm.types.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/interfaces/issue.types.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/interfaces/issueBase.types.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/interfaces/manager.type.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/manager/buyer/index.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/manager/logistics/index.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/manager/seller/index.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/middleware/requestValidator.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/routes/igm.routes.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/services/buyerServices/index.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/services/igm.services.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/services/logisticsServices/index.ts create mode 100644 utilities/ondc-igm-sdk/src/igmManager/services/sellerServices/index.ts create mode 100644 utilities/ondc-igm-sdk/src/index.ts create mode 100644 utilities/ondc-igm-sdk/src/shared/cityCode.ts create mode 100644 utilities/ondc-igm-sdk/src/shared/contents.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/commonFunction.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/httpRequest.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/posApi.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/OnIssueStatus.schema.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/index.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/issue.schema.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/issueStatus.scehma.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/logistics.issue.schema.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/logistics.onIssue.schema.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/schema/on_issue.schema.ts create mode 100644 utilities/ondc-igm-sdk/src/utils/validator.schema.ts create mode 100644 utilities/ondc-igm-sdk/tsconfig.json create mode 100644 utilities/ondc-igm-sdk/tslint.json diff --git a/utilities/ondc-igm-sdk/.gitignore b/utilities/ondc-igm-sdk/.gitignore new file mode 100644 index 0000000..a64ade4 --- /dev/null +++ b/utilities/ondc-igm-sdk/.gitignore @@ -0,0 +1,3 @@ +node_modules +/lib +/example \ No newline at end of file diff --git a/utilities/ondc-igm-sdk/.prettierrc b/utilities/ondc-igm-sdk/.prettierrc new file mode 100644 index 0000000..a0d1c9a --- /dev/null +++ b/utilities/ondc-igm-sdk/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 120, + "trailingComma": "all", + "singleQuote": true +} diff --git a/utilities/ondc-igm-sdk/jestconfig.json b/utilities/ondc-igm-sdk/jestconfig.json new file mode 100644 index 0000000..20c25c0 --- /dev/null +++ b/utilities/ondc-igm-sdk/jestconfig.json @@ -0,0 +1,7 @@ +{ + "transform": { + "^.+\\.(t|j)sx?$": "ts-jest" + }, + "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"] +} diff --git a/utilities/ondc-igm-sdk/package.json b/utilities/ondc-igm-sdk/package.json new file mode 100644 index 0000000..abff505 --- /dev/null +++ b/utilities/ondc-igm-sdk/package.json @@ -0,0 +1,46 @@ +{ + "name": "ondc-igm-sdk", + "version": "1.0.0", + "description": "ONDC official IGM Package", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "homepage": "https://github.com/robin-chauhan1/ondc-igm-sdk", + "scripts": { + "test": "jest --config jestconfig.json", + "build": "tsc", + "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"", + "lint": "tslint -p tsconfig.json", + "prepare": "npm run build", + "prepublishOnly": "npm run lint", + "preversion": "npm run lint", + "version": "npm run format && git add -A src", + "postversion": "git push && git push --tags" + }, + "repository": { + "type": "git", + "url": "https://github.com/robin-chauhan1/ondc-igm-sdk" + }, + "keywords": [], + "author": "", + "license": "ISC", + "devDependencies": { + "@types/express": "^4.17.17", + "@types/jest": "^29.5.3", + "@types/uuid": "^9.0.2", + "jest": "^29.6.1", + "nodemon": "^3.0.1", + "prettier": "^3.0.0", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "typescript": "^5.1.6" + }, + "dependencies": { + "axios": "^1.4.0", + "express": "^4.18.2", + "firebase-admin": "^11.10.1", + "joi": "^17.9.2", + "uuid": "^9.0.0" + } +} diff --git a/utilities/ondc-igm-sdk/src/.DS_Store b/utilities/ondc-igm-sdk/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..aa2dbf0d048851ce28a74248bb0a0e1c24cf528c GIT binary patch literal 6148 zcmeHKy-EW?5T4aUVr)`c$rYA1K|u=xXE?DE0%^3%pCp0A3;F5q2?TAdd=U#fA3@*2 z2e9{>*)`cSIkXay8QA@n*_qw%zTDnqiO5uEoib60hze+oxgxq1#`D~kY|VK%*~l7G zYSJ}LX)@?8MXN&lve#t%!_&e;Y zRJlmc`W&MC{@d-5aPabd2CE~|`+vSLOhfIDD}b8KR@kzry(*vzr~-2Z`1=r`F@_Ek zi}L9}CszPq4sJ1wrDg*Ib^t?%iA8u|#-;*os&Q8gW7FXeTwLfdv1rrD$j(^D?QGl) z#mMgP2NF)UGTX8Cs(>o6P+;8-OI-g?v+w_l1RbdYs=&Wfz~rKORK;Vt+Pd_BTx$cg q1{xd3B^D(Goh!#O;8MJeCWg6y2f)x_Vi6vg{t*xvv{MCsRe=xG4v{JV literal 0 HcmV?d00001 diff --git a/utilities/ondc-igm-sdk/src/constants/endpoints.ts b/utilities/ondc-igm-sdk/src/constants/endpoints.ts new file mode 100644 index 0000000..addb2e7 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/constants/endpoints.ts @@ -0,0 +1,5 @@ +const ALL_ROUTES = { + ISSUE: '/issue', +}; + +export default ALL_ROUTES; diff --git a/.DS_Store b/utilities/ondc-igm-sdk/src/igmManager/.DS_Store similarity index 76% rename from .DS_Store rename to utilities/ondc-igm-sdk/src/igmManager/.DS_Store index ec27d074a32fc092fa236281f3ac128f81448ec2..25443adb696ff04a0f73382724450b8374015f04 100644 GIT binary patch literal 8196 zcmeHMF>4e-6n^8yb8`w>rZFrSu@hn=h=KLEL?n&o3JXCrx$_L%-G+;I>B54wq)w3^ zA*8amHW2&?_7?sCzxQVJW^QMVjYjazGV?7v-`n@)%gk=xhKNja+*u}CAfg1F@!Dk! zk;e1fOYMTYavf+8Pc)*O`Z&5c)20rn1L}Y}pbn@5|DpqUXLCy`-ure|M|D6Q_%9vc z=R=Clm^myg%A*5=lmNgvT$YA&)BzHcI?Nmv79|w-wAF)gp~jUM#)e})WjZi(SXi{- zWNbJYm)W=q#YlFE9)C~KR&4Dc7B_?^V-iZyShQ!qLRNZyrP#--KE`7=gkk2JHqpInk$E2 zzOFc(QSMadS=>NbXx5qfL#T@Kd~HvgHtii}VeT8RnL!Gh)>#|42*ej*AmrS59nD=$9-+H^@ z_Qnin`rE7GM06xrJG>7ja4oVAmX4sM#PRj4zFT|x&H5DKO*Q?B7wVF=kF_m60aHle zwVpXFEaD29zW>Dr9n^tybD(B3FL3?8TK)b1-1KQ;bwC~X^A4D~R=d?i9{Xx8C*)c? tMSp?Ljd_Jd3BkY=zAoiB@aI1aah|%l%wb^>GidsUfY_jeI`CH=_zsk5{?q^f literal 8196 zcmeHMO-~a+7=8y)wp3uXplG5tX-qr-77&$iuoesf|L*1~QX?C|DHYB~O zR}*hu`~iB?Kj1Gg@uq)4k9yK~X0}ka66C{-!}B?Z=df)yS?dn1fL1^&pcT*xXa$af0{G4r$vEJ> zuSRvL70?PCO9jOJ5XUSq6<|%FygIOuApl}KcFTly`PCmWE;A*r z5Q7Af15tDwPX+chg^CVDdd7JI&m@RYNDz3CxHJcnQm9L_1&SuCk8M`qTWMZl1y6D_YQTsXk*wKYt&S#d48%u9 z$9D$e)$x(!KzwX8xw8{7`V!YC=Cd14iSbuzsU)~AK&-Pdy~f7wdNwmIb2uwvpRkYC z^?(v^C_n`qpx}kn`GA&<>O^53T(oE4qcua`ATsR`OK3XOplK&OfEk#Cd+-P{SPr4j zLWmfoLtvAhZ9@Gey}EcEh84 z+ivW3XxqKSMPNE`+lg)2VqtcEGdNJ>O?_cM>IW*)89m+A-D95VIolJ9_4b`Rf9^uo zjODESM$r|AWRg4FO*<93QgrP?rflVHR$TJwb3bFhpjq>5$aJ0-p6qokY?sldcdtWE zH|mK!&8tTid9v-4p@i5PpeVa3Hk-8q@nq%dtGt1K4_jzgA za$SoRX?i;_e@YSdXKr;G_bqDa0O3hyFu=e*a6|b#c5E_y@=M Bau@&r diff --git a/utilities/ondc-igm-sdk/src/igmManager/Issue/index.ts b/utilities/ondc-igm-sdk/src/igmManager/Issue/index.ts new file mode 100644 index 0000000..a1d3e43 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/Issue/index.ts @@ -0,0 +1,5 @@ +import Issue from './service'; + +const issue = new Issue(); + +export default issue; diff --git a/utilities/ondc-igm-sdk/src/igmManager/Issue/service.ts b/utilities/ondc-igm-sdk/src/igmManager/Issue/service.ts new file mode 100644 index 0000000..98a4b98 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/Issue/service.ts @@ -0,0 +1,116 @@ +import { IGM_ROUTES, EvaluateRoute, IssuesParamaters, ERROR_CODES } from '../interfaces/igm.types'; +import igmController from '../controller/igm.controller'; +import BuyerManager from '../manager/buyer'; +import { RouteSpecificManagerProps } from '../interfaces/manager.type'; +import SellerManager from '../manager/seller'; +import LogisticsServices from '../services/logisticsServices'; + +const buyerManager = new BuyerManager(); +const sellerManager = new SellerManager(); +const logisticsService = new LogisticsServices(); + +class Issues { + config: IssuesParamaters | undefined; + + init(params: IssuesParamaters) { + if (!this.config) this.config = { ...params }; + else throw new Error('Issues class has already been initialised'); + } + + /** + * Evaluates the provided route and invokes the corresponding controller function. + * + * @param req - The HTTP request object. + * @param res - The HTTP response object. + * @param route - The route to be evaluated. + * @returns An object with error information if an error occurs; otherwise, it returns undefined. + */ + evaluateRoute({ req, res, route }: EvaluateRoute) { + try { + switch (route) { + case IGM_ROUTES.ISSUE: + // TO-DO: split validation logic in different function + + if (!(this.config?.npType.includes('SELLER') || this.config?.npType.includes('LOGISTICS'))) + throw new Error('issue endpoint cannot be hosted if NP is not seller'); + igmController.issue({ req, res }); + + // TO-DO: split post-callback action in different function + if (this.config.onSuccess?.[IGM_ROUTES.ISSUE]) { + this.config.onSuccess?.[IGM_ROUTES.ISSUE](''); + } + break; + case IGM_ROUTES.ON_ISSUE: + // TO-DO: split validation logic in different function + if (!this.config?.npType.includes('BUYER')) + throw new Error('on_issue endpoint cannot be hosted if NP is not buyer'); + igmController.on_issue(req, res); + // TO-DO: split post-callback action in different function + if (this.config.onSuccess?.[IGM_ROUTES.ON_ISSUE]) { + this.config.onSuccess?.[IGM_ROUTES.ON_ISSUE](''); + } + break; + case IGM_ROUTES.ISSUE_STATUS: + // TO-DO: split validation logic in different function + if (!(this.config?.npType.includes('SELLER') || this.config?.npType.includes('LOGISTICS'))) + throw new Error('issue_status endpoint cannot be hosted if NP is not seller'); + igmController.issue_status(req, res); + // TO-DO: split post-callback action in different function + if (this.config.onSuccess?.[IGM_ROUTES.ISSUE_STATUS]) { + this.config.onSuccess?.[IGM_ROUTES.ISSUE_STATUS](''); + } + break; + case IGM_ROUTES.ON_ISSUE_STATUS: + // TO-DO: split validation logic in different function + if (!this.config?.npType.includes('BUYER')) + throw new Error('on_issue_status endpoint cannot be hosted if NP is not buyer'); + igmController.on_issue_status(req, res); + // TO-DO: split post-callback action in different function + if (this.config.onSuccess?.[IGM_ROUTES.ON_ISSUE_STATUS]) { + this.config.onSuccess?.[IGM_ROUTES.ON_ISSUE_STATUS](''); + } + break; + default: + throw new Error('Unknown route'); + } + } catch (err: any) { + const errPayload = { message: err?.message, code: ERROR_CODES.ROUTE_NOT_VALID }; + console.log('here', this.config?.onError); + if (this.config?.onError) this.config?.onError(errPayload); + return { ...errPayload, error: true }; + } + return { success: true }; + } + + buyerIssue({ issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return buyerManager.issue({ issue, onError, onNack, onSuccess }); + } + + sellerOnIssue({ on_issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return sellerManager.on_issue({ on_issue, onError, onNack, onSuccess }); + } + + buyerIsseStatus({ issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return buyerManager.issue_status({ issue_status, onError, onNack, onSuccess }); + } + + sellerOnIssueStatus({ on_issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return sellerManager.on_issue_status({ on_issue_status, onError, onNack, onSuccess }); + } + + issueSellerToLogisitics({ issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return sellerManager.logistics_issue({ issue, onError, onNack, onSuccess }); + } + issueStatusSellerToLogisitics({ issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return sellerManager.logistics_issue_status({ issue_status, onError, onNack, onSuccess }); + } + + onIssueFromLogisitics({ on_issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return logisticsService.on_issue({ on_issue, onError, onNack, onSuccess }); + } + onIssueStatusFromLogistics({ on_issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + return logisticsService.on_issue_status({ on_issue_status, onError, onNack, onSuccess }); + } +} + +export default Issues; diff --git a/utilities/ondc-igm-sdk/src/igmManager/controller/igm.controller.ts b/utilities/ondc-igm-sdk/src/igmManager/controller/igm.controller.ts new file mode 100644 index 0000000..6707a1c --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/controller/igm.controller.ts @@ -0,0 +1,51 @@ +import { Request, Response } from 'express'; +import IgmServices from '../services/igm.services'; + +const igmServices = new IgmServices(); + +class IGMController { + constructor() { + this.issue = this.issue.bind(this); + } + + /** + * Handles an issue-related HTTP request and invokes the corresponding service method. + * + * @param req - The HTTP request object. + * @param res - The HTTP response object. + */ + + async issue({ req, res }: { req: Request; res: Response }) { + try { + igmServices.issue(req, res); + } catch (err) { + console.log(err); + } + } + + on_issue(req: Request, res: Response) { + try { + igmServices.on_issue(req, res); + } catch (err) { + console.log(err); + } + } + + issue_status(req: Request, res: Response) { + try { + igmServices.issue_status(req, res); + } catch (err) { + console.log(err); + } + } + + on_issue_status(req: Request, res: Response) { + try { + igmServices.on_issue_status(req, res); + } catch (err) { + console.log(err); + } + } +} + +export default new IGMController(); diff --git a/utilities/ondc-igm-sdk/src/igmManager/interfaces/igm.types.ts b/utilities/ondc-igm-sdk/src/igmManager/interfaces/igm.types.ts new file mode 100644 index 0000000..064e02c --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/interfaces/igm.types.ts @@ -0,0 +1,48 @@ +import { Request, Response } from 'express'; + +export enum IGM_ROUTES { + ISSUE = 'issue', + ON_ISSUE = 'on_issue', + ISSUE_STATUS = 'issue_status', + ON_ISSUE_STATUS = 'on_issue_status', +} + +export enum ERROR_CODES { + ROUTE_NOT_VALID = 'ROUTE_NOT_VALID', +} + +export type DOMAINS = 'RETAIL' | 'MOBILITY' | 'LOGISTICS'; + +export type NP_TYPES = 'BUYER' | 'SELLER' | 'LOGISTICS'; + +export type IgmRoutes = IGM_ROUTES.ISSUE | IGM_ROUTES.ON_ISSUE | IGM_ROUTES.ISSUE_STATUS | IGM_ROUTES.ON_ISSUE_STATUS; + +export interface EvaluateRoute { + req: Request; + res: Response; + route: IgmRoutes; +} + +export interface IssueParameterContext { + subscriberType: NP_TYPES; + subscriberId: string; + subscriberURL: string; + subscriberDomain: string; + subscriberCountry: string; + subcriberState: string; + subscriberCity: string; + expected_response_time: string; + expected_resolution_time: string; + ttl: string; +} + +export interface IssuesParamaters { + validateSchema: boolean; + domain: DOMAINS[]; + npType: NP_TYPES[]; + context: IssueParameterContext[]; + onSuccess?: { + [k in IgmRoutes]?: (args: T) => any; + }; + onError?: (args: K) => any; +} diff --git a/utilities/ondc-igm-sdk/src/igmManager/interfaces/issue.types.ts b/utilities/ondc-igm-sdk/src/igmManager/interfaces/issue.types.ts new file mode 100644 index 0000000..174b35f --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/interfaces/issue.types.ts @@ -0,0 +1,161 @@ +import { + ComplainantInfo, + Context, + IBaseIssue, + Issue, + IssueActions, + Item, + Message, + OrderDetails, + Person, +} from './issueBase.types'; + +export type ChangeFields = Omit & R; + +export type OmitKey = Pick>; + +// use this for /on_issue +export type OnIssue = ChangeFields< + Omit, + { + context: Omit; + message: ChangeFields< + Message, + { + issue: ChangeFields< + Omit< + Issue, + | 'order_details' + | 'issue_type' + | 'category' + | 'complainant_info' + | 'description' + | 'expected_resolution_time' + | 'expected_response_time' + | 'source' + | 'status' + | 'sub_category' + | 'rating' + | 'resolution' + | 'resolution_provider' + >, + { + issue_actions: Omit; + } + >; + } + >; + } +>; + +// issue for logistics payload +export type IssueRequestLogistics = ChangeFields< + Omit, + { + message: ChangeFields< + Message, + { + issue: ChangeFields< + Omit, + { + complainant_info: ChangeFields< + ComplainantInfo, + { + person: Omit; + } + >; + + order_details: ChangeFields< + Omit, + { + items: Omit[]; + } + >; + } + >; + } + >; + } +>; + +export type IssueRequestLogisticsResolved = ChangeFields< + Omit, + { + message: ChangeFields< + Message, + { + issue: ChangeFields< + Issue, + { + complainant_info: ChangeFields< + ComplainantInfo, + { + person: Omit; + } + >; + order_details: ChangeFields< + Omit, + { + items: Omit[]; + } + >; + } + >; + } + >; + } +>; + +// issue_request contains complainent actions +export type IssueRequest = ChangeFields< + IBaseIssue, + { + message: ChangeFields< + Message, + { + issue: Omit; + } + >; + } +>; + + +// use this for /on_issue_status when Seller has RESOLVED the issue + +export type OnIssueStatusResoloved = ChangeFields< + Omit, + { + context: Omit; + message: ChangeFields< + Message, + { + issue: ChangeFields< + Omit< + Issue, + | 'order_details' + | 'issue_type' + | 'category' + | 'complainant_info' + | 'description' + | 'expected_resolution_time' + | 'expected_response_time' + | 'source' + | 'status' + | 'sub_category' + | 'rating' + >, + { + issue_actions: Omit; + } + >; + } + >; + } +>; + +export type IssueStatusPayload = { + context: Context; + message: { + issue_id: string; + }; +}; diff --git a/utilities/ondc-igm-sdk/src/igmManager/interfaces/issueBase.types.ts b/utilities/ondc-igm-sdk/src/igmManager/interfaces/issueBase.types.ts new file mode 100644 index 0000000..aeb502f --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/interfaces/issueBase.types.ts @@ -0,0 +1,189 @@ +/// Base interface for all the All Responses +export interface IBaseIssue { + context: Context; + message: Message; +} +export interface Context { + domain: string; + country: string; + city: string; + state?: string; + action: string; + core_version: string; + bap_id: string; + bap_uri: string; + bpp_id: string; + bpp_uri: string; + transaction_id: string; + message_id: string; + timestamp: string; + ttl: string; +} +export interface Message { + issue: Issue; +} + +export enum Rating { + 'THUMBS-UP', + 'THUMBS-DOWN', +} + +export interface Issue { + id: string; + category: string; + sub_category: string; + complainant_info: ComplainantInfo; + order_details: OrderDetails; + description: Description; + source: Source; + expected_response_time: ExpectedResTime; + expected_resolution_time: ExpectedResTime; + status: string; + issue_type: string; + issue_actions: IssueActions; + rating?: Rating; + resolution: Resolution | ResolutionWithoutRefund; + resolution_provider: ResolutionProvider; + created_at: string; + updated_at: string; +} + +export interface ResolutionProvider { + respondent_info: RespondentInfo; +} + +export interface Organization { + org: Org; + contact: Contact; + person: Org; +} + +export interface Contact { + phone: string; + email: string; +} + +export interface Org { + name: string; +} + +export interface ResolutionSupport { + chat_link: string; + contact: Contact; + gros: Gro[]; +} + +export interface Gro { + person: Org; + contact: Contact; + gro_type: string; +} + +export interface RespondentInfo { + type: string; + organization: Organization; + resolution_support: ResolutionSupport; +} + +export interface Resolution { + short_desc: string; + long_desc: string; + action_triggered: 'REFUND'; + refund_amount: string; +} + +export interface ResolutionWithoutRefund { + short_desc: string; + long_desc: string; + action_triggered: 'RESOLVED' | 'REPLACE' | 'NO-ACTION' | 'CASCADED' | string; +} + +export interface ComplainantInfo { + person: Person; + contact: ComplainantInfoContact; +} +export interface ComplainantInfoContact { + phone: string; + email: string; +} +export interface Person { + name: string; + email: string; +} +export interface Description { + short_desc: string; + long_desc: string; + additional_desc: AdditionalDesc; + images: string[]; +} +export interface AdditionalDesc { + url: string; + content_type: string; +} +export interface ExpectedResTime { + duration: string; +} +export interface IssueActions { + complainant_actions: ComplainantAction[]; + respondent_actions: RespondentAction[]; +} +export interface ComplainantAction { + complainant_action: string; + short_desc: string; + updated_at: string; + updated_by: UpdatedBy; +} +export interface UpdatedBy { + org: Org; + contact: UpdatedByContact; + person: Org; +} +export interface RespondentAction { + respondent_action: string; + short_desc: string; + updated_at: string; + updated_by: UpdatedBy; + cascaded_level: number; +} + +export interface UpdatedBy { + org: Org; + contact: Contact; + person: Org; +} + +export interface Contact { + phone: string; + email: string; +} + +export interface Org { + name: string; +} +export interface UpdatedByContact { + phone: string; + email: string; +} +export interface Org { + name: string; +} +export interface OrderDetails { + id: string; + state: string; + items: Item[]; + fulfillments: Fulfillment[]; + provider_id: string; + merchant_order_id?: string; +} +export interface Fulfillment { + id: string; + state: string; +} +export interface Item { + id: string; + quantity: number; +} +export interface Source { + network_participant_id: string; + type: string; +} diff --git a/utilities/ondc-igm-sdk/src/igmManager/interfaces/manager.type.ts b/utilities/ondc-igm-sdk/src/igmManager/interfaces/manager.type.ts new file mode 100644 index 0000000..e807da1 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/interfaces/manager.type.ts @@ -0,0 +1,65 @@ +import { ChangeFields, IssueRequest, IssueStatusPayload, OnIssue, OnIssueStatusResoloved } from './issue.types'; + +export type IssuePayloadProps = ChangeFields< + IssueRequest, + { + context: Omit< + IssueRequest['context'], + 'bap_id' | 'bap_uri' | 'city' | 'state' | 'country' | 'timestamp' | 'transaction_id' | 'message_id' + >; + message: { + issue: Omit; + }; + } +>; + +export type OnIssuePayloadProps = ChangeFields< + IssueRequest, + { + context: Omit; + message: { + issue: Omit; + }; + } +>; + +export type IssueStatusPayloadProps = ChangeFields< + IssueStatusPayload, + { + context: Omit< + IssueStatusPayload['context'], + 'bap_id' | 'bap_uri' | 'city' | 'state' | 'country' | 'domain' | 'core_version' + >; + } +>; + +export type OnIssueStatusPayloadProps = ChangeFields< + OnIssueStatusResoloved, + { + context: Omit< + IssueStatusPayload['context'], + 'bpp_id' | 'bpp_uri' | 'city' | 'state' | 'country' | 'domain' | 'core_version' + >; + } +>; + +interface Callbacks { + onSuccess: (successResponse: any) => void; + onError: (errorResponse: any) => void; + onNack: (nackResponse: any) => void; +} + +export type ManagerProps = { + issue?: U; + on_issue?: V; + issue_status?: W; + on_issue_status?: K; +} & Callbacks; + +export type RouteSpecificManagerProps = ManagerProps< + 'issue' | 'on_issue' | 'issue_status' | 'on_issue_status', + IssuePayloadProps, + OnIssuePayloadProps, + IssueStatusPayloadProps, + OnIssueStatusPayloadProps +>; diff --git a/utilities/ondc-igm-sdk/src/igmManager/manager/buyer/index.ts b/utilities/ondc-igm-sdk/src/igmManager/manager/buyer/index.ts new file mode 100644 index 0000000..14e1d10 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/manager/buyer/index.ts @@ -0,0 +1,54 @@ +import { RouteSpecificManagerProps } from '../../interfaces/manager.type'; +import BuyerServices from '../../services/buyerServices'; + +const buyerServices = new BuyerServices(); + +class BuyerManager { + constructor() { + this.issue = this.issue.bind(this); + } + + async issue({ issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await buyerServices.issue(issue!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } + + async issue_status({ issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await buyerServices.issue_status(issue_status!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } +} + +export default BuyerManager; diff --git a/utilities/ondc-igm-sdk/src/igmManager/manager/logistics/index.ts b/utilities/ondc-igm-sdk/src/igmManager/manager/logistics/index.ts new file mode 100644 index 0000000..48bdbde --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/manager/logistics/index.ts @@ -0,0 +1,50 @@ +import { RouteSpecificManagerProps } from '../../interfaces/manager.type'; +import LogisticsServices from '../../services/logisticsServices'; + +const logisticsService = new LogisticsServices(); + +class LogisticsManager { + async on_issue({ on_issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await logisticsService.on_issue(on_issue!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } + + async on_issue_status({ on_issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await logisticsService.on_issue_status(on_issue_status!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } +} + +export default LogisticsManager; diff --git a/utilities/ondc-igm-sdk/src/igmManager/manager/seller/index.ts b/utilities/ondc-igm-sdk/src/igmManager/manager/seller/index.ts new file mode 100644 index 0000000..5df1af6 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/manager/seller/index.ts @@ -0,0 +1,91 @@ +import { RouteSpecificManagerProps } from '../../interfaces/manager.type'; +import SellerService from '../../services/sellerServices'; + +const sellerService = new SellerService(); + +class SellerManager { + async logistics_issue({ issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await sellerService.issueToLogistics(issue!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } + + async logistics_issue_status({ issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await sellerService.issue_statusToLogistics(issue_status!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } + + async on_issue({ on_issue, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await sellerService.on_issue_post(on_issue!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } + async on_issue_status({ on_issue_status, onError, onNack, onSuccess }: RouteSpecificManagerProps) { + try { + const response: any = await sellerService.on_issue_status_post(on_issue_status!); + + if (response.status === 200) { + if (response.data.message.ack.status === 'ACK') { + return onSuccess(response.data); + } else { + if (onNack) { + return onNack(response.data); + } + } + } + return onError(response.data); + } catch (e) { + if (onError) { + onError(e); + } + } + } +} + +export default SellerManager; diff --git a/utilities/ondc-igm-sdk/src/igmManager/middleware/requestValidator.ts b/utilities/ondc-igm-sdk/src/igmManager/middleware/requestValidator.ts new file mode 100644 index 0000000..53cce29 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/middleware/requestValidator.ts @@ -0,0 +1,46 @@ +import { Request, NextFunction, Response } from 'express'; +import IssueInstance from '../Issue'; +import ALL_ROUTES from '../../constants/endpoints'; +import { IssueSchema } from '../../utils/schema'; + +/** + * Middleware for validating the request body against the given Joi schema. + * + * @param schema - The Joi schema used for request body validation. + * @returns A middleware function that validates the request body, returning a 400 response with error details if invalid. + */ + +function validateSchema({ requestedBody, url }: { url: string; requestedBody: T }) { + switch (url) { + case ALL_ROUTES.ISSUE: + const { error } = IssueSchema.validate(requestedBody); + return error; + + default: + return { message: 'Somthing went wrong in validation ' }; + } +} + +function validateRequest(req: Request, res: Response, next: NextFunction) { + // Check if the request URL contains 'issue' or 'issue_status' (with enabled schema validation) + + let validationError; + + if (IssueInstance.config?.validateSchema) { + // Validate the request body against the provided schema + + // (req.originalUrl.includes('issue') || (req.originalUrl.includes('issue_status') && )) + + validationError = validateSchema({ url: req.originalUrl, requestedBody: req.body }); + + if (validationError) { + console.log('error :', validationError.message); + return res.status(400).json({ Response: [], message: 'Invalid payload data', error: validationError.message }); + } + } + // If the validation passes, continue to the next middleware or route handler + + return next(); +} + +export { validateRequest }; diff --git a/utilities/ondc-igm-sdk/src/igmManager/routes/igm.routes.ts b/utilities/ondc-igm-sdk/src/igmManager/routes/igm.routes.ts new file mode 100644 index 0000000..03eeb1d --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/routes/igm.routes.ts @@ -0,0 +1,56 @@ +import express, { Response } from 'express'; +import issue from '../Issue'; +import { ERROR_CODES, IGM_ROUTES, IgmRoutes } from '../interfaces/igm.types'; +// import { validateRequest } from '../middleware/requestValidator'; +// import issueSchema from '../../utils/schema/issue.schema'; + +const router = express.Router(); + +/** + * Evaluates an error code and sends an appropriate HTTP response based on the error code. + * + * @param error - The error object containing the error code and other details. + * @param res - The HTTP response object used to send the response. + */ + +const evaluateErrorCode = (error: { [key: string]: any; code: ERROR_CODES }, res: Response) => { + switch (error.code) { + case ERROR_CODES.ROUTE_NOT_VALID: + return res.sendStatus(404); + default: + return res.json(500).json({ message: 'Something went wrong' }); + } +}; + +/** + * Route handler for handling issue-related POST requests with different routes. + * + * @param route - The route extracted from the request parameters. + * @param validateRequest - Middleware function for validating the request body against the issue schema. + * @param req - The HTTP request object. + * @param res - The HTTP response object. + */ + +// validateRequest(issueSchema), +router.post('/:route(issue|on_issue|issue_status|on_issue_status)', (req, res) => { + // Extract the 'route' from the request parameters and cast it to the 'IgmRoutes' type. + + const route: IgmRoutes = req.params.route; + + // If 'issue.config' is not available, throw an error indicating that IGM has not been initialized. + if (!issue.config) throw new Error('IGM has not been initialised'); + + // Evaluate the route using the 'evaluateRoute' method from the 'issue' object. + const response: any = issue.evaluateRoute({ req, res, route }); + + // If the response contains an error, handle the error using 'evaluateErrorCode' and send the appropriate HTTP response. + if (response?.error) { + return evaluateErrorCode(response, res); + } + + // If no error occurs, send a 200 response with the JSON containing the 'route' name. + // return res.status(200).json({ name: route }); + return; +}); + +export default router; diff --git a/utilities/ondc-igm-sdk/src/igmManager/services/buyerServices/index.ts b/utilities/ondc-igm-sdk/src/igmManager/services/buyerServices/index.ts new file mode 100644 index 0000000..2603312 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/services/buyerServices/index.ts @@ -0,0 +1,277 @@ +import { Response, Request } from 'express'; +import { AxiosResponse } from 'axios'; +import { v4 as uuid } from 'uuid'; +import { PROTOCOL_CONTEXT } from '../../../shared/contents'; +import { IssueStatusPayload, IssueRequest, OnIssue, OnIssueStatusResoloved } from '../../interfaces/issue.types'; +import IssueInstance from '../../Issue'; +import postApi from '../../../utils/posApi'; +import { IssuePayloadProps, IssueStatusPayloadProps } from '../../interfaces/manager.type'; +import { SchemaValidator } from '../../../utils/validator.schema'; +import { OnIssueSchema, OnIssueStatusScehma, OnIssueStatusResolovedSchema } from '../../../utils/schema'; +import { hasResolvedAction } from '../../../utils/commonFunction'; + +class BuyerServices { + constructor() { + this.issue = this.issue.bind(this); + ``; + } + + /** + * Creates and submits a new issue based on the provided request. + * + * @param req - The incoming HTTP request containing the issue data in the request body. + * @returns A promise that resolves to the response containing the status of the submitted issue. + * @throws Will throw an error if an issue schema validation fails or an API call encounters an error. + */ + async issue(issue: IssuePayloadProps) { + try { + const issueRequest: IssueRequest = { + context: { + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: PROTOCOL_CONTEXT.ISSUE, + core_version: '1.0.0', + bap_id: IssueInstance.config?.context[0].subscriberId!, + bap_uri: IssueInstance.config?.context[0].subscriberURL!, + bpp_id: issue.context.bpp_id, + bpp_uri: issue.context.bpp_uri, + transaction_id: uuid(), + message_id: uuid(), + timestamp: new Date().toISOString(), + ttl: issue.context.ttl, + }, + message: { + issue: { + id: uuid(), + category: issue.message.issue.category, + sub_category: issue.message.issue.sub_category, + complainant_info: issue.message.issue.complainant_info, + status: issue.message.issue.status || 'OPEN', + issue_type: PROTOCOL_CONTEXT?.ISSUE.toUpperCase(), + issue_actions: issue.message.issue.issue_actions, + order_details: { + id: issue.message.issue.order_details?.id, + state: issue.message.issue.order_details?.state, + items: issue.message.issue.order_details.items, + fulfillments: issue.message.issue.order_details.fulfillments, + provider_id: issue.message.issue.order_details?.provider_id, + }, + description: { + short_desc: issue.message.issue.description?.short_desc, + long_desc: issue.message.issue.description?.long_desc, + additional_desc: issue.message.issue.description?.additional_desc, + images: issue.message.issue.description?.images, + }, + source: { + network_participant_id: IssueInstance.config?.context[0].subscriberId!, + type: 'CONSUMER', + }, + expected_response_time: { + duration: IssueInstance.config?.context[0].expected_resolution_time!, + }, + expected_resolution_time: { + duration: IssueInstance.config?.context[0].expected_resolution_time!, + }, + created_at: issue.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + + const response: AxiosResponse = await postApi({ + baseUrl: issueRequest.context.bpp_uri, + data: issueRequest, + endpoint: PROTOCOL_CONTEXT.ISSUE, + method: 'POST', + }); + if (response.status === 200) { + return response; + } + return { payload: issueRequest, status: response.status, message: 'Something went wrong' }; + } catch (err) { + throw err; + } + } + + async on_issue(req: Request, res: Response) { + try { + const issueRequestpayload: OnIssue = req.body; + + const isOnIssueSchemaValid = SchemaValidator({ schema: OnIssueSchema, data: issueRequestpayload }); + + if (isOnIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isOnIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isOnIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.on_issue) { + IssueInstance.config?.onSuccess.on_issue({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + /** + * Retrieves the status of a specific issue based on the provided request. + * + * @param req - The incoming HTTP request containing the issue ID in the request body. + * @param res - The HTTP response object to send the issue status response. + * @returns A promise that resolves to the response containing the status of the requested issue. + * @throws Will throw an error if an API call encounters an error. + */ + async issue_status(payload: IssueStatusPayloadProps) { + try { + const issueStatusPayload: IssueStatusPayload = { + context: { + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: 'issue_status', + core_version: '1.0.0', + bap_id: IssueInstance.config?.context[0].subscriberId!, + bap_uri: IssueInstance.config?.context[0].subscriberURL!, + bpp_id: payload.context.bpp_id, + bpp_uri: payload.context.bpp_uri, + transaction_id: payload.context.transaction_id, + message_id: uuid(), + timestamp: payload.context.timestamp, + ttl: payload.context.ttl, + }, + message: { + issue_id: payload.message.issue_id, + }, + }; + + const response: AxiosResponse = await postApi({ + baseUrl: payload.context.bpp_uri, + data: issueStatusPayload, + endpoint: '/issue_status', + method: 'POST', + }); + return { payload: issueStatusPayload, data: response.data, status: response.status }; + } catch (err) { + throw err; + } + } + + async on_issue_status(req: Request, res: Response) { + let isOnIssueSchemaValid; + + try { + const issueRequestpayload: OnIssueStatusResoloved = req.body; + + const respondent_actions = issueRequestpayload.message.issue.issue_actions.respondent_actions; + + if (hasResolvedAction(respondent_actions)) { + isOnIssueSchemaValid = SchemaValidator({ schema: OnIssueStatusResolovedSchema, data: issueRequestpayload }); + } else { + isOnIssueSchemaValid = SchemaValidator({ schema: OnIssueStatusScehma, data: issueRequestpayload }); + } + + if (isOnIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isOnIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isOnIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.on_issue_status) { + IssueInstance.config?.onSuccess.on_issue_status({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } +} + +export default BuyerServices; diff --git a/utilities/ondc-igm-sdk/src/igmManager/services/igm.services.ts b/utilities/ondc-igm-sdk/src/igmManager/services/igm.services.ts new file mode 100644 index 0000000..8af77b0 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/services/igm.services.ts @@ -0,0 +1,44 @@ +import { Request, Response } from 'express'; +import BuyerServices from './buyerServices'; +import SellerService from './sellerServices'; +import IssueInstance from '../Issue/index'; +import LogisticsServices from './logisticsServices'; + +const sellerService = new SellerService(); +const buyerServices = new BuyerServices(); +const logisticsServices = new LogisticsServices(); +class IgmServices { + constructor() { + this.issue = this.issue.bind(this); + } + + issue(req: Request, res: Response) { + if (IssueInstance.config?.npType[0] === 'SELLER') { + return sellerService.issue(req, res); + } + return logisticsServices.issue(req, res); + } + + on_issue(req: Request, res: Response) { + if (IssueInstance.config?.npType[0] === 'BUYER') { + return buyerServices.on_issue(req, res); + } + return sellerService.on_issue(req, res); + } + + issue_status(req: Request, res: Response) { + if (IssueInstance.config?.npType[0] === 'SELLER') { + return sellerService.issue_status(req, res); + } + return logisticsServices.issue_status(req, res); + } + + on_issue_status(req: Request, res: Response) { + if (IssueInstance.config?.npType[0] === 'BUYER') { + return buyerServices.on_issue_status(req, res); + } + return sellerService.on_issue_status(req, res); + } +} + +export default IgmServices; diff --git a/utilities/ondc-igm-sdk/src/igmManager/services/logisticsServices/index.ts b/utilities/ondc-igm-sdk/src/igmManager/services/logisticsServices/index.ts new file mode 100644 index 0000000..043d898 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/services/logisticsServices/index.ts @@ -0,0 +1,418 @@ +import { Request, Response } from 'express'; +import IssueInstance from '../../Issue/'; +import { SchemaValidator } from '../../../utils/validator.schema'; +import { IssueStatusSchema, LogisticsIssueSchema } from '../../../utils/schema'; +import { IssueStatusPayload, OnIssue } from '../../interfaces/issue.types'; +import { AxiosResponse } from 'axios'; +import postApi from '../../../utils/posApi'; +import { hasRefundKey, hasResolvedAction } from '../../../utils/commonFunction'; + +class LogisticsServices { + async issue(req: Request, res: Response) { + try { + const issueRequestpayload: OnIssue = req.body; + + const isIssueSchemaValid = SchemaValidator({ schema: LogisticsIssueSchema, data: issueRequestpayload }); + + if (isIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.issue) { + IssueInstance.config?.onSuccess.issue({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + async issue_status(req: Request, res: Response) { + try { + const issueRequestpayload: IssueStatusPayload = req.body; + + const isIssueSchemaValid = SchemaValidator({ schema: IssueStatusSchema, data: issueRequestpayload }); + + if (isIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.issue_status) { + IssueInstance.config?.onSuccess.issue_status({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + async on_issue(payload: any) { + let on_issue_payload; + if (!hasResolvedAction(payload.message.issue.issue_actions.respondent_actions)) { + on_issue_payload = { + context: { + ttl: payload.context.ttl, + domain: payload.context.domain, + country: payload.context.country, + city: payload.context.city, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + complainant_actions: payload.message.issue.issue_actions.complainant_actions, + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + created_at: payload.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + } else if (hasRefundKey(payload)) { + on_issue_payload = { + context: { + ttl: payload.context.ttl, + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + complainant_actions: payload.message.issue.issue_actions.complainant_actions, + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + resolution_provider: { + respondent_info: { + organization: { + contact: { + email: payload.message.issue.resolution_provider.respondent_info.organization.contact.email, + phone: payload.message.issue.resolution_provider.respondent_info.organization.contact.phone, + }, + org: { + name: payload.message.issue.resolution_provider.respondent_info.organization.org.name, + }, + person: { + name: payload.message.issue.resolution_provider.respondent_info.organization.person.name, + }, + }, + type: payload.message.issue.resolution_provider.respondent_info.type, + resolution_support: { + chat_link: payload.message.issue.resolution_provider.respondent_info.resolution_support.chat_link, + contact: { + phone: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.phone, + email: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.email, + }, + gros: payload.message.issue.resolution_provider.respondent_info.resolution_support.gros, + }, + }, + }, + resolution: { + short_desc: payload.message.issue.resolution.short_desc, + long_desc: payload.message.issue.resolution.long_desc, + action_triggered: 'REFUND', + refund_amount: payload.message.issue.resolution.refund_amount, + }, + created_at: payload.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + } else { + on_issue_payload = { + context: { + ttl: payload.context.ttl, + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + complainant_actions: payload.message.issue.issue_actions.complainant_actions, + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + resolution_provider: { + respondent_info: { + organization: { + contact: { + email: payload.message.issue.resolution_provider.respondent_info.organization.contact.email, + phone: payload.message.issue.resolution_provider.respondent_info.organization.contact.phone, + }, + org: { + name: payload.message.issue.resolution_provider.respondent_info.organization.org.name, + }, + person: { + name: payload.message.issue.resolution_provider.respondent_info.organization.person.name, + }, + }, + type: payload.message.issue.resolution_provider.respondent_info.type, + resolution_support: { + chat_link: payload.message.issue.resolution_provider.respondent_info.resolution_support.chat_link, + contact: { + phone: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.phone, + email: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.email, + }, + gros: payload.message.issue.resolution_provider.respondent_info.resolution_support.gros, + }, + }, + }, + resolution: { + short_desc: payload.message.issue.resolution.short_desc, + long_desc: payload.message.issue.resolution.long_desc, + action_triggered: payload.message.issue.resolution.action_triggered, + }, + created_at: payload.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + } + + try { + const response: AxiosResponse = await postApi({ + baseUrl: payload.context.bap_uri, + data: on_issue_payload, + endpoint: '/on_issue_status', + method: 'POST', + }); + + if (response.status === 200) { + return response; + } + + return { payload: on_issue_payload, status: response.status, message: 'Something went wrong' }; + } catch (e) { + return e; + } + } + + async on_issue_status(payload: any) { + console.log('🚀 ~ file: index.ts:310 ~ LogisticsServices ~ on_issue_status ~ payload:', payload); + let on_issue_payload; + + if (hasResolvedAction(payload.message.issue.issue_actions.respondent_actions)) { + on_issue_payload = { + context: { + ttl: payload.context.ttl, + domain: payload.context.domain, + country: payload.context.country, + city: payload.context.city, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + complainant_actions: payload.message.issue.issue_actions.complainant_actions, + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + resolution_provider: { + respondent_info: { + organization: { + contact: { + email: payload.message.issue.resolution_provider.respondent_info.organization.contact.email, + phone: payload.message.issue.resolution_provider.respondent_info.organization.contact.phone, + }, + org: { + name: payload.message.issue.resolution_provider.respondent_info.organization.org.name, + }, + person: { + name: payload.message.issue.resolution_provider.respondent_info.organization.person.name, + }, + }, + type: payload.message.issue.resolution_provider.respondent_info.type, + resolution_support: { + chat_link: payload.message.issue.resolution_provider.respondent_info.resolution_support.chat_link, + contact: { + phone: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.phone, + email: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.email, + }, + gros: payload.message.issue.resolution_provider.respondent_info.resolution_support.gros, + }, + }, + }, + resolution: payload.message.issue.resolution, + created_at: payload.message.issue.created_at, + updated_at: payload.message.issue.updated_at, + }, + }, + }; + } else { + on_issue_payload = { + context: { + ttl: payload.context.ttl, + domain: payload.context.domain, + country: payload.context.country, + city: payload.context.city, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + complainant_actions: payload.message.issue.issue_actions.complainant_actions, + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + created_at: payload.message.issue.created_at, + updated_at: payload.message.issue.updated_at, + }, + }, + }; + } + + try { + const response: AxiosResponse = await postApi({ + baseUrl: payload.context.bap_uri, + data: on_issue_payload, + endpoint: '/on_issue_status', + method: 'POST', + }); + + if (response.status === 200) { + return response; + } + + return { payload: on_issue_payload, status: response.status, message: 'Something went wrong' }; + } catch (e) { + return e; + } + } +} + +export default LogisticsServices; diff --git a/utilities/ondc-igm-sdk/src/igmManager/services/sellerServices/index.ts b/utilities/ondc-igm-sdk/src/igmManager/services/sellerServices/index.ts new file mode 100644 index 0000000..4bbe282 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/igmManager/services/sellerServices/index.ts @@ -0,0 +1,544 @@ +import { Request, Response } from 'express'; +import { v4 as uuid } from 'uuid'; +import IssueInstance from '../../Issue/'; +import { IssueRequest, IssueStatusPayload, OnIssue, OnIssueStatusResoloved } from '../../interfaces/issue.types'; +import { AxiosResponse } from 'axios'; +import postApi from '../../../utils/posApi'; +import { SchemaValidator } from '../../../utils/validator.schema'; +import { + IssueSchema, + IssueStatusSchema, + LogisticOnIssueSchema, + OnIssueStatusResolovedSchema, + OnIssueStatusScehma, +} from '../../../utils/schema'; +import { OnIssuePayloadProps } from '../../interfaces/manager.type'; +import { PROTOCOL_CONTEXT } from '../../../shared/contents'; +import { hasRefundKey, hasResolvedAction } from '../../../utils/commonFunction'; + +class SellerService { + async issue(req: Request, res: Response) { + try { + const issueRequestpayload: IssueRequest = req.body; + + const isIssueSchemaValid = SchemaValidator({ schema: IssueSchema, data: issueRequestpayload }); + + if (isIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.issue) { + IssueInstance.config?.onSuccess.issue({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + async issueToLogistics(issue: any) { + try { + const issueRequest: IssueRequest = { + context: { + domain: issue.context.domain, + country: issue.context.country, + city: issue.context.city, + action: PROTOCOL_CONTEXT.ISSUE, + core_version: '1.0.0', + bap_id: IssueInstance.config?.context[0].subscriberId!, + bap_uri: IssueInstance.config?.context[0].subscriberURL!, + bpp_id: issue.context.bpp_id, + bpp_uri: issue.context.bpp_uri, + transaction_id: uuid(), + message_id: uuid(), + timestamp: new Date().toISOString(), + ttl: issue.context.ttl, + }, + message: { + issue: { + id: issue.message.issue.id, + category: issue.message.issue.category, + sub_category: issue.message.issue.sub_category, + complainant_info: issue.message.issue.complainant_info, + status: issue.message.issue.status || 'OPEN', + issue_type: PROTOCOL_CONTEXT?.ISSUE.toUpperCase(), + issue_actions: issue.message.issue.issue_actions, + order_details: { + id: issue.message.issue.order_details?.id, + state: issue.message.issue.order_details?.state, + items: issue.message.issue.order_details.items, + fulfillments: issue.message.issue.order_details.fulfillments, + provider_id: issue.message.issue.order_details?.provider_id, + }, + description: { + short_desc: issue.message.issue.description?.short_desc, + long_desc: issue.message.issue.description?.long_desc, + additional_desc: issue.message.issue.description?.additional_desc, + images: issue.message.issue.description?.images, + }, + source: { + network_participant_id: issue.message.issue.source.network_participant_id, + type: issue.message.issue.source.type, + }, + expected_response_time: { + duration: issue.message.issue.expected_response_time.duration, + }, + expected_resolution_time: { + duration: issue.message.issue.expected_response_time.duration, + }, + created_at: issue.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + + const response: AxiosResponse = await postApi({ + baseUrl: issueRequest.context.bpp_uri, + data: issueRequest, + endpoint: PROTOCOL_CONTEXT.ISSUE, + method: 'POST', + }); + if (response.status === 200) { + return response; + } + return { payload: issueRequest, status: response.status, message: 'Something went wrong' }; + } catch (err) { + throw err; + } + } + + async issue_statusToLogistics(payload: any) { + try { + const issueStatusPayload: IssueStatusPayload = { + context: { + domain: payload.context.domain, + country: payload.context.country, + city: payload.context.city, + action: PROTOCOL_CONTEXT.ISSUE, + core_version: '1.0.0', + bap_id: IssueInstance.config?.context[0].subscriberId!, + bap_uri: IssueInstance.config?.context[0].subscriberURL!, + bpp_id: payload.context.bpp_id, + bpp_uri: payload.context.bpp_uri, + transaction_id: uuid(), + message_id: uuid(), + timestamp: new Date().toISOString(), + ttl: payload.context.ttl, + }, + message: { + issue_id: payload.message.issue_id, + }, + }; + + const response: AxiosResponse = await postApi({ + baseUrl: payload.context.bpp_uri, + data: issueStatusPayload, + endpoint: '/issue_status', + method: 'POST', + }); + return { payload: issueStatusPayload, data: response.data, status: response.status }; + } catch (err) { + throw err; + } + } + + async on_issue(req: Request, res: Response) { + try { + const issueRequestpayload: OnIssue = req.body; + + const isOnIssueSchemaValid = SchemaValidator({ schema: LogisticOnIssueSchema, data: issueRequestpayload }); + + if (isOnIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isOnIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isOnIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.on_issue) { + IssueInstance.config?.onSuccess.on_issue({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + async on_issue_post(payload: OnIssuePayloadProps) { + const on_issue_payload: OnIssue = { + context: { + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: 'on_issue', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + created_at: payload.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + + try { + const response: AxiosResponse = await postApi({ + baseUrl: payload.context.bap_uri, + data: on_issue_payload, + endpoint: '/on_issue', + method: 'POST', + }); + + if (response.status === 200) { + return response; + } + + return { payload: on_issue_payload, status: response.status, message: 'Something went wrong' }; + } catch (e) { + return e; + } + } + + async issue_status(req: Request, res: Response) { + try { + const issueRequestpayload: IssueStatusPayload = req.body; + + const isIssueSchemaValid = SchemaValidator({ schema: IssueStatusSchema, data: issueRequestpayload }); + + if (isIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.issue_status) { + IssueInstance.config?.onSuccess.issue_status({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + async on_issue_status(req: Request, res: Response) { + try { + const issueRequestpayload: OnIssue | OnIssueStatusResoloved = req.body; + + let isIssueSchemaValid; + + if (!hasResolvedAction(issueRequestpayload.message.issue.issue_actions.respondent_actions)) { + isIssueSchemaValid = SchemaValidator({ schema: OnIssueStatusScehma, data: issueRequestpayload }); + } else { + isIssueSchemaValid = SchemaValidator({ schema: OnIssueStatusResolovedSchema, data: issueRequestpayload }); + } + + if (isIssueSchemaValid) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + error: isIssueSchemaValid.message, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + + if (IssueInstance.config?.onSuccess?.on_issue_status) { + IssueInstance.config?.onSuccess.on_issue_status({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } + + return res.status(200).send({ + payload: issueRequestpayload, + message: { + ack: { + status: 'ACK', + }, + }, + }); + } catch (err) { + if (IssueInstance.config?.onError) { + IssueInstance.config?.onError({ + error: err, + message: { + ack: { + status: 'NACK', + }, + }, + }); + } + throw err; + } + } + + async on_issue_status_post(payload: any) { + let on_issue_payload: OnIssue | OnIssueStatusResoloved; + const respondent_action = payload.message.issue.issue_actions.respondent_actions; + + if (respondent_action.some((item: any) => item.respondent_action === 'RESOLVED') && hasRefundKey(payload)) { + on_issue_payload = { + context: { + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + resolution_provider: { + respondent_info: { + organization: { + contact: { + email: payload.message.issue.resolution_provider.respondent_info.organization.contact.email, + phone: payload.message.issue.resolution_provider.respondent_info.organization.contact.phone, + }, + org: { + name: payload.message.issue.resolution_provider.respondent_info.organization.org.name, + }, + person: { + name: payload.message.issue.resolution_provider.respondent_info.organization.person.name, + }, + }, + type: payload.message.issue.resolution_provider.respondent_info.type, + resolution_support: { + chat_link: payload.message.issue.resolution_provider.respondent_info.resolution_support.chat_link, + contact: { + phone: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.phone, + email: payload.message.issue.resolution_provider.respondent_info.resolution_support.contact.email, + }, + gros: payload.message.issue.resolution_provider.respondent_info.resolution_support.gros, + }, + }, + }, + resolution: { + short_desc: payload.message.issue.resolution.short_desc, + long_desc: payload.message.issue.resolution.long_desc, + action_triggered: 'REFUND', + refund_amount: payload.message.issue.resolution.refund_amount, + }, + created_at: payload.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + } else { + on_issue_payload = { + context: { + domain: IssueInstance.config?.context[0].subscriberDomain!, + country: IssueInstance.config?.context[0].subscriberCountry!, + city: IssueInstance.config?.context[0].subscriberCity!, + action: 'on_issue_status', + core_version: '1.0.0', + bap_id: payload.context.bap_id, + bap_uri: payload.context.bap_uri, + bpp_id: IssueInstance.config?.context[0].subscriberId!, + bpp_uri: IssueInstance.config?.context[0].subscriberURL!, + transaction_id: payload.context.transaction_id, + message_id: payload.context.message_id, + timestamp: payload.context.timestamp, + }, + message: { + issue: { + id: payload.message.issue.id, + issue_actions: { + respondent_actions: payload.message.issue.issue_actions.respondent_actions, + }, + created_at: payload.message.issue.created_at, + updated_at: new Date().toISOString(), + }, + }, + }; + } + + try { + const response: AxiosResponse = await postApi({ + baseUrl: payload.context.bap_uri, + data: on_issue_payload, + endpoint: '/on_issue_status', + method: 'POST', + }); + + if (response.status === 200) { + return response; + } + + return { payload: on_issue_payload, status: response.status, message: 'Something went wrong' }; + } catch (e) { + return e; + } + } +} + +export default SellerService; diff --git a/utilities/ondc-igm-sdk/src/index.ts b/utilities/ondc-igm-sdk/src/index.ts new file mode 100644 index 0000000..4c29b1b --- /dev/null +++ b/utilities/ondc-igm-sdk/src/index.ts @@ -0,0 +1,3 @@ +import router from './igmManager/routes/igm.routes'; + +export { router as issueRoutes }; diff --git a/utilities/ondc-igm-sdk/src/shared/cityCode.ts b/utilities/ondc-igm-sdk/src/shared/cityCode.ts new file mode 100644 index 0000000..0cc96f0 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/shared/cityCode.ts @@ -0,0 +1,778 @@ +export const CITY_CODE = [ + { + State: 'Andhra Pradesh', + City: 'Chittoor', + Code: 'std:08572', + }, + { + State: 'Andhra Pradesh', + City: 'Vuyyuru', + Code: 'std:08676', + }, + { + State: 'Andhra Pradesh', + City: 'Vizayanagaram', + Code: 'std:08922', + }, + { + State: 'Bihar', + City: 'Patna', + Code: 'std:0612', + }, + { + State: 'Bihar', + City: 'Samastipur', + Code: 'std:06274', + }, + { + State: 'Bihar', + City: 'Khagaria', + Code: 'std:06244', + }, + { + State: 'Bihar', + City: 'Muzaffarpur', + Code: 'std:0621', + }, + { + State: 'Bihar', + City: 'Katihar', + Code: 'std:06452', + }, + { + State: 'Bihar', + City: 'Raxaul', + Code: 'std:06255', + }, + { + State: 'Bihar', + City: 'Kishanganj', + Code: 'std:06466', + }, + { + State: 'Bihar', + City: 'Darbhanga', + Code: 'std:06272', + }, + { + State: 'Bihar', + City: 'Jamui', + Code: 'std:06345', + }, + { + State: 'Bihar', + City: 'Madhubani', + Code: 'std:06276', + }, + { + State: 'Bihar', + City: 'Nawada', + Code: 'std:06324', + }, + { + State: 'Bihar', + City: 'Munger', + }, + { + State: 'Bihar', + City: 'Bhagalpur', + Code: 'std:0641', + }, + { + State: 'Bihar', + City: 'Purnia', + }, + { + State: 'Bihar', + City: 'Hajipur', + Code: 'std:06224', + }, + { + State: 'Bihar', + City: 'Begusarai', + Code: 'std:06243', + }, + { + State: 'Delhi', + City: 'Delhi', + Code: 'std:011', + }, + { + State: 'Goa', + City: 'Panaji', + Code: 'std:0832', + }, + { + State: 'Goa', + City: 'Porvorim', + Code: 'std:0832217', + }, + { + State: 'Gujarat', + City: 'Rajkot', + Code: 'std:0281', + }, + { + State: 'Gujarat', + City: 'Patan', + Code: 'std:02766', + }, + { + State: 'Gujarat', + City: 'Anand', + Code: 'std:02692', + }, + { + State: 'Gujarat', + City: 'Mahesana', + Code: 'std:02762', + }, + { + State: 'Gujarat', + City: 'Mehsana', + Code: 'std:02762', + }, + { + State: 'Gujarat', + City: 'Bhavnagar', + Code: 'std:0278', + }, + { + State: 'Gujarat', + City: 'Gandhidham', + Code: 'std:02836', + }, + { + State: 'Gujarat', + City: 'Amreli', + Code: 'std:02792', + }, + { + State: 'Gujarat', + City: 'Vapi', + Code: 'std:0260', + }, + { + State: 'Gujarat', + City: 'Mundra', + Code: 'std:02838', + }, + { + State: 'Gujarat', + City: 'Ahmedabad', + Code: 'std:079', + }, + { + State: 'Gujarat', + City: 'Navsari', + Code: 'std:02637', + }, + { + State: 'Gujarat', + City: 'Surendranagar', + Code: 'std:02752', + }, + { + State: 'Gujarat', + City: 'Jamnagar', + Code: 'std:0288', + }, + { + State: 'Gujarat', + City: 'Vadodara', + Code: 'std:0265', + }, + { + State: 'Gujarat', + City: 'Unjha', + }, + { + State: 'Gujarat', + City: 'Petlad', + }, + { + State: 'Gujarat', + City: 'Valsad', + Code: 'std:02632', + }, + { + State: 'Gujarat', + City: 'Vallabh Vidyanagar', + }, + { + State: 'Gujarat', + City: 'Surat', + Code: 'std:0261', + }, + { + State: 'Gujarat', + City: 'Nadiad', + Code: 'std:0268', + }, + { + State: 'Haryana', + City: 'Gurgaon', + Code: 'std:0124', + }, + { + State: 'Haryana', + City: 'Faridabad', + Code: 'std:0129', + }, + { + State: 'Jammu & Kashmir', + City: 'Jammu', + Code: 'std:0191', + }, + { + State: 'Jammu & Kashmir', + City: 'Srinagar', + Code: 'std:0194', + Column4: 'Direct code for Ooty not available, 3 sub-divisions have been mentioned with codes', + }, + { + State: 'Karnataka', + City: 'Bengaluru', + Code: 'std:080', + }, + { + State: 'Karnataka', + City: 'Udupi', + Code: 'std:0820', + }, + { + State: 'Karnataka', + City: 'Mysuru', + Code: 'std:0821', + }, + { + State: 'Karnataka', + City: 'Mandya', + Code: 'std:08232', + Column4: "Mentioned as 'Theni' in STD codes", + }, + { + State: 'Karnataka', + City: 'Mangaluru', + Code: 'std:0824', + }, + { + State: 'Karnataka', + City: 'Achladi', + Code: 'std:08252', + }, + { + State: 'Karnataka', + City: 'Karkala', + Code: 'std:08258', + }, + { + State: 'Karnataka', + City: 'Chikmagalur', + Code: 'std:08262', + }, + { + State: 'Karnataka', + City: 'Bailhongal', + Code: 'std:08288', + }, + { + State: 'Karnataka', + City: 'Ranebennur', + Code: 'std:08373', + }, + { + State: 'Kerala', + City: 'Thiruvananthapuram', + Code: 'std:0471', + }, + { + State: 'Kerala', + City: 'Quilon', + Code: 'std:0474', + }, + { + State: 'Kerala', + City: 'Alleppy', + Code: 'std:0477', + }, + { + State: 'Kerala', + City: 'Mavelikkara', + Code: 'std:0479', + }, + { + State: 'Kerala', + City: 'Ernakulam', + Code: 'std:0484', + }, + { + State: 'Kerala', + City: 'Trichur', + Code: 'std:0487', + }, + { + State: 'Kerala', + City: 'Kannur', + Code: 'std:0497', + }, + { + State: 'Madhya Pradesh', + City: 'Chhindwara', + Code: 'std:07162', + }, + { + State: 'Madhya Pradesh', + City: 'Indore', + Code: 'std:0731', + }, + { + State: 'Madhya Pradesh', + City: 'Bareli', + Code: 'std:07486', + }, + { + State: 'Madhya Pradesh', + City: 'Bhopal', + Code: 'std:0755', + }, + { + State: 'Maharashtra', + City: 'Pune', + Code: 'std:020', + }, + { + State: 'Maharashtra', + City: 'Mumbai', + Code: 'std:022', + }, + { + State: 'Meghalaya', + City: 'Shillong', + Code: 'std:0364', + }, + { + State: 'Orissa', + City: 'Cuttack', + Code: 'std:0671', + }, + { + State: 'Punjab', + City: 'Chandigarh', + Code: 'std:0172', + }, + { + State: 'Rajasthan', + City: 'Jaipur', + Code: 'std:0141', + }, + { + State: 'Rajasthan', + City: 'Kotputli', + Code: 'std:01421', + Column4: 'Direct code for Ghaziabad not available; sub-divisions mentioned with codes', + }, + { + State: 'Rajasthan', + City: 'Bansur', + Code: 'std:01461', + }, + { + State: 'Rajasthan', + City: 'Sriganganagar', + Code: 'std:0154', + }, + { + State: 'Sikkim', + City: 'Gangtok', + Code: 'std:03592', + }, + { + State: 'Tamil Nadu', + City: 'Thanjavur', + Code: 'std:04362', + }, + { + State: 'Tamil Nadu', + City: 'Nagercoil', + Code: 'std:04652', + }, + { + State: 'Tamil Nadu', + City: 'Villupuram', + Code: 'std:04146', + }, + { + State: 'Tamil Nadu', + City: 'Coimbatore', + Code: 'std:0422', + }, + { + State: 'Tamil Nadu', + City: 'Erode', + Code: 'std:0424', + }, + { + State: 'Tamil Nadu', + City: 'Madurai', + Code: 'std:0452', + }, + { + State: 'Tamil Nadu', + City: 'Vellore', + Code: 'std:0416', + }, + { + State: 'Tamil Nadu', + City: 'Chennai', + Code: 'std:044', + }, + { + State: 'Tamil Nadu', + City: 'Tiruppur', + Code: 'std:0421', + }, + { + State: 'Tamil Nadu', + City: 'Salem', + Code: 'std:0427', + }, + { + State: 'Tamil Nadu', + City: 'Ooty', + }, + { + State: 'Tamil Nadu', + City: 'Kumbakonam', + Code: 'std:0435', + }, + { + State: 'Tamil Nadu', + City: 'Dindigul', + Code: 'std:0451', + }, + { + State: 'Tamil Nadu', + City: 'Namakkal', + Code: 'std:04286', + }, + { + State: 'Tamil Nadu', + City: 'Theni Allinagaram', + Code: 'std:04546', + }, + { + State: 'Tamil Nadu', + City: 'Cuddalore', + Code: 'std:04142', + Column4: 'Direct code for Lakhimpur not available; sub-divisions mentioned with codes', + }, + { + State: 'Tamil Nadu', + City: 'Karur', + Code: 'std:04324', + Column4: 'Direct code for Bahraich not available; sub-divisions mentioned with codes', + }, + { + State: 'Tamil Nadu', + City: 'Rajapalayam', + Code: 'std:04563', + }, + { + State: 'Tamil Nadu', + City: 'KK Nagar', + }, + { + State: 'Tamil Nadu', + City: 'Sivakasi', + }, + { + State: 'Tamil Nadu', + City: 'Pollachi', + Code: 'std:04259', + }, + { + State: 'Tamil Nadu', + City: 'Tiruvannamalai', + Code: 'std:04175', + }, + { + State: 'Tamil Nadu', + City: 'Sivaganga', + Code: 'std:04575', + }, + { + State: 'Tamil Nadu', + City: 'Kotagiri', + Code: 'std:04266', + }, + { + State: 'Tamil Nadu', + City: 'Trichy', + Code: 'std:0431', + }, + { + State: 'Tamil Nadu', + City: 'Ambur', + }, + { + State: 'Tamil Nadu', + City: 'Vaniyambadi', + Code: 'std:04174', + }, + { + State: 'Tamil Nadu', + City: 'Tirupur', + Code: 'std:0421', + }, + { + State: 'Tamil Nadu', + City: 'Gandhipuram', + }, + { + State: 'Tamil Nadu', + City: 'Coonoor', + }, + { + State: 'Tamil Nadu', + City: 'Tirunelveli', + }, + { + State: 'Tamil Nadu', + City: 'Kovilpatti', + Code: 'std:04632', + }, + { + State: 'Tamil Nadu', + City: 'Ramanathapuram', + }, + { + State: 'Tamil Nadu', + City: 'Melvisharam', + }, + { + State: 'Tamil Nadu', + City: 'Hosur', + Code: 'std:04344', + }, + { + State: 'Tamil Nadu', + City: 'Thoothukudi', + }, + { + State: 'Tamil Nadu', + City: 'Iyyengarkulam', + Code: 'std:04112', + }, + { + State: 'Tamil Nadu', + City: 'Manavalanagar', + Code: 'std:04116', + }, + { + State: 'Tamil Nadu', + City: 'Tindivanam', + Code: 'std:04147', + }, + { + State: 'Tamil Nadu', + City: 'Mettupalayam', + Code: 'std:04254', + }, + { + State: 'Tamil Nadu', + City: 'Mayiladuthura', + Code: 'std:04364', + }, + { + State: 'Tamil Nadu', + City: 'Ramanathpuram', + Code: 'std:04567', + }, + { + State: 'Tamil Nadu', + City: 'Tirunelvelli', + Code: 'std:0462', + }, + { + State: 'Telangana', + City: 'Hyderabad', + Code: 'std:040', + }, + { + State: 'Uttar Pradesh', + City: 'Varanasi', + Code: 'std:0542', + }, + { + State: 'Uttar Pradesh', + City: 'Prayagraj', + Code: 'std:0532', + }, + { + State: 'Uttar Pradesh', + City: 'Ghaziabad', + Code: 'std:0120', + }, + { + State: 'Uttar Pradesh', + City: 'Agra', + Code: 'std:0562', + }, + { + State: 'Uttar Pradesh', + City: 'Bareilly', + Code: 'std:0581', + }, + { + State: 'Uttar Pradesh', + City: 'Gorakhpur', + Code: 'std:0551', + }, + { + State: 'Uttar Pradesh', + City: 'Basti', + Code: 'std:05542', + }, + { + State: 'Uttar Pradesh', + City: 'Kanpur', + Code: 'std:0512', + }, + { + State: 'Uttar Pradesh', + City: 'Balrampur', + Code: 'std:05263', + }, + { + State: 'Uttar Pradesh', + City: 'Khalilabad', + Code: 'std:05547', + }, + { + State: 'Uttar Pradesh', + City: 'Noida', + }, + { + State: 'Uttar Pradesh', + City: 'Meerut', + Code: 'std:0121', + }, + { + State: 'Uttar Pradesh', + City: 'Hardoi', + Code: 'std:05852', + }, + { + State: 'Uttar Pradesh', + City: 'Shahjahanpur', + Code: 'std:05842', + }, + { + State: 'Uttar Pradesh', + City: 'Sitapur', + Code: 'std:05862', + }, + { + State: 'Uttar Pradesh', + City: 'Aligarh', + Code: 'std:0571', + }, + { + State: 'Uttar Pradesh', + City: 'Barabanki', + Code: 'std:05248', + }, + { + State: 'Uttar Pradesh', + City: 'lakhimpur kheri', + Code: 'std:05872', + }, + { + State: 'Uttar Pradesh', + City: 'Farrukhabad', + Code: 'std:05692', + }, + { + State: 'Uttar Pradesh', + City: 'Lucknow', + Code: 'std:0522', + }, + { + State: 'Uttar Pradesh', + City: 'Sultanpur', + Code: 'std:05362', + }, + { + State: 'Uttar Pradesh', + City: 'Lakhimpur', + }, + { + State: 'Uttar Pradesh', + City: 'Bahraich', + }, + { + State: 'Uttar Pradesh', + City: 'Greater Noida', + }, + { + State: 'Uttar Pradesh', + City: 'Akbarpur', + Code: 'std:05271', + }, + { + State: 'Uttar Pradesh', + City: 'Saharanpur', + Code: 'std:0132', + }, + { + State: 'Uttar Pradesh', + City: 'Muzaffarnagar', + Code: 'std:0131', + }, + { + State: 'Uttar Pradesh', + City: 'Bijnore', + Code: 'std:01342', + }, + { + State: 'Uttar Pradesh', + City: 'Kotdwara', + Code: 'std:01382', + }, + { + State: 'Uttar Pradesh', + City: 'Hamirpur', + Code: 'std:05282', + }, + { + State: 'Uttar Pradesh', + City: 'Moradabad', + Code: 'std:0591', + }, + { + State: 'Uttar Pradesh', + City: 'Bilari', + Code: 'std:05921', + }, + { + State: 'Uttar Pradesh', + City: 'Chhapra', + Code: 'std:06152', + }, + { + State: 'Uttarakhand', + City: 'Haridwar', + Code: 'std:01334', + }, + { + State: 'Uttarakhand', + City: 'Dehradun', + Code: 'std:0135', + }, + { + State: 'West Bengal', + City: 'Kolkata', + Code: 'std:033', + }, +]; diff --git a/utilities/ondc-igm-sdk/src/shared/contents.ts b/utilities/ondc-igm-sdk/src/shared/contents.ts new file mode 100644 index 0000000..eac37b4 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/shared/contents.ts @@ -0,0 +1,58 @@ +export const SYSTEM_ROLES = { + SUPER_ADMIN: 'SUPER_ADMIN', +}; + +export const RESOURCE_POSSESSION = { + OWN: 'OWN', + ANY: 'ANY', + SUB: 'SUB', +}; + +export const HEADERS = { + ACCESS_TOKEN: 'access-token', + AUTH_TOKEN: 'Authorization', +}; + +export const PAYMENT_TYPES = { + 'ON-ORDER': 'ON-ORDER', + 'PRE-FULFILLMENT': 'PRE-FULFILLMENT', + 'ON-FULFILLMENT': 'ON-FULFILLMENT', + 'POST-FULFILLMENT': 'POST-FULFILLMENT', +}; + +export const PROTOCOL_CONTEXT = { + ISSUE: 'issue', + ON_ISSUE: 'on_issue', + ISSUE_STATUS: 'issue_status', + ON_ISSUE_STATUS: 'on_issue_status', +}; + +export const PROTOCOL_PAYMENT = { + PAID: 'PAID', + 'NOT-PAID': 'NOT-PAID', +}; + +export const PROTOCOL_VERSION = { + v_0_9_1: '0.9.1', + v_0_9_3: '0.9.3', + v_1_0_0: '1.0.0', +}; + +export const SUBSCRIBER_TYPE = { + BAP: 'BAP', + BPP: 'BPP', + BG: 'BG', + LREG: 'LREG', + CREG: 'CREG', + RREG: 'RREG', +}; + +export const ORDER_STATUS = { + COMPLETED: 'completed', + 'IN-PROGRESS': 'in-progress', +}; + +export const PAYMENT_COLLECTED_BY = { + BAP: 'BAP', + BPP: 'BPP', +}; diff --git a/utilities/ondc-igm-sdk/src/utils/commonFunction.ts b/utilities/ondc-igm-sdk/src/utils/commonFunction.ts new file mode 100644 index 0000000..92bf3e3 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/commonFunction.ts @@ -0,0 +1,7 @@ +export function hasResolvedAction(respondentActions: any[]): boolean { + return respondentActions.some((action) => action.respondent_action === 'RESOLVED'); +} + +export function hasRefundKey(payload: any) { + return Object.keys(payload.message.issue.resolution).includes('refund_amount'); +} diff --git a/utilities/ondc-igm-sdk/src/utils/httpRequest.ts b/utilities/ondc-igm-sdk/src/utils/httpRequest.ts new file mode 100644 index 0000000..6fb792a --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/httpRequest.ts @@ -0,0 +1,92 @@ +import axios from 'axios'; + +/** + * Used to communicate with server + */ + +class HttpRequest { + baseUrl: string | any; + url: string; + method: string; + data: any; + headers: any; + options: any; + /** + * @param {*} baseUrl Base URL(domain url) + * @param {*} url Resource URL + * @param {*} method HTTP method(GET | POST | PUT | PATCH | DELETE) + * @param {*} headers HTTP request headers (If applicable) + * @param {*} data HTTP request data (If applicable) + * @param {*} options other params + */ + constructor( + baseUrl: string | any, + url: string, + method: string = 'get', + data: any = {}, + headers?: any, + options?: any, + ) { + this.baseUrl = baseUrl; + this.url = url; + this.method = method; + this.data = data; + this.headers = headers; + this.options = options; + this.send = this.send.bind(this); + } + + /** + * Send http request to server to write data to / read data from server + * axios library provides promise implementation to send request to server + * Here we are using axios library for requesting a resource + */ + async send() { + try { + let headers = { + ...this.headers, + ...(this.method.toLowerCase() != 'get' && { + 'Content-Type': 'application/json', + }), + }; + + let result; + + if (this.method.toLowerCase() == 'get') { + result = await axios({ + baseURL: this.baseUrl, + url: this.url, + method: this.method, + headers: headers, + timeout: 180000, // If the request takes longer than `timeout`, the request will be aborted. + }); + } else { + // Make server request using axios + result = await axios({ + baseURL: this.baseUrl, + url: this.url, + method: this.method, + headers: headers, + timeout: 180000, // If the request takes longer than `timeout`, the request will be aborted. + data: JSON.stringify(this.data), + }); + } + return result; + } catch (err: any) { + if (err.response) { + // The client was given an error response (5xx, 4xx) + console.info('Error response', err, '\n', err.response); + } else if (err.request) { + // The client never received a response, and the request was never left + console.info('Error request', err, '\n', err.request); + } else { + // Anything else + console.info('Error message', err, '\n', err.message); + } + + throw err; + } + } +} + +export default HttpRequest; diff --git a/utilities/ondc-igm-sdk/src/utils/posApi.ts b/utilities/ondc-igm-sdk/src/utils/posApi.ts new file mode 100644 index 0000000..77e7a50 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/posApi.ts @@ -0,0 +1,32 @@ +import HttpRequest from './httpRequest'; + +/** + * Performs an HTTP POST or GET request to the specified endpoint with the provided data. + * + * @param data - The data to be sent in the request body for POST requests. + * @param endpoint - The endpoint URL where the request will be sent. + * @param method - The HTTP method to be used for the request (either 'POST' or 'GET'). + * @returns A promise that resolves to the response data from the API call. + * @throws Will throw an error if the API call encounters an error. + */ + +const postApi = async ({ + baseUrl, + data, + endpoint, + method, +}: { + baseUrl: string; + endpoint: string; + data: T; + method: 'POST' | 'GET'; +}) => { + const apiCall = new HttpRequest(baseUrl, endpoint, method, { + ...data, + }); + + const response = apiCall.send(); + return response; +}; + +export default postApi; diff --git a/utilities/ondc-igm-sdk/src/utils/schema/OnIssueStatus.schema.ts b/utilities/ondc-igm-sdk/src/utils/schema/OnIssueStatus.schema.ts new file mode 100644 index 0000000..3cf0a07 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/OnIssueStatus.schema.ts @@ -0,0 +1,170 @@ +import Joi from 'joi'; + +const customMessages = { + 'string.base': '{#label} should be a type of text', + 'string.empty': '{#label} cannot be empty', + 'any.required': '{#label} is required', + 'string.email': '{#label} must be a valid email', + 'string.phone': '{#label} must be a valid phone number', + 'string.uri': '{#label} must be a valid URI', + 'string.isoDate': '{#label} must be a valid ISO date', + 'number.base': '{#label} should be a type of number', + 'number.integer': '{#label} must be an integer', +}; + +export const OnIssueStatusScehma = Joi.object({ + context: Joi.object({ + domain: Joi.string().required().messages(customMessages), + country: Joi.string().required().messages(customMessages), + city: Joi.string().required().messages(customMessages), + action: Joi.string().required().messages(customMessages), + core_version: Joi.string().required().messages(customMessages), + bap_id: Joi.string().required().messages(customMessages), + bap_uri: Joi.string().required().messages(customMessages), + bpp_id: Joi.string().required().messages(customMessages), + bpp_uri: Joi.string().required().messages(customMessages), + transaction_id: Joi.string().required().messages(customMessages), + message_id: Joi.string().required().messages(customMessages), + timestamp: Joi.string().isoDate().required().messages(customMessages), + }).required(), + + message: Joi.object({ + issue: Joi.object({ + id: Joi.string().required().messages(customMessages), + issue_actions: Joi.object({ + respondent_actions: Joi.array() + .items( + Joi.object({ + respondent_action: Joi.string().required().messages(customMessages), + short_desc: Joi.string().required().messages(customMessages), + updated_at: Joi.string().isoDate().required().messages(customMessages), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + contact: Joi.object({ + phone: Joi.string() + .pattern(/^[0-9]{10}$/) + .required() + .messages(customMessages), + email: Joi.string().email().required().messages(customMessages), + }).required(), + person: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + }).required(), + cascaded_level: Joi.number().integer().required().messages(customMessages), + }), + ) + .required(), + }).required(), + created_at: Joi.string().isoDate().required().messages(customMessages), + updated_at: Joi.string().isoDate().required().messages(customMessages), + }).required(), + }).required(), +}); + +export const OnIssueStatusResolovedSchema = Joi.object({ + context: Joi.object({ + domain: Joi.string().required().messages(customMessages), + country: Joi.string().required().messages(customMessages), + city: Joi.string().required().messages(customMessages), + action: Joi.string().required().messages(customMessages), + core_version: Joi.string().required().messages(customMessages), + bap_id: Joi.string().required().messages(customMessages), + bap_uri: Joi.string().required().messages(customMessages), + bpp_id: Joi.string().required().messages(customMessages), + bpp_uri: Joi.string().required().messages(customMessages), + transaction_id: Joi.string().required().messages(customMessages), + message_id: Joi.string().required().messages(customMessages), + timestamp: Joi.string().isoDate().required().messages(customMessages), + }).required(), + + message: Joi.object({ + issue: Joi.object({ + id: Joi.string().required().messages(customMessages), + issue_actions: Joi.object({ + respondent_actions: Joi.array() + .items( + Joi.object({ + respondent_action: Joi.string().required().messages(customMessages), + short_desc: Joi.string().required().messages(customMessages), + updated_at: Joi.string().isoDate().required().messages(customMessages), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + contact: Joi.object({ + phone: Joi.string() + .pattern(/^[0-9]{10}$/) + .required() + .messages(customMessages), + email: Joi.string().email().required().messages(customMessages), + }).required(), + person: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + }).required(), + cascaded_level: Joi.number().integer().required().messages(customMessages), + }), + ) + .required(), + }).required(), + created_at: Joi.string().isoDate().required().messages(customMessages), + updated_at: Joi.string().isoDate().required().messages(customMessages), + resolution_provider: Joi.object({ + respondent_info: Joi.object({ + type: Joi.string().required().messages(customMessages), + organization: Joi.object({ + org: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + contact: Joi.object({ + phone: Joi.string() + .pattern(/^[0-9]{10}$/) + .required() + .messages(customMessages), + email: Joi.string().email().required().messages(customMessages), + }).required(), + person: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + }).required(), + resolution_support: Joi.object({ + chat_link: Joi.string().required().messages(customMessages), + contact: Joi.object({ + phone: Joi.string() + .pattern(/^[0-9]{10}$/) + .required() + .messages(customMessages), + email: Joi.string().email().required().messages(customMessages), + }).required(), + gros: Joi.array() + .items( + Joi.object({ + person: Joi.object({ + name: Joi.string().required().messages(customMessages), + }).required(), + contact: Joi.object({ + phone: Joi.string() + .pattern(/^[0-9]{10}$/) + .required() + .messages(customMessages), + email: Joi.string().email().required().messages(customMessages), + }).required(), + gro_type: Joi.string().required().messages(customMessages), + }), + ) + .required(), + }).required(), + }).required(), + }).required(), + resolution: Joi.object({ + short_desc: Joi.string().required().messages(customMessages), + long_desc: Joi.string().required().messages(customMessages), + action_triggered: Joi.string().required().messages(customMessages), + refund_amount: Joi.number().required().messages(customMessages), + }).required(), + }).required(), + }).required(), +}); diff --git a/utilities/ondc-igm-sdk/src/utils/schema/index.ts b/utilities/ondc-igm-sdk/src/utils/schema/index.ts new file mode 100644 index 0000000..852465e --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/index.ts @@ -0,0 +1,16 @@ +import IssueSchema from './issue.schema'; +import OnIssueSchema from './on_issue.schema'; +import { OnIssueStatusScehma, OnIssueStatusResolovedSchema } from './OnIssueStatus.schema'; +import IssueStatusSchema from './issueStatus.scehma'; +import LogisticOnIssueSchema from './logistics.onIssue.schema'; +import LogisticsIssueSchema from './logistics.issue.schema' + +export { + IssueSchema, + OnIssueSchema, + OnIssueStatusScehma, + OnIssueStatusResolovedSchema, + IssueStatusSchema, + LogisticOnIssueSchema, + LogisticsIssueSchema +}; diff --git a/utilities/ondc-igm-sdk/src/utils/schema/issue.schema.ts b/utilities/ondc-igm-sdk/src/utils/schema/issue.schema.ts new file mode 100644 index 0000000..47f23d1 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/issue.schema.ts @@ -0,0 +1,263 @@ +import Joi from 'joi'; + +const issueSchema = Joi.object({ + context: Joi.object({ + domain: Joi.string().required().messages({ + 'string.base': 'Context: Domain must be a string.', + 'any.required': 'Context: Domain is required.', + }), + country: Joi.string().required().messages({ + 'string.base': 'Context: Country must be a string.', + 'any.required': 'Context: Country is required.', + }), + city: Joi.string().required().messages({ + 'string.base': 'Context: City must be a string.', + 'any.required': 'Context: City is required.', + }), + action: Joi.string().required().messages({ + 'string.base': 'Context: Action must be a string.', + 'any.required': 'Context: Action is required.', + }), + core_version: Joi.string().required().messages({ + 'string.base': 'Context: Core version must be a string.', + 'any.required': 'Context: Core version is required.', + }), + bap_id: Joi.string().required().messages({ + 'string.base': 'Context: Bap ID must be a string.', + 'any.required': 'Context: Bap ID is required.', + }), + bap_uri: Joi.string().required().messages({ + 'string.base': 'Context: Bap URI must be a string.', + 'string.uri': 'Context: Bap URI must be a valid URI.', + 'any.required': 'Context: Bap URI is required.', + }), + bpp_id: Joi.string().required().messages({ + 'string.base': 'Context: Bpp ID must be a string.', + 'any.required': 'Context: Bpp ID is required.', + }), + bpp_uri: Joi.string().required().messages({ + 'string.base': 'Context: Bpp URI must be a string.', + 'string.uri': 'Context: Bpp URI must be a valid URI.', + 'any.required': 'Context: Bpp URI is required.', + }), + transaction_id: Joi.string().required().messages({ + 'string.base': 'Context: Transaction ID must be a string.', + 'any.required': 'Context: Transaction ID is required.', + }), + message_id: Joi.string().required().messages({ + 'string.base': 'Context: Message ID must be a string.', + 'any.required': 'Context: Message ID is required.', + }), + timestamp: Joi.string().isoDate().required().messages({ + 'string.base': 'Context: Timestamp must be a valid ISO date string.', + 'string.isoDate': 'Context: Timestamp must be a valid ISO date string.', + 'any.required': 'Context: Timestamp is required.', + }), + ttl: Joi.string().required().messages({ + 'string.base': 'Context: TTL must be a string.', + 'any.required': 'Context: TTL is required.', + }), + }) + .required() + .messages({ + 'any.required': 'Context is required.', + }), + + message: Joi.object({ + issue: Joi.object({ + id: Joi.string().required().messages({ + 'string.base': 'Issue: ID must be a string.', + 'any.required': 'Issue: ID is required.', + }), + category: Joi.string().required().messages({ + 'string.base': 'Issue: Category must be a string.', + 'any.required': 'Issue: Category is required.', + }), + sub_category: Joi.string().required().messages({ + 'string.base': 'Issue: Sub-category must be a string.', + 'any.required': 'Issue: Sub-category is required.', + }), + complainant_info: Joi.object({ + person: Joi.object({ + name: Joi.string().required().messages({ + 'string.base': 'Complainant: Name must be a string.', + 'any.required': 'Complainant: Name is required.', + }), + }).required(), + contact: Joi.object({ + phone: Joi.string().required().messages({ + 'string.base': 'Complainant: Phone must be a string.', + 'any.required': 'Complainant: Phone is required.', + }), + email: Joi.string().email().required().messages({ + 'string.base': 'Complainant: Email must be a string.', + 'string.email': 'Complainant: Email must be a valid email address.', + 'any.required': 'Complainant: Email is required.', + }), + }).required(), + }).required(), + order_details: Joi.object({ + id: Joi.string().uuid().required().messages({ + 'string.base': 'Order Details: ID must be a string.', + 'string.uuid': 'Order Details: ID must be a valid UUID.', + 'any.required': 'Order Details: ID is required.', + }), + state: Joi.string().required().messages({ + 'string.base': 'Order Details: State must be a string.', + 'any.required': 'Order Details: State is required.', + }), + items: Joi.array() + .items( + Joi.object({ + id: Joi.string().required().messages({ + 'string.base': 'Order Item: ID must be a string.', + 'any.required': 'Order Item: ID is required.', + }), + quantity: Joi.number().integer().required().messages({ + 'number.base': 'Order Item: Quantity must be a number.', + 'number.integer': 'Order Item: Quantity must be an integer.', + 'any.required': 'Order Item: Quantity is required.', + }), + }), + ) + .required(), + fulfillments: Joi.array() + .items( + Joi.object({ + id: Joi.string().required().messages({ + 'string.base': 'Fulfillment: ID must be a string.', + 'any.required': 'Fulfillment: ID is required.', + }), + state: Joi.string().required().messages({ + 'string.base': 'Fulfillment: State must be a string.', + 'any.required': 'Fulfillment: State is required.', + }), + }), + ) + .required(), + provider_id: Joi.string().required().messages({ + 'string.base': 'Order Details: Provider ID must be a string.', + 'any.required': 'Order Details: Provider ID is required.', + }), + }).required(), + description: Joi.object({ + short_desc: Joi.string().required().messages({ + 'string.base': 'Description: Short description must be a string.', + 'any.required': 'Description: Short description is required.', + }), + long_desc: Joi.string().required().messages({ + 'string.base': 'Description: Long description must be a string.', + 'any.required': 'Description: Long description is required.', + }), + additional_desc: Joi.object({ + url: Joi.string().required().messages({ + 'string.base': 'Additional Description: URL must be a string.', + 'string.uri': 'Additional Description: URL must be a valid URI.', + 'any.required': 'Additional Description: URL is required.', + }), + content_type: Joi.string().required().messages({ + 'string.base': 'Additional Description: Content type must be a string.', + 'any.required': 'Additional Description: Content type is required.', + }), + }).required(), + images: Joi.array().items(Joi.string()).required().messages({ + 'array.base': 'Images must be an array.', + 'any.required': 'Images is required.', + 'string.uri': 'Each image must be a valid URI.', + }), + }).required(), + source: Joi.object({ + network_participant_id: Joi.string().required().messages({ + 'string.base': 'Source: Network participant ID must be a string.', + 'any.required': 'Source: Network participant ID is required.', + }), + type: Joi.string().required().messages({ + 'string.base': 'Source: Type must be a string.', + 'any.required': 'Source: Type is required.', + }), + }).required(), + expected_response_time: Joi.object({ + duration: Joi.string().required().messages({ + 'string.base': 'Expected Response Time: Duration must be a string.', + 'any.required': 'Expected Response Time: Duration is required.', + }), + }).required(), + expected_resolution_time: Joi.object({ + duration: Joi.string().required().messages({ + 'string.base': 'Expected Resolution Time: Duration must be a string.', + 'any.required': 'Expected Resolution Time: Duration is required.', + }), + }).required(), + status: Joi.string().required().messages({ + 'string.base': 'Status must be a string.', + 'any.required': 'Status is required.', + }), + issue_type: Joi.string().required().messages({ + 'string.base': 'Issue Type must be a string.', + 'any.required': 'Issue Type is required.', + }), + issue_actions: Joi.object({ + complainant_actions: Joi.array() + .items( + Joi.object({ + complainant_action: Joi.string().required().messages({ + 'string.base': 'Complainant Action must be a string.', + 'any.required': 'Complainant Action is required.', + }), + short_desc: Joi.string().required().messages({ + 'string.base': 'Complainant Action: Short description must be a string.', + 'any.required': 'Complainant Action: Short description is required.', + }), + updated_at: Joi.string().isoDate().required().messages({ + 'string.base': 'Complainant Action: Updated at must be a valid ISO date string.', + 'string.isoDate': 'Complainant Action: Updated at must be a valid ISO date string.', + 'any.required': 'Complainant Action: Updated at is required.', + }), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required().messages({ + 'string.base': 'Updated By: Organization name must be a string.', + 'any.required': 'Updated By: Organization name is required.', + }), + }).required(), + contact: Joi.object({ + phone: Joi.string().required().messages({ + 'string.base': 'Updated By: Contact phone must be a string.', + 'any.required': 'Updated By: Contact phone is required.', + }), + email: Joi.string().email().required().messages({ + 'string.base': 'Updated By: Contact email must be a string.', + 'string.email': 'Updated By: Contact email must be a valid email address.', + 'any.required': 'Updated By: Contact email is required.', + }), + }).required(), + person: Joi.object({ + name: Joi.string().required().messages({ + 'string.base': 'Updated By: Person name must be a string.', + 'any.required': 'Updated By: Person name is required.', + }), + }).required(), + }).required(), + }), + ) + .required(), + }).required(), + created_at: Joi.string().isoDate().required().messages({ + 'string.base': 'Created at must be a valid ISO date string.', + 'string.isoDate': 'Created at must be a valid ISO date string.', + 'any.required': 'Created at is required.', + }), + updated_at: Joi.string().isoDate().required().messages({ + 'string.base': 'Updated at must be a valid ISO date string.', + 'string.isoDate': 'Updated at must be a valid ISO date string.', + 'any.required': 'Updated at is required.', + }), + }).required(), + }) + .required() + .messages({ + 'any.required': 'Message is required.', + }), +}); + +export default issueSchema; diff --git a/utilities/ondc-igm-sdk/src/utils/schema/issueStatus.scehma.ts b/utilities/ondc-igm-sdk/src/utils/schema/issueStatus.scehma.ts new file mode 100644 index 0000000..26e29d4 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/issueStatus.scehma.ts @@ -0,0 +1,63 @@ +import Joi from 'joi'; + +const IssueStatusSchema = Joi.object({ + context: Joi.object({ + domain: Joi.string().required().messages({ + 'any.required': 'Domain is required', + }), + country: Joi.string().required().messages({ + 'any.required': 'Country is required', + }), + city: Joi.string().required().messages({ + 'any.required': 'City is required', + }), + action: Joi.string().required().messages({ + 'any.required': 'Action is required', + }), + core_version: Joi.string().required().messages({ + 'any.required': 'Core version is required', + }), + bap_id: Joi.string().required().messages({ + 'any.required': 'BAP ID is required', + }), + bap_uri: Joi.string().required().messages({ + 'any.required': 'BAP URI is required', + 'string.uri': 'BAP URI must be a valid URI', + }), + bpp_id: Joi.string().required().messages({ + 'any.required': 'BPP ID is required', + }), + bpp_uri: Joi.string().required().messages({ + 'any.required': 'BPP URI is required', + 'string.uri': 'BPP URI must be a valid URI', + }), + transaction_id: Joi.string().required().messages({ + 'any.required': 'Transaction ID is required', + }), + message_id: Joi.string().required().messages({ + 'any.required': 'Message ID is required', + }), + timestamp: Joi.string().isoDate().required().messages({ + 'any.required': 'Timestamp is required', + 'string.isoDate': 'Timestamp must be a valid ISO date', + }), + ttl: Joi.string().required().messages({ + 'any.required': 'TTL is required', + }), + }) + .required() + .messages({ + 'any.required': 'Context is required', + }), + message: Joi.object({ + issue_id: Joi.string().required().messages({ + 'any.required': 'Issue ID is required', + }), + }) + .required() + .messages({ + 'any.required': 'Message is required', + }), +}); + +export default IssueStatusSchema; diff --git a/utilities/ondc-igm-sdk/src/utils/schema/logistics.issue.schema.ts b/utilities/ondc-igm-sdk/src/utils/schema/logistics.issue.schema.ts new file mode 100644 index 0000000..a819070 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/logistics.issue.schema.ts @@ -0,0 +1,137 @@ +import Joi from 'joi'; + +const LogisticsIssueSchema = Joi.object({ + context: Joi.object({ + domain: Joi.string().required(), + country: Joi.string().required(), + city: Joi.string().required(), + action: Joi.string().required(), + core_version: Joi.string().required(), + bap_id: Joi.string().required(), + bap_uri: Joi.string().required(), + bpp_id: Joi.string().required(), + bpp_uri: Joi.string().required(), + transaction_id: Joi.string().required(), + message_id: Joi.string().required(), + timestamp: Joi.string().isoDate().required(), + ttl: Joi.string().required(), + }).required(), + + message: Joi.object({ + issue: Joi.object({ + id: Joi.string().required(), + category: Joi.string().required(), + sub_category: Joi.string().required(), + complainant_info: Joi.object({ + person: Joi.object({ + name: Joi.string().required(), + }).required(), + contact: Joi.object({ + phone: Joi.string().required(), + email: Joi.string().email().required(), + }).required(), + }).required(), + + order_details: Joi.object({ + id: Joi.string().uuid().required(), + state: Joi.string().required(), + items: Joi.array() + .items( + Joi.object({ + id: Joi.string().required(), + quantity: Joi.number().required(), + }), + ) + .required(), + fulfillments: Joi.array() + .items( + Joi.object({ + id: Joi.string().required(), + state: Joi.string().required(), + }), + ) + .required(), + provider_id: Joi.string().required(), + merchant_order_id: Joi.string(), + }).required(), + + description: Joi.object({ + short_desc: Joi.string().required(), + long_desc: Joi.string().required(), + additional_desc: Joi.object({ + url: Joi.string().required(), + content_type: Joi.string().required(), + }).required(), + images: Joi.array().items(Joi.string()).required(), + }).required(), + + source: Joi.object({ + network_participant_id: Joi.string().required(), + type: Joi.string().required(), + }).required(), + + expected_response_time: Joi.object({ + duration: Joi.string().required(), + }).required(), + + expected_resolution_time: Joi.object({ + duration: Joi.string().required(), + }).required(), + + status: Joi.string().required(), + issue_type: Joi.string().required(), + + issue_actions: Joi.object({ + complainant_actions: Joi.array() + .items( + Joi.object({ + complainant_action: Joi.string().required(), + short_desc: Joi.string().required(), + updated_at: Joi.string().isoDate().required(), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required(), + }).required(), + contact: Joi.object({ + phone: Joi.string().required(), + email: Joi.string().email().required(), + }).required(), + person: Joi.object({ + name: Joi.string().required(), + }).required(), + }).required(), + }), + ) + .required(), + + respondent_actions: Joi.array() + .items( + Joi.object({ + respondent_action: Joi.string().required(), + short_desc: Joi.string().required(), + updated_at: Joi.string().isoDate().required(), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required(), + }).required(), + contact: Joi.object({ + phone: Joi.string().required(), + email: Joi.string().email().required(), + }).required(), + person: Joi.object({ + name: Joi.string().required(), + }).required(), + }).required(), + cascaded_level: Joi.number().required(), + }), + ) + .required(), + }).required(), + + created_at: Joi.string().isoDate().required(), + updated_at: Joi.string().isoDate().required(), + }).required(), + }).required(), +}); + +export default LogisticsIssueSchema; diff --git a/utilities/ondc-igm-sdk/src/utils/schema/logistics.onIssue.schema.ts b/utilities/ondc-igm-sdk/src/utils/schema/logistics.onIssue.schema.ts new file mode 100644 index 0000000..f422c53 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/logistics.onIssue.schema.ts @@ -0,0 +1,137 @@ +import Joi from 'joi'; + +const LogisticOnIssueSchema = Joi.object({ + context: Joi.object({ + domain: Joi.string().required(), + country: Joi.string().required(), + city: Joi.string().required(), + action: Joi.string().required(), + core_version: Joi.string().required(), + bap_id: Joi.string().required(), + bap_uri: Joi.string().required(), + bpp_id: Joi.string().required(), + bpp_uri: Joi.string().required(), + transaction_id: Joi.string().required(), + message_id: Joi.string().required(), + timestamp: Joi.string().isoDate().required(), + }).required(), + + message: Joi.object({ + issue: Joi.object({ + id: Joi.string().required(), + category: Joi.string().required(), + sub_category: Joi.string().required(), + complainant_info: Joi.object({ + person: Joi.object({ + name: Joi.string().required(), + }).required(), + contact: Joi.object({ + phone: Joi.string().required(), + email: Joi.string().email().required(), + }).required(), + }).required(), + order_details: Joi.object({ + id: Joi.string().uuid().required(), + state: Joi.string().required(), + items: Joi.array() + .items( + Joi.object({ + id: Joi.string().required(), + quantity: Joi.number().integer().required(), + }), + ) + .required(), + fulfillments: Joi.array() + .items( + Joi.object({ + id: Joi.string().required(), + state: Joi.string().required(), + }), + ) + .required(), + provider_id: Joi.string().required(), + merchant_order_id: Joi.string(), + }).required(), + description: Joi.object({ + short_desc: Joi.string().required(), + long_desc: Joi.string().required(), + additional_desc: Joi.object({ + url: Joi.string().uri().required(), + content_type: Joi.string().required(), + }).required(), + images: Joi.array().items(Joi.string().uri()).required(), + }).required(), + source: Joi.object({ + network_participant_id: Joi.string().required(), + type: Joi.string().required(), + }).required(), + expected_response_time: Joi.object({ + duration: Joi.string() + .regex(/^PT\d+[HS]$/) + .required() + .messages({ + 'string.pattern.base': 'Expected response time must be in ISO 8601 duration format (e.g., PT2H)', + }), + }).required(), + expected_resolution_time: Joi.object({ + duration: Joi.string() + .regex(/^P\d+D$/) + .required() + .messages({ + 'string.pattern.base': 'Expected resolution time must be in ISO 8601 duration format (e.g., P1D)', + }), + }).required(), + status: Joi.string().required(), + issue_type: Joi.string().required(), + issue_actions: Joi.object({ + complainant_actions: Joi.array() + .items( + Joi.object({ + complainant_action: Joi.string().required(), + short_desc: Joi.string().required(), + updated_at: Joi.string().isoDate().required(), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required(), + }).required(), + contact: Joi.object({ + phone: Joi.string().required(), + email: Joi.string().email().required(), + }).required(), + person: Joi.object({ + name: Joi.string().required(), + }).required(), + }).required(), + }), + ) + .required(), + respondent_actions: Joi.array() + .items( + Joi.object({ + respondent_action: Joi.string().required(), + short_desc: Joi.string().required(), + updated_at: Joi.string().isoDate().required(), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required(), + }).required(), + contact: Joi.object({ + phone: Joi.string().required(), + email: Joi.string().email().required(), + }).required(), + person: Joi.object({ + name: Joi.string().required(), + }).required(), + }).required(), + cascaded_level: Joi.number().integer().required(), + }), + ) + .required(), + }).required(), + created_at: Joi.string().isoDate().required(), + updated_at: Joi.string().isoDate().required(), + }).required(), + }).required(), +}); + +export default LogisticOnIssueSchema; diff --git a/utilities/ondc-igm-sdk/src/utils/schema/on_issue.schema.ts b/utilities/ondc-igm-sdk/src/utils/schema/on_issue.schema.ts new file mode 100644 index 0000000..84885c2 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/schema/on_issue.schema.ts @@ -0,0 +1,72 @@ +import Joi from 'joi'; + +const customMessages = { + 'string.base': '{{#label}} must be a string', + 'string.uri': '{{#label}} must be a valid URI', + 'string.isoDate': '{{#label}} must be a valid ISO date', + 'string.email': '{{#label}} must be a valid email address', + 'number.base': '{{#label}} must be a number', + 'array.base': '{{#label}} must be an array', +}; + +const OnIssueSchema = Joi.object({ + context: Joi.object({ + domain: Joi.string().required().messages(customMessages), + country: Joi.string().required().messages(customMessages), + city: Joi.string().required().messages(customMessages), + action: Joi.string().required().messages(customMessages), + core_version: Joi.string().required().messages(customMessages), + bap_id: Joi.string().required().messages(customMessages), + bap_uri: Joi.string().required().messages(customMessages), + bpp_id: Joi.string().required().messages(customMessages), + bpp_uri: Joi.string().required().messages(customMessages), + transaction_id: Joi.string().required().messages(customMessages), + message_id: Joi.string().required().messages(customMessages), + timestamp: Joi.string().isoDate().required().messages(customMessages), + }).required(), + message: Joi.object({ + issue: Joi.object({ + id: Joi.string().required().messages(customMessages), + issue_actions: Joi.object({ + respondent_actions: Joi.array().items( + Joi.object({ + respondent_action: Joi.string().required().messages(customMessages), + short_desc: Joi.string().required().messages(customMessages), + updated_at: Joi.string().isoDate().required().messages(customMessages), + updated_by: Joi.object({ + org: Joi.object({ + name: Joi.string().required().messages(customMessages), + }) + .required() + .messages(customMessages), + contact: Joi.object({ + phone: Joi.string().required().messages(customMessages), + email: Joi.string().email().required().messages(customMessages), + }) + .required() + .messages(customMessages), + person: Joi.object({ + name: Joi.string().required().messages(customMessages), + }) + .required() + .messages(customMessages), + }) + .required() + .messages(customMessages), + cascaded_level: Joi.number().required().messages(customMessages), + }), + ), + }) + .required() + .messages(customMessages), + created_at: Joi.string().isoDate().required().messages(customMessages), + updated_at: Joi.string().isoDate().required().messages(customMessages), + }) + .required() + .messages(customMessages), + }) + .required() + .messages(customMessages), +}); + +export default OnIssueSchema; diff --git a/utilities/ondc-igm-sdk/src/utils/validator.schema.ts b/utilities/ondc-igm-sdk/src/utils/validator.schema.ts new file mode 100644 index 0000000..006eb75 --- /dev/null +++ b/utilities/ondc-igm-sdk/src/utils/validator.schema.ts @@ -0,0 +1,16 @@ +import { Schema, ValidationError } from 'joi'; + +/** + * Performs schema validation on the provided data using the given schema definition. + * + * @param schema - The schema definition used for validation. + * @param data - The data to be validated against the schema. + * @returns A `ValidationError` object if the data fails validation, or `undefined` if the data is valid. + * @template T - The type of data to be validated. + */ + +export function SchemaValidator({ schema, data }: { schema: Schema; data: T }): ValidationError | undefined { + const { error } = schema.validate(data, { abortEarly: false }); + + return error; +} diff --git a/utilities/ondc-igm-sdk/tsconfig.json b/utilities/ondc-igm-sdk/tsconfig.json new file mode 100644 index 0000000..1e8cfdd --- /dev/null +++ b/utilities/ondc-igm-sdk/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "commonjs", + "declaration": true, + "outDir": "./lib", + "strict": true, + "esModuleInterop": true + }, + "include": ["src"], + "exclude": ["node_modules", "**/__tests__/*"] +} diff --git a/utilities/ondc-igm-sdk/tslint.json b/utilities/ondc-igm-sdk/tslint.json new file mode 100644 index 0000000..267f369 --- /dev/null +++ b/utilities/ondc-igm-sdk/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": ["tslint:recommended", "tslint-config-prettier"] +} From 21acc66da783213cfe0cd48c5e8946035ebae8c7 Mon Sep 17 00:00:00 2001 From: Robin Date: Fri, 24 May 2024 02:59:36 +0530 Subject: [PATCH 217/228] chore: removed dsstore file --- utilities/ondc-igm-sdk/src/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 utilities/ondc-igm-sdk/src/.DS_Store diff --git a/utilities/ondc-igm-sdk/src/.DS_Store b/utilities/ondc-igm-sdk/src/.DS_Store deleted file mode 100644 index aa2dbf0d048851ce28a74248bb0a0e1c24cf528c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKy-EW?5T4aUVr)`c$rYA1K|u=xXE?DE0%^3%pCp0A3;F5q2?TAdd=U#fA3@*2 z2e9{>*)`cSIkXay8QA@n*_qw%zTDnqiO5uEoib60hze+oxgxq1#`D~kY|VK%*~l7G zYSJ}LX)@?8MXN&lve#t%!_&e;Y zRJlmc`W&MC{@d-5aPabd2CE~|`+vSLOhfIDD}b8KR@kzry(*vzr~-2Z`1=r`F@_Ek zi}L9}CszPq4sJ1wrDg*Ib^t?%iA8u|#-;*os&Q8gW7FXeTwLfdv1rrD$j(^D?QGl) z#mMgP2NF)UGTX8Cs(>o6P+;8-OI-g?v+w_l1RbdYs=&Wfz~rKORK;Vt+Pd_BTx$cg q1{xd3B^D(Goh!#O;8MJeCWg6y2f)x_Vi6vg{t*xvv{MCsRe=xG4v{JV From 0399412d3368acb05bea10bc528588b4eb22c24d Mon Sep 17 00:00:00 2001 From: Mohd Ahsan <63741546+mofahsan@users.noreply.github.com> Date: Thu, 30 May 2024 13:41:04 +0530 Subject: [PATCH 218/228] fix : signature mismatch between python and other utilities due to directly using json text without minifying --- utilities/signing_and_verification/python/cryptic_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/utilities/signing_and_verification/python/cryptic_utils.py b/utilities/signing_and_verification/python/cryptic_utils.py index cab39c0..4a4d6eb 100644 --- a/utilities/signing_and_verification/python/cryptic_utils.py +++ b/utilities/signing_and_verification/python/cryptic_utils.py @@ -15,6 +15,8 @@ f = open(os.getenv("REQUEST_BODY_PATH", "request_body_raw_text.txt"), "r") request_body_raw_text = f.read() +request_body_raw_text = json.loads(request_body_raw_text) # parse the string into a python dictionary object +request_body_raw_text = json.dumps(request_body_raw_text, separators=(',', ':')) #minify the payload to remove any extra spaces and line breaks def hash_message(msg: str): HASHER = nacl.hash.blake2b From cea0ad6dfd600b700ce06c6d61013f195ab02b96 Mon Sep 17 00:00:00 2001 From: Nishtha Monga Date: Wed, 19 Jun 2024 13:57:11 +0530 Subject: [PATCH 219/228] Fix: Utility fixes in functions , missing composer and env file --- .../signing_and_verification/php/.env.example | 9 + .../signing_and_verification/php/.gitignore | 4 +- .../php/composer.json | 27 ++ .../php/src/index.php | 31 +- .../utils/ECPublicKeyAlgorithmIdentifier.php | 303 ++++++++++++++++++ .../src/utils/Ed25519AlgorithmIdentifier.php | 44 +++ .../src/utils/Ed448AlgorithmIdentifier.php | 44 +++ .../utils/RFC8410EdAlgorithmIdentifier.php | 59 ++++ .../src/utils/RFC8410XAlgorithmIdentifier.php | 53 +++ .../RSAEncryptionAlgorithmIdentifier.php | 68 ++++ .../src/utils/X25519AlgorithmIdentifier.php | 31 ++ .../php/src/utils/X448AlgorithmIdentifier.php | 29 ++ 12 files changed, 694 insertions(+), 8 deletions(-) create mode 100644 utilities/signing_and_verification/php/.env.example create mode 100644 utilities/signing_and_verification/php/composer.json create mode 100644 utilities/signing_and_verification/php/src/utils/ECPublicKeyAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/Ed25519AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/Ed448AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/RFC8410EdAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/RFC8410XAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/RSAEncryptionAlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/X25519AlgorithmIdentifier.php create mode 100644 utilities/signing_and_verification/php/src/utils/X448AlgorithmIdentifier.php diff --git a/utilities/signing_and_verification/php/.env.example b/utilities/signing_and_verification/php/.env.example new file mode 100644 index 0000000..ee82cbf --- /dev/null +++ b/utilities/signing_and_verification/php/.env.example @@ -0,0 +1,9 @@ +SIGNING_PRIV_KEY="173R1y60uRfoYE4U/u2yah+tGZfDKcRHq+7jFWf+lzYldbkqOJM6fe37yK1G3L0QliSf0Lg8V40CdrdXWguSHw==" +SIGNING_PUB_KEY="JXW5KjiTOn3t+8itRty9EJYkn9C4PFeNAna3V1oLkh8=" +ENC_PUB_KEY="MCowBQYDK2VuAyEATyMZS0JgITqabWn1BE1axD/ftEwDBpt3ui/29+ylaUc=" +ENC_PRIV_KEY="MC4CAQAwBQYDK2VuBCIEIJ8lqYi12VF9CGYvCLPcudO2Pb1JdHI7R9ovOtliFN3d" +COUNTERPARTY_PUB_KEY="MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=" +SUBSCRIBER_ID="abc.com" +UNIQUE_KEY_ID="e0b3cefa-e46a-4273-a15b-4f195ee9e07b" +AUTH_HEADER='Signature keyId="abc.com|e0b3cefa-e46a-4273-a15b-4f195ee9e07b|ed25519",algorithm="ed25519",created="1718784841",expires="1718788441",headers="(created) (expires) digest",signature="WA40jyUjHXIlVko3+AhjrLHHRc3sPZ3GLZRsPeaik3yfelSd3fQ2okUjG9TS2JnoTJZYkuig4JKQcWAGszzpBQ=="' +REQUEST_BODY={"context":{"domain":"nic2004:60212","country":"IND","city":"Kochi","action":"search","core_version":"0.9.1","bap_id":"bap.stayhalo.in","bap_uri":"https://8f9f-49-207-209-131.ngrok.io/protocol/","transaction_id":"e6d9f908-1d26-4ff3-a6d1-3af3d3721054","message_id":"a2fe6d52-9fe4-4d1a-9d0b-dccb8b48522d","timestamp":"2022-01-04T09:17:55.971Z","ttl":"P1M"},"message":{"intent":{"fulfillment":{"start":{"location":{"gps":"10.108768, 76.347517"}},"end":{"location":{"gps":"10.102997, 76.353480"}}}}}} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/.gitignore b/utilities/signing_and_verification/php/.gitignore index 546d906..27fad11 100644 --- a/utilities/signing_and_verification/php/.gitignore +++ b/utilities/signing_and_verification/php/.gitignore @@ -470,4 +470,6 @@ composer.lock ##### SASS .sass-cache/ *.css.map -*.sass.map \ No newline at end of file +*.sass.map + +.env \ No newline at end of file diff --git a/utilities/signing_and_verification/php/composer.json b/utilities/signing_and_verification/php/composer.json new file mode 100644 index 0000000..041881f --- /dev/null +++ b/utilities/signing_and_verification/php/composer.json @@ -0,0 +1,27 @@ +{ + "name": "charnpreet/subscription", + "type": "project", + "autoload": { + "psr-4": { + "Charnpreet\\Subscription\\": "src/", + "Custom\\AlgorithmIdentifier\\Asymmetric\\": "src/utils" + } + }, + "authors": [ + { + "name": "b" + } + ], + "require": { + "sop/crypto-types": "^0.3.0", + "phpseclib/phpseclib": "^3.0", + "vlucas/phpdotenv": "^5.6", + "ramsey/uuid": "^4.7", + "sop/asn1": "^4.1", + "sop/crypto-encoding": "^0.3.0", + "sop/x501": "^0.6.1" + }, + "scripts": { + "start": "php -f src/index.php --" + } + } diff --git a/utilities/signing_and_verification/php/src/index.php b/utilities/signing_and_verification/php/src/index.php index 07d265d..386badb 100644 --- a/utilities/signing_and_verification/php/src/index.php +++ b/utilities/signing_and_verification/php/src/index.php @@ -4,7 +4,7 @@ use phpseclib3\Crypt\AES; use Sop\ASN1\Type\Primitive\BitString; -use Sop\CryptoTypes\AlgorithmIdentifier\Asymmetric\X25519AlgorithmIdentifier; +use Custom\AlgorithmIdentifier\Asymmetric\X25519AlgorithmIdentifier; use Sop\CryptoTypes\Asymmetric\OneAsymmetricKey; use Sop\CryptoTypes\Asymmetric\PublicKeyInfo; @@ -40,9 +40,25 @@ function sign_response(string $signing_key, string $private_key): string function verify_response(string $signature, string $signing_key, string $public_key): bool { - return sodium_crypto_sign_verify_detached(base64_decode($signature), $signing_key, base64_decode($public_key)); + $decoded_public_key = base64_decode($public_key); + + if ($decoded_public_key === false) { + throw new Exception('Failed to decode public key from base64.'); + } + + // Check if the public key has the correct length + if (strlen($decoded_public_key) !== SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES) { + throw new Exception('The public key is not the correct length.'); + } + + // Verify the signature + $verification_result = sodium_crypto_sign_verify_detached(base64_decode($signature), $signing_key, $decoded_public_key); + echo "Verification Result: ", $verification_result ? 'True' : 'False', PHP_EOL; + + return $verification_result; } + function create_authorisation_header(string $request_body, string $created = null, string $expires = null) { $now = new DateTime(); @@ -81,14 +97,15 @@ function get_filter_dict(string $filter_string) function verify_authorisation_header(string $auth_header, string $request_body_str, string $public_key): bool { - $auth_header = str_replace("Signature ", "", $auth_header); + $auth_header = str_replace("Signature ", "", $_ENV['AUTH_HEADER']); + $header_parts = get_filter_dict($auth_header); $created = (int) $header_parts["created"]; $expires = (int) $header_parts["expires"]; $now = new DateTime(); if ($created <= $now->getTimestamp() && $expires >= $now->getTimestamp()) { - $signing_key = create_signing_string(hash_msg($request_body_str), $created, $expires); + $signing_key = create_signing_string(hash_msg($_ENV['REQUEST_BODY']), $created, $expires); return verify_response($header_parts['signature'], $signing_key, $public_key); } return false; @@ -150,16 +167,16 @@ function main(array $args) gen_keys(); break; case "-e": - echo encrypt($_ENV['ENC_PRIV_KEY'], $_ENV['COUNTERPARTY_PUB_KEY'], $args[2]); + echo encrypt($_ENV['ENC_PRIV_KEY'], $_ENV['ENC_PUB_KEY'], $args[2]); break; case "-d": - echo decrypt($_ENV['ENC_PRIV_KEY'], $_ENV['ENC_PUB_KEY'], $args[2]); + echo decrypt($_ENV['ENC_PRIV_KEY'], $_ENV['COUNTERPARTY_PUB_KEY'], $args[2]); break; case "-s": echo create_authorisation_header($_ENV['REQUEST_BODY']); break; case "-v": - echo verify_authorisation_header($_ENV['AUTH_HEADER'] || '', $_ENV['REQUEST_BODY'] || '', $_ENV["COUNTERPARTY_SIGNING_PUB_KEY"]); + echo verify_authorisation_header($_ENV['AUTH_HEADER'] || '', $_ENV['REQUEST_BODY'] || '', $_ENV["SIGNING_PUB_KEY"]); break; default: echo "$args[1] is not a valid argument: please check" . "\n"; diff --git a/utilities/signing_and_verification/php/src/utils/ECPublicKeyAlgorithmIdentifier.php b/utilities/signing_and_verification/php/src/utils/ECPublicKeyAlgorithmIdentifier.php new file mode 100644 index 0000000..367af2d --- /dev/null +++ b/utilities/signing_and_verification/php/src/utils/ECPublicKeyAlgorithmIdentifier.php @@ -0,0 +1,303 @@ + 192, + self::CURVE_PRIME192V2 => 192, + self::CURVE_PRIME192V3 => 192, + self::CURVE_PRIME239V1 => 239, + self::CURVE_PRIME239V2 => 239, + self::CURVE_PRIME239V3 => 239, + self::CURVE_PRIME256V1 => 256, + self::CURVE_SECP112R1 => 112, + self::CURVE_SECP112R2 => 112, + self::CURVE_SECP128R1 => 128, + self::CURVE_SECP128R2 => 128, + self::CURVE_SECP160K1 => 160, + self::CURVE_SECP160R1 => 160, + self::CURVE_SECP160R2 => 160, + self::CURVE_SECP192K1 => 192, + self::CURVE_SECP224K1 => 224, + self::CURVE_SECP224R1 => 224, + self::CURVE_SECP256K1 => 256, + self::CURVE_SECP384R1 => 384, + self::CURVE_SECP521R1 => 521, + ]; + + /** + * OID of the named curve. + * + * @var string + */ + protected $_namedCurve; + + /** + * Constructor. + * + * @param string $named_curve Curve identifier + */ + public function __construct(string $named_curve) + { + $this->_oid = self::OID_EC_PUBLIC_KEY; + $this->_namedCurve = $named_curve; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'ecPublicKey'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $named_curve = $params->asObjectIdentifier()->oid(); + return new self($named_curve); + } + + /** + * Get OID of the named curve. + */ + public function namedCurve(): string + { + return $this->_namedCurve; + } + + /** + * {@inheritdoc} + * + * @return ObjectIdentifier + */ + protected function _paramsASN1(): ?Element + { + return new ObjectIdentifier($this->_namedCurve); + } +} diff --git a/utilities/signing_and_verification/php/src/utils/Ed25519AlgorithmIdentifier.php b/utilities/signing_and_verification/php/src/utils/Ed25519AlgorithmIdentifier.php new file mode 100644 index 0000000..f7ccb13 --- /dev/null +++ b/utilities/signing_and_verification/php/src/utils/Ed25519AlgorithmIdentifier.php @@ -0,0 +1,44 @@ +_oid = self::OID_ED25519; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-Ed25519'; + } + + /** + * {@inheritdoc} + */ + public function supportsKeyAlgorithm(AlgorithmIdentifier $algo): bool + { + return self::OID_ED25519 === $algo->oid(); + } +} diff --git a/utilities/signing_and_verification/php/src/utils/Ed448AlgorithmIdentifier.php b/utilities/signing_and_verification/php/src/utils/Ed448AlgorithmIdentifier.php new file mode 100644 index 0000000..888ac6a --- /dev/null +++ b/utilities/signing_and_verification/php/src/utils/Ed448AlgorithmIdentifier.php @@ -0,0 +1,44 @@ +_oid = self::OID_ED448; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-Ed448'; + } + + /** + * {@inheritdoc} + */ + public function supportsKeyAlgorithm(AlgorithmIdentifier $algo): bool + { + return self::OID_ED448 === $algo->oid(); + } +} diff --git a/utilities/signing_and_verification/php/src/utils/RFC8410EdAlgorithmIdentifier.php b/utilities/signing_and_verification/php/src/utils/RFC8410EdAlgorithmIdentifier.php new file mode 100644 index 0000000..a86bacc --- /dev/null +++ b/utilities/signing_and_verification/php/src/utils/RFC8410EdAlgorithmIdentifier.php @@ -0,0 +1,59 @@ +_oid = self::OID_RSA_ENCRYPTION; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'rsaEncryption'; + } + + /** + * {@inheritdoc} + * + * @return self + */ + public static function fromASN1Params( + ?UnspecifiedType $params = null): SpecificAlgorithmIdentifier + { + if (!isset($params)) { + throw new \UnexpectedValueException('No parameters.'); + } + $params->asNull(); + return new self(); + } + + /** + * {@inheritdoc} + * + * @return NullType + */ + protected function _paramsASN1(): ?Element + { + return new NullType(); + } +} diff --git a/utilities/signing_and_verification/php/src/utils/X25519AlgorithmIdentifier.php b/utilities/signing_and_verification/php/src/utils/X25519AlgorithmIdentifier.php new file mode 100644 index 0000000..213e64c --- /dev/null +++ b/utilities/signing_and_verification/php/src/utils/X25519AlgorithmIdentifier.php @@ -0,0 +1,31 @@ +_oid = self::OID_X25519; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-X25519'; + } +} diff --git a/utilities/signing_and_verification/php/src/utils/X448AlgorithmIdentifier.php b/utilities/signing_and_verification/php/src/utils/X448AlgorithmIdentifier.php new file mode 100644 index 0000000..638b244 --- /dev/null +++ b/utilities/signing_and_verification/php/src/utils/X448AlgorithmIdentifier.php @@ -0,0 +1,29 @@ +_oid = self::OID_X448; + } + + /** + * {@inheritdoc} + */ + public function name(): string + { + return 'id-X448'; + } +} From f47f91272413637021611e96821eefaa16835bf0 Mon Sep 17 00:00:00 2001 From: Nishtha Monga Date: Thu, 20 Jun 2024 14:17:38 +0530 Subject: [PATCH 220/228] fix: env changed and error handling --- .../signing_and_verification/php/.env.example | 17 +++++++++-------- .../signing_and_verification/php/src/index.php | 3 ++- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/utilities/signing_and_verification/php/.env.example b/utilities/signing_and_verification/php/.env.example index ee82cbf..1a9c1f6 100644 --- a/utilities/signing_and_verification/php/.env.example +++ b/utilities/signing_and_verification/php/.env.example @@ -1,9 +1,10 @@ -SIGNING_PRIV_KEY="173R1y60uRfoYE4U/u2yah+tGZfDKcRHq+7jFWf+lzYldbkqOJM6fe37yK1G3L0QliSf0Lg8V40CdrdXWguSHw==" -SIGNING_PUB_KEY="JXW5KjiTOn3t+8itRty9EJYkn9C4PFeNAna3V1oLkh8=" -ENC_PUB_KEY="MCowBQYDK2VuAyEATyMZS0JgITqabWn1BE1axD/ftEwDBpt3ui/29+ylaUc=" -ENC_PRIV_KEY="MC4CAQAwBQYDK2VuBCIEIJ8lqYi12VF9CGYvCLPcudO2Pb1JdHI7R9ovOtliFN3d" -COUNTERPARTY_PUB_KEY="MCowBQYDK2VuAyEAduMuZgmtpjdCuxv+Nc49K0cB6tL/Dj3HZetvVN7ZekM=" -SUBSCRIBER_ID="abc.com" -UNIQUE_KEY_ID="e0b3cefa-e46a-4273-a15b-4f195ee9e07b" -AUTH_HEADER='Signature keyId="abc.com|e0b3cefa-e46a-4273-a15b-4f195ee9e07b|ed25519",algorithm="ed25519",created="1718784841",expires="1718788441",headers="(created) (expires) digest",signature="WA40jyUjHXIlVko3+AhjrLHHRc3sPZ3GLZRsPeaik3yfelSd3fQ2okUjG9TS2JnoTJZYkuig4JKQcWAGszzpBQ=="' +SIGNING_PRIV_KEY="your signing private key" +SIGNING_PUB_KEY="your signing public key" +COUNTERPARTY_SIGNING_PUB_KEY="the other party's signing public key" +ENC_PUB_KEY="your encryption/crypto public key" +ENC_PRIV_KEY="your encryption/crypto private key" +COUNTERPARTY_PUB_KEY="the other party's encryption/crypto public key" +SUBSCRIBER_ID="your subscriber id" +UNIQUE_KEY_ID="your ukid" +AUTH_HEADER="the auth header that is to be verified" REQUEST_BODY={"context":{"domain":"nic2004:60212","country":"IND","city":"Kochi","action":"search","core_version":"0.9.1","bap_id":"bap.stayhalo.in","bap_uri":"https://8f9f-49-207-209-131.ngrok.io/protocol/","transaction_id":"e6d9f908-1d26-4ff3-a6d1-3af3d3721054","message_id":"a2fe6d52-9fe4-4d1a-9d0b-dccb8b48522d","timestamp":"2022-01-04T09:17:55.971Z","ttl":"P1M"},"message":{"intent":{"fulfillment":{"start":{"location":{"gps":"10.108768, 76.347517"}},"end":{"location":{"gps":"10.102997, 76.353480"}}}}}} \ No newline at end of file diff --git a/utilities/signing_and_verification/php/src/index.php b/utilities/signing_and_verification/php/src/index.php index 386badb..4dce0df 100644 --- a/utilities/signing_and_verification/php/src/index.php +++ b/utilities/signing_and_verification/php/src/index.php @@ -98,7 +98,6 @@ function get_filter_dict(string $filter_string) function verify_authorisation_header(string $auth_header, string $request_body_str, string $public_key): bool { $auth_header = str_replace("Signature ", "", $_ENV['AUTH_HEADER']); - $header_parts = get_filter_dict($auth_header); $created = (int) $header_parts["created"]; $expires = (int) $header_parts["expires"]; @@ -107,6 +106,8 @@ function verify_authorisation_header(string $auth_header, string $request_body_s if ($created <= $now->getTimestamp() && $expires >= $now->getTimestamp()) { $signing_key = create_signing_string(hash_msg($_ENV['REQUEST_BODY']), $created, $expires); return verify_response($header_parts['signature'], $signing_key, $public_key); + }else{ + throw new Exception('The signature has expired.'); } return false; } From d6585ca623d6d94996d8b0507ffceedd870baee7 Mon Sep 17 00:00:00 2001 From: Nishtha Monga Date: Thu, 20 Jun 2024 14:23:08 +0530 Subject: [PATCH 221/228] chore: env and readme.md changed and error handling --- utilities/signing_and_verification/php/.env.example | 3 +-- utilities/signing_and_verification/php/README.md | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/utilities/signing_and_verification/php/.env.example b/utilities/signing_and_verification/php/.env.example index 1a9c1f6..11a8856 100644 --- a/utilities/signing_and_verification/php/.env.example +++ b/utilities/signing_and_verification/php/.env.example @@ -1,9 +1,8 @@ SIGNING_PRIV_KEY="your signing private key" SIGNING_PUB_KEY="your signing public key" -COUNTERPARTY_SIGNING_PUB_KEY="the other party's signing public key" ENC_PUB_KEY="your encryption/crypto public key" ENC_PRIV_KEY="your encryption/crypto private key" -COUNTERPARTY_PUB_KEY="the other party's encryption/crypto public key" +COUNTERPARTY_PUB_KEY="the other party's signing public key" SUBSCRIBER_ID="your subscriber id" UNIQUE_KEY_ID="your ukid" AUTH_HEADER="the auth header that is to be verified" diff --git a/utilities/signing_and_verification/php/README.md b/utilities/signing_and_verification/php/README.md index 38fb8f9..7d7f03b 100644 --- a/utilities/signing_and_verification/php/README.md +++ b/utilities/signing_and_verification/php/README.md @@ -28,10 +28,9 @@ composer install ```sh SIGNING_PRIV_KEY="your signing private key" SIGNING_PUB_KEY="your signing public key" -COUNTERPARTY_SIGNING_PUB_KEY="the other party's signing public key" ENC_PUB_KEY="your encryption/crypto public key" ENC_PRIV_KEY="your encryption/crypto private key" -COUNTERPARTY_PUB_KEY="the other party's encryption/crypto public key" +COUNTERPARTY_PUB_KEY="the other party's signing public key" SUBSCRIBER_ID="your subscriber id" UNIQUE_KEY_ID="your ukid" AUTH_HEADER="the auth header that is to be verified" From a37f56c9865803ccf37b14471c067f699f59a175 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Tue, 25 Jun 2024 16:12:00 +0530 Subject: [PATCH 222/228] added vlookup and signuature endpoint --- .../ondc/onboarding/utility/AppConfig.java | 12 ++++ .../java/ondc/onboarding/utility/Routes.java | 55 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java index 3c7c55d..477b63e 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java @@ -45,4 +45,16 @@ public String ondcPublicKey(){ public String gatewayUrl(){ return "https://staging.registry.ondc.org/subscribe"; } + + @Bean + public String vlookupUrl(){ + //Staging + return "https://staging.registry.ondc.org/vlookup"; + + //Preprod + //return "https://preprod.registry.ondc.org/ondc/vlookup"; + + //Prod + //return "https://prod.registry.ondc.org/vlookup"; + } } \ No newline at end of file diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java index 7991449..7b201d0 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java @@ -40,6 +40,10 @@ public class Routes extends Utils{ @Autowired private String ondcPublicKey; + + @Autowired + private String vlookupUrl; + @Autowired private String requestId; @@ -150,4 +154,55 @@ public ResponseEntity onSubscribe(@RequestBody JsonNode request) throws logger.info(response.toString()); return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(response.toString()); } + + @PostMapping("/sign") + public ResponseEntity sign(@RequestBody JsonNode request) { + + JsonNode searchParamsNode = request.get("search_parameters"); + if (searchParamsNode == null) { + return ResponseEntity.badRequest() + .contentType(MediaType.APPLICATION_JSON) + .body("{\"error\": \"search_parameters not found in request\"}"); + } + + String country = searchParamsNode.get("country").asText(); + String domain = searchParamsNode.get("domain").asText(); + String type = searchParamsNode.get("type").asText(); + String city = searchParamsNode.get("city").asText(); + String subscriberId = searchParamsNode.get("subscriber_id").asText(); + + String formattedString = String.format("%s|%s|%s|%s|%s", country, domain, type, city, subscriberId); + + String privateKeyBase64 = request.get("privatekey").asText(); + byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyBase64); + + String signature = sign(privateKeyBytes, formattedString.getBytes()); + + String jsonResponse = String.format("{\"signature\": \"%s\"}", signature); + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(jsonResponse); + } + + @PostMapping("/vlookup") + public ResponseEntity vLookup(@RequestBody JsonNode request) throws IOException, InterruptedException { + // Log the received JSON request + String requestString = request.toString(); + System.out.println("Received request: " + requestString); + + // Prepare HTTP request to vlookupUrl + HttpRequest httpRequest = HttpRequest.newBuilder() + .uri(URI.create(vlookupUrl)) + .POST(HttpRequest.BodyPublishers.ofString(requestString)) + .build(); + + // Send HTTP request and get the response + HttpClient httpClient = HttpClient.newHttpClient(); + HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); + + // Return the response from vlookupUrl back to the user + return ResponseEntity.ok() + .contentType(MediaType.APPLICATION_JSON) + .body(httpResponse.body()); + } } \ No newline at end of file From 415d0d792ea0d47bdd99d3c617596268c4bdbb7d Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 26 Jun 2024 22:19:23 +0530 Subject: [PATCH 223/228] updated readme --- utilities/on_subscibe-service/java/Readme.md | 36 +++++++++++++++++++ .../ondc/onboarding/utility/AppConfig.java | 3 +- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/utilities/on_subscibe-service/java/Readme.md b/utilities/on_subscibe-service/java/Readme.md index b9f0561..3eed378 100644 --- a/utilities/on_subscibe-service/java/Readme.md +++ b/utilities/on_subscibe-service/java/Readme.md @@ -89,3 +89,39 @@ curl --location 'localhost:8080/verify-header' \ --data-raw '{"value":{"test":"test"}},"public_key":"public_key","header":"Signature keyId=\"abc.com|ukid|ed25519\",algorithm=\"ed25519\",created=\"1712239689\",expires=\"1712539689\",headers=\"(created) (expires) digest\",signature=\"Gy5wiiJYGeNOBsiXJKo4OF7fSKR65zkxa/FJjgBgenmRplhq9vNewz/ivXDFegSnrdQK9U9T19Ta55J7Aa6RBw==\"" }' ``` + +### How to generate vlookup signature +To generate sigature for vlookup kindly use the following curl request: +``` +curl --location 'localhost:8080/sign' \ +--header 'Content-Type: application/json' \ +--data '{ + "privatekey": "private_key", + "search_parameters": { + "country": "IND", + "domain": "ONDC:RET11", + "type": "sellerApp", + "city": "std:079", + "subscriber_id": "subscriber_id" + } +}' +``` + +To Use vlookup +``` +curl --location 'localhost:8080/vlookup' \ +--header 'Content-Type: application/json' \ +--data '{ + "sender_subscriber_id": "sender_sigature_id", + "request_id": "LUmqWztvAH/S9UBqiYUMN/iwvYcYRz5mC/vVSTfxaYzafs8NCd94UcK2UQSa4lvw4y8WWjacJfxvDzEQGnmgAQ==", + "timestamp": "2024-06-26T16:45:46.745Z", + "signature": "BJkw0KsxSBTD4gJ0TwJpyOgM+seqbn9CdvOYQ/HUHvod38qazTYZBZ3gUsvYvQFlrKKU/vitUUXCDKlAgwoDCQ==", + "search_parameters": { + "country": "IND", + "domain": "ONDC:RET11", + "type": "sellerApp", + "city": "std:079", + "subscriber_id": "subscriber_id" + } +}' +``` diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java index 477b63e..cb3713d 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/AppConfig.java @@ -57,4 +57,5 @@ public String vlookupUrl(){ //Prod //return "https://prod.registry.ondc.org/vlookup"; } -} \ No newline at end of file +} + From 100a3dde97e855cb1d13591a29456ae8396d9147 Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Wed, 26 Jun 2024 22:27:03 +0530 Subject: [PATCH 224/228] removed comments --- .../java/src/main/java/ondc/onboarding/utility/Routes.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java index 7b201d0..e6b99cc 100644 --- a/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java +++ b/utilities/on_subscibe-service/java/src/main/java/ondc/onboarding/utility/Routes.java @@ -186,21 +186,17 @@ public ResponseEntity sign(@RequestBody JsonNode request) { @PostMapping("/vlookup") public ResponseEntity vLookup(@RequestBody JsonNode request) throws IOException, InterruptedException { - // Log the received JSON request String requestString = request.toString(); System.out.println("Received request: " + requestString); - // Prepare HTTP request to vlookupUrl HttpRequest httpRequest = HttpRequest.newBuilder() .uri(URI.create(vlookupUrl)) .POST(HttpRequest.BodyPublishers.ofString(requestString)) .build(); - // Send HTTP request and get the response HttpClient httpClient = HttpClient.newHttpClient(); HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString()); - // Return the response from vlookupUrl back to the user return ResponseEntity.ok() .contentType(MediaType.APPLICATION_JSON) .body(httpResponse.body()); From 51d21f85d6be032be3c013bfc47dbaa4de121227 Mon Sep 17 00:00:00 2001 From: Shivang Dudani Date: Thu, 4 Jul 2024 16:41:32 +0530 Subject: [PATCH 225/228] Vlookup in Python --- utilities/vlookup/python/README.md | 65 +++++++++++++ utilities/vlookup/python/main.py | 31 +++++++ utilities/vlookup/python/requirements.txt | 8 ++ utilities/vlookup/python/utils.py | 108 ++++++++++++++++++++++ 4 files changed, 212 insertions(+) create mode 100644 utilities/vlookup/python/README.md create mode 100644 utilities/vlookup/python/main.py create mode 100644 utilities/vlookup/python/requirements.txt create mode 100644 utilities/vlookup/python/utils.py diff --git a/utilities/vlookup/python/README.md b/utilities/vlookup/python/README.md new file mode 100644 index 0000000..4452c9a --- /dev/null +++ b/utilities/vlookup/python/README.md @@ -0,0 +1,65 @@ +# ONDC VLookup Service + +This repository contains a simple FASTAPI server that facilitates the ONDC (Open Network for Digital Commerce) VLookup service. The VLookup service allows you to perform lookups in the ONDC registry and obtain relevant information based on specified parameters. + +## Getting Started + +### Prerequisites + +- Python installed on your machine + +### Installation + +1. Clone this repository to your local machine. +2. Navigate to the project directory in the terminal. +3. Run `pip install -r requirements.txt` to install the required dependencies. + +### Usage + +1. Start the server by running `python -m uvicorn main:app --reload` in the terminal. +2. The server will run on http://localhost:8000. + +## Routes + +### VLookup + +Perform a VLookup operation by sending a POST request to `http://localhost:9900/vlookup`. The payload should be in the following format: + +```json +{ + "senderSubscriberId": "your_subscriber_id", + "privateKey": "your_private_key", + + //search parameters of the NP whose details need to be fetched from registry + + "domain": "ONDC:RET10", + "subscriberId": "subscriber_id", // subscriber_id you want to lookup + "country": "IND", // country + "type": "buyerApp", //buyerApp, sellerApp, gateway + "city": "std:022", // city code + "env": "staging" //staging,preprod,prod +} +``` + +## Important Note + +Make sure to replace the sample private key with your actual private key. + +## Dependencies + +- pybase64 +- datetime +- uuid +- requests +- PyNaCl +- fastapi +- uvicorn +- pydantic + +## Contributing + +Feel free to contribute to the development of this project by submitting pull requests. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/utilities/vlookup/python/main.py b/utilities/vlookup/python/main.py new file mode 100644 index 0000000..2c2dba1 --- /dev/null +++ b/utilities/vlookup/python/main.py @@ -0,0 +1,31 @@ +from fastapi import FastAPI +import uvicorn +from pydantic import BaseModel +import json +from utils import vlookup + +app = FastAPI() + +class VLookupRequest(BaseModel): + senderSubscriberId: str + privateKey: str + domain : str + subscriberId: str + country: str + type_: str + city: str + env: str + +@app.post("/vlookup") +def vlookup_func(request_data: VLookupRequest): + request_dict = request_data.model_dump() + + try: + result = vlookup(request_dict) + result = json.loads(result) + return result + except Exception as e: + raise e + +if __name__ == "__main__": + uvicorn.run(app, host="127.0.0.1", port=8000) diff --git a/utilities/vlookup/python/requirements.txt b/utilities/vlookup/python/requirements.txt new file mode 100644 index 0000000..1f4606d --- /dev/null +++ b/utilities/vlookup/python/requirements.txt @@ -0,0 +1,8 @@ +pybase64 +datetime +uuid +requests +PyNaCl +fastapi +uvicorn +pydantic \ No newline at end of file diff --git a/utilities/vlookup/python/utils.py b/utilities/vlookup/python/utils.py new file mode 100644 index 0000000..a6e4397 --- /dev/null +++ b/utilities/vlookup/python/utils.py @@ -0,0 +1,108 @@ +import base64 +from datetime import datetime, timezone +import uuid +import requests +import nacl.encoding; +import nacl.hash +from nacl.bindings import crypto_sign_ed25519_sk_to_seed +from nacl.signing import SigningKey +import json + +def create_signing_string(data): + country = data.get('country') + domain = data.get('domain') + type_ = data.get('type_') # 'type' is a reserved keyword in Python, using 'type_' instead + city = data.get('city') + subscriber_id = data.get('subscriberId') + return "|".join([country, domain, type_, city, subscriber_id]) + + +def get_env_details(env): + env_link = "" + if env == "preprod": + env_link = "https://preprod.registry.ondc.org/ondc/vlookup" + elif env == "prod": + env_link = "https://prod.registry.ondc.org/vlookup" + elif env == "staging": + env_link = "https://staging.registry.ondc.org/vlookup" + else: + raise ValueError("Unsupported environment") + return env_link + +def fetchRegistryResponse(request_id,timestamp,signature,search_parameters,sender_subscriber_id,envLink): + try: + payload = { + 'sender_subscriber_id': sender_subscriber_id, + 'request_id': str(request_id), + 'timestamp': timestamp, + 'search_parameters': search_parameters, + 'signature': signature + } + + # Make the HTTP POST request + json_data = json.loads(json.dumps(payload)) + response = requests.post(envLink,json=json_data) + return response + + except Exception as e: + raise e + +def getVLookUpData(signature,data): + requestId = uuid.uuid4() + timestamp = datetime.now(timezone.utc) + formatted_timestamp = timestamp.strftime('%Y-%m-%dT%H:%M:%S.%f')[:-3] + 'Z' + country = data.get('country') + domain = data.get('domain') + type_ = data.get('type_') # 'type' is a reserved keyword in Python, so using 'type_' instead + city = data.get('city') + subscriber_id = data.get('subscriberId') + + search_parameters = { + 'country': country, + 'domain': domain, + 'type': type_, + 'city': city, + 'subscriber_id': subscriber_id, + } + + sender_subscriber_id = data['senderSubscriberId'] + env_link = get_env_details(data['env']) + + try: + res = fetchRegistryResponse(requestId, + formatted_timestamp, + signature, + search_parameters, + sender_subscriber_id, + env_link + ) + return res + except Exception as e: + raise e + + + +def sign_response(signing_key, private_key): + private_key64 = base64.b64decode(private_key) + seed = crypto_sign_ed25519_sk_to_seed(private_key64) + signer = SigningKey(seed) + signed = signer.sign(bytes(signing_key, encoding='utf8')) + signature = base64.b64encode(signed.signature).decode() + return signature + + +def vlookup(data): + try: + private_key = data.get('privateKey') + signingString = create_signing_string(data) + signature = sign_response(signingString,private_key) + result = getVLookUpData(signature, data) + result = result.content + return result + + except Exception as e: + raise(e) + + + + From a9eed845137eb56eb465b3048a970e20e7f43fe1 Mon Sep 17 00:00:00 2001 From: Shivang Dudani Date: Thu, 4 Jul 2024 16:47:24 +0530 Subject: [PATCH 226/228] Readme change --- utilities/vlookup/python/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utilities/vlookup/python/README.md b/utilities/vlookup/python/README.md index 4452c9a..1f3e8f2 100644 --- a/utilities/vlookup/python/README.md +++ b/utilities/vlookup/python/README.md @@ -23,7 +23,7 @@ This repository contains a simple FASTAPI server that facilitates the ONDC (Open ### VLookup -Perform a VLookup operation by sending a POST request to `http://localhost:9900/vlookup`. The payload should be in the following format: +Perform a VLookup operation by sending a POST request to `http://localhost:8000/vlookup`. The payload should be in the following format: ```json { From 0e8e9872a413fe537fc519132799cda5656ec399 Mon Sep 17 00:00:00 2001 From: NishthaMonga <57255861+NishthaMonga@users.noreply.github.com> Date: Wed, 17 Jul 2024 13:03:39 +0530 Subject: [PATCH 227/228] Chore: Added package.json file --- utilities/on_subscibe-service/node/package.json | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 utilities/on_subscibe-service/node/package.json diff --git a/utilities/on_subscibe-service/node/package.json b/utilities/on_subscibe-service/node/package.json new file mode 100644 index 0000000..d18000f --- /dev/null +++ b/utilities/on_subscibe-service/node/package.json @@ -0,0 +1,17 @@ +{ + "name": "subscription_utility", + "version": "1.0.0", + "description": "This Node.js package facilitates the subscription process within the network. It includes hosting an HTML file and providing an on_subscribe endpoint.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "body-parser": "^1.20.2", + "crypto": "^1.0.1", + "express": "^4.19.2", + "libsodium-wrappers": "^0.7.14" + } +} From 6aa190f748a8cf8bab49a4550988829aec348480 Mon Sep 17 00:00:00 2001 From: extedcouD <89811591+extedcouD@users.noreply.github.com> Date: Wed, 24 Jul 2024 12:59:39 +0530 Subject: [PATCH 228/228] skd update --- utilities/ondc-crypto-sdk-nodejs/package.json | 2 +- utilities/ondc-crypto-sdk-nodejs/src/index.ts | 10 +++++++++- utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/utilities/ondc-crypto-sdk-nodejs/package.json b/utilities/ondc-crypto-sdk-nodejs/package.json index 54059bc..9bb5de7 100644 --- a/utilities/ondc-crypto-sdk-nodejs/package.json +++ b/utilities/ondc-crypto-sdk-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "ondc-crypto-sdk-nodejs", - "version": "2.1.0", + "version": "2.1.1", "description": "A crypto utility for exposing signing and verification functions by ONDC", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/utilities/ondc-crypto-sdk-nodejs/src/index.ts b/utilities/ondc-crypto-sdk-nodejs/src/index.ts index 2a1420c..54e97b0 100644 --- a/utilities/ondc-crypto-sdk-nodejs/src/index.ts +++ b/utilities/ondc-crypto-sdk-nodejs/src/index.ts @@ -1,10 +1,18 @@ -import { createAuthorizationHeader, isHeaderValid, createVLookupSignature } from './utility'; +import { + createAuthorizationHeader, + isHeaderValid, + createVLookupSignature, + verifyMessage, + signMessage, +} from './utility'; import { ICreateAuthorizationHeader, IsHeaderValid, CreateVLookupSignature } from './types'; export { createAuthorizationHeader, isHeaderValid, createVLookupSignature, + verifyMessage, + signMessage, ICreateAuthorizationHeader, IsHeaderValid, CreateVLookupSignature, diff --git a/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts b/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts index 5f01848..64d114c 100644 --- a/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts +++ b/utilities/ondc-crypto-sdk-nodejs/src/utility/index.ts @@ -82,7 +82,7 @@ const splitAuthHeader = (authHeader: string): GenericObject | IHeaderParts => { return parts; }; -const verifyMessage = async ({ signedString, signingString, publicKey }: IVerifyMessage) => { +export const verifyMessage = async ({ signedString, signingString, publicKey }: IVerifyMessage) => { try { await _sodium.ready; const sodium = _sodium;